import logging import pytest from opcua import Client from opcua import Server from opcua import ua from .tests_common import add_server_methods from .tests_enum_struct import add_server_custom_enum_struct port_num1 = 48510 _logger = logging.getLogger(__name__) pytestmark = pytest.mark.asyncio @pytest.fixture() async def admin_client(): # start admin client # long timeout since travis (automated testing) can be really slow clt = Client(f'opc.tcp://admin@127.0.0.1:{port_num1}', timeout=10) await clt.connect() yield clt await clt.disconnect() @pytest.fixture() async def client(): # start anonymous client ro_clt = Client(f'opc.tcp://127.0.0.1:{port_num1}') await ro_clt.connect() yield ro_clt await ro_clt.disconnect() @pytest.fixture() async def server(): # start our own server srv = Server() await srv.init() srv.set_endpoint(f'opc.tcp://127.0.0.1:{port_num1}') await add_server_methods(srv) await add_server_custom_enum_struct(srv) await srv.start() yield srv # stop the server await srv.stop() async def test_service_fault(server, admin_client): request = ua.ReadRequest() request.TypeId = ua.FourByteNodeId(999) # bad type! with pytest.raises(ua.UaStatusCodeError): await admin_client.uaclient.protocol.send_request(request) async def test_objects_anonymous(server, client): objects = client.get_objects_node() with pytest.raises(ua.UaStatusCodeError): await objects.set_attribute(ua.AttributeIds.WriteMask, ua.DataValue(999)) with pytest.raises(ua.UaStatusCodeError): await objects.add_folder(3, 'MyFolder') async def test_folder_anonymous(server, client): objects = client.get_objects_node() f = await objects.add_folder(3, 'MyFolderRO') f_ro = client.get_node(f.nodeid) assert f == f_ro with pytest.raises(ua.UaStatusCodeError): await f_ro.add_folder(3, 'MyFolder2') async def test_variable_anonymous(server, admin_client, client): objects = admin_client.get_objects_node() v = await objects.add_variable(3, 'MyROVariable', 6) await v.set_value(4) # this should work v_ro = client.get_node(v.nodeid) with pytest.raises(ua.UaStatusCodeError): await v_ro.set_value(2) assert await v_ro.get_value() == 4 await v.set_writable(True) await v_ro.set_value(2) # now it should work assert await v_ro.get_value() == 2 await v.set_writable(False) with pytest.raises(ua.UaStatusCodeError): await v_ro.set_value(9) assert await v_ro.get_value() == 2 async def test_context_manager(server): """Context manager calls connect() and disconnect()""" state = [0] async def increment_state(*args, **kwargs): state[0] += 1 # create client and replace instance methods with dummy methods client = Client('opc.tcp://dummy_address:10000') client.connect = increment_state.__get__(client) client.disconnect = increment_state.__get__(client) assert state[0] == 0 async with client: # test if client connected assert state[0] == 1 # test if client disconnected assert state[0] == 2 async def test_enumstrings_getvalue(server, client): """ The real exception is server side, but is detected by using a client. All due the server trace is also visible on the console. The client only 'sees' an TimeoutError """ nenumstrings = client.get_node(ua.ObjectIds.AxisScaleEnumeration_EnumStrings) value = ua.Variant(await nenumstrings.get_value()) async def test_custom_enum_struct(server, client): client.load_type_definitions() ns = await client.get_namespace_index('http://yourorganisation.org/struct_enum_example/') myvar = client.get_node(ua.NodeId(6009, ns)) val = await myvar.get_value() assert 242 == val.IntVal1 assert ua.ExampleEnum.EnumVal2 == val.EnumVal