Override does not change the order of inherited accessibles.

except when explicitely mentioned with reorder=True
improved test_modules for unique accessibles, as this
was related with Accessible.ctr

Change-Id: I61877de9300bb0297c88a6c44bb265c634937856
Reviewed-on: https://forge.frm2.tum.de/review/19693
Tested-by: JenkinsCodeReview <bjoern_pedersen@frm2.tum.de>
Reviewed-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de>
This commit is contained in:
2019-01-08 14:44:06 +01:00
committed by Enrico Faulhaber
parent 1c33a41748
commit 4f83bc42cc
4 changed files with 75 additions and 32 deletions

View File

@ -25,9 +25,9 @@ from __future__ import division, print_function
# no fixtures needed
import pytest
from secop.datatypes import BoolType, EnumType
from secop.datatypes import BoolType, EnumType, FloatRange
from secop.metaclass import ModuleMeta
from secop.modules import Communicator, Drivable, Module, Readable, Writable
from secop.modules import Communicator, Drivable, Module
from secop.params import Command, Override, Parameter
try:
@ -60,8 +60,9 @@ def test_Communicator():
q.get()
def test_ModuleMeta():
newclass = ModuleMeta.__new__(ModuleMeta, 'TestReadable', (Drivable, Writable, Readable, Module), {
newclass1 = ModuleMeta.__new__(ModuleMeta, 'TestDrivable', (Drivable,), {
"parameters" : {
'pollinterval': Override(reorder=True),
'param1' : Parameter('param1', datatype=BoolType(), default=False),
'param2': Parameter('param2', datatype=BoolType(), default=True),
},
@ -83,12 +84,19 @@ def test_ModuleMeta():
"read_value": lambda self, *args: True,
"init": lambda self, *args: [None for self.accessibles['value'].datatype in [EnumType('value', OK=1, Bad=2)]],
})
# every cmd/param has to be collected to accessibles
assert newclass.accessibles
with pytest.raises(AttributeError):
assert newclass.commands
with pytest.raises(AttributeError):
assert newclass.parameters
# first inherited accessibles, then Overrides with reorder=True and new accessibles
sortcheck1 = ['value', 'status', 'target', 'pollinterval',
'param1', 'param2', 'cmd', 'a1', 'a2', 'cmd2']
newclass2 = ModuleMeta.__new__(ModuleMeta, 'UpperClass', (newclass1,), {
"accessibles": {
'cmd2': Override('another stuff'),
'a1': Override(datatype=FloatRange(), reorder=True),
'b2': Parameter('a2', datatype=BoolType(), default=True),
},
})
sortcheck2 = ['value', 'status', 'target', 'pollinterval',
'param1', 'param2', 'cmd', 'a2', 'cmd2', 'a1', 'b2']
logger = type('LoggerStub', (object,), dict(
debug = lambda self, *a: print(*a),
@ -103,21 +111,45 @@ def test_ModuleMeta():
dispatcher = dispatcher,
))()
o1 = newclass('o1', logger, {}, srv)
o2 = newclass('o2', logger, {}, srv)
params_found= set()
ctr_found = set()
for obj in [o1, o2]:
for n, o in obj.accessibles.items():
print(n)
params_found = set() # set of instance accessibles
objects = []
for newclass, sortcheck in [(newclass1, sortcheck1), (newclass2, sortcheck2)]:
o1 = newclass('o1', logger, {}, srv)
o2 = newclass('o2', logger, {}, srv)
for obj in [o1, o2]:
objects.append(obj)
ctr_found = set()
for n, o in obj.accessibles.items():
# check that instance accessibles are unique objects
assert o not in params_found
params_found.add(o)
assert o.ctr not in ctr_found
ctr_found.add(o.ctr)
check_order = [(obj.accessibles[n].ctr, n) for n in sortcheck]
assert check_order == sorted(check_order)
# check on the level of classes
# this checks newclass1 too, as it is inherited by newclass2
for baseclass in newclass2.__mro__:
# every cmd/param has to be collected to accessibles
acs = getattr(baseclass, 'accessibles', None)
if issubclass(baseclass, Module):
assert acs is not None
else: # do not check object or mixin
acs = {}
with pytest.raises(AttributeError):
assert baseclass.commands
with pytest.raises(AttributeError):
assert baseclass.parameters
for n, o in acs.items():
# check that class accessibles are not reused as instance accessibles
assert o not in params_found
params_found.add(o)
assert o.ctr not in ctr_found
ctr_found.add(o.ctr)
o1.early_init()
o2.early_init()
o1.init_module()
o2.init_module()
for o in objects:
o.early_init()
for o in objects:
o.init_module()
q = queue.Queue()
o1.start_module(q.put)
o2.start_module(q.put)
for o in objects:
o.start_module(q.put)