Commit 3505fc6d authored by Christian Bergmiller's avatar Christian Bergmiller

refactored tests and async fixes

parent 4221be7d
...@@ -521,6 +521,7 @@ class Client(object): ...@@ -521,6 +521,7 @@ class Client(object):
async def get_namespace_index(self, uri): async def get_namespace_index(self, uri):
uries = await self.get_namespace_array() uries = await self.get_namespace_array()
_logger.info('get_namespace_index %s %r', type(uries), uries)
return uries.index(uri) return uries.index(uri)
async def delete_nodes(self, nodes, recursive=False): async def delete_nodes(self, nodes, recursive=False):
......
...@@ -37,18 +37,18 @@ async def call_method_full(parent, methodid, *args): ...@@ -37,18 +37,18 @@ async def call_method_full(parent, methodid, *args):
elif isinstance(methodid, node.Node): elif isinstance(methodid, node.Node):
methodid = methodid.nodeid methodid = methodid.nodeid
result = _call_method(parent.server, parent.nodeid, methodid, to_variant(*args)) result = await _call_method(parent.server, parent.nodeid, methodid, to_variant(*args))
result.OutputArguments = [var.Value for var in result.OutputArguments] result.OutputArguments = [var.Value for var in result.OutputArguments]
return result return result
def _call_method(server, parentnodeid, methodid, arguments): async def _call_method(server, parentnodeid, methodid, arguments):
request = ua.CallMethodRequest() request = ua.CallMethodRequest()
request.ObjectId = parentnodeid request.ObjectId = parentnodeid
request.MethodId = methodid request.MethodId = methodid
request.InputArguments = arguments request.InputArguments = arguments
methodstocall = [request] methodstocall = [request]
results = server.call(methodstocall) results = await server.call(methodstocall)
res = results[0] res = results[0]
res.StatusCode.check() res.StatusCode.check()
return res return res
......
...@@ -96,11 +96,11 @@ class Subscription(object): ...@@ -96,11 +96,11 @@ class Subscription(object):
self.loop.create_task(self.server.publish()) self.loop.create_task(self.server.publish())
self.loop.create_task(self.server.publish()) self.loop.create_task(self.server.publish())
def delete(self): async def delete(self):
""" """
Delete subscription on server. This is automatically done by Client and Server classes on exit Delete subscription on server. This is automatically done by Client and Server classes on exit
""" """
results = self.server.delete_subscriptions([self.subscription_id]) results = await self.server.delete_subscriptions([self.subscription_id])
results[0].check() results[0].check()
def publish_callback(self, publishresult): def publish_callback(self, publishresult):
......
...@@ -361,7 +361,7 @@ class InternalSession(object): ...@@ -361,7 +361,7 @@ class InternalSession(object):
def republish(self, params): def republish(self, params):
return self.subscription_service.republish(params) return self.subscription_service.republish(params)
def delete_subscriptions(self, ids): async def delete_subscriptions(self, ids):
for i in ids: for i in ids:
if i in self.subscriptions: if i in self.subscriptions:
self.subscriptions.remove(i) self.subscriptions.remove(i)
......
...@@ -23,6 +23,7 @@ async def server(): ...@@ -23,6 +23,7 @@ async def server():
await srv.init() await srv.init()
srv.set_endpoint(f'opc.tcp://127.0.0.1:{port_num}') srv.set_endpoint(f'opc.tcp://127.0.0.1:{port_num}')
await add_server_methods(srv) await add_server_methods(srv)
await add_server_custom_enum_struct(srv)
await srv.start() await srv.start()
yield srv yield srv
# stop the server # stop the server
...@@ -46,7 +47,7 @@ async def discovery_server(): ...@@ -46,7 +47,7 @@ async def discovery_server():
async def admin_client(): async def admin_client():
# start admin client # start admin client
# long timeout since travis (automated testing) can be really slow # long timeout since travis (automated testing) can be really slow
clt = Client(f'opc.tcp://admin@127.0.0.1:{port_num1}', timeout=10) clt = Client(f'opc.tcp://admin@127.0.0.1:{port_num}', timeout=10)
await clt.connect() await clt.connect()
yield clt yield clt
await clt.disconnect() await clt.disconnect()
...@@ -55,7 +56,7 @@ async def admin_client(): ...@@ -55,7 +56,7 @@ async def admin_client():
@pytest.fixture() @pytest.fixture()
async def client(): async def client():
# start anonymous client # start anonymous client
ro_clt = Client(f'opc.tcp://127.0.0.1:{port_num1}') ro_clt = Client(f'opc.tcp://127.0.0.1:{port_num}')
await ro_clt.connect() await ro_clt.connect()
yield ro_clt yield ro_clt
await ro_clt.disconnect() await ro_clt.disconnect()
......
...@@ -3,7 +3,7 @@ import logging ...@@ -3,7 +3,7 @@ import logging
import pytest import pytest
from opcua import Client from opcua import Client
from opcua import Server
from opcua import ua from opcua import ua
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
......
...@@ -583,17 +583,17 @@ async def test_method_array(opc): ...@@ -583,17 +583,17 @@ async def test_method_array(opc):
m = await o.get_child("2:ServerMethodArray") m = await o.get_child("2:ServerMethodArray")
result = await o.call_method(m, "sin", ua.Variant(math.pi)) result = await o.call_method(m, "sin", ua.Variant(math.pi))
assert result < 0.01 assert result < 0.01
with pytest.raises(ua.UaStatusCodeError) as cm: with pytest.raises(ua.UaStatusCodeError) as exc_info:
await o.call_method(m, "cos", ua.Variant(math.pi)) await o.call_method(m, "cos", ua.Variant(math.pi))
assert ua.StatusCodes.BadInvalidArgument == cm.exception.code assert ua.StatusCodes.BadInvalidArgument == exc_info.type.code
with pytest.raises(ua.UaStatusCodeError) as cm: with pytest.raises(ua.UaStatusCodeError) as exc_info:
await o.call_method(m, "panic", ua.Variant(math.pi)) await o.call_method(m, "panic", ua.Variant(math.pi))
assert ua.StatusCodes.BadOutOfMemory == cm.exception.code assert ua.StatusCodes.BadOutOfMemory == exc_info.type.code
async def test_method_array2(opc): async def test_method_array2(opc):
o = opc.opc.get_objects_node() o = opc.opc.get_objects_node()
m = o.get_child("2:ServerMethodArray2") m = await o.get_child("2:ServerMethodArray2")
result = await o.call_method(m, [1.1, 3.4, 9]) result = await o.call_method(m, [1.1, 3.4, 9])
assert [2.2, 6.8, 18] == result assert [2.2, 6.8, 18] == result
result = await call_method_full(o, m, [1.1, 3.4, 9]) result = await call_method_full(o, m, [1.1, 3.4, 9])
......
import unittest import pytest
import os.path import os.path
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
...@@ -49,19 +49,19 @@ def get_refs(e): ...@@ -49,19 +49,19 @@ def get_refs(e):
find_elem(e, 'References')) find_elem(e, 'References'))
class StandardAddressSpaceTests(unittest.TestCase): def test_std_address_space_references():
aspace = AddressSpace()
def setUp(self): node_mgt_service = NodeManagementService(aspace)
self.aspace = AddressSpace() standard_address_space.fill_address_space(node_mgt_service)
self.node_mgt_service = NodeManagementService(self.aspace) std_nodes = read_nodes(
standard_address_space.fill_address_space(self.node_mgt_service) os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'schemas', 'Opc.Ua.NodeSet2.xml'))
)
def test_std_address_space_references(self): for k in aspace.keys():
std_nodes = read_nodes( refs = set(
os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'schemas', 'Opc.Ua.NodeSet2.xml'))) (r.ReferenceTypeId.to_string(), r.NodeId.to_string(), r.IsForward) for r in aspace[k].references
for k in self.aspace.keys(): )
refs = set( xml_refs = set(
(r.ReferenceTypeId.to_string(), r.NodeId.to_string(), r.IsForward) for r in self.aspace[k].references) (r.attrib['ReferenceType'], r.text, r.attrib.get('IsForward', 'true') == 'true') for r in
xml_refs = set((r.attrib['ReferenceType'], r.text, r.attrib.get('IsForward', 'true') == 'true') for r in find_elem(std_nodes[k.to_string()], 'References')
find_elem(std_nodes[k.to_string()], 'References')) )
self.assertTrue(len(xml_refs - refs) == 0) assert 0 == len(xml_refs - refs)
...@@ -67,11 +67,11 @@ class MySubHandlerCounter(): ...@@ -67,11 +67,11 @@ class MySubHandlerCounter():
async def test_subscription_failure(opc): async def test_subscription_failure(opc):
myhandler = MySubHandler() myhandler = MySubHandler()
o = opc.get_objects_node() o = opc.opc.get_objects_node()
sub = await opc.create_subscription(100, myhandler) sub = await opc.opc.create_subscription(100, myhandler)
with pytest.raises(ua.UaStatusCodeError): with pytest.raises(ua.UaStatusCodeError):
handle1 = sub.subscribe_data_change(o) # we can only subscribe to variables so this should fail handle1 = await sub.subscribe_data_change(o) # we can only subscribe to variables so this should fail
sub.delete() await sub.delete()
async def test_subscription_overload(opc): async def test_subscription_overload(opc):
...@@ -85,18 +85,18 @@ async def test_subscription_overload(opc): ...@@ -85,18 +85,18 @@ async def test_subscription_overload(opc):
v = await o.add_variable(3, f'SubscriptionVariableOverload{i}', 99) v = await o.add_variable(3, f'SubscriptionVariableOverload{i}', 99)
variables.append(v) variables.append(v)
for i in range(nb): for i in range(nb):
sub.subscribe_data_change(variables) await sub.subscribe_data_change(variables)
for i in range(nb): for i in range(nb):
for j in range(nb): for j in range(nb):
await variables[i].set_value(j) await variables[i].set_value(j)
s = await opc.opc.create_subscription(1, myhandler) s = await opc.opc.create_subscription(1, myhandler)
s.subscribe_data_change(variables) await s.subscribe_data_change(variables)
subs.append(s) subs.append(s)
sub.subscribe_data_change(variables[i]) await sub.subscribe_data_change(variables[i])
for i in range(nb): for i in range(nb):
for j in range(nb): for j in range(nb):
await variables[i].set_value(j) await variables[i].set_value(j)
sub.delete() await sub.delete()
for s in subs: for s in subs:
s.delete() s.delete()
...@@ -113,7 +113,7 @@ async def test_subscription_count(opc): ...@@ -113,7 +113,7 @@ async def test_subscription_count(opc):
await var.set_value(val + 1) await var.set_value(val + 1)
await sleep(0.2) # let last event arrive await sleep(0.2) # let last event arrive
assert nb + 1 == myhandler.datachange_count assert nb + 1 == myhandler.datachange_count
sub.delete() await sub.delete()
async def test_subscription_count_list(opc): async def test_subscription_count_list(opc):
...@@ -129,7 +129,7 @@ async def test_subscription_count_list(opc): ...@@ -129,7 +129,7 @@ async def test_subscription_count_list(opc):
await var.set_value(val) await var.set_value(val)
await sleep(0.2) # let last event arrive await sleep(0.2) # let last event arrive
assert nb + 1 == myhandler.datachange_count assert nb + 1 == myhandler.datachange_count
sub.delete() await sub.delete()
async def test_subscription_count_no_change(opc): async def test_subscription_count_no_change(opc):
...@@ -144,7 +144,7 @@ async def test_subscription_count_no_change(opc): ...@@ -144,7 +144,7 @@ async def test_subscription_count_no_change(opc):
var.set_value(val) var.set_value(val)
await sleep(0.2) # let last event arrive await sleep(0.2) # let last event arrive
assert 1 == myhandler.datachange_count assert 1 == myhandler.datachange_count
sub.delete() await sub.delete()
async def test_subscription_count_empty(opc): async def test_subscription_count_empty(opc):
...@@ -161,7 +161,7 @@ async def test_subscription_count_empty(opc): ...@@ -161,7 +161,7 @@ async def test_subscription_count_empty(opc):
break break
await sleep(0.2) # let last event arrive await sleep(0.2) # let last event arrive
assert 4 == myhandler.datachange_count assert 4 == myhandler.datachange_count
sub.delete() await sub.delete()
async def test_subscription_overload_simple(opc): async def test_subscription_overload_simple(opc):
...@@ -174,7 +174,7 @@ async def test_subscription_overload_simple(opc): ...@@ -174,7 +174,7 @@ async def test_subscription_overload_simple(opc):
variables.append(await o.add_variable(3, f'SubVarOverload{i}', i)) variables.append(await o.add_variable(3, f'SubVarOverload{i}', i))
for i in range(nb): for i in range(nb):
sub.subscribe_data_change(variables) sub.subscribe_data_change(variables)
sub.delete() await sub.delete()
async def test_subscription_data_change(opc): async def test_subscription_data_change(opc):
...@@ -206,7 +206,7 @@ async def test_subscription_data_change(opc): ...@@ -206,7 +206,7 @@ async def test_subscription_data_change(opc):
await sub.unsubscribe(handle1) await sub.unsubscribe(handle1)
with pytest.raises(ua.UaStatusCodeError): with pytest.raises(ua.UaStatusCodeError):
await sub.unsubscribe(handle1) # second try should fail await sub.unsubscribe(handle1) # second try should fail
sub.delete() await sub.delete()
with pytest.raises(ua.UaStatusCodeError): with pytest.raises(ua.UaStatusCodeError):
await sub.unsubscribe(handle1) # sub does not exist anymore await sub.unsubscribe(handle1) # sub does not exist anymore
...@@ -235,7 +235,7 @@ async def test_subscription_data_change_bool(opc): ...@@ -235,7 +235,7 @@ async def test_subscription_data_change_bool(opc):
node, val, data = await myhandler.result() node, val, data = await myhandler.result()
assert v1 == node assert v1 == node
assert val is False assert val is False
sub.delete() # should delete our monitoreditem too await sub.delete() # should delete our monitoreditem too
async def test_subscription_data_change_many(opc): async def test_subscription_data_change_many(opc):
...@@ -270,7 +270,7 @@ async def test_subscription_data_change_many(opc): ...@@ -270,7 +270,7 @@ async def test_subscription_data_change_many(opc):
assert val == startv2 assert val == startv2
else: else:
raise RuntimeError("Error node {0} is neither {1} nor {2}".format(node, v1, v2)) raise RuntimeError("Error node {0} is neither {1} nor {2}".format(node, v1, v2))
sub.delete() await sub.delete()
async def test_subscribe_server_time(opc): async def test_subscribe_server_time(opc):
...@@ -283,7 +283,7 @@ async def test_subscribe_server_time(opc): ...@@ -283,7 +283,7 @@ async def test_subscribe_server_time(opc):
delta = datetime.utcnow() - val delta = datetime.utcnow() - val
assert delta < timedelta(seconds=2) assert delta < timedelta(seconds=2)
await sub.unsubscribe(handle) await sub.unsubscribe(handle)
sub.delete() await sub.delete()
async def test_create_delete_subscription(opc): async def test_create_delete_subscription(opc):
...@@ -293,7 +293,7 @@ async def test_create_delete_subscription(opc): ...@@ -293,7 +293,7 @@ async def test_create_delete_subscription(opc):
handle = await sub.subscribe_data_change(v) handle = await sub.subscribe_data_change(v)
await sleep(0.1) await sleep(0.1)
await sub.unsubscribe(handle) await sub.unsubscribe(handle)
sub.delete() await sub.delete()
async def test_subscribe_events(opc): async def test_subscribe_events(opc):
...@@ -301,7 +301,7 @@ async def test_subscribe_events(opc): ...@@ -301,7 +301,7 @@ async def test_subscribe_events(opc):
handle = await sub.subscribe_events() handle = await sub.subscribe_events()
await sleep(0.1) await sleep(0.1)
await sub.unsubscribe(handle) await sub.unsubscribe(handle)
sub.delete() await sub.delete()
async def test_subscribe_events_to_wrong_node(opc): async def test_subscribe_events_to_wrong_node(opc):
...@@ -312,7 +312,7 @@ async def test_subscribe_events_to_wrong_node(opc): ...@@ -312,7 +312,7 @@ async def test_subscribe_events_to_wrong_node(opc):
v = await o.add_variable(3, 'VariableNoEventNofierAttribute', 4) v = await o.add_variable(3, 'VariableNoEventNofierAttribute', 4)
with pytest.raises(ua.UaStatusCodeError): with pytest.raises(ua.UaStatusCodeError):
handle = await sub.subscribe_events(v) handle = await sub.subscribe_events(v)
sub.delete() await sub.delete()
async def test_get_event_from_type_node_BaseEvent(opc): async def test_get_event_from_type_node_BaseEvent(opc):
...@@ -355,7 +355,7 @@ async def test_events_default(opc): ...@@ -355,7 +355,7 @@ async def test_events_default(opc):
assert msg == ev.Message.Text assert msg == ev.Message.Text
assert tid == ev.Time assert tid == ev.Time
await sub.unsubscribe(handle) await sub.unsubscribe(handle)
sub.delete() await sub.delete()
async def test_events_MyObject(opc): async def test_events_MyObject(opc):
...@@ -377,7 +377,7 @@ async def test_events_MyObject(opc): ...@@ -377,7 +377,7 @@ async def test_events_MyObject(opc):
assert msg == ev.Message.Text assert msg == ev.Message.Text
assert tid == ev.Time assert tid == ev.Time
await sub.unsubscribe(handle) await sub.unsubscribe(handle)
sub.delete() await sub.delete()
async def test_events_wrong_source(opc): async def test_events_wrong_source(opc):
...@@ -393,7 +393,7 @@ async def test_events_wrong_source(opc): ...@@ -393,7 +393,7 @@ async def test_events_wrong_source(opc):
with pytest.raises(TimeoutError): # we should not receive event with pytest.raises(TimeoutError): # we should not receive event
ev = await myhandler.result() ev = await myhandler.result()
await sub.unsubscribe(handle) await sub.unsubscribe(handle)
sub.delete() await sub.delete()
async def test_events_CustomEvent(opc): async def test_events_CustomEvent(opc):
...@@ -424,7 +424,7 @@ async def test_events_CustomEvent(opc): ...@@ -424,7 +424,7 @@ async def test_events_CustomEvent(opc):
assert propertynum == ev.PropertyNum assert propertynum == ev.PropertyNum
assert propertystring == ev.PropertyString assert propertystring == ev.PropertyString
sub.unsubscribe(handle) sub.unsubscribe(handle)
sub.delete() await sub.delete()
async def test_events_CustomEvent_MyObject(opc): async def test_events_CustomEvent_MyObject(opc):
...@@ -455,7 +455,7 @@ async def test_events_CustomEvent_MyObject(opc): ...@@ -455,7 +455,7 @@ async def test_events_CustomEvent_MyObject(opc):
assert propertynum == ev.PropertyNum assert propertynum == ev.PropertyNum
assert propertystring == ev.PropertyString assert propertystring == ev.PropertyString
sub.unsubscribe(handle) sub.unsubscribe(handle)
sub.delete() await sub.delete()
async def test_several_different_events(opc): async def test_several_different_events(opc):
...@@ -498,7 +498,7 @@ async def test_several_different_events(opc): ...@@ -498,7 +498,7 @@ async def test_several_different_events(opc):
assert 4 == len(ev2s) assert 4 == len(ev2s)
assert 7 == len(ev1s) assert 7 == len(ev1s)
sub.unsubscribe(handle) sub.unsubscribe(handle)
sub.delete() await sub.delete()
async def test_several_different_events_2(opc): async def test_several_different_events_2(opc):
...@@ -553,4 +553,4 @@ async def test_several_different_events_2(opc): ...@@ -553,4 +553,4 @@ async def test_several_different_events_2(opc):
assert 9999 == ev3s[-1].PropertyNum3 assert 9999 == ev3s[-1].PropertyNum3
assert ev1s[0].PropertyNum3 is None assert ev1s[0].PropertyNum3 is None
sub.unsubscribe(handle) sub.unsubscribe(handle)
sub.delete() await sub.delete()
import os
from opcua import ua from opcua import ua
from opcua.ua import uatypes from opcua.ua import uatypes
from enum import IntEnum from enum import IntEnum
from opcua import Server from opcua import Server
TEST_DIR = os.path.dirname(__file__) + os.sep
class ExampleEnum(IntEnum): class ExampleEnum(IntEnum):
EnumVal1 = 0 EnumVal1 = 0
...@@ -27,15 +30,14 @@ class ExampleStruct(uatypes.FrozenClass): ...@@ -27,15 +30,14 @@ class ExampleStruct(uatypes.FrozenClass):
self._freeze = True self._freeze = True
def __str__(self): def __str__(self):
return 'ExampleStruct(' + 'IntVal1:' + str(self.IntVal1) + ', ' + \ return f'ExampleStruct(IntVal1:{self.IntVal1}, EnumVal:{self.EnumVal})'
'EnumVal:' + str(self.EnumVal) + ')'
__repr__ = __str__ __repr__ = __str__
async def add_server_custom_enum_struct(server: Server): async def add_server_custom_enum_struct(server: Server):
# import some nodes from xml # import some nodes from xml
await server.import_xml("tests/enum_struct_test_nodes.xml") await server.import_xml(f"{TEST_DIR}enum_struct_test_nodes.xml")
ns = await server.get_namespace_index('http://yourorganisation.org/struct_enum_example/') ns = await server.get_namespace_index('http://yourorganisation.org/struct_enum_example/')
uatypes.register_extension_object('ExampleStruct', ua.NodeId(5001, ns), ExampleStruct) uatypes.register_extension_object('ExampleStruct', ua.NodeId(5001, ns), ExampleStruct)
val = ua.ExampleStruct() val = ua.ExampleStruct()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment