class TestResourceManager(unittest.TestCase): """Test the pyvisa ResourceManager. """ def setUp(self): """Create a ResourceManager with the default backend library. """ self.rm = ResourceManager() def tearDown(self): """Close the ResourceManager. """ self.rm.close() del rm gc.collect() def test_lifecycle(self): """Test creation and closing of the resource manager. """ self.assertIsNotNone(self.rm.session) self.assertIsNotNone(self.rm.visalib) self.assertIs(self.rm, self.rm.visalib.resource_manager) self.assertFalse(self.rm.list_opened_resources()) self.assertIs(self.rm.visalib, ResourceManager(self.rm.visalib).visalib) self.rm.close() with self.assertRaises(InvalidSession): self.rm.session self.assertIsNone(self.rm.visalib.resource_manager) def test_cleanup_on_del(self): """Test that deleting the rm does clean the VISA session """ # The test seems to assert what it should even though the coverage report # seems wrong rm = highlevel.ResourceManager() with self.assertLogs(level=logging.DEBUG) as log: del rm gc.collect() self.assertIn('Closing ResourceManager', log.output) def test_resource_manager_unicity(self): """Test the resource manager is unique per backend as expected. """ new_rm = ResourceManager() self.assertIs(self.rm, new_rm) self.assertEqual(self.rm.session, new_rm.session) def test_str(self): """Test computing the string representation of the resource manager """ self.assertRegex(str(self.rm), r"Resource Manager of .*") self.rm.close() self.assertRegex(str(self.rm), r"Resource Manager of .*") def test_repr(self): """Test computing the repr of the resource manager """ self.assertRegex(repr(self.rm), r"<ResourceManager\(<.*>\)>") self.rm.close() self.assertRegex(repr(self.rm), r"<ResourceManager\(<.*>\)>") def test_last_status(self): """Test accessing the status of the last operation. """ self.assertEqual(self.rm.last_status, StatusCode.success) # Access the generic last status through the visalib self.assertEqual(self.rm.last_status, self.rm.visalib.last_status) # Test accessing the status for an invalid session with self.assertRaises(errors.Error) as cm: self.rm.visalib.get_last_status_in_session("_nonexisting_") self.assertIn("The session", cm.exception.args[0]) def test_list_resource(self): """Test listing the available resources. """ # Default settings self.assertSequenceEqual( sorted(self.rm.list_resources()), sorted([ str(ResourceName.from_string(v)) for v in RESOURCE_ADDRESSES.values() if v.endswith("INSTR") ])) # All resources self.assertSequenceEqual( sorted(self.rm.list_resources("?*")), sorted([ str(ResourceName.from_string(v)) for v in RESOURCE_ADDRESSES.values() ])) def test_accessing_resource_infos(self): """Test accessing resource infos. """ rname = list(RESOURCE_ADDRESSES.values())[0] rinfo_ext = self.rm.resource_info(rname) rinfo = self.rm.resource_info(rname, extended=False) rname = ResourceName().from_string(rname) self.assertEqual(rinfo_ext.interface_type, getattr(InterfaceType, rname.interface_type.lower())) self.assertEqual(rinfo_ext.interface_board_number, int(rname.board)) self.assertEqual(rinfo_ext.resource_class, rname.resource_class) self.assertEqual(rinfo_ext.resource_name, str(rname)) self.assertEqual(rinfo.interface_type, getattr(InterfaceType, rname.interface_type.lower())) self.assertEqual(rinfo.interface_board_number, int(rname.board)) def test_listing_resource_infos(self): """Test listing resource infos. """ infos = self.rm.list_resources_info() for rname, rinfo_ext in infos.items(): rname = ResourceName().from_string(rname) self.assertEqual( rinfo_ext.interface_type, getattr(InterfaceType, rname.interface_type.lower())) self.assertEqual(rinfo_ext.interface_board_number, int(rname.board)) self.assertEqual(rinfo_ext.resource_class, rname.resource_class) self.assertEqual(rinfo_ext.resource_name, str(rname)) def test_opening_resource(self): """Test opening and closing resources. """ rname = list(RESOURCE_ADDRESSES.values())[0] rsc = self.rm.open_resource(rname, timeout=1234) # Check the resource is listed as opened and the attributes are right. self.assertIn(rsc, self.rm.list_opened_resources()) self.assertEqual(rsc.timeout, 1234) # Close the rm to check that we close all resources. self.rm.close() self.assertFalse(self.rm.list_opened_resources()) with self.assertRaises(InvalidSession): rsc.session def test_opening_resource_bad_open_timeout(self): """Test opening a resource with a non integer open_timeout. """ rname = list(RESOURCE_ADDRESSES.values())[0] with self.assertRaises(ValueError) as cm: rsc = self.rm.open_resource(rname, open_timeout="") self.assertIn("integer (or compatible type)", str(cm.exception)) def test_opening_resource_with_lock(self): """Test opening a locked resource """ rname = list(RESOURCE_ADDRESSES.values())[0] rsc = self.rm.open_resource(rname, access_mode=AccessModes.exclusive_lock) self.assertEqual(len(self.rm.list_opened_resources()), 1) # Timeout when accessing a locked resource with self.assertRaises(VisaIOError): self.rm.open_resource(rname, access_mode=AccessModes.exclusive_lock) self.assertEqual(len(self.rm.list_opened_resources()), 1) # Success to access an unlocked resource. rsc.unlock() rsc2 = self.rm.open_resource(rname, access_mode=AccessModes.exclusive_lock) self.assertEqual(len(self.rm.list_opened_resources()), 2) def test_opening_resource_specific_class(self): """Test opening a resource requesting a specific class. """ rname = list(RESOURCE_ADDRESSES.values())[0] with self.assertRaises(TypeError): rsc = self.rm.open_resource(rname, resource_pyclass=object) self.assertEqual(len(self.rm.list_opened_resources()), 0) def test_open_resource_unknown_resource_type(self): """Test opening a resource for which no registered class exist. """ rc = highlevel.ResourceManager._resource_classes old = rc.copy() class FakeResource: def __init__(self, *args): raise RuntimeError() rc[(constants.InterfaceType.unknown, "")] = FakeResource rm = highlevel.ResourceManager() try: with self.assertLogs(level=logging.WARNING): highlevel.ResourceManager.open_resource( "TCPIP::192.168.0.1::INSTR") self.assertIs( highlevel.ResourceManager._resource_classes[( constants.InterfaceType.tcpip, "INSTR")], object) finally: highlevel.ResourceManager._resource_classes = old def test_opening_resource_unknown_attribute(self): """Test opening a resource and attempting to set an unknown attr. """ rname = list(RESOURCE_ADDRESSES.values())[0] with self.assertRaises(ValueError): rsc = self.rm.open_resource(rname, unknown_attribute=None) self.assertEqual(len(self.rm.list_opened_resources()), 0) def test_get_instrument(self): """Check that we get the expected deprecation warning. """ rname = list(RESOURCE_ADDRESSES.values())[0] with self.assertWarns(FutureWarning): rsc = self.rm.get_instrument(rname)
class TestResourceManager: """Test the pyvisa ResourceManager.""" def setup_method(self): """Create a ResourceManager with the default backend library.""" self.rm = ResourceManager() def teardown_method(self): """Close the ResourceManager.""" if self.rm is not None: self.rm.close() del self.rm gc.collect() def test_lifecycle(self, caplog): """Test creation and closing of the resource manager.""" assert self.rm.session is not None assert self.rm.visalib is not None assert self.rm is self.rm.visalib.resource_manager assert not self.rm.list_opened_resources() assert self.rm.visalib is ResourceManager(self.rm.visalib).visalib with caplog.at_level(level=logging.DEBUG, logger="pyvisa"): self.rm.close() assert caplog.records with pytest.raises(InvalidSession): self.rm.session assert self.rm.visalib.resource_manager is None def test_cleanup_on_del(self, caplog): """Test that deleting the rm does clean the VISA session""" # The test seems to assert what it should even though the coverage report # seems wrong rm = self.rm self.rm = None with caplog.at_level(logging.DEBUG, logger="pyvisa"): del rm gc.collect() assert "Closing ResourceManager" in caplog.records[0].message def test_resource_manager_unicity(self): """Test the resource manager is unique per backend as expected.""" new_rm = ResourceManager() assert self.rm is new_rm assert self.rm.session == new_rm.session def test_str(self): """Test computing the string representation of the resource manager""" assert re.match(r"Resource Manager of .*", str(self.rm)) self.rm.close() assert re.match(r"Resource Manager of .*", str(self.rm)) def test_repr(self): """Test computing the repr of the resource manager""" assert re.match(r"<ResourceManager\(<.*>\)>", repr(self.rm)) self.rm.close() assert re.match(r"<ResourceManager\(<.*>\)>", repr(self.rm)) def test_last_status(self): """Test accessing the status of the last operation.""" assert self.rm.last_status == StatusCode.success # Access the generic last status through the visalib assert self.rm.last_status == self.rm.visalib.last_status # Test accessing the status for an invalid session with pytest.raises(errors.Error) as cm: self.rm.visalib.get_last_status_in_session("_nonexisting_") assert "The session" in cm.exconly() def test_list_resource(self): """Test listing the available resources.""" # Default settings resources = self.rm.list_resources() for v in (v for v in RESOURCE_ADDRESSES.values() if v.endswith("INSTR")): assert str(ResourceName.from_string(v)) in resources # All resources resources = self.rm.list_resources("?*") for v in RESOURCE_ADDRESSES.values(): assert str(ResourceName.from_string(v)) in resources def test_accessing_resource_infos(self): """Test accessing resource infos.""" rname = list(RESOURCE_ADDRESSES.values())[0] rinfo_ext = self.rm.resource_info(rname) rinfo = self.rm.resource_info(rname, extended=False) rname = ResourceName().from_string(rname) assert rinfo_ext.interface_type == getattr( InterfaceType, rname.interface_type.lower()) assert rinfo_ext.interface_board_number == int(rname.board) assert rinfo_ext.resource_class == rname.resource_class assert rinfo_ext.resource_name == str(rname) assert rinfo.interface_type == getattr(InterfaceType, rname.interface_type.lower()) assert rinfo.interface_board_number == int(rname.board) def test_listing_resource_infos(self): """Test listing resource infos.""" infos = self.rm.list_resources_info() for rname, rinfo_ext in infos.items(): rname = ResourceName().from_string(rname) assert rinfo_ext.interface_type == getattr( InterfaceType, rname.interface_type.lower()) assert rinfo_ext.interface_board_number == int(rname.board) assert rinfo_ext.resource_class == rname.resource_class assert rinfo_ext.resource_name == str(rname) def test_opening_resource(self): """Test opening and closing resources.""" rname = list(RESOURCE_ADDRESSES.values())[0] rsc = self.rm.open_resource(rname, timeout=1234) # Check the resource is listed as opened and the attributes are right. assert rsc in self.rm.list_opened_resources() assert rsc.timeout == 1234 # Close the rm to check that we close all resources. self.rm.close() assert not self.rm.list_opened_resources() with pytest.raises(InvalidSession): rsc.session def test_opening_resource_bad_open_timeout(self): """Test opening a resource with a non integer open_timeout.""" rname = list(RESOURCE_ADDRESSES.values())[0] with pytest.raises(ValueError) as cm: self.rm.open_resource(rname, open_timeout="") assert "integer (or compatible type)" in str(cm.exconly()) def test_opening_resource_with_lock(self): """Test opening a locked resource""" rname = list(RESOURCE_ADDRESSES.values())[0] rsc = self.rm.open_resource(rname, access_mode=AccessModes.exclusive_lock) assert len(self.rm.list_opened_resources()) == 1 # Timeout when accessing a locked resource with pytest.raises(VisaIOError): self.rm.open_resource(rname, access_mode=AccessModes.exclusive_lock) assert len(self.rm.list_opened_resources()) == 1 # Success to access an unlocked resource. rsc.unlock() with self.rm.open_resource( rname, access_mode=AccessModes.exclusive_lock) as rsc2: assert rsc.session != rsc2.session assert len(self.rm.list_opened_resources()) == 2 def test_opening_resource_specific_class(self): """Test opening a resource requesting a specific class.""" rname = list(RESOURCE_ADDRESSES.values())[0] with pytest.raises(TypeError): self.rm.open_resource(rname, resource_pyclass=object) assert len(self.rm.list_opened_resources()) == 0 def test_open_resource_unknown_resource_type(self, caplog): """Test opening a resource for which no registered class exist.""" rc = ResourceManager._resource_classes old = rc.copy() class FakeResource: def __init__(self, *args): raise RuntimeError() rc[(InterfaceType.unknown, "")] = FakeResource del rc[(InterfaceType.tcpip, "INSTR")] rm = ResourceManager() try: caplog.clear() with caplog.at_level(level=logging.DEBUG, logger="pyvisa"): with pytest.raises(RuntimeError): rm.open_resource("TCPIP::192.168.0.1::INSTR") assert caplog.records finally: ResourceManager._resource_classes = old def test_opening_resource_unknown_attribute(self): """Test opening a resource and attempting to set an unknown attr.""" rname = list(RESOURCE_ADDRESSES.values())[0] with pytest.raises(ValueError): self.rm.open_resource(rname, unknown_attribute=None) assert len(self.rm.list_opened_resources()) == 0 def test_get_instrument(self): """Check that we get the expected deprecation warning.""" rname = list(RESOURCE_ADDRESSES.values())[0] with pytest.warns(FutureWarning): self.rm.get_instrument(rname)
class ResourceTestCase: """Base test case for all resources. """ #: Type of resource being tested in this test case. #: See RESOURCE_ADDRESSES in the __init__.py file of this package for #: acceptable values RESOURCE_TYPE = "" #: Minimal timeout value accepted by the resource. When setting the timeout #: to VI_TMO_IMMEDIATE, Visa (Keysight at least) may actually use a #: different value depending on the values supported by the resource. MINIMAL_TIMEOUT = VI_TMO_IMMEDIATE def setUp(self): """Create a resource using the address matching the type. """ name = RESOURCE_ADDRESSES[self.RESOURCE_TYPE] self.rname = ResourceName.from_string(name) self.rm = ResourceManager() self.instr = self.rm.open_resource(name) self.instr.clear() def tearDown(self): """Close the resource at the end of the test. """ if self.instr: self.instr.close() if self.rm: self.rm.close() def test_lifecycle(self): """Test the lifecyle of a resource and the use as a context manager. """ self.assertIsNotNone(self.instr.session) self.assertIsNotNone(self.instr.visalib) self.assertEqual(self.instr.last_status, StatusCode.success) self.instr.close() with self.assertRaises(InvalidSession): self.instr.session with self.rm.open_resource(str(self.rname), read_termination="\0") as instr: self.assertEqual(len(self.rm.list_opened_resources()), 1) self.assertEqual(instr.read_termination, "\0") self.assertEqual(len(self.rm.list_opened_resources()), 0) def test_close_on_del(self): """Test the lifecyle of a resource and the use as a context manager. """ with self.assertLogs(level="DEBUG") as cm: self.instr = None gc.collect() self.assertIn("- closing", cm.output[0]) self.assertIn("- is closed", cm.output[-1]) def test_alias_bypassing(self): """Test that a resource that cannot normalize an alias keep the alias. """ instr = Resource(self.rm, "visa_alias") self.assertRegex(str(instr), r".* at %s" % "visa_alias") def test_str(self): """Test the string representation of a resource. """ self.assertRegex(str(self.instr), r".* at %s" % str(self.rname)) self.instr.close() self.assertRegex(str(self.instr), r".* at %s" % str(self.rname)) def test_repr(self): """Test the repr of a resource. """ self.assertRegex(repr(self.instr), r"<.*\('%s'\)>" % str(self.rname)) self.instr.close() self.assertRegex(repr(self.instr), r"<.*\('%s'\)>" % str(self.rname)) def test_timeout(self): """Test setting the timeout attribute. """ self.instr.timeout = None self.assertEqual(self.instr.timeout, float("+inf")) self.assertEqual(self.instr.get_visa_attribute(VI_ATTR_TMO_VALUE), VI_TMO_INFINITE) self.instr.timeout = 0.1 self.assertEqual(self.instr.timeout, 1) self.assertEqual(self.instr.get_visa_attribute(VI_ATTR_TMO_VALUE), self.MINIMAL_TIMEOUT) self.instr.timeout = 10 self.assertEqual(self.instr.timeout, 10) self.assertEqual(self.instr.get_visa_attribute(VI_ATTR_TMO_VALUE), 10) with self.assertRaises(ValueError): self.instr.timeout = 10000000000 del self.instr.timeout self.assertEqual(self.instr.timeout, float("+inf")) self.assertEqual(self.instr.get_visa_attribute(VI_ATTR_TMO_VALUE), VI_TMO_INFINITE) def test_resource_info(self): """Test accessing the resource info. """ rinfo = self.instr.resource_info self.assertEqual( rinfo.interface_type, getattr(InterfaceType, self.rname.interface_type.lower()), ) self.assertEqual(rinfo.interface_board_number, int(self.rname.board)) self.assertEqual(rinfo.resource_class, self.rname.resource_class) self.assertEqual(rinfo.resource_name, str(self.rname)) def test_interface_type(self): """Test accessing the resource interface_type. """ self.assertEqual( self.instr.interface_type, getattr(InterfaceType, self.rname.interface_type.lower()), ) def test_attribute_handling(self): """Test directly manipulating attributes ie not using descriptors. This should extended in subclasses to test a broader range of attributes. """ self.instr.set_visa_attribute(VI_ATTR_TMO_VALUE, 10) self.assertEqual(self.instr.get_visa_attribute(VI_ATTR_TMO_VALUE), 10) self.assertEqual(self.instr.timeout, 10) self.instr.set_visa_attribute(VI_ATTR_TMO_VALUE, VI_TMO_IMMEDIATE) self.assertEqual(self.instr.get_visa_attribute(VI_ATTR_TMO_VALUE), self.MINIMAL_TIMEOUT) self.assertEqual(self.instr.timeout, 1) self.instr.set_visa_attribute(VI_ATTR_TMO_VALUE, VI_TMO_INFINITE) self.assertEqual(self.instr.get_visa_attribute(VI_ATTR_TMO_VALUE), VI_TMO_INFINITE) self.assertEqual(self.instr.timeout, float("+inf")) def test_wait_on_event(self): """Test waiting on a VISA event. Should be implemented on subclasses, since the way to generate the event may be dependent on the resource type. """ raise NotImplementedError() def test_managing_visa_handler(self): """Test using visa handlers. Should be implemented on subclasses, since the way to generate the event may be dependent on the resource type. """ raise NotImplementedError() def test_shared_locking(self): """Test locking/unlocking a resource. """ raise NotImplementedError() def test_exclusive_locking(self): """Test locking/unlocking a resource. """ raise NotImplementedError()
class ResourceTestCase: """Base test case for all resources.""" #: Type of resource being tested in this test case. #: See RESOURCE_ADDRESSES in the __init__.py file of this package for #: acceptable values RESOURCE_TYPE = "" #: Minimal timeout value accepted by the resource. When setting the timeout #: to Timeouts.immediate, Visa (Keysight at least) may actually use a #: different value depending on the values supported by the resource. MINIMAL_TIMEOUT: Union[int, Timeouts] = Timeouts.immediate def setup_method(self): """Create a resource using the address matching the type.""" name = RESOURCE_ADDRESSES[self.RESOURCE_TYPE] self.rname = ResourceName.from_string(name) self.rm = ResourceManager() self.instr = self.rm.open_resource(name) self.instr.clear() def teardown_method(self): """Close the resource at the end of the test.""" if self.instr: self.instr.close() if self.rm: self.rm.close() def test_lifecycle(self): """Test the lifecyle of a resource and the use as a context manager.""" assert self.instr.session is not None assert self.instr.visalib is not None assert self.instr.last_status == StatusCode.success self.instr.close() with pytest.raises(InvalidSession): self.instr.session with self.rm.open_resource(str(self.rname), read_termination="\0") as instr: assert len(self.rm.list_opened_resources()) == 1 assert instr.read_termination == "\0" assert len(self.rm.list_opened_resources()) == 0 def test_close_on_del(self, caplog): """Test the lifecyle of a resource and the use as a context manager.""" with caplog.at_level(logging.DEBUG): self.instr = None gc.collect() assert "- closing" in caplog.records[0].message assert "- is closed", caplog.output[-1].message def test_alias_bypassing(self): """Test that a resource that cannot normalize an alias keep the alias.""" instr = Resource(self.rm, "visa_alias") assert re.match(r".* at %s" % "visa_alias", str(instr)) def test_str(self): """Test the string representation of a resource.""" assert re.match(r".* at %s" % str(self.rname), str(self.instr)) self.instr.close() assert re.match(r".* at %s" % str(self.rname), str(self.instr)) def test_repr(self): """Test the repr of a resource.""" assert re.match(r"<.*\('%s'\)>" % str(self.rname), repr(self.instr)) self.instr.close() assert re.match(r"<.*\('%s'\)>" % str(self.rname), repr(self.instr)) def test_timeout(self): """Test setting the timeout attribute.""" self.instr.timeout = None assert self.instr.timeout == float("+inf") assert (self.instr.get_visa_attribute( ResourceAttribute.timeout_value) == Timeouts.infinite) self.instr.timeout = 0.1 assert self.instr.timeout == 1 assert (self.instr.get_visa_attribute( ResourceAttribute.timeout_value) == self.MINIMAL_TIMEOUT) self.instr.timeout = 10 assert self.instr.timeout == 10 assert self.instr.get_visa_attribute( ResourceAttribute.timeout_value) == 10 with pytest.raises(ValueError): self.instr.timeout = 10000000000 del self.instr.timeout assert self.instr.timeout == float("+inf") assert (self.instr.get_visa_attribute( ResourceAttribute.timeout_value) == Timeouts.infinite) def test_resource_info(self): """Test accessing the resource info.""" rinfo = self.instr.resource_info assert rinfo.interface_type == getattr( InterfaceType, self.rname.interface_type.lower()) assert rinfo.interface_board_number == int(self.rname.board) assert rinfo.resource_class == self.rname.resource_class assert rinfo.resource_name == str(self.rname) def test_interface_type(self): """Test accessing the resource interface_type.""" assert self.instr.interface_type == getattr( InterfaceType, self.rname.interface_type.lower()) def test_attribute_handling(self): """Test directly manipulating attributes ie not using descriptors. This should extended in subclasses to test a broader range of attributes. """ self.instr.set_visa_attribute(ResourceAttribute.timeout_value, 10) assert self.instr.get_visa_attribute( ResourceAttribute.timeout_value) == 10 assert self.instr.timeout == 10 self.instr.set_visa_attribute(ResourceAttribute.timeout_value, Timeouts.immediate) assert (self.instr.get_visa_attribute( ResourceAttribute.timeout_value) == self.MINIMAL_TIMEOUT) assert self.instr.timeout == 1 self.instr.set_visa_attribute(ResourceAttribute.timeout_value, Timeouts.infinite) assert (self.instr.get_visa_attribute( ResourceAttribute.timeout_value) == Timeouts.infinite) assert self.instr.timeout == float("+inf")