AVT相机arm版本SDK
This commit is contained in:
346
Vimba_6_0/VimbaPython/Source/Tests/basic_tests/c_binding_test.py
Normal file
346
Vimba_6_0/VimbaPython/Source/Tests/basic_tests/c_binding_test.py
Normal file
@@ -0,0 +1,346 @@
|
||||
"""BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2019, Allied Vision Technologies GmbH
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import ctypes
|
||||
|
||||
from vimba.c_binding import *
|
||||
|
||||
|
||||
class VimbaCommonTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_decode_cstr_behavior(self):
|
||||
# Expected Behavior:
|
||||
# c_char_p() == ''
|
||||
# c_char_p(b'foo') == 'foo'
|
||||
|
||||
expected = ''
|
||||
actual = decode_cstr(ctypes.c_char_p())
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
expected = 'test'
|
||||
actual = decode_cstr(ctypes.c_char_p(b'test').value)
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_decode_flags_zero(self):
|
||||
# Expected Behavior: In case no bytes are set the
|
||||
# zero value of the Flag Enum must be returned
|
||||
|
||||
expected = (VmbFeatureFlags.None_,)
|
||||
actual = decode_flags(VmbFeatureFlags, 0)
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_decode_flags_some(self):
|
||||
# Expected Behavior: Given Integer must be decided correctly.
|
||||
# the order of the fields does not matter for this test.
|
||||
|
||||
expected = (
|
||||
VmbFeatureFlags.Write,
|
||||
VmbFeatureFlags.Read,
|
||||
VmbFeatureFlags.ModifyWrite
|
||||
)
|
||||
|
||||
input_data = 0
|
||||
|
||||
for val in expected:
|
||||
input_data |= int(val)
|
||||
|
||||
actual = decode_flags(VmbFeatureFlags, input_data)
|
||||
|
||||
# Convert both collections into a list and sort it.
|
||||
# That way order doesn't matter. It is only important that values are
|
||||
# decoded correctly.
|
||||
self.assertEqual(list(expected).sort(), list(actual).sort())
|
||||
|
||||
|
||||
class CBindingVimbaCTypesTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_enum_vmb_error(self):
|
||||
self.assertEqual(VmbError.Success, 0)
|
||||
self.assertEqual(VmbError.InternalFault, -1)
|
||||
self.assertEqual(VmbError.ApiNotStarted, -2)
|
||||
self.assertEqual(VmbError.NotFound, -3)
|
||||
self.assertEqual(VmbError.BadHandle, -4)
|
||||
self.assertEqual(VmbError.DeviceNotOpen, -5)
|
||||
self.assertEqual(VmbError.InvalidAccess, -6)
|
||||
self.assertEqual(VmbError.BadParameter, -7)
|
||||
self.assertEqual(VmbError.StructSize, -8)
|
||||
self.assertEqual(VmbError.MoreData, -9)
|
||||
self.assertEqual(VmbError.WrongType, -10)
|
||||
self.assertEqual(VmbError.InvalidValue, -11)
|
||||
self.assertEqual(VmbError.Timeout, -12)
|
||||
self.assertEqual(VmbError.Other, -13)
|
||||
self.assertEqual(VmbError.Resources, -14)
|
||||
self.assertEqual(VmbError.InvalidCall, -15)
|
||||
self.assertEqual(VmbError.NoTL, -16)
|
||||
self.assertEqual(VmbError.NotImplemented_, -17)
|
||||
self.assertEqual(VmbError.NotSupported, -18)
|
||||
self.assertEqual(VmbError.Incomplete, -19)
|
||||
self.assertEqual(VmbError.IO, -20)
|
||||
|
||||
def test_enum_vmb_pixel_format(self):
|
||||
self.assertEqual(VmbPixelFormat.Mono8, 0x01080001)
|
||||
self.assertEqual(VmbPixelFormat.Mono10, 0x01100003)
|
||||
self.assertEqual(VmbPixelFormat.Mono10p, 0x010A0046)
|
||||
self.assertEqual(VmbPixelFormat.Mono12, 0x01100005)
|
||||
self.assertEqual(VmbPixelFormat.Mono12Packed, 0x010C0006)
|
||||
self.assertEqual(VmbPixelFormat.Mono12p, 0x010C0047)
|
||||
self.assertEqual(VmbPixelFormat.Mono14, 0x01100025)
|
||||
self.assertEqual(VmbPixelFormat.Mono16, 0x01100007)
|
||||
self.assertEqual(VmbPixelFormat.BayerGR8, 0x01080008)
|
||||
self.assertEqual(VmbPixelFormat.BayerRG8, 0x01080009)
|
||||
self.assertEqual(VmbPixelFormat.BayerGB8, 0x0108000A)
|
||||
self.assertEqual(VmbPixelFormat.BayerBG8, 0x0108000B)
|
||||
self.assertEqual(VmbPixelFormat.BayerGR10, 0x0110000C)
|
||||
self.assertEqual(VmbPixelFormat.BayerRG10, 0x0110000D)
|
||||
self.assertEqual(VmbPixelFormat.BayerGB10, 0x0110000E)
|
||||
self.assertEqual(VmbPixelFormat.BayerBG10, 0x0110000F)
|
||||
self.assertEqual(VmbPixelFormat.BayerGR12, 0x01100010)
|
||||
self.assertEqual(VmbPixelFormat.BayerRG12, 0x01100011)
|
||||
self.assertEqual(VmbPixelFormat.BayerGB12, 0x01100012)
|
||||
self.assertEqual(VmbPixelFormat.BayerBG12, 0x01100013)
|
||||
self.assertEqual(VmbPixelFormat.BayerGR12Packed, 0x010C002A)
|
||||
self.assertEqual(VmbPixelFormat.BayerRG12Packed, 0x010C002B)
|
||||
self.assertEqual(VmbPixelFormat.BayerGB12Packed, 0x010C002C)
|
||||
self.assertEqual(VmbPixelFormat.BayerBG12Packed, 0x010C002D)
|
||||
self.assertEqual(VmbPixelFormat.BayerGR10p, 0x010A0056)
|
||||
self.assertEqual(VmbPixelFormat.BayerRG10p, 0x010A0058)
|
||||
self.assertEqual(VmbPixelFormat.BayerGB10p, 0x010A0054)
|
||||
self.assertEqual(VmbPixelFormat.BayerBG10p, 0x010A0052)
|
||||
self.assertEqual(VmbPixelFormat.BayerGR12p, 0x010C0057)
|
||||
self.assertEqual(VmbPixelFormat.BayerRG12p, 0x010C0059)
|
||||
self.assertEqual(VmbPixelFormat.BayerGB12p, 0x010C0055)
|
||||
self.assertEqual(VmbPixelFormat.BayerBG12p, 0x010C0053)
|
||||
self.assertEqual(VmbPixelFormat.BayerGR16, 0x0110002E)
|
||||
self.assertEqual(VmbPixelFormat.BayerRG16, 0x0110002F)
|
||||
self.assertEqual(VmbPixelFormat.BayerGB16, 0x01100030)
|
||||
self.assertEqual(VmbPixelFormat.BayerBG16, 0x01100031)
|
||||
self.assertEqual(VmbPixelFormat.Rgb8, 0x02180014)
|
||||
self.assertEqual(VmbPixelFormat.Bgr8, 0x02180015)
|
||||
self.assertEqual(VmbPixelFormat.Rgb10, 0x02300018)
|
||||
self.assertEqual(VmbPixelFormat.Bgr10, 0x02300019)
|
||||
self.assertEqual(VmbPixelFormat.Rgb12, 0x0230001A)
|
||||
self.assertEqual(VmbPixelFormat.Bgr12, 0x0230001B)
|
||||
self.assertEqual(VmbPixelFormat.Rgb14, 0x0230005E)
|
||||
self.assertEqual(VmbPixelFormat.Bgr14, 0x0230004A)
|
||||
self.assertEqual(VmbPixelFormat.Rgb16, 0x02300033)
|
||||
self.assertEqual(VmbPixelFormat.Bgr16, 0x0230004B)
|
||||
self.assertEqual(VmbPixelFormat.Argb8, 0x02200016)
|
||||
self.assertEqual(VmbPixelFormat.Rgba8, 0x02200016)
|
||||
self.assertEqual(VmbPixelFormat.Bgra8, 0x02200017)
|
||||
self.assertEqual(VmbPixelFormat.Rgba10, 0x0240005F)
|
||||
self.assertEqual(VmbPixelFormat.Bgra10, 0x0240004C)
|
||||
self.assertEqual(VmbPixelFormat.Rgba12, 0x02400061)
|
||||
self.assertEqual(VmbPixelFormat.Bgra12, 0x0240004E)
|
||||
self.assertEqual(VmbPixelFormat.Rgba14, 0x02400063)
|
||||
self.assertEqual(VmbPixelFormat.Bgra14, 0x02400050)
|
||||
self.assertEqual(VmbPixelFormat.Rgba16, 0x02400064)
|
||||
self.assertEqual(VmbPixelFormat.Bgra16, 0x02400051)
|
||||
self.assertEqual(VmbPixelFormat.Yuv411, 0x020C001E)
|
||||
self.assertEqual(VmbPixelFormat.Yuv422, 0x0210001F)
|
||||
self.assertEqual(VmbPixelFormat.Yuv444, 0x02180020)
|
||||
self.assertEqual(VmbPixelFormat.YCbCr411_8_CbYYCrYY, 0x020C003C)
|
||||
self.assertEqual(VmbPixelFormat.YCbCr422_8_CbYCrY, 0x02100043)
|
||||
self.assertEqual(VmbPixelFormat.YCbCr8_CbYCr, 0x0218003A)
|
||||
|
||||
def test_enum_vmb_interface(self):
|
||||
self.assertEqual(VmbInterface.Unknown, 0)
|
||||
self.assertEqual(VmbInterface.Firewire, 1)
|
||||
self.assertEqual(VmbInterface.Ethernet, 2)
|
||||
self.assertEqual(VmbInterface.Usb, 3)
|
||||
self.assertEqual(VmbInterface.CL, 4)
|
||||
self.assertEqual(VmbInterface.CSI2, 5)
|
||||
|
||||
def test_enum_vmb_access_mode(self):
|
||||
self.assertEqual(VmbAccessMode.None_, 0)
|
||||
self.assertEqual(VmbAccessMode.Full, 1)
|
||||
self.assertEqual(VmbAccessMode.Read, 2)
|
||||
self.assertEqual(VmbAccessMode.Config, 4)
|
||||
self.assertEqual(VmbAccessMode.Lite, 8)
|
||||
|
||||
def test_enum_vmb_feature_data(self):
|
||||
self.assertEqual(VmbFeatureData.Unknown, 0)
|
||||
self.assertEqual(VmbFeatureData.Int, 1)
|
||||
self.assertEqual(VmbFeatureData.Float, 2)
|
||||
self.assertEqual(VmbFeatureData.Enum, 3)
|
||||
self.assertEqual(VmbFeatureData.String, 4)
|
||||
self.assertEqual(VmbFeatureData.Bool, 5)
|
||||
self.assertEqual(VmbFeatureData.Command, 6)
|
||||
self.assertEqual(VmbFeatureData.Raw, 7)
|
||||
self.assertEqual(VmbFeatureData.None_, 8)
|
||||
|
||||
def test_enum_vmb_feature_persist(self):
|
||||
self.assertEqual(VmbFeaturePersist.All, 0)
|
||||
self.assertEqual(VmbFeaturePersist.Streamable, 1)
|
||||
self.assertEqual(VmbFeaturePersist.NoLUT, 2)
|
||||
|
||||
def test_enum_vmb_feature_visibility(self):
|
||||
self.assertEqual(VmbFeatureVisibility.Unknown, 0)
|
||||
self.assertEqual(VmbFeatureVisibility.Beginner, 1)
|
||||
self.assertEqual(VmbFeatureVisibility.Expert, 2)
|
||||
self.assertEqual(VmbFeatureVisibility.Guru, 3)
|
||||
self.assertEqual(VmbFeatureVisibility.Invisible, 4)
|
||||
|
||||
def test_enum_vmb_feature_flags(self):
|
||||
self.assertEqual(VmbFeatureFlags.None_, 0)
|
||||
self.assertEqual(VmbFeatureFlags.Read, 1)
|
||||
self.assertEqual(VmbFeatureFlags.Write, 2)
|
||||
self.assertEqual(VmbFeatureFlags.Volatile, 8)
|
||||
self.assertEqual(VmbFeatureFlags.ModifyWrite, 16)
|
||||
|
||||
def test_enum_vmb_frame_status(self):
|
||||
self.assertEqual(VmbFrameStatus.Complete, 0)
|
||||
self.assertEqual(VmbFrameStatus.Incomplete, -1)
|
||||
self.assertEqual(VmbFrameStatus.TooSmall, -2)
|
||||
self.assertEqual(VmbFrameStatus.Invalid, -3)
|
||||
|
||||
def test_enum_vmd_frame_flags(self):
|
||||
self.assertEqual(VmbFrameFlags.None_, 0)
|
||||
self.assertEqual(VmbFrameFlags.Dimension, 1)
|
||||
self.assertEqual(VmbFrameFlags.Offset, 2)
|
||||
self.assertEqual(VmbFrameFlags.FrameID, 4)
|
||||
self.assertEqual(VmbFrameFlags.Timestamp, 8)
|
||||
|
||||
|
||||
class VimbaCTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_call_vimba_c_valid(self):
|
||||
# Expectation for valid call: No exceptions, no errors
|
||||
expected_ver_info = (1, 9, 0)
|
||||
ver_info = VmbVersionInfo()
|
||||
|
||||
call_vimba_c('VmbVersionQuery', byref(ver_info), sizeof(ver_info))
|
||||
|
||||
ver_info = (ver_info.major, ver_info.minor, ver_info.patch)
|
||||
|
||||
# Not an actual check for compatibility. Just make sure a sensible value was filled
|
||||
self.assertGreaterEqual(ver_info, expected_ver_info)
|
||||
|
||||
def test_call_vimba_c_invalid_func_name(self):
|
||||
# Expectation: An invalid function name must throw an AttributeError
|
||||
|
||||
ver_info = VmbVersionInfo()
|
||||
self.assertRaises(AttributeError, call_vimba_c, 'VmbVersionQuer', byref(ver_info),
|
||||
sizeof(ver_info))
|
||||
|
||||
def test_call_vimba_c_invalid_arg_number(self):
|
||||
# Expectation: Invalid number of arguments with sane types.
|
||||
# must lead to TypeErrors
|
||||
|
||||
ver_info = VmbVersionInfo()
|
||||
self.assertRaises(TypeError, call_vimba_c, 'VmbVersionQuery', byref(ver_info))
|
||||
|
||||
def test_call_vimba_c_invalid_arg_type(self):
|
||||
# Expectation: Arguments with invalid types must lead to TypeErrors
|
||||
|
||||
# Call with unexpected base types
|
||||
self.assertRaises(ctypes.ArgumentError, call_vimba_c, 'VmbVersionQuery', 0, 'hi')
|
||||
|
||||
# Call with valid ctypes used wrongly
|
||||
ver_info = VmbVersionInfo()
|
||||
self.assertRaises(ctypes.ArgumentError, call_vimba_c, 'VmbVersionQuery', byref(ver_info),
|
||||
ver_info)
|
||||
|
||||
def test_call_vimba_c_exception(self):
|
||||
# Expectation: Errors returned from the C-Layer must be mapped
|
||||
# to a special Exception Type call VimbaCError. This error must
|
||||
# contain the returned Error Code from the failed C-Call.
|
||||
|
||||
# VmbVersionQuery has two possible Errors (taken from VimbaC.h):
|
||||
# - VmbErrorStructSize: The given struct size is not valid for this version of the API
|
||||
# - VmbErrorBadParameter: If "pVersionInfo" is NULL.
|
||||
|
||||
ver_info = VmbVersionInfo()
|
||||
|
||||
try:
|
||||
call_vimba_c('VmbVersionQuery', byref(ver_info), sizeof(ver_info) - 1)
|
||||
self.fail("Previous call must raise Exception.")
|
||||
|
||||
except VimbaCError as e:
|
||||
self.assertEqual(e.get_error_code(), VmbError.StructSize)
|
||||
|
||||
try:
|
||||
call_vimba_c('VmbVersionQuery', None, sizeof(ver_info))
|
||||
self.fail("Previous call must raise Exception.")
|
||||
|
||||
except VimbaCError as e:
|
||||
self.assertEqual(e.get_error_code(), VmbError.BadParameter)
|
||||
|
||||
|
||||
class ImageTransformTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_call_vimba_image_transform_valid(self):
|
||||
# Expectation for valid call: No exceptions, no errors
|
||||
expected_ver_info = EXPECTED_VIMBA_IMAGE_TRANSFORM_VERSION
|
||||
v = VmbUint32()
|
||||
|
||||
call_vimba_image_transform('VmbGetVersion', byref(v))
|
||||
|
||||
ver_info = str(v.value >> 24 & 0xff) + '.' + str(v.value >> 16 & 0xff)
|
||||
|
||||
self.assertEqual(expected_ver_info, ver_info)
|
||||
|
||||
def test_call_vimba_c_invalid_func_name(self):
|
||||
# Expectation: An invalid function name must throw an AttributeError
|
||||
v = VmbUint32()
|
||||
self.assertRaises(AttributeError, call_vimba_image_transform, 'VmbGetVersio', byref(v))
|
||||
|
||||
def test_call_vimba_c_invalid_arg_number(self):
|
||||
# Expectation: Invalid number of arguments with sane types must lead to TypeErrors
|
||||
self.assertRaises(TypeError, call_vimba_image_transform, 'VmbGetVersion')
|
||||
|
||||
def test_call_vimba_c_invalid_arg_type(self):
|
||||
# Expectation: Arguments with invalid types must lead to TypeErrors
|
||||
self.assertRaises(ctypes.ArgumentError, call_vimba_image_transform, 'VmbGetVersion',
|
||||
VmbDouble())
|
||||
self.assertRaises(ctypes.ArgumentError, call_vimba_image_transform, 'VmbGetVersion', 0)
|
||||
self.assertRaises(ctypes.ArgumentError, call_vimba_image_transform, 'VmbGetVersion',
|
||||
'invalid')
|
||||
|
||||
def test_call_vimba_c_exception(self):
|
||||
# Expectation: Failed operations must raise a VimbaCError
|
||||
self.assertRaises(VimbaCError, call_vimba_image_transform, 'VmbGetVersion', None)
|
||||
176
Vimba_6_0/VimbaPython/Source/Tests/basic_tests/interface_test.py
Normal file
176
Vimba_6_0/VimbaPython/Source/Tests/basic_tests/interface_test.py
Normal file
@@ -0,0 +1,176 @@
|
||||
"""BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2019, Allied Vision Technologies GmbH
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from vimba import *
|
||||
|
||||
|
||||
class InterfaceTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.vimba = Vimba.get_instance()
|
||||
self.vimba._startup()
|
||||
|
||||
inters = self.vimba.get_all_interfaces()
|
||||
|
||||
if not inters:
|
||||
self.vimba._shutdown()
|
||||
self.skipTest('No Interface available to test against. Abort.')
|
||||
|
||||
def tearDown(self):
|
||||
self.vimba._shutdown()
|
||||
|
||||
def test_interface_decode_id(self):
|
||||
# Expectation all interface ids can be decoded in something not ''
|
||||
for i in self.vimba.get_all_interfaces():
|
||||
self.assertNotEqual(i.get_id(), '')
|
||||
|
||||
def test_interface_decode_type(self):
|
||||
# Expectation all interface types be in interface types
|
||||
excpected = (
|
||||
InterfaceType.Firewire,
|
||||
InterfaceType.Ethernet,
|
||||
InterfaceType.Usb,
|
||||
InterfaceType.CL,
|
||||
InterfaceType.CSI2,
|
||||
)
|
||||
|
||||
for i in self.vimba.get_all_interfaces():
|
||||
self.assertIn(i.get_type(), excpected)
|
||||
|
||||
def test_interface_decode_name(self):
|
||||
# Expectation all interface names can be decoded in something not ''
|
||||
for i in self.vimba.get_all_interfaces():
|
||||
self.assertNotEqual(i.get_name(), '')
|
||||
|
||||
def test_interface_decode_serial(self):
|
||||
# Expectation: Serials can be '' on some interfaces. This test success
|
||||
# if get serial does not raise
|
||||
for i in self.vimba.get_all_interfaces():
|
||||
self.assertNoRaise(i.get_serial)
|
||||
|
||||
def test_interface_get_all_features(self):
|
||||
# Expectation: Call get_all_features raises RuntimeError outside of with
|
||||
# Inside of with return a non empty set
|
||||
with self.vimba.get_all_interfaces()[0] as inter:
|
||||
self.assertNotEqual(inter.get_all_features(), ())
|
||||
|
||||
def test_interface_get_features_affected_by(self):
|
||||
# Expectation: Call get_features_affected_by raises RuntimeError outside of with.
|
||||
# Inside with it must either return and empty set if the given feature has no affected
|
||||
# Feature or a set off affected features
|
||||
with self.vimba.get_all_interfaces()[0] as inter:
|
||||
try:
|
||||
affects_feats = inter.get_feature_by_name('DeviceUpdateList')
|
||||
|
||||
except VimbaFeatureError:
|
||||
self.skipTest('Test requires Feature \'DeviceUpdateList\'.')
|
||||
|
||||
try:
|
||||
not_affects_feats = inter.get_feature_by_name('DeviceCount')
|
||||
|
||||
except VimbaFeatureError:
|
||||
self.skipTest('Test requires Feature \'DeviceCount\'.')
|
||||
|
||||
self.assertTrue(affects_feats.has_affected_features())
|
||||
self.assertNotEquals(inter.get_features_affected_by(affects_feats), ())
|
||||
|
||||
self.assertFalse(not_affects_feats.has_affected_features())
|
||||
self.assertEquals(inter.get_features_affected_by(not_affects_feats), ())
|
||||
|
||||
def test_interface_get_features_selected_by(self):
|
||||
# Expectation: Call get_features_selected_by raises RuntimeError outside of with.
|
||||
# Inside with it must either return and empty set if the given feature has no selected
|
||||
# Feature or a set off affected features
|
||||
with self.vimba.get_all_interfaces()[0] as inter:
|
||||
try:
|
||||
selects_feats = inter.get_feature_by_name('DeviceSelector')
|
||||
|
||||
except VimbaFeatureError:
|
||||
self.skipTest('Test requires Feature \'DeviceSelector\'.')
|
||||
|
||||
try:
|
||||
not_selects_feats = inter.get_feature_by_name('DeviceCount')
|
||||
|
||||
except VimbaFeatureError:
|
||||
self.skipTest('Test requires Feature \'DeviceCount\'.')
|
||||
|
||||
self.assertTrue(selects_feats.has_selected_features())
|
||||
self.assertNotEquals(inter.get_features_selected_by(selects_feats), ())
|
||||
|
||||
self.assertFalse(not_selects_feats.has_selected_features())
|
||||
self.assertEquals(inter.get_features_selected_by(not_selects_feats), ())
|
||||
|
||||
def test_interface_get_features_by_type(self):
|
||||
# Expectation: Call get_features_by_type raises RuntimeError outside of with
|
||||
# Inside of with return a non empty set for IntFeature (DeviceCount is IntFeature)
|
||||
with self.vimba.get_all_interfaces()[0] as inter:
|
||||
self.assertNotEqual(inter.get_features_by_type(IntFeature), ())
|
||||
|
||||
def test_interface_get_features_by_category(self):
|
||||
# Expectation: Call get_features_by_category raises RuntimeError outside of with
|
||||
# Inside of with return a non empty set for /DeviceEnumeration)
|
||||
with self.vimba.get_all_interfaces()[0] as inter:
|
||||
self.assertNotEqual(inter.get_features_by_category('/DeviceEnumeration'), ())
|
||||
|
||||
def test_interface_get_feature_by_name(self):
|
||||
# Expectation: Call get_feature_by_name raises RuntimeError outside of with
|
||||
# Inside of with return dont raise VimbaFeatureError for 'DeviceCount'
|
||||
# A invalid name must raise VimbaFeatureError
|
||||
with self.vimba.get_all_interfaces()[0] as inter:
|
||||
self.assertNoRaise(inter.get_feature_by_name, 'DeviceCount')
|
||||
self.assertRaises(VimbaFeatureError, inter.get_feature_by_name, 'Invalid Name')
|
||||
|
||||
def test_interface_context_manager_reentrancy(self):
|
||||
# Expectation: Implemented Context Manager must be reentrant, not causing
|
||||
# multiple interface openings (would cause C-Errors)
|
||||
with self.vimba.get_all_interfaces()[0] as inter:
|
||||
with inter:
|
||||
with inter:
|
||||
pass
|
||||
|
||||
def test_interface_api_context_sensitivity_inside_context(self):
|
||||
# Expectation: Interface has functions that shall only be callable inside the Context,
|
||||
# calling outside must cause a runtime error. This test check only if the RuntimeErrors
|
||||
# are triggered then called Outside of the with block.
|
||||
inter = self.vimba.get_all_interfaces()[0]
|
||||
|
||||
self.assertRaises(RuntimeError, inter.read_memory, 0, 0)
|
||||
self.assertRaises(RuntimeError, inter.write_memory, 0, b'foo')
|
||||
self.assertRaises(RuntimeError, inter.read_registers, ())
|
||||
self.assertRaises(RuntimeError, inter.write_registers, {0: 0})
|
||||
self.assertRaises(RuntimeError, inter.get_all_features)
|
||||
|
||||
# Enter scope to get handle on Features as valid parameters for the test:
|
||||
# Don't to this in production code because the features will be invalid if used.
|
||||
with inter:
|
||||
feat = inter.get_all_features()[0]
|
||||
|
||||
self.assertRaises(RuntimeError, inter.get_features_affected_by, feat)
|
||||
self.assertRaises(RuntimeError, inter.get_features_selected_by, feat)
|
||||
self.assertRaises(RuntimeError, inter.get_features_by_type, IntFeature)
|
||||
self.assertRaises(RuntimeError, inter.get_features_by_category, 'foo')
|
||||
self.assertRaises(RuntimeError, inter.get_feature_by_name, 'foo')
|
||||
@@ -0,0 +1,84 @@
|
||||
"""BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2019, Allied Vision Technologies GmbH
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from vimba.util import *
|
||||
|
||||
|
||||
class TestObj:
|
||||
@LeaveContextOnCall()
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@EnterContextOnCall()
|
||||
def __enter__(self):
|
||||
pass
|
||||
|
||||
@LeaveContextOnCall()
|
||||
def __exit__(self, _1, _2, _3):
|
||||
pass
|
||||
|
||||
@RaiseIfOutsideContext()
|
||||
def works_inside_context(self):
|
||||
pass
|
||||
|
||||
@RaiseIfInsideContext()
|
||||
def works_outside_context(self):
|
||||
pass
|
||||
|
||||
|
||||
class ContextDecoratorTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.test_obj = TestObj()
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_raise_if_inside_context(self):
|
||||
# Expectation: a decorated method must raise a RuntimeError if a
|
||||
# Decorated function is called within a with - statement and
|
||||
# run properly outside of the context.
|
||||
|
||||
self.assertNoRaise(self.test_obj.works_outside_context)
|
||||
|
||||
with self.test_obj:
|
||||
self.assertRaises(RuntimeError, self.test_obj.works_outside_context)
|
||||
|
||||
self.assertNoRaise(self.test_obj.works_outside_context)
|
||||
|
||||
def test_raise_if_outside_context(self):
|
||||
# Expectation: a decorated method must raise a RuntimeError if a
|
||||
# Decorated function is called outside a with - statement and
|
||||
# run properly inside of the context.
|
||||
|
||||
self.assertRaises(RuntimeError, self.test_obj.works_inside_context)
|
||||
|
||||
with self.test_obj:
|
||||
self.assertNoRaise(self.test_obj.works_inside_context)
|
||||
|
||||
self.assertRaises(RuntimeError, self.test_obj.works_inside_context)
|
||||
@@ -0,0 +1,256 @@
|
||||
"""BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2019, Allied Vision Technologies GmbH
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from typing import Union, Optional, Tuple, Callable, Dict, Type
|
||||
from vimba.util import *
|
||||
|
||||
|
||||
class RuntimeTypeCheckTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_func_mixed_args_kwargs_and_defaults(self):
|
||||
# Expectation: The typecheck must be able to deal with a valid mixture of args, kwargs
|
||||
# and default values.
|
||||
|
||||
@RuntimeTypeCheckEnable()
|
||||
def test_func(a: int, b: str, c: float = 11.0 / 7.0):
|
||||
pass
|
||||
|
||||
self.assertNoRaise(test_func, 1, '2', 0.0)
|
||||
self.assertNoRaise(test_func, c=0.0, b='str', a=1)
|
||||
self.assertNoRaise(test_func, 1, c=0.0, b='str')
|
||||
self.assertNoRaise(test_func, 1, b='str')
|
||||
self.assertNoRaise(test_func, 1, 'str')
|
||||
|
||||
self.assertRaises(TypeError, test_func, c=0.0, b='str', a=0.0)
|
||||
self.assertRaises(TypeError, test_func, c='invalid type', b='str', a=0.0)
|
||||
|
||||
def test_func_no_hints(self):
|
||||
# Expectation: Functions without type hints
|
||||
# should not throw any type errors
|
||||
|
||||
@RuntimeTypeCheckEnable()
|
||||
def test_func(arg1, arg2):
|
||||
return str()
|
||||
|
||||
self.assertNoRaise(test_func, 'str', 0)
|
||||
|
||||
def test_func_some_hints(self):
|
||||
# Expectation: Type checks are only enforced on Arguments with hint.
|
||||
# Argument without hints should be accepted
|
||||
|
||||
@RuntimeTypeCheckEnable()
|
||||
def test_func(arg1, arg2: int):
|
||||
return str()
|
||||
|
||||
self.assertNoRaise(test_func, 'str', 0)
|
||||
self.assertNoRaise(test_func, 0.5, 0)
|
||||
self.assertRaises(TypeError, test_func, 'str', 0.0)
|
||||
|
||||
def test_object(self):
|
||||
# Expectation: The runtime checker must work on Objects just as on
|
||||
# functions.
|
||||
|
||||
class TestObject:
|
||||
@RuntimeTypeCheckEnable()
|
||||
def __init__(self, arg1: str, arg2: int):
|
||||
pass
|
||||
|
||||
@RuntimeTypeCheckEnable()
|
||||
def __call__(self, arg: str) -> str:
|
||||
return arg
|
||||
|
||||
# Invalid construction
|
||||
self.assertRaises(TypeError, TestObject, 0.0, 0)
|
||||
|
||||
obj = TestObject('str', 0)
|
||||
self.assertNoRaise(obj, 'arg')
|
||||
|
||||
self.assertRaises(TypeError, obj, 0.0)
|
||||
|
||||
def test_type(self):
|
||||
# Expectation: types as parameters must be detected like any other values.
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(arg: Type[int]):
|
||||
pass
|
||||
|
||||
self.assertNoRaise(func, int)
|
||||
self.assertRaises(TypeError, func, str)
|
||||
self.assertRaises(TypeError, func, 0)
|
||||
|
||||
def test_union(self):
|
||||
# Expectation: int and string are valid parameters. Everything else must throw
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(arg: Union[int, str]) -> Union[int, str]:
|
||||
return arg
|
||||
|
||||
self.assertNoRaise(func, 0)
|
||||
self.assertNoRaise(func, 'str')
|
||||
self.assertRaises(TypeError, func, 0.0)
|
||||
|
||||
def test_optional(self):
|
||||
# Expectation: For optionals the check must accept the given type or None.
|
||||
# Anything else must lead to an TypeError
|
||||
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(arg: Optional[int]) -> Optional[str]:
|
||||
return str(arg)
|
||||
|
||||
self.assertNoRaise(func, 0)
|
||||
self.assertNoRaise(func, None)
|
||||
self.assertRaises(TypeError, func, 'str')
|
||||
|
||||
def test_tuple(self):
|
||||
# Expectation: Fixed size tuples checking must verify that size and type order is
|
||||
# enforced.
|
||||
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(arg: Tuple[int, str, float]) -> Tuple[float, int, str]:
|
||||
i, s, f = arg
|
||||
return (f, i, s)
|
||||
|
||||
self.assertNoRaise(func, (1, 'str', 0.1))
|
||||
|
||||
self.assertRaises(TypeError, func, (1, 'str'))
|
||||
self.assertRaises(TypeError, func, (1, 'str', 0.0, 'extra'))
|
||||
self.assertRaises(TypeError, func, ('str1', 'str', 0.0))
|
||||
|
||||
def test_tuple_var_length(self):
|
||||
# Expectation: Var length tuples checking must verify that contained type is enforced.
|
||||
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(arg: Tuple[int, ...]) -> Tuple[str, ...]:
|
||||
return tuple([str(i) for i in arg])
|
||||
|
||||
self.assertNoRaise(func, ())
|
||||
self.assertNoRaise(func, (1,))
|
||||
self.assertNoRaise(func, (1, 2, 3, 4, 5, 6))
|
||||
self.assertRaises(TypeError, func, ('str', ))
|
||||
self.assertRaises(TypeError, func, (1, 'str'))
|
||||
|
||||
def test_tuple_empty(self):
|
||||
# Empty Tuples must satisfy the requirements to Tuple types as argument and results
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(arg: Tuple[int, ...]) -> Tuple[int, ...]:
|
||||
return ()
|
||||
|
||||
self.assertNoRaise(func, ())
|
||||
self.assertEqual(func(()), ())
|
||||
|
||||
def test_tuple_union(self):
|
||||
# Tuples of union types must be detected correctly
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(arg: Tuple[Union[int, str], ...]):
|
||||
return arg
|
||||
|
||||
self.assertNoRaise(func, (0,))
|
||||
self.assertNoRaise(func, ('1',))
|
||||
self.assertNoRaise(func, (2, 3))
|
||||
self.assertNoRaise(func, ('4', '5'))
|
||||
self.assertNoRaise(func, (6, '7'))
|
||||
self.assertNoRaise(func, ('8', 9))
|
||||
self.assertRaises(TypeError, func, (2, 0.0))
|
||||
|
||||
def test_dict(self):
|
||||
# Expectation: Dictionaries must be detected correctly.
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(arg: Dict[int, str]):
|
||||
pass
|
||||
|
||||
self.assertNoRaise(func, {0: 'ok'})
|
||||
self.assertRaises(TypeError, func, None)
|
||||
self.assertRaises(TypeError, func, 0)
|
||||
self.assertRaises(TypeError, func, 'No Dict')
|
||||
self.assertRaises(TypeError, func, {0.0: 'Err'})
|
||||
self.assertRaises(TypeError, func, {0: b'bytes'})
|
||||
|
||||
def test_callable_no_func(self):
|
||||
# Expectation: The Callable verification shall fail if given Parameter is no callable.
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(fn: Callable[[], None]):
|
||||
fn()
|
||||
|
||||
self.assertRaises(TypeError, func, 'no_callable')
|
||||
|
||||
def test_callable_func(self):
|
||||
# Expectation: A Callable without any hints must comply as long as the number of parameters
|
||||
# matches to given hints. The Return Type doesn't matter if not given.
|
||||
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(fn: Callable[[str, float], int], arg1: str, arg2: float) -> int:
|
||||
return fn(arg1, arg2)
|
||||
|
||||
def ok(arg1, arg2):
|
||||
return 0.0
|
||||
|
||||
def err1(arg1):
|
||||
return 'str'
|
||||
|
||||
def err2(arg1, arg2, arg3):
|
||||
return 23
|
||||
|
||||
self.assertNoRaise(func, ok, 'str', 0.0)
|
||||
self.assertRaises(TypeError, func, err1, 'str', 0.0)
|
||||
self.assertRaises(TypeError, func, err2, 'str', 0.0)
|
||||
|
||||
def test_callable_obj(self):
|
||||
# Expectation: A Object that is callable must pass the runtime check
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(fn: Callable[[str], None], arg: str) -> str:
|
||||
return fn(arg)
|
||||
|
||||
class Ok:
|
||||
def __call__(self, arg: str) -> str:
|
||||
return str
|
||||
|
||||
class Err1:
|
||||
def __call__(self) -> str:
|
||||
return 'Err1'
|
||||
|
||||
class Err2:
|
||||
def __call__(self, arg1: str, arg2: str) -> str:
|
||||
return arg1 + arg2
|
||||
|
||||
self.assertNoRaise(func, Ok(), 'str')
|
||||
self.assertRaises(TypeError, func, Err1(), 'str')
|
||||
self.assertRaises(TypeError, func, Err2(), 'str')
|
||||
|
||||
def test_callable_lambda(self):
|
||||
# Expectation: RuntimeTypeCheck must behave with lambas as with functions
|
||||
|
||||
@RuntimeTypeCheckEnable()
|
||||
def func(fn: Callable[[str, float], int], arg1: str, arg2: float) -> int:
|
||||
return fn(arg1, arg2)
|
||||
|
||||
self.assertNoRaise(func, lambda a1, a2: 0.0, 'str', 0.0)
|
||||
self.assertRaises(TypeError, func, lambda a1: 'foo', 'str', 0.0)
|
||||
self.assertRaises(TypeError, func, lambda a1, a2, a3: 23, 'str', 0.0)
|
||||
@@ -0,0 +1,157 @@
|
||||
"""BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2019, Allied Vision Technologies GmbH
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from vimba.util import *
|
||||
|
||||
|
||||
class TracerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
# Enable logging and setup hidden buffer
|
||||
self.log = Log.get_instance()
|
||||
self.log._test_buffer = []
|
||||
|
||||
self.log.enable(LOG_CONFIG_CRITICAL_CONSOLE_ONLY)
|
||||
|
||||
def tearDown(self):
|
||||
# Disable logging and clear hidden buffer
|
||||
self.log.disable()
|
||||
|
||||
self.log._test_buffer = None
|
||||
|
||||
def test_trace_inactive(self):
|
||||
# Expectation: A disabled log must not contain any trace entries.
|
||||
|
||||
@TraceEnable()
|
||||
def test_func(arg):
|
||||
return str(arg)
|
||||
|
||||
self.log.disable()
|
||||
|
||||
self.assertEqual(test_func(1), '1')
|
||||
self.assertFalse(self.log._test_buffer)
|
||||
|
||||
self.assertEqual(test_func('test'), 'test')
|
||||
self.assertFalse(self.log._test_buffer)
|
||||
|
||||
self.assertEqual(test_func(2.0), '2.0')
|
||||
self.assertFalse(self.log._test_buffer)
|
||||
|
||||
def test_trace_normal_exit(self):
|
||||
# Expectation: Must not throw on call normal func.
|
||||
# Each call traced call must add two Log entries:
|
||||
|
||||
@TraceEnable()
|
||||
def test_func(arg):
|
||||
return str(arg)
|
||||
|
||||
self.assertEqual(test_func(1), '1')
|
||||
self.assertEqual(len(self.log._test_buffer), 2)
|
||||
|
||||
self.assertEqual(test_func('test'), 'test')
|
||||
self.assertEqual(len(self.log._test_buffer), 4)
|
||||
|
||||
self.assertEqual(test_func(2.0), '2.0')
|
||||
self.assertEqual(len(self.log._test_buffer), 6)
|
||||
|
||||
def test_trace_raised_exit(self):
|
||||
# Expectation: Throws internally thrown exception and adds two log entries
|
||||
# Each call traced call must add two Log entries:
|
||||
|
||||
@TraceEnable()
|
||||
def test_func(arg):
|
||||
raise TypeError('my error')
|
||||
|
||||
self.assertRaises(TypeError, test_func, 1)
|
||||
self.assertEqual(len(self.log._test_buffer), 2)
|
||||
|
||||
self.assertRaises(TypeError, test_func, 'test')
|
||||
self.assertEqual(len(self.log._test_buffer), 4)
|
||||
|
||||
self.assertRaises(TypeError, test_func, 2.0)
|
||||
self.assertEqual(len(self.log._test_buffer), 6)
|
||||
|
||||
def test_trace_function(self):
|
||||
# Expectation: Normal functions must be traceable
|
||||
@TraceEnable()
|
||||
def test_func():
|
||||
pass
|
||||
|
||||
test_func()
|
||||
self.assertEqual(len(self.log._test_buffer), 2)
|
||||
|
||||
test_func()
|
||||
self.assertEqual(len(self.log._test_buffer), 4)
|
||||
|
||||
test_func()
|
||||
self.assertEqual(len(self.log._test_buffer), 6)
|
||||
|
||||
def test_trace_lambda(self):
|
||||
# Expectation: Lambdas must be traceable
|
||||
|
||||
test_lambda = TraceEnable()(lambda: 0)
|
||||
|
||||
test_lambda()
|
||||
self.assertEqual(len(self.log._test_buffer), 2)
|
||||
|
||||
test_lambda()
|
||||
self.assertEqual(len(self.log._test_buffer), 4)
|
||||
|
||||
test_lambda()
|
||||
self.assertEqual(len(self.log._test_buffer), 6)
|
||||
|
||||
def test_trace_object(self):
|
||||
# Expectation: Objects must be traceable including constructors.
|
||||
class TestObj:
|
||||
@TraceEnable()
|
||||
def __init__(self, arg):
|
||||
self.arg = arg
|
||||
|
||||
@TraceEnable()
|
||||
def __str__(self):
|
||||
return 'TestObj({})'.format(str(self.arg))
|
||||
|
||||
@TraceEnable()
|
||||
def __repr__(self):
|
||||
return 'TestObj({})'.format(repr(self.arg))
|
||||
|
||||
@TraceEnable()
|
||||
def __call__(self):
|
||||
pass
|
||||
|
||||
test_obj = TestObj('test')
|
||||
self.assertEqual(len(self.log._test_buffer), 2)
|
||||
|
||||
str(test_obj)
|
||||
self.assertEqual(len(self.log._test_buffer), 4)
|
||||
|
||||
repr(test_obj)
|
||||
self.assertEqual(len(self.log._test_buffer), 6)
|
||||
|
||||
test_obj()
|
||||
self.assertEqual(len(self.log._test_buffer), 8)
|
||||
@@ -0,0 +1,89 @@
|
||||
"""BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2019, Allied Vision Technologies GmbH
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
from vimba.c_binding import _select_vimba_home
|
||||
from vimba.error import VimbaSystemError
|
||||
|
||||
|
||||
class RankVimbaHomeCandidatesTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_empty_gentl_path(self):
|
||||
candidates = []
|
||||
with self.assertRaises(VimbaSystemError):
|
||||
_select_vimba_home(candidates)
|
||||
|
||||
def test_empty_string(self):
|
||||
candidates = ['']
|
||||
with self.assertRaises(VimbaSystemError):
|
||||
_select_vimba_home(candidates)
|
||||
|
||||
def test_single_bad_vimba_home_candidate(self):
|
||||
candidates = ['/some/path']
|
||||
with self.assertRaises(VimbaSystemError):
|
||||
_select_vimba_home(candidates)
|
||||
|
||||
def test_single_good_vimba_home_candidate(self):
|
||||
candidates = ['/opt/Vimba_3_1']
|
||||
expected = '/opt/Vimba_3_1'
|
||||
self.assertEquals(expected, _select_vimba_home(candidates))
|
||||
|
||||
def test_presorted_vimba_home_candidates(self):
|
||||
candidates = ['/home/username/Vimba_4_0', '/opt/some/other/gentl/provider']
|
||||
expected = '/home/username/Vimba_4_0'
|
||||
self.assertEqual(expected, _select_vimba_home(candidates))
|
||||
|
||||
def test_unsorted_vimba_home_candidates(self):
|
||||
candidates = ['/opt/some/other/gentl/provider', '/home/username/Vimba_4_0']
|
||||
expected = '/home/username/Vimba_4_0'
|
||||
self.assertEqual(expected, _select_vimba_home(candidates))
|
||||
|
||||
def test_many_vimba_home_candidates(self):
|
||||
candidates = ['/some/random/path',
|
||||
'/opt/some/gentl/provider',
|
||||
'/opt/Vimba_4_0', # This should be selected
|
||||
'/opt/another/gentl/provider',
|
||||
'/another/incorrect/path']
|
||||
expected = '/opt/Vimba_4_0'
|
||||
self.assertEqual(expected, _select_vimba_home(candidates))
|
||||
|
||||
def test_multiple_vimba_home_directories(self):
|
||||
# If multiple VIMBA_HOME directories are found an error should be raised
|
||||
candidates = ['/some/random/path',
|
||||
'/opt/some/gentl/provider',
|
||||
'/opt/Vimba_4_0', # first installation
|
||||
'/home/username/Vimba_4_0', # second installation
|
||||
'/opt/another/gentl/provider',
|
||||
'/another/incorrect/path']
|
||||
with self.assertRaises(VimbaSystemError):
|
||||
_select_vimba_home(candidates)
|
||||
126
Vimba_6_0/VimbaPython/Source/Tests/basic_tests/vimba_test.py
Normal file
126
Vimba_6_0/VimbaPython/Source/Tests/basic_tests/vimba_test.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""BSD 2-Clause License
|
||||
|
||||
Copyright (c) 2019, Allied Vision Technologies GmbH
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from vimba import *
|
||||
|
||||
|
||||
class VimbaTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.vimba = Vimba.get_instance()
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_singleton(self):
|
||||
# Expected behavior: Multiple calls to Vimba.get_instance() return the same object.
|
||||
self.assertEqual(self.vimba, Vimba.get_instance())
|
||||
|
||||
def test_get_version(self):
|
||||
# Expectation: Returned Version is not empty and does not raise any exceptions.
|
||||
self.assertNotEqual(self.vimba.get_version(), "")
|
||||
|
||||
def test_get_camera_by_id_failure(self):
|
||||
# Expected behavior: Lookup of a currently unavailable camera must throw an
|
||||
# VimbaCameraError
|
||||
with self.vimba:
|
||||
self.assertRaises(VimbaCameraError, self.vimba.get_camera_by_id, 'Invalid ID')
|
||||
|
||||
def test_get_interface_by_id_failure(self):
|
||||
# Expected behavior: Lookup of a currently unavailable interface must throw an
|
||||
# VimbaInterfaceError
|
||||
with self.vimba:
|
||||
self.assertRaises(VimbaInterfaceError, self.vimba.get_interface_by_id, 'Invalid ID')
|
||||
|
||||
def test_get_feature_by_name_failure(self):
|
||||
# Expected behavior: Lookup of a currently unavailable feature must throw an
|
||||
# VimbaFeatureError
|
||||
with self.vimba:
|
||||
self.assertRaises(VimbaFeatureError, self.vimba.get_feature_by_name, 'Invalid ID')
|
||||
|
||||
def test_runtime_check_failure(self):
|
||||
self.assertRaises(TypeError, self.vimba.set_network_discovery, 0.0)
|
||||
|
||||
with self.vimba:
|
||||
# All functions with RuntimeTypeCheckEnable must return a TypeError on Failure
|
||||
self.assertRaises(TypeError, self.vimba.get_camera_by_id, 0)
|
||||
self.assertRaises(TypeError, self.vimba.get_interface_by_id, 1)
|
||||
self.assertRaises(TypeError, self.vimba.get_feature_by_name, 0)
|
||||
self.assertRaises(TypeError, self.vimba.enable_log, '-1')
|
||||
|
||||
self.assertRaises(TypeError, self.vimba.get_features_affected_by, '-1')
|
||||
self.assertRaises(TypeError, self.vimba.get_features_selected_by, '-1')
|
||||
self.assertRaises(TypeError, self.vimba.get_features_by_type, [])
|
||||
self.assertRaises(TypeError, self.vimba.register_camera_change_handler, 0)
|
||||
self.assertRaises(TypeError, self.vimba.unregister_camera_change_handler, 0)
|
||||
self.assertRaises(TypeError, self.vimba.register_interface_change_handler, 0)
|
||||
self.assertRaises(TypeError, self.vimba.unregister_interface_change_handler, 0)
|
||||
|
||||
def test_vimba_context_manager_reentrancy(self):
|
||||
# Expectation: Implemented Context Manager must be reentrant, not causing
|
||||
# multiple starts of the Vimba API (would cause C-Errors)
|
||||
|
||||
with self.vimba:
|
||||
with self.vimba:
|
||||
with self.vimba:
|
||||
pass
|
||||
|
||||
def test_vimba_api_context_sensitity_outside_context(self):
|
||||
# Expectation: Vimba has functions that shall only be callable outside the Context and
|
||||
# calling within the context must cause a runtime error.
|
||||
|
||||
self.assertNoRaise(self.vimba.set_network_discovery, True)
|
||||
|
||||
with self.vimba:
|
||||
self.assertRaises(RuntimeError, self.vimba.set_network_discovery, True)
|
||||
|
||||
self.assertNoRaise(self.vimba.set_network_discovery, True)
|
||||
|
||||
def test_vimba_api_context_sensitity_inside_context(self):
|
||||
# Expectation: Vimba has functions that shall only be callable inside the Context and
|
||||
# calling outside must cause a runtime error. This test check only if the RuntimeErrors
|
||||
# are triggered then called Outside of the with block.
|
||||
self.assertRaises(RuntimeError, self.vimba.read_memory, 0, 0)
|
||||
self.assertRaises(RuntimeError, self.vimba.write_memory, 0, b'foo')
|
||||
self.assertRaises(RuntimeError, self.vimba.read_registers, ())
|
||||
self.assertRaises(RuntimeError, self.vimba.write_registers, {0: 0})
|
||||
self.assertRaises(RuntimeError, self.vimba.get_all_interfaces)
|
||||
self.assertRaises(RuntimeError, self.vimba.get_interface_by_id, 'id')
|
||||
self.assertRaises(RuntimeError, self.vimba.get_all_cameras)
|
||||
self.assertRaises(RuntimeError, self.vimba.get_camera_by_id, 'id')
|
||||
self.assertRaises(RuntimeError, self.vimba.get_all_features)
|
||||
|
||||
# Enter scope to get handle on Features as valid parameters for the test:
|
||||
# Don't to this in production code because the feature will be invalid if use.
|
||||
with self.vimba:
|
||||
feat = self.vimba.get_all_features()[0]
|
||||
|
||||
self.assertRaises(RuntimeError, self.vimba.get_features_affected_by, feat)
|
||||
self.assertRaises(RuntimeError, self.vimba.get_features_selected_by, feat)
|
||||
self.assertRaises(RuntimeError, self.vimba.get_features_by_type, IntFeature)
|
||||
self.assertRaises(RuntimeError, self.vimba.get_features_by_category, 'foo')
|
||||
self.assertRaises(RuntimeError, self.vimba.get_feature_by_name, 'foo')
|
||||
Reference in New Issue
Block a user