4 sys.path.insert(0,
"../../build/bin/")
7 from threading
import Thread, Event
9 from queue
import Queue
11 from Queue
import Queue
13 from threading
import Condition
21 Dummy subscription client 31 More advanced subscription client using conditions, so we can wait for events in tests 48 self.cond.notify_all()
53 self.cond.notify_all()
55 class Unit(unittest.TestCase):
57 Simple unit test that do not need to setup a server or a client 61 nid1 = opcua.NodeId(999, 2)
62 nid2 = opcua.NodeId(999, 2)
63 self.assertTrue(nid1==nid2)
64 self.assertTrue(id(nid1)!=id(nid2))
67 self.assertEqual(opcua.NodeId(), opcua.NodeId(0,0))
68 self.assertEqual(opcua.NodeId(), opcua.NodeId(
'ns=0;i=0;'))
71 nid = opcua.NodeId(
'titi', 1)
72 self.assertEqual(nid.namespace_index, 1)
73 self.assertEqual(nid.identifier,
'titi')
74 self.assertTrue(nid.is_string)
77 nid = opcua.NodeId(999, 2)
78 self.assertEqual(nid.namespace_index, 2)
79 self.assertEqual(nid.identifier, 999)
80 self.assertTrue(nid.is_integer)
83 nid = opcua.NodeId(
'ns=2;s=PLC1.Manufacturer;')
84 self.assertEqual(nid.namespace_index, 2)
85 self.assertEqual(nid.identifier,
'PLC1.Manufacturer')
89 nid = opcua.NodeId(
'ns=2;s=PLC1.Manufacturer;')
90 self.assertEqual(str(nid),
'ns=2;s=PLC1.Manufacturer;')
91 self.assertEqual(repr(nid),
'ns=2;s=PLC1.Manufacturer;')
94 qn = opcua.QualifiedName(
'qname', 2)
95 self.assertEqual(qn.namespace_index, 2)
96 self.assertEqual(qn.name,
'qname')
97 self.assertEqual(repr(qn),
'QualifiedName(2:qname)')
98 self.assertEqual(repr(qn), str(qn))
99 qn2 = opcua.QualifiedName(2,
'qname')
100 self.assertEqual(qn,qn2)
103 dv = opcua.DataValue(123)
104 self.assertEqual(dv.value, 123)
105 dv = opcua.DataValue(
'abc')
106 self.assertEqual(dv.value,
'abc')
107 tnow = int(time.time())
108 dv.source_timestamp = opcua.DateTime.from_time_t(tnow)
109 self.assertEqual(dv.source_timestamp.to_time_t(), tnow)
110 dv = opcua.DataValue(
True, opcua.VariantType.BOOLEAN)
111 self.assertEqual(dv.value,
True)
112 self.assertEqual(type(dv.value), bool)
115 ad=opcua.ApplicationDescription()
116 self.assertEqual(ad.type,opcua.ApplicationType.Server)
117 ad.discovery_urls=[
'a',
'b',
'c']
118 self.assertEqual(ad.discovery_urls,[
'a',
'b',
'c'])
121 utp = opcua.UserTokenPolicy()
122 self.assertEqual(utp.token_type,opcua.UserTokenType.Anonymous)
125 ed=opcua.EndpointDescription()
126 self.assertEqual(ed.security_mode, opcua.MessageSecurityMode.Invalid)
127 self.assertEqual(ed.security_level,0)
128 ed.server_description=opcua.ApplicationDescription()
129 self.assertEqual(ed.user_identify_tokens,[])
130 ed.user_identify_tokens = [opcua.UserTokenPolicy()]*3
131 self.assertEqual(len(ed.user_identify_tokens),3)
134 rd=opcua.ReferenceDescription()
135 self.assertEqual(rd.browse_name,opcua.QualifiedName())
136 self.assertEqual(rd.is_forward,
False)
137 self.assertEqual(rd.reference_type_id,opcua.NodeId())
138 self.assertEqual(rd.target_node_class,opcua.NodeClass.Unspecified)
139 self.assertEqual(rd.target_node_id,opcua.NodeId())
140 self.assertEqual(rd.target_node_type_definition,opcua.NodeId())
143 avid=opcua.ReadValueId()
144 self.assertEqual(avid.node_id, opcua.NodeId())
145 self.assertEqual(avid.attribute_id, opcua.AttributeId())
146 self.assertEqual(avid.index_range,
'')
147 self.assertEqual(avid.data_encoding, opcua.QualifiedName())
150 wv=opcua.WriteValue()
151 self.assertEqual(wv.node_id, opcua.NodeId())
152 self.assertEqual(wv.attribute_id, opcua.AttributeId())
153 self.assertEqual(wv.index_range,
'')
154 self.assertEqual(wv.value.value,
None)
157 tnow1 = int(time.time())
158 tnow = int((datetime.datetime.utcnow() - datetime.datetime(1970,1,1)).total_seconds())
159 self.assertEqual(tnow, tnow1)
161 dt = opcua.DateTime.from_time_t(tnow)
162 self.assertEqual(tnow, dt.to_time_t())
164 pydt = dt.to_datetime()
165 self.assertEqual(tnow, int((pydt - datetime.datetime(1970,1,1)).total_seconds()))
167 dt2 = opcua.DateTime(pydt)
169 pydt2 = dt.to_datetime()
170 self.assertEqual(pydt, pydt2)
173 event = opcua.Event()
174 txt =
"This is string" 176 self.assertEqual(txt, event.message)
182 Tests that will be run twice. Once on server side and once on 183 client side since we have been carefull to have the exact 184 same api on server and client side 188 root = self.opc.get_root_node()
189 self.assertEqual(opcua.QualifiedName(
'Root', 0), root.get_browse_name())
190 nid = opcua.NodeId(84, 0)
191 self.assertEqual(nid, root.get_id())
194 objects = self.opc.get_objects_node()
195 self.assertEqual(opcua.QualifiedName(
'Objects', 0), objects.get_browse_name())
196 nid = opcua.NodeId(85, 0)
197 self.assertEqual(nid, objects.get_id())
200 objects = self.opc.get_objects_node()
201 f = objects.add_folder(3,
'MyFolder')
202 v = f.add_variable(3,
'MyVariable', 6)
203 p = f.add_property(3,
'MyProperty', 10)
204 childs = f.get_children()
205 self.assertTrue(v
in childs)
206 self.assertTrue(p
in childs)
209 objects = self.opc.get_objects_node()
210 v = objects.add_variable(
'ns=3;i=888;',
'3:numericnodefromstring', 99)
211 nid = opcua.NodeId(888, 3)
212 qn = opcua.QualifiedName(
'numericnodefromstring', 3)
213 self.assertEqual(nid, v.get_id())
214 self.assertEqual(qn, v.get_browse_name())
217 objects = self.opc.get_objects_node()
218 v = objects.add_variable(
'ns=3;s=stringid;',
'3:stringnodefromstring', [68])
219 nid = opcua.NodeId(
'stringid', 3)
220 qn = opcua.QualifiedName(
'stringnodefromstring', 3)
221 self.assertEqual(nid, v.get_id())
222 self.assertEqual(qn, v.get_browse_name())
225 objects = self.opc.get_objects_node()
226 v = objects.add_variable(
'ns=3;s=stringarrayid;',
'9:stringarray', [
'l',
'b'])
227 nid = opcua.NodeId(
'stringarrayid', 3)
228 qn = opcua.QualifiedName(
'stringarray', 9)
229 self.assertEqual(nid, v.get_id())
230 self.assertEqual(qn, v.get_browse_name())
232 self.assertEqual([
'l',
'b'], val)
235 objects = self.opc.get_objects_node()
236 nid = opcua.NodeId(9999, 3)
237 qn = opcua.QualifiedName(
'AddNodeVar1', 3)
238 v1 = objects.add_variable(nid, qn, 0)
239 self.assertEqual(nid, v1.get_id())
240 self.assertEqual(qn, v1.get_browse_name())
243 objects = self.opc.get_objects_node()
244 qn = opcua.QualifiedName(
'AddNodeVar2', 3)
245 nid = opcua.NodeId(
'AddNodeVar2Id', 3)
246 v2 = objects.add_variable(nid, qn, 0)
247 self.assertEqual(nid, v2.get_id())
248 self.assertEqual(qn, v2.get_browse_name())
251 objects = self.opc.get_objects_node()
252 o = objects.add_object(
'ns=2;i=101;',
'2:AddFindObject')
253 o2 = objects.get_child(
'2:AddFindObject')
254 self.assertEqual(o, o2)
257 objects = self.opc.get_objects_node()
258 o = objects.add_object(
'ns=2;i=105;',
'2:NodePathObject')
259 root = self.opc.get_root_node()
260 o2 = root.get_child([
'0:Objects',
'2:NodePathObject'])
261 self.assertEqual(o, o2)
264 objects = self.opc.get_objects_node()
265 o = objects.add_object(
'ns=2;i=102;',
'2:AddReadObject')
266 nid = opcua.NodeId(102, 2)
267 self.assertEqual(o.get_id(), nid)
268 qn = opcua.QualifiedName(
'AddReadObject', 2)
269 self.assertEqual(o.get_browse_name(), qn)
272 o = self.opc.get_objects_node()
273 v = o.add_variable(3,
'VariableTestValue', 4.32)
275 self.assertEqual(4.32, val)
278 objects = self.opc.get_objects_node()
279 o = objects.add_object(
'ns=2;i=103;',
'2:AddReadObject')
280 with self.assertRaises(RuntimeError):
281 o2 = objects.add_object(
'ns=2;i=103;',
'2:AddReadObject')
284 o = self.opc.get_objects_node()
285 v = o.add_variable(3,
'VariableNegativeValue', 4)
288 self.assertEqual(-4.54, val)
291 statenode = self.opc.get_node(opcua.ObjectId.Server_ServerStatus_State)
292 state = statenode.get_value()
293 self.assertEqual(state, 0)
296 o = self.opc.get_objects_node()
297 v = o.add_variable(3,
'VariableArrayValue', [1, 2, 3])
299 self.assertEqual([1, 2, 3], val)
302 o = self.opc.get_objects_node()
303 v = o.add_variable(3,
'VariableArrayValue', [1, 2, 3])
306 self.assertEqual([1], val)
309 o = self.opc.get_objects_node()
310 v = o.add_variable(3,
'SubscriptionVariable', [1, 2, 3])
311 sub = self.opc.create_subscription(100, sclt)
312 handle = sub.subscribe_data_change(v)
314 sub.unsubscribe(handle)
318 sub = self.opc.create_subscription(100, sclt)
319 handle = sub.subscribe_events()
321 sub.unsubscribe(handle)
327 sub = self.opc.create_subscription(100, msclt)
328 handle = sub.subscribe_events()
331 msg =
"this is my msg " 333 tid = datetime.datetime.now()
335 ev.source_node = self.opc.get_server_node().get_id()
336 ev.source_name =
"our server node" 338 self.srv.trigger_event(ev)
341 ret = cond.wait(50000)
342 if sys.version_info.major>2: self.assertEqual(ret,
True)
344 self.assertIsNot(msclt.ev,
None)
345 self.assertEqual(msclt.ev.message, msg)
346 self.assertEqual(msclt.ev.time.to_datetime(), tid)
347 self.assertEqual(msclt.ev.severity, 500)
348 self.assertEqual(msclt.ev.source_node, self.opc.get_server_node().get_id())
351 sub.unsubscribe(handle)
356 idx = self.opc.get_namespace_index(
'http://freeopcua.github.io')
357 self.assertEqual(idx, 1)
360 root = self.opc.get_root_node()
361 idx = self.opc.get_namespace_index(
'http://freeopcua.github.io')
362 o = root.add_object(idx,
'test_namespace')
363 self.assertEqual(idx, o.get_id().namespace_index)
364 o2 = root.get_child(
'{}:test_namespace'.
format(idx))
365 self.assertEqual(o, o2)
368 root = self.opc.get_root_node()
369 with self.assertRaises(RuntimeError):
370 server_time_node = root.get_child([
'0:Objects',
'0:Server',
'0:nonexistingnode'])
374 test subscriptions. This is far too complicated for a unittest but, setting up subscriptions requires a lot of code, so when we first set it up, it is best to test as many things as possible 379 o = self.opc.get_objects_node()
383 v1 = o.add_variable(3,
'SubscriptionVariableV1', startv1)
384 sub = self.opc.create_subscription(100, msclt)
385 handle1 = sub.subscribe_data_change(v1)
390 if sys.version_info.major>2: self.assertEqual(ret,
True)
392 self.assertEqual(msclt.value, startv1)
393 self.assertEqual(msclt.node, v1)
399 if sys.version_info.major>2: self.assertEqual(ret,
True)
401 self.assertEqual(msclt.node, v1)
402 self.assertEqual(msclt.value, [5])
404 sub.unsubscribe(handle1)
408 root = self.opc.get_root_node()
409 server_time_node = root.get_child([
'0:Objects',
'0:Server',
'0:ServerStatus',
'0:CurrentTime'])
410 correct = self.opc.get_node(opcua.ObjectId.Server_ServerStatus_CurrentTime)
411 self.assertEqual(server_time_node, correct)
417 server_time_node = self.opc.get_node(opcua.ObjectId.Server_ServerStatus_CurrentTime)
419 sub = self.opc.create_subscription(200, msclt)
420 handle = sub.subscribe_data_change(server_time_node)
424 if sys.version_info.major>2: self.assertEqual(ret,
True)
426 self.assertEqual(msclt.node, server_time_node)
429 sub.unsubscribe(handle)
433 time_node = self.opc.get_node(opcua.ObjectId.Server_ServerStatus_CurrentTime)
434 dt = time_node.get_value()
435 pydt = dt.to_datetime()
436 utcnow = datetime.datetime.utcnow()
437 delta = utcnow - pydt
438 self.assertTrue(delta < datetime.timedelta(seconds=1))
441 time_node = self.opc.get_node(opcua.ObjectId.Server_ServerStatus_CurrentTime)
442 now = datetime.datetime.now()
443 objects = self.opc.get_objects_node()
444 v1 = objects.add_variable(4,
"test_datetime", now)
446 self.assertEqual(now, tid.to_datetime())
453 Start a server in another process 456 Thread.__init__(self)
463 self.srv.set_endpoint(
'opc.tcp://localhost:%d' % port_num1)
466 while not self._exit.is_set():
468 if not self._queue.empty():
469 ev = self._queue.get()
470 self.srv.trigger_event(ev)
482 Run common tests on client side 483 Of course we need a server so we start a server in another 484 process using python Process module 485 Tests that can only be run on client side must be defined here 493 self.srv.started.wait()
496 self.
clt = opcua.Client();
497 self.clt.connect(
'opc.tcp://localhost:%d' % port_num1)
502 self.clt.disconnect()
512 Run common tests on server side 513 Tests that can only be run on server side must be defined here 518 self.srv.set_endpoint(
'opc.tcp://localhost:%d' % port_num2)
527 uri =
'http://mycustom.namespace.com' 528 idx1 = self.opc.register_namespace(uri)
529 idx2 = self.opc.get_namespace_index(uri)
530 self.assertEqual(idx1, idx2)
533 uri =
'http://my_very_custom.namespace.com' 534 idx = self.opc.register_namespace(uri)
535 root = self.opc.get_root_node()
536 myvar = root.add_variable(idx,
'var_in_custom_namespace', [5])
537 myid = myvar.get_id()
538 self.assertEqual(idx, myid.namespace_index)
544 if __name__ ==
'__main__':
548 unittest.main(verbosity=3)
def trigger_event(self, ev)
def test_non_existing_node(self)
def test_user_token_policy(self)
def test_add_numeric_node(self)
def event(self, handle, event)
def test_get_node_by_nodeid(self)
def test_qualifiedstring_nodeid(self)
def test_numeric_nodeid(self)
def test_subscribe_events(self)
def test_read_server_state(self)
std::string format(CStringRef format_str, ArgList args)
def test_add_exception(self)
def test_equal_nodeid(self)
def test_add_numeric_variable(self)
def test_add_string_node(self)
def test_add_find_node_(self)
def test_localized_text(self)
def event(self, handle, event)
def test_write_value(self)
def test_array_value(self)
def data_change(self, handle, node, val, attr)
def test_add_string_array_variable(self)
def test_register_use_namespace(self)
def test_qualified_name(self)
def test_register_namespace(self)
def test_datetime_read(self)
def test_endpoint_description(self)
def test_strrepr_nodeid(self)
def test_add_read_node(self)
def test_create_delete_subscription(self)
def test_zero_nodeid(self)
def data_change(self, handle, node, val, attr)
def test_array_size_one_value(self)
def test_application_description(self)
def test_subscribe_server_time(self)
def test_datetime_write(self)
def test_attribute_valueid(self)
def test_use_namespace(self)
def test_get_namespace_index(self)
def test_simple_value(self)
def test_subscription_data_change(self)
def test_add_string_variable(self)
def test_negative_value(self)
def test_string_nodeid(self)
def test_reference_description(self)