Completed
Pull Request — master (#24)
by Olivier
02:42
created

tests.test_common   F

Complexity

Total Complexity 92

Size/Duplication

Total Lines 955
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 718
dl 0
loc 955
rs 1.882
c 0
b 0
f 0
wmc 92

How to fix   Complexity   

Complexity

Complex classes like tests.test_common often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# encoding: utf-8
2
3
"""
4
Tests that will be run twice. Once on server side and once on
5
client side since we have been carefull to have the exact
6
same api on server and client side
7
"""
8
9
import pytest
10
from datetime import datetime
11
from datetime import timedelta
12
import math
13
14
from asyncua import ua, call_method_full, copy_node, uamethod, instantiate
15
from asyncua.common import ua_utils
16
17
pytestmark = pytest.mark.asyncio
18
19
20
async def add_server_methods(srv):
21
    @uamethod
22
    def func(parent, value):
23
        return value * 2
24
25
    o = srv.get_objects_node()
26
    await o.add_method(
27
        ua.NodeId("ServerMethod", 2), ua.QualifiedName('ServerMethod', 2),
28
        func, [ua.VariantType.Int64], [ua.VariantType.Int64]
29
    )
30
31
    @uamethod
32
    def func2(parent, methodname, value):
33
        if methodname == "panic":
34
            return ua.StatusCode(ua.StatusCodes.BadOutOfMemory)
35
        if methodname != "sin":
36
            res = ua.CallMethodResult()
37
            res.StatusCode = ua.StatusCode(ua.StatusCodes.BadInvalidArgument)
38
            res.InputArgumentResults = [ua.StatusCode(ua.StatusCodes.BadNotSupported), ua.StatusCode()]
39
            return res
40
        return math.sin(value)
41
42
    o = srv.get_objects_node()
43
    await o.add_method(
44
        ua.NodeId("ServerMethodArray", 2), ua.QualifiedName('ServerMethodArray', 2), func2,
45
        [ua.VariantType.String, ua.VariantType.Int64], [ua.VariantType.Int64]
46
    )
47
48
    @uamethod
49
    def func3(parent, mylist):
50
        return [i * 2 for i in mylist]
51
52
    o = srv.get_objects_node()
53
    await o.add_method(
54
        ua.NodeId("ServerMethodArray2", 2), ua.QualifiedName('ServerMethodArray2', 2), func3,
55
        [ua.VariantType.Int64], [ua.VariantType.Int64]
56
    )
57
58
    @uamethod
59
    def func4(parent):
60
        return None
61
62
    base_otype = srv.get_node(ua.ObjectIds.BaseObjectType)
63
    custom_otype = await base_otype.add_object_type(2, 'ObjectWithMethodsType')
64
    await custom_otype.add_method(2, 'ServerMethodDefault', func4)
65
    await (await custom_otype.add_method(2, 'ServerMethodMandatory', func4)).set_modelling_rule(True)
66
    await (await custom_otype.add_method(2, 'ServerMethodOptional', func4)).set_modelling_rule(False)
67
    await (await custom_otype.add_method(2, 'ServerMethodNone', func4)).set_modelling_rule(None)
68
    await o.add_object(2, 'ObjectWithMethods', custom_otype)
69
70
    @uamethod
71
    def func5(parent):
72
        return 1, 2, 3
73
74
    o = srv.get_objects_node()
75
    await o.add_method(
76
        ua.NodeId("ServerMethodTuple", 2), ua.QualifiedName('ServerMethodTuple', 2), func5, [],
77
        [ua.VariantType.Int64, ua.VariantType.Int64, ua.VariantType.Int64]
78
    )
79
80
81
async def test_find_servers(opc):
82
    servers = await opc.opc.find_servers()
83
    # FIXME : finish
84
85
86
async def test_add_node_bad_args(opc):
87
    obj = opc.opc.get_objects_node()
88
89
    with pytest.raises(TypeError):
90
        fold = await obj.add_folder(1.2, "kk")
91
92
    with pytest.raises(TypeError):
93
        fold = await obj.add_folder(ua.UaError, "khjh")
94
95
    with pytest.raises(ua.UaError):
96
        fold = await obj.add_folder("kjk", 1.2)
97
98
    with pytest.raises(TypeError):
99
        fold = await obj.add_folder("i=0;s='oooo'", 1.2)
100
101
    with pytest.raises(ua.UaError):
102
        fold = await obj.add_folder("i=0;s='oooo'", "tt:oioi")
103
104
105
async def test_delete_nodes(opc):
106
    obj = opc.opc.get_objects_node()
107
    fold = await obj.add_folder(2, "FolderToDelete")
108
    var = await fold.add_variable(2, "VarToDelete", 9.1)
109
    childs = await fold.get_children()
110
    assert var in childs
111
    await opc.opc.delete_nodes([var])
112
    with pytest.raises(ua.UaStatusCodeError):
113
        await var.set_value(7.8)
114
    with pytest.raises(ua.UaStatusCodeError):
115
        await obj.get_child(["2:FolderToDelete", "2:VarToDelete"])
116
    childs = await fold.get_children()
117
    assert var not in childs
118
119
120
async def test_delete_nodes_recursive(opc):
121
    obj = opc.opc.get_objects_node()
122
    fold = await obj.add_folder(2, "FolderToDeleteR")
123
    var = await fold.add_variable(2, "VarToDeleteR", 9.1)
124
    await opc.opc.delete_nodes([fold, var])
125
    with pytest.raises(ua.UaStatusCodeError):
126
        await var.set_value(7.8)
127
    with pytest.raises(ua.UaStatusCodeError):
128
        await obj.get_child(["2:FolderToDelete", "2:VarToDelete"])
129
130
131
async def test_delete_nodes_recursive2(opc):
132
    obj = opc.opc.get_objects_node()
133
    fold = await obj.add_folder(2, "FolderToDeleteRoot")
134
    nfold = fold
135
    mynodes = []
136
    for i in range(7):
137
        nfold = await fold.add_folder(2, "FolderToDeleteRoot")
138
        var = await fold.add_variable(2, "VarToDeleteR", 9.1)
139
        var = await fold.add_property(2, "ProToDeleteR", 9.1)
140
        prop = await fold.add_property(2, "ProToDeleteR", 9.1)
141
        o = await fold.add_object(3, "ObjToDeleteR")
142
        mynodes.append(nfold)
143
        mynodes.append(var)
144
        mynodes.append(prop)
145
        mynodes.append(o)
146
    await opc.opc.delete_nodes([fold], recursive=True)
147
    for node in mynodes:
148
        with pytest.raises(ua.UaStatusCodeError):
149
            await node.get_browse_name()
150
151
152
async def test_delete_references(opc):
153
    newtype = await opc.opc.get_node(ua.ObjectIds.HierarchicalReferences).add_reference_type(0, "HasSuperSecretVariable")
154
155
    obj = opc.opc.get_objects_node()
156
    fold = await obj.add_folder(2, "FolderToRef")
157
    var = await fold.add_variable(2, "VarToRef", 42)
158
159
    await fold.add_reference(var, newtype)
160
161
    assert [fold] == await var.get_referenced_nodes(newtype)
162
    assert [var] == await fold.get_referenced_nodes(newtype)
163
164
    await fold.delete_reference(var, newtype)
165
166
    assert [] == await var.get_referenced_nodes(newtype)
167
    assert [] == await fold.get_referenced_nodes(newtype)
168
169
    await fold.add_reference(var, newtype, bidirectional=False)
170
171
    assert [] == await var.get_referenced_nodes(newtype)
172
    assert [var] == await fold.get_referenced_nodes(newtype)
173
174
    await fold.delete_reference(var, newtype)
175
176
    assert [] == await var.get_referenced_nodes(newtype)
177
    assert [] == await fold.get_referenced_nodes(newtype)
178
179
    await var.add_reference(fold, newtype, forward=False, bidirectional=False)
180
181
    assert [fold] == await var.get_referenced_nodes(newtype)
182
    assert [] == await fold.get_referenced_nodes(newtype)
183
184
    with pytest.raises(ua.UaStatusCodeError):
185
        await fold.delete_reference(var, newtype)
186
187
    assert [fold] == await var.get_referenced_nodes(newtype)
188
    assert [] == await fold.get_referenced_nodes(newtype)
189
190
    with pytest.raises(ua.UaStatusCodeError):
191
        await var.delete_reference(fold, newtype)
192
193
    assert [fold] == await var.get_referenced_nodes(newtype)
194
    assert [] == await fold.get_referenced_nodes(newtype)
195
196
    await var.delete_reference(fold, newtype, forward=False)
197
198
    assert [] == await var.get_referenced_nodes(newtype)
199
    assert [] == await fold.get_referenced_nodes(newtype)
200
201
    # clean-up
202
    await opc.opc.delete_nodes([fold, newtype], recursive=True)
203
204
205
async def test_server_node(opc):
206
    node = opc.opc.get_server_node()
207
    assert ua.QualifiedName('Server', 0) == await node.get_browse_name()
208
209
210
async def test_root(opc):
211
    root = opc.opc.get_root_node()
212
    assert ua.QualifiedName('Root', 0) == await root.get_browse_name()
213
    assert ua.LocalizedText('Root') == await root.get_display_name()
214
    nid = ua.NodeId(84, 0)
215
    assert nid == root.nodeid
216
217
218
async def test_objects(opc):
219
    objects = opc.opc.get_objects_node()
220
    assert ua.QualifiedName('Objects', 0) == await objects.get_browse_name()
221
    nid = ua.NodeId(85, 0)
222
    assert nid == objects.nodeid
223
224
225
async def test_browse(opc):
226
    objects = opc.opc.get_objects_node()
227
    obj = await objects.add_object(4, "browsetest")
228
    folder = await obj.add_folder(4, "folder")
229
    prop = await obj.add_property(4, "property", 1)
230
    prop2 = await obj.add_property(4, "property2", 2)
231
    var = await obj.add_variable(4, "variable", 3)
232
    obj2 = await obj.add_object(4, "obj")
233
    alle = await obj.get_children()
234
    assert prop in alle
235
    assert prop2 in alle
236
    assert var in alle
237
    assert folder in alle
238
    assert obj not in alle
239
    props = await obj.get_children(refs=ua.ObjectIds.HasProperty)
240
    assert prop in props
241
    assert prop2 in props
242
    assert var not in props
243
    assert folder not in props
244
    assert obj2 not in props
245
    all_vars = await obj.get_children(nodeclassmask=ua.NodeClass.Variable)
246
    assert prop in all_vars
247
    assert var in all_vars
248
    assert folder not in props
249
    assert obj2 not in props
250
    all_objs = await obj.get_children(nodeclassmask=ua.NodeClass.Object)
251
    assert folder in all_objs
252
    assert obj2 in all_objs
253
    assert var not in all_objs
254
255
256
async def test_browse_references(opc):
257
    objects = opc.opc.get_objects_node()
258
    folder = await objects.add_folder(4, "folder")
259
260
    childs = await objects.get_referenced_nodes(
261
        refs=ua.ObjectIds.Organizes, direction=ua.BrowseDirection.Forward, includesubtypes=False
262
    )
263
    assert folder in childs
264
265
    childs = await objects.get_referenced_nodes(
266
        refs=ua.ObjectIds.Organizes, direction=ua.BrowseDirection.Both, includesubtypes=False
267
    )
268
    assert folder in childs
269
270
    childs = await objects.get_referenced_nodes(
271
        refs=ua.ObjectIds.Organizes, direction=ua.BrowseDirection.Inverse, includesubtypes=False
272
    )
273
    assert folder not in childs
274
275
    parents = await folder.get_referenced_nodes(
276
        refs=ua.ObjectIds.Organizes, direction=ua.BrowseDirection.Inverse, includesubtypes=False
277
    )
278
    assert objects in parents
279
280
    parents = await folder.get_referenced_nodes(
281
        refs=ua.ObjectIds.HierarchicalReferences, direction=ua.BrowseDirection.Inverse, includesubtypes=False
282
    )
283
    assert objects in parents
284
    assert await folder.get_parent() == objects
285
286
287
async def test_browsename_with_spaces(opc):
288
    o = opc.opc.get_objects_node()
289
    v = await o.add_variable(3, 'BNVariable with spaces and %&+?/', 1.3)
290
    v2 = await o.get_child("3:BNVariable with spaces and %&+?/")
291
    assert v == v2
292
293
294
async def test_non_existing_path(opc):
295
    root = opc.opc.get_root_node()
296
    with pytest.raises(ua.UaStatusCodeError):
297
        await root.get_child(['0:Objects', '0:Server', '0:nonexistingnode'])
298
299
300
async def test_bad_attribute(opc):
301
    root = opc.opc.get_root_node()
302
    with pytest.raises(ua.UaStatusCodeError):
303
        await root.set_value(99)
304
305
306
async def test_get_node_by_nodeid(opc):
307
    root = opc.opc.get_root_node()
308
    server_time_node = await root.get_child(['0:Objects', '0:Server', '0:ServerStatus', '0:CurrentTime'])
309
    correct = opc.opc.get_node(ua.NodeId(ua.ObjectIds.Server_ServerStatus_CurrentTime))
310
    assert server_time_node == correct
311
312
313
async def test_datetime_read(opc):
314
    time_node = opc.opc.get_node(ua.NodeId(ua.ObjectIds.Server_ServerStatus_CurrentTime))
315
    dt = await time_node.get_value()
316
    utcnow = datetime.utcnow()
317
    delta = utcnow - dt
318
    assert delta < timedelta(seconds=1)
319
320
321
async def test_datetime_write(opc):
322
    time_node = opc.opc.get_node(ua.NodeId(ua.ObjectIds.Server_ServerStatus_CurrentTime))
323
    now = datetime.utcnow()
324
    objects = opc.opc.get_objects_node()
325
    v1 = await objects.add_variable(4, "test_datetime", now)
326
    tid = await v1.get_value()
327
    assert now == tid
328
329
330
async def test_variant_array_dim(opc):
331
    objects = opc.opc.get_objects_node()
332
    l = [[[1.0, 1.0, 1.0, 1.0], [2.0, 2.0, 2.0, 2.0], [3.0, 3.0, 3.0, 3.0]],
333
        [[5.0, 5.0, 5.0, 5.0], [7.0, 8.0, 9.0, 01.0], [1.0, 1.0, 1.0, 1.0]]]
334
    v = await objects.add_variable(3, 'variableWithDims', l)
335
336
    await v.set_array_dimensions([0, 0, 0])
337
    dim = await v.get_array_dimensions()
338
    assert [0, 0, 0] == dim
339
340
    await v.set_value_rank(0)
341
    rank = await v.get_value_rank()
342
    assert 0 == rank
343
344
    v2 = await v.get_value()
345
    assert l == v2
346
    dv = await v.get_data_value()
347
    assert [2, 3, 4] == dv.Value.Dimensions
348
349
    l = [[[], [], []], [[], [], []]]
350
    variant = ua.Variant(l, ua.VariantType.UInt32)
351
    v = await objects.add_variable(3, 'variableWithDimsEmpty', variant)
352
    v2 = await v.get_value()
353
    assert l == v2
354
    dv = await v.get_data_value()
355
    assert [2, 3, 0] == dv.Value.Dimensions
356
357
358
async def test_add_numeric_variable(opc):
359
    objects = opc.opc.get_objects_node()
360
    v = await objects.add_variable('ns=3;i=888;', '3:numericnodefromstring', 99)
361
    nid = ua.NodeId(888, 3)
362
    qn = ua.QualifiedName('numericnodefromstring', 3)
363
    assert nid == v.nodeid
364
    assert qn == await v.get_browse_name()
365
366
367
async def test_add_string_variable(opc):
368
    objects = opc.opc.get_objects_node()
369
    v = await objects.add_variable('ns=3;s=stringid;', '3:stringnodefromstring', [68])
370
    nid = ua.NodeId('stringid', 3)
371
    qn = ua.QualifiedName('stringnodefromstring', 3)
372
    assert nid == v.nodeid
373
    assert qn == await v.get_browse_name()
374
375
376
async def test_utf8(opc):
377
    objects = opc.opc.get_objects_node()
378
    utf_string = "æøå@%&"
379
    bn = ua.QualifiedName(utf_string, 3)
380
    nid = ua.NodeId("æølå", 3)
381
    val = "æøå"
382
    v = await objects.add_variable(nid, bn, val)
383
    assert nid == v.nodeid
384
    val2 = await v.get_value()
385
    assert val == val2
386
    bn2 = await v.get_browse_name()
387
    assert bn == bn2
388
389
390
async def test_null_variable(opc):
391
    objects = opc.opc.get_objects_node()
392
    var = await objects.add_variable(3, 'nullstring', "a string")
393
    await var.set_value(None)
394
    val = await var.get_value()
395
    assert val is None
396
    await var.set_value("")
397
    val = await var.get_value()
398
    assert val is not None
399
    assert "" == val
400
401
402
async def test_variable_data_type(opc):
403
    objects = opc.opc.get_objects_node()
404
    var = await objects.add_variable(3, 'stringfordatatype', "a string")
405
    val = await var.get_data_type_as_variant_type()
406
    assert ua.VariantType.String == val
407
    var = await objects.add_variable(3, 'stringarrayfordatatype', ["a", "b"])
408
    val = await var.get_data_type_as_variant_type()
409
    assert ua.VariantType.String == val
410
411
412
async def test_add_string_array_variable(opc):
413
    objects = opc.opc.get_objects_node()
414
    v = await objects.add_variable('ns=3;s=stringarrayid;', '9:stringarray', ['l', 'b'])
415
    nid = ua.NodeId('stringarrayid', 3)
416
    qn = ua.QualifiedName('stringarray', 9)
417
    assert nid == v.nodeid
418
    assert qn == await v.get_browse_name()
419
    val = await v.get_value()
420
    assert ['l', 'b'] == val
421
422
423
async def test_add_numeric_node(opc):
424
    objects = opc.opc.get_objects_node()
425
    nid = ua.NodeId(9999, 3)
426
    qn = ua.QualifiedName('AddNodeVar1', 3)
427
    v1 = await objects.add_variable(nid, qn, 0)
428
    assert nid == v1.nodeid
429
    assert qn == await v1.get_browse_name()
430
431
432
async def test_add_string_node(opc):
433
    objects = opc.opc.get_objects_node()
434
    qn = ua.QualifiedName('AddNodeVar2', 3)
435
    nid = ua.NodeId('AddNodeVar2Id', 3)
436
    v2 = await objects.add_variable(nid, qn, 0)
437
    assert nid == v2.nodeid
438
    assert qn == await v2.get_browse_name()
439
440
441
async def test_add_find_node_(opc):
442
    objects = opc.opc.get_objects_node()
443
    o = await objects.add_object('ns=2;i=101;', '2:AddFindObject')
444
    o2 = await objects.get_child('2:AddFindObject')
445
    assert o == o2
446
447
448
async def test_node_path(opc):
449
    objects = opc.opc.get_objects_node()
450
    o = await objects.add_object('ns=2;i=105;', '2:NodePathObject')
451
    root = opc.opc.get_root_node()
452
    o2 = await root.get_child(['0:Objects', '2:NodePathObject'])
453
    assert o == o2
454
455
456
async def test_add_read_node(opc):
457
    objects = opc.opc.get_objects_node()
458
    o = await objects.add_object('ns=2;i=102;', '2:AddReadObject')
459
    nid = ua.NodeId(102, 2)
460
    assert nid == o.nodeid
461
    qn = ua.QualifiedName('AddReadObject', 2)
462
    assert qn == await o.get_browse_name()
463
464
465
async def test_simple_value(opc):
466
    o = opc.opc.get_objects_node()
467
    v = await o.add_variable(3, 'VariableTestValue', 4.32)
468
    val = await v.get_value()
469
    assert 4.32 == val
470
471
472
async def test_add_exception(opc):
473
    objects = opc.opc.get_objects_node()
474
    await objects.add_object('ns=2;i=103;', '2:AddReadObject')
475
    with pytest.raises(ua.UaStatusCodeError):
476
        await objects.add_object('ns=2;i=103;', '2:AddReadObject')
477
478
479
async def test_negative_value(opc):
480
    o = opc.opc.get_objects_node()
481
    v = await o.add_variable(3, 'VariableNegativeValue', 4)
482
    await v.set_value(-4.54)
483
    assert -4.54 == await v.get_value()
484
485
486
async def test_read_server_state(opc):
487
    statenode = opc.opc.get_node(ua.NodeId(ua.ObjectIds.Server_ServerStatus_State))
488
    assert 0 == await statenode.get_value()
489
490
491
async def test_bad_node(opc):
492
    bad = opc.opc.get_node(ua.NodeId(999, 999))
493
    with pytest.raises(ua.UaStatusCodeError):
494
        await bad.get_browse_name()
495
    with pytest.raises(ua.UaStatusCodeError):
496
        await bad.set_value(89)
497
    with pytest.raises(ua.UaStatusCodeError):
498
        await bad.add_object(0, "0:myobj")
499
    with pytest.raises(ua.UaStatusCodeError):
500
        await bad.get_child("0:myobj")
501
502
503
async def test_value(opc):
504
    o = opc.opc.get_objects_node()
505
    var = ua.Variant(1.98, ua.VariantType.Double)
506
    v = await o.add_variable(3, 'VariableValue', var)
507
    assert 1.98 == await v.get_value()
508
    dvar = ua.DataValue(var)
509
    dv = await v.get_data_value()
510
    assert ua.DataValue == type(dv)
511
    assert dvar.Value == dv.Value
512
    assert dvar.Value == var
513
514
515
async def test_set_value(opc):
516
    o = opc.opc.get_objects_node()
517
    var = ua.Variant(1.98, ua.VariantType.Double)
518
    dvar = ua.DataValue(var)
519
    v = await o.add_variable(3, 'VariableValue', var)
520
    await v.set_value(var.Value)
521
    v1 = await v.get_value()
522
    assert v1 == var.Value
523
    await v.set_value(var)
524
    v2 = await v.get_value()
525
    assert v2 == var.Value
526
    await v.set_data_value(dvar)
527
    v3 = await v.get_data_value()
528
    assert v3.Value == dvar.Value
529
530
531
async def test_array_value(opc):
532
    o = opc.opc.get_objects_node()
533
    v = await o.add_variable(3, 'VariableArrayValue', [1, 2, 3])
534
    assert [1, 2, 3] == await v.get_value()
535
536
537
async def test_bool_variable(opc):
538
    o = opc.opc.get_objects_node()
539
    v = await o.add_variable(3, 'BoolVariable', True)
540
    dt = await v.get_data_type_as_variant_type()
541
    assert ua.VariantType.Boolean == dt
542
    val = await v.get_value()
543
    assert val is True
544
    await v.set_value(False)
545
    val = await v.get_value()
546
    assert val is False
547
548
549
async def test_array_size_one_value(opc):
550
    o = opc.opc.get_objects_node()
551
    v = await o.add_variable(3, 'VariableArrayValue', [1, 2, 3])
552
    await v.set_value([1])
553
    assert [1] == await v.get_value()
554
555
556
async def test_use_namespace(opc):
557
    idx = await opc.opc.get_namespace_index("urn:freeopcua:python:server")
558
    assert 1 == idx
559
    root = opc.opc.get_root_node()
560
    myvar = await root.add_variable(idx, 'var_in_custom_namespace', [5])
561
    myid = myvar.nodeid
562
    assert idx == myid.NamespaceIndex
563
564
565
async def test_method(opc):
566
    o = opc.opc.get_objects_node()
567
    await o.get_child("2:ServerMethod")
568
    result = await o.call_method("2:ServerMethod", 2.1)
569
    assert 4.2 == result
570
    with pytest.raises(ua.UaStatusCodeError):
571
        # FIXME: we should raise a more precise exception
572
        await o.call_method("2:ServerMethod", 2.1, 89, 9)
573
    with pytest.raises(ua.UaStatusCodeError):
574
        await o.call_method(ua.NodeId(999), 2.1)  # non existing method
575
576
577
async def test_method_array(opc):
578
    o = opc.opc.get_objects_node()
579
    m = await o.get_child("2:ServerMethodArray")
580
    result = await o.call_method(m, "sin", ua.Variant(math.pi))
581
    assert result < 0.01
582
    with pytest.raises(ua.UaStatusCodeError) as exc_info:
583
        await o.call_method(m, "cos", ua.Variant(math.pi))
584
    assert ua.StatusCodes.BadInvalidArgument == exc_info.type.code
585
    with pytest.raises(ua.UaStatusCodeError) as exc_info:
586
        await o.call_method(m, "panic", ua.Variant(math.pi))
587
    assert ua.StatusCodes.BadOutOfMemory == exc_info.type.code
588
589
590
async def test_method_array2(opc):
591
    o = opc.opc.get_objects_node()
592
    m = await o.get_child("2:ServerMethodArray2")
593
    result = await o.call_method(m, [1.1, 3.4, 9])
594
    assert [2.2, 6.8, 18] == result
595
    result = await call_method_full(o, m, [1.1, 3.4, 9])
596
    assert [[2.2, 6.8, 18]] == result.OutputArguments
597
598
599
async def test_method_tuple(opc):
600
    o = opc.opc.get_objects_node()
601
    m = await o.get_child("2:ServerMethodTuple")
602
    result = await o.call_method(m)
603
    assert [1, 2, 3] == result
604
    result = await call_method_full(o, m)
605
    assert [1, 2, 3] == result.OutputArguments
606
607
608
async def test_method_none(opc):
609
    # this test calls the function linked to the type's method..
610
    o = await opc.opc.get_node(ua.ObjectIds.BaseObjectType).get_child("2:ObjectWithMethodsType")
611
    m = await o.get_child("2:ServerMethodDefault")
612
    result = await o.call_method(m)
613
    assert result is None
614
    result = await call_method_full(o, m)
615
    assert [] == result.OutputArguments
616
617
618
async def test_add_nodes(opc):
619
    objects = opc.opc.get_objects_node()
620
    f = await objects.add_folder(3, 'MyFolder')
621
    child = await objects.get_child("3:MyFolder")
622
    assert child == f
623
    o = await f.add_object(3, 'MyObject')
624
    child = await f.get_child("3:MyObject")
625
    assert child == o
626
    v = await f.add_variable(3, 'MyVariable', 6)
627
    child = await f.get_child("3:MyVariable")
628
    assert child == v
629
    p = await f.add_property(3, 'MyProperty', 10)
630
    child = await f.get_child("3:MyProperty")
631
    assert child == p
632
    childs = await f.get_children()
633
    assert o in childs
634
    assert v in childs
635
    assert p in childs
636
637
638
async def test_modelling_rules(opc):
639
    obj = await opc.opc.nodes.base_object_type.add_object_type(2, 'MyFooObjectType')
640
    v = await obj.add_variable(2, "myvar", 1.1)
641
    await v.set_modelling_rule(True)
642
    p = await obj.add_property(2, "myvar", 1.1)
643
    await p.set_modelling_rule(False)
644
645
    refs = await obj.get_referenced_nodes(refs=ua.ObjectIds.HasModellingRule)
646
    assert 0 == len(refs)
647
648
    refs = await v.get_referenced_nodes(refs=ua.ObjectIds.HasModellingRule)
649
    assert opc.opc.get_node(ua.ObjectIds.ModellingRule_Mandatory) == refs[0]
650
651
    refs = await p.get_referenced_nodes(refs=ua.ObjectIds.HasModellingRule)
652
    assert opc.opc.get_node(ua.ObjectIds.ModellingRule_Optional) == refs[0]
653
654
    await p.set_modelling_rule(None)
655
    refs = await p.get_referenced_nodes(refs=ua.ObjectIds.HasModellingRule)
656
    assert 0 == len(refs)
657
658
659
async def test_incl_subtypes(opc):
660
    base_type = await opc.opc.get_root_node().get_child(["0:Types", "0:ObjectTypes", "0:BaseObjectType"])
661
    descs = await base_type.get_children_descriptions(includesubtypes=True)
662
    assert len(descs) > 10
663
    descs = await base_type.get_children_descriptions(includesubtypes=False)
664
    assert 0 == len(descs)
665
666
667
async def test_add_node_with_type(opc):
668
    objects = opc.opc.get_objects_node()
669
    f = await objects.add_folder(3, 'MyFolder_TypeTest')
670
671
    o = await f.add_object(3, 'MyObject1', ua.ObjectIds.BaseObjectType)
672
    assert ua.ObjectIds.BaseObjectType == (await o.get_type_definition()).Identifier
673
674
    o = await f.add_object(3, 'MyObject2', ua.NodeId(ua.ObjectIds.BaseObjectType, 0))
675
    assert ua.ObjectIds.BaseObjectType == (await o.get_type_definition()).Identifier
676
677
    base_otype = opc.opc.get_node(ua.ObjectIds.BaseObjectType)
678
    custom_otype = await base_otype.add_object_type(2, 'MyFooObjectType')
679
680
    o = await f.add_object(3, 'MyObject3', custom_otype.nodeid)
681
    assert custom_otype.nodeid.Identifier == (await o.get_type_definition()).Identifier
682
683
    references = await o.get_references(refs=ua.ObjectIds.HasTypeDefinition, direction=ua.BrowseDirection.Forward)
684
    assert 1 == len(references)
685
    assert custom_otype.nodeid == references[0].NodeId
686
687
688
async def test_references_for_added_nodes(opc):
689
    objects = opc.opc.get_objects_node()
690
    o = await objects.add_object(3, 'MyObject')
691
    nodes = await objects.get_referenced_nodes(
692
        refs=ua.ObjectIds.Organizes, direction=ua.BrowseDirection.Forward, includesubtypes=False
693
    )
694
    assert o in nodes
695
    nodes = await o.get_referenced_nodes(
696
        refs=ua.ObjectIds.Organizes, direction=ua.BrowseDirection.Inverse, includesubtypes=False
697
    )
698
    assert objects in nodes
699
    assert objects == await o.get_parent()
700
    assert ua.ObjectIds.BaseObjectType == (await o.get_type_definition()).Identifier
701
    assert [] == await o.get_references(ua.ObjectIds.HasModellingRule)
702
703
    o2 = await o.add_object(3, 'MySecondObject')
704
    nodes = await o.get_referenced_nodes(
705
        refs=ua.ObjectIds.HasComponent, direction=ua.BrowseDirection.Forward, includesubtypes=False
706
    )
707
    assert o2 in nodes
708
    nodes = await o2.get_referenced_nodes(
709
        refs=ua.ObjectIds.HasComponent, direction=ua.BrowseDirection.Inverse, includesubtypes=False
710
    )
711
    assert o in nodes
712
    assert o == await o2.get_parent()
713
    assert ua.ObjectIds.BaseObjectType == (await o2.get_type_definition()).Identifier
714
    assert [] == await o2.get_references(ua.ObjectIds.HasModellingRule)
715
716
    v = await o.add_variable(3, 'MyVariable', 6)
717
    nodes = await o.get_referenced_nodes(
718
        refs=ua.ObjectIds.HasComponent, direction=ua.BrowseDirection.Forward, includesubtypes=False
719
    )
720
    assert v in nodes
721
    nodes = await v.get_referenced_nodes(
722
        refs=ua.ObjectIds.HasComponent, direction=ua.BrowseDirection.Inverse, includesubtypes=False
723
    )
724
    assert o in nodes
725
    assert o == await v.get_parent()
726
    assert ua.ObjectIds.BaseDataVariableType == (await v.get_type_definition()).Identifier
727
    assert [] == await v.get_references(ua.ObjectIds.HasModellingRule)
728
729
    p = await o.add_property(3, 'MyProperty', 2)
730
    nodes = await o.get_referenced_nodes(
731
        refs=ua.ObjectIds.HasProperty, direction=ua.BrowseDirection.Forward, includesubtypes=False
732
    )
733
    assert p in nodes
734
    nodes = await p.get_referenced_nodes(
735
        refs=ua.ObjectIds.HasProperty, direction=ua.BrowseDirection.Inverse, includesubtypes=False
736
    )
737
    assert o in nodes
738
    assert o == await p.get_parent()
739
    assert ua.ObjectIds.PropertyType == (await p.get_type_definition()).Identifier
740
    assert [] == await p.get_references(ua.ObjectIds.HasModellingRule)
741
742
    m = await objects.get_child("2:ServerMethod")
743
    assert [] == await m.get_references(ua.ObjectIds.HasModellingRule)
744
745
746
async def test_path_string(opc):
747
    o = await (await opc.opc.nodes.objects.add_folder(1, "titif")).add_object(3, "opath")
748
    path = await o.get_path(as_string=True)
749
    assert ["0:Root", "0:Objects", "1:titif", "3:opath"] == path
750
    path = await o.get_path(2, as_string=True)
751
    assert ["1:titif", "3:opath"] == path
752
753
754
async def test_path(opc):
755
    of = await opc.opc.nodes.objects.add_folder(1, "titif")
756
    op = await of.add_object(3, "opath")
757
    path = await op.get_path()
758
    assert [opc.opc.nodes.root, opc.opc.nodes.objects, of, op] == path
759
    path = await op.get_path(2)
760
    assert [of, op] == path
761
    target = opc.opc.get_node("i=13387")
762
    path = await target.get_path()
763
    assert [
764
               opc.opc.nodes.root, opc.opc.nodes.types, opc.opc.nodes.object_types, opc.opc.nodes.base_object_type,
765
               opc.opc.nodes.folder_type, opc.opc.get_node(ua.ObjectIds.FileDirectoryType), target
766
           ] == path
767
768
769
async def test_get_endpoints(opc):
770
    endpoints = await opc.opc.get_endpoints()
771
    assert len(endpoints) > 0
772
    assert endpoints[0].EndpointUrl.startswith("opc.tcp://")
773
774
775
async def test_copy_node(opc):
776
    dev_t = await opc.opc.nodes.base_data_type.add_object_type(0, "MyDevice")
777
    v_t = await dev_t.add_variable(0, "sensor", 1.0)
778
    p_t = await dev_t.add_property(0, "sensor_id", "0340")
779
    ctrl_t = await dev_t.add_object(0, "controller")
780
    prop_t = await ctrl_t.add_property(0, "state", "Running")
781
    # Create device sutype
782
    devd_t = await dev_t.add_object_type(0, "MyDeviceDervived")
783
    v_t = await devd_t.add_variable(0, "childparam", 1.0)
784
    p_t = await devd_t.add_property(0, "sensorx_id", "0340")
785
    nodes = await copy_node(opc.opc.nodes.objects, dev_t)
786
    mydevice = nodes[0]
787
    assert ua.NodeClass.ObjectType == await mydevice.get_node_class()
788
    assert 4 == len(await mydevice.get_children())
789
    obj = await mydevice.get_child(["0:controller"])
790
    prop = await mydevice.get_child(["0:controller", "0:state"])
791
    assert ua.ObjectIds.PropertyType == (await prop.get_type_definition()).Identifier
792
    assert "Running" == await prop.get_value()
793
    assert prop.nodeid != prop_t.nodeid
794
795
796
async def test_instantiate_1(opc):
797
    # Create device type
798
    dev_t = await opc.opc.nodes.base_object_type.add_object_type(0, "MyDevice")
799
    v_t = await dev_t.add_variable(0, "sensor", 1.0)
800
    await v_t.set_modelling_rule(True)
801
    p_t = await dev_t.add_property(0, "sensor_id", "0340")
802
    await p_t.set_modelling_rule(True)
803
    ctrl_t = await dev_t.add_object(0, "controller")
804
    await ctrl_t.set_modelling_rule(True)
805
    v_opt_t = await dev_t.add_variable(0, "vendor", 1.0)
806
    await v_opt_t.set_modelling_rule(False)
807
    v_none_t = await dev_t.add_variable(0, "model", 1.0)
808
    await v_none_t.set_modelling_rule(None)
809
    prop_t = await ctrl_t.add_property(0, "state", "Running")
810
    await prop_t.set_modelling_rule(True)
811
812
    # Create device sutype
813
    devd_t = await dev_t.add_object_type(0, "MyDeviceDervived")
814
    v_t = await devd_t.add_variable(0, "childparam", 1.0)
815
    await v_t.set_modelling_rule(True)
816
    p_t = await devd_t.add_property(0, "sensorx_id", "0340")
817
    await p_t.set_modelling_rule(True)
818
819
    # instanciate device
820
    nodes = await instantiate(opc.opc.nodes.objects, dev_t, bname="2:Device0001")
821
    mydevice = nodes[0]
822
823
    assert ua.NodeClass.Object == await mydevice.get_node_class()
824
    assert dev_t.nodeid == await mydevice.get_type_definition()
825
    obj = await mydevice.get_child(["0:controller"])
826
    prop = await mydevice.get_child(["0:controller", "0:state"])
827
    with pytest.raises(ua.UaError):
828
        await mydevice.get_child(["0:controller", "0:vendor"])
829
    with pytest.raises(ua.UaError):
830
        await mydevice.get_child(["0:controller", "0:model"])
831
832
    assert ua.ObjectIds.PropertyType == (await prop.get_type_definition()).Identifier
833
    assert "Running" == await prop.get_value()
834
    assert prop.nodeid != prop_t.nodeid
835
836
    # instanciate device subtype
837
    nodes = await instantiate(opc.opc.nodes.objects, devd_t, bname="2:Device0002")
838
    mydevicederived = nodes[0]
839
    prop1 = await mydevicederived.get_child(["0:sensorx_id"])
840
    var1 = await mydevicederived.get_child(["0:childparam"])
841
    var_parent = await mydevicederived.get_child(["0:sensor"])
842
    prop_parent = await mydevicederived.get_child(["0:sensor_id"])
843
844
845
async def test_instantiate_string_nodeid(opc):
846
    # Create device type
847
    dev_t = await opc.opc.nodes.base_object_type.add_object_type(0, "MyDevice2")
848
    v_t = await dev_t.add_variable(0, "sensor", 1.0)
849
    await v_t.set_modelling_rule(True)
850
    p_t = await dev_t.add_property(0, "sensor_id", "0340")
851
    await p_t.set_modelling_rule(True)
852
    ctrl_t = await dev_t.add_object(0, "controller")
853
    await ctrl_t.set_modelling_rule(True)
854
    prop_t = await ctrl_t.add_property(0, "state", "Running")
855
    await prop_t.set_modelling_rule(True)
856
857
    # instanciate device
858
    nodes = await instantiate(opc.opc.nodes.objects, dev_t, nodeid=ua.NodeId("InstDevice", 2, ua.NodeIdType.String),
859
        bname="2:InstDevice")
860
    mydevice = nodes[0]
861
862
    assert ua.NodeClass.Object == await mydevice.get_node_class()
863
    assert dev_t.nodeid == await mydevice.get_type_definition()
864
    obj = await mydevice.get_child(["0:controller"])
865
    obj_nodeid_ident = obj.nodeid.Identifier
866
    prop = await mydevice.get_child(["0:controller", "0:state"])
867
    assert "InstDevice.controller" == obj_nodeid_ident
868
    assert ua.ObjectIds.PropertyType == (await prop.get_type_definition()).Identifier
869
    assert "Running" == await prop.get_value()
870
    assert prop.nodeid != prop_t.nodeid
871
872
873
async def test_variable_with_datatype(opc):
874
    v1 = await opc.opc.nodes.objects.add_variable(
875
        3, 'VariableEnumType1', ua.ApplicationType.ClientAndServer, datatype=ua.NodeId(ua.ObjectIds.ApplicationType)
876
    )
877
    tp1 = await v1.get_data_type()
878
    assert tp1 == ua.NodeId(ua.ObjectIds.ApplicationType)
879
880
    v2 = await opc.opc.nodes.objects.add_variable(
881
        3, 'VariableEnumType2', ua.ApplicationType.ClientAndServer, datatype=ua.NodeId(ua.ObjectIds.ApplicationType)
882
    )
883
    tp2 = await v2.get_data_type()
884
    assert tp2 == ua.NodeId(ua.ObjectIds.ApplicationType)
885
886
887
async def test_enum(opc):
888
    # create enum type
889
    enums = await opc.opc.get_root_node().get_child(["0:Types", "0:DataTypes", "0:BaseDataType", "0:Enumeration"])
890
    myenum_type = await enums.add_data_type(0, "MyEnum")
891
    es = await myenum_type.add_variable(
892
        0, "EnumStrings", [ua.LocalizedText("String0"), ua.LocalizedText("String1"), ua.LocalizedText("String2")],
893
        ua.VariantType.LocalizedText
894
    )
895
    # es.set_value_rank(1)
896
    # instantiate
897
    o = opc.opc.get_objects_node()
898
    myvar = await o.add_variable(2, "MyEnumVar", ua.LocalizedText("String1"), datatype=myenum_type.nodeid)
899
    # myvar.set_writable(True)
900
    # tests
901
    assert myenum_type.nodeid == await myvar.get_data_type()
902
    await myvar.set_value(ua.LocalizedText("String2"))
903
904
905
async def test_supertypes(opc):
906
    nint32 = opc.opc.get_node(ua.ObjectIds.Int32)
907
    node = await ua_utils.get_node_supertype(nint32)
908
    assert opc.opc.get_node(ua.ObjectIds.Integer) == node
909
910
    nodes = await ua_utils.get_node_supertypes(nint32)
911
    assert opc.opc.get_node(ua.ObjectIds.Number) == nodes[1]
912
    assert opc.opc.get_node(ua.ObjectIds.Integer) == nodes[0]
913
914
    # test custom
915
    dtype = await nint32.add_data_type(0, "MyCustomDataType")
916
    node = await ua_utils.get_node_supertype(dtype)
917
    assert nint32 == node
918
919
    dtype2 = await dtype.add_data_type(0, "MyCustomDataType2")
920
    node = await ua_utils.get_node_supertype(dtype2)
921
    assert dtype == node
922
923
924
async def test_base_data_type(opc):
925
    nint32 = opc.opc.get_node(ua.ObjectIds.Int32)
926
    dtype = await nint32.add_data_type(0, "MyCustomDataType")
927
    dtype2 = await dtype.add_data_type(0, "MyCustomDataType2")
928
    assert nint32 == await ua_utils.get_base_data_type(dtype)
929
    assert nint32 == await ua_utils.get_base_data_type(dtype2)
930
931
    ext = await opc.opc.nodes.objects.add_variable(0, "MyExtensionObject", ua.Argument())
932
    d = await ext.get_data_type()
933
    d = opc.opc.get_node(d)
934
    assert opc.opc.get_node(ua.ObjectIds.Structure) == await ua_utils.get_base_data_type(d)
935
    assert ua.VariantType.ExtensionObject == await ua_utils.data_type_to_variant_type(d)
936
937
938
async def test_data_type_to_variant_type(opc):
939
    test_data = {
940
        ua.ObjectIds.Boolean: ua.VariantType.Boolean,
941
        ua.ObjectIds.Byte: ua.VariantType.Byte,
942
        ua.ObjectIds.String: ua.VariantType.String,
943
        ua.ObjectIds.Int32: ua.VariantType.Int32,
944
        ua.ObjectIds.UInt32: ua.VariantType.UInt32,
945
        ua.ObjectIds.NodeId: ua.VariantType.NodeId,
946
        ua.ObjectIds.LocalizedText: ua.VariantType.LocalizedText,
947
        ua.ObjectIds.Structure: ua.VariantType.ExtensionObject,
948
        ua.ObjectIds.EnumValueType: ua.VariantType.ExtensionObject,
949
        ua.ObjectIds.Enumeration: ua.VariantType.Int32,  # enumeration
950
        ua.ObjectIds.AttributeWriteMask: ua.VariantType.UInt32,
951
        ua.ObjectIds.AxisScaleEnumeration: ua.VariantType.Int32  # enumeration
952
    }
953
    for dt, vdt in test_data.items():
954
        assert vdt == await ua_utils.data_type_to_variant_type(opc.opc.get_node(ua.NodeId(dt)))
955