ut_lockable.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #!/usr/bin/env python3
  2. """
  3. test/unit_tests_d/ut_lockable.py: unit test for the MMGen suite's Lockable class
  4. """
  5. from mmgen.common import *
  6. class unit_test(object):
  7. def run_test(self,name,ut):
  8. from mmgen.base_obj import AttrCtrl,Lockable
  9. from decimal import Decimal
  10. qmsg_r('Testing class AttrCtrl...')
  11. class MyAttrCtrl(AttrCtrl):
  12. _autolock = False
  13. foo = 'fooval'
  14. ac = MyAttrCtrl()
  15. ac.lock()
  16. ac.foo = 'new fooval'
  17. ac.foo = 'new fooval2'
  18. class MyAttrCtrlAutolock(AttrCtrl): pass
  19. aca = MyAttrCtrlAutolock()
  20. class MyAttrCtrlClsCheck(AttrCtrl):
  21. _autolock = False
  22. _use_class_attr = True
  23. foo = 'fooval'
  24. bar = None
  25. acc = MyAttrCtrlClsCheck()
  26. acc.lock()
  27. acc.foo = 'new_fooval'
  28. acc.foo = 'new_fooval2'
  29. acc.bar = 'bar val'
  30. acc.bar = 1 # class attribute bar is None, so can be set to any type
  31. class MyAttrCtrlDflNone(AttrCtrl):
  32. _default_to_none = True
  33. foo = 'fooval'
  34. bar = None
  35. acdn = MyAttrCtrlDflNone()
  36. assert acdn.foo == 'fooval', f'{acdn.foo}'
  37. assert acdn.bar == None, f'{acdn.bar}'
  38. assert acdn.baz == None, f'{acdn.baz}'
  39. qmsg('OK')
  40. qmsg_r('Testing class Lockable...')
  41. class MyLockable(Lockable): # class has no attrs, like UserOpts
  42. _autolock = False
  43. _set_ok = ('foo','baz','alpha','beta','gamma','delta','epsilon')
  44. _reset_ok = ('bar','baz')
  45. lc = MyLockable()
  46. lc.foo = None
  47. lc.bar = 'barval'
  48. lc.baz = 1
  49. lc.qux = 1
  50. # are these considered set?
  51. lc.alpha = 0 # yes
  52. lc.beta = False # yes
  53. lc.gamma = Decimal('0') # yes
  54. lc.delta = 0.0 # yes
  55. lc.epsilon = [] # no
  56. lc.lock()
  57. lc.foo = 'fooval2'
  58. lc.bar = 'barval2'
  59. lc.bar = 'barval3'
  60. lc.baz = 2
  61. lc.baz = 3
  62. lc.epsilon = [0]
  63. class MyLockableClsCheck(Lockable): # class has attrs, like GlobalContext
  64. _autolock = False
  65. _use_class_attr = True
  66. _set_ok = ('foo','baz')
  67. _reset_ok = ('bar','baz')
  68. foo = None
  69. bar = 1
  70. baz = 3.5
  71. qux = 'quxval'
  72. lcc = MyLockableClsCheck()
  73. lcc.lock()
  74. lcc.foo = 'fooval2' # class attribute foo is None, so can be set to any type
  75. lcc.bar = 2
  76. lcc.bar = 3 # bar is in reset list
  77. lcc.baz = 3.2
  78. lcc.baz = 3.1 # baz is in both lists
  79. qmsg('OK')
  80. qmsg_r('Testing class Lockable with autolock...')
  81. class MyLockableAutolock(Lockable):
  82. def __init__(self):
  83. self.foo = True
  84. lca = MyLockableAutolock()
  85. assert lca._autolock == True
  86. assert lca._lock == True
  87. assert lca.foo == True
  88. class MyLockableAutolockDflNone(Lockable):
  89. _default_to_none = True
  90. foo = 0
  91. lcdn = MyLockableAutolockDflNone()
  92. assert lcdn.foo == 0
  93. assert lcdn.bar == None
  94. class MyLockableBad(Lockable):
  95. _set_ok = ('foo','bar')
  96. foo = 1
  97. qmsg('OK')
  98. qmsg_r('Checking error handling...')
  99. vmsg('')
  100. def bad1(): ac.x = 1
  101. def bad2(): acc.foo = 1
  102. def bad3(): lc.foo = 'fooval3'
  103. def bad4(): lc.baz = 'str'
  104. def bad5(): lcc.bar = 'str'
  105. def bad6(): lc.qux = 2
  106. def bad7(): lcc.qux = 'quxval2'
  107. def bad8(): lcc.foo = 'fooval3'
  108. def bad9(): lc.x = 1
  109. def bad10(): lcc.x = 1
  110. def bad11(): lc.alpha = 0
  111. def bad12(): lc.beta = False
  112. def bad13(): lc.gamma = Decimal('0')
  113. def bad14(): lc.delta = float(0)
  114. def bad15(): lc.epsilon = [0]
  115. def bad16(): lca.foo = None
  116. def bad17(): lb = MyLockableBad()
  117. def bad18(): aca.lock()
  118. def bad19(): acdn.baz = None
  119. def bad20(): lcdn.foo = 1
  120. def bad21(): lcdn.bar = None
  121. ut.process_bad_data((
  122. ('attr (1)', 'AttributeError', 'has no attr', bad1 ),
  123. ('attr (2)', 'AttributeError', 'has no attr', bad9 ),
  124. ('attr (3)', 'AttributeError', 'has no attr', bad10 ),
  125. ('attr (4)', 'AttributeError', 'has no attr', bad19 ),
  126. ('attr (5)', 'AttributeError', 'has no attr', bad21 ),
  127. ('attr type (1)', 'AttributeError', 'type', bad2 ),
  128. ("attr type (2)", 'AttributeError', 'type', bad4 ),
  129. ("attr type (3)", 'AttributeError', 'type', bad5 ),
  130. ("attr (can't set)", 'AttributeError', 'read-only', bad6 ),
  131. ("attr (can't set)", 'AttributeError', 'read-only', bad7 ),
  132. ("attr (can't set)", 'AttributeError', 'read-only', bad20 ),
  133. ("attr (can't reset)", 'AttributeError', 'reset', bad3 ),
  134. ("attr (can't reset)", 'AttributeError', 'reset', bad8 ),
  135. ("attr (can't reset)", 'AttributeError', 'reset', bad11 ),
  136. ("attr (can't reset)", 'AttributeError', 'reset', bad12 ),
  137. ("attr (can't reset)", 'AttributeError', 'reset', bad13 ),
  138. ("attr (can't reset)", 'AttributeError', 'reset', bad14 ),
  139. ("attr (can't reset)", 'AttributeError', 'reset', bad15 ),
  140. ("attr (can't set)", 'AttributeError', 'read-only', bad16 ),
  141. ("attr (bad _set_ok)", 'AssertionError', 'not found in',bad17 ),
  142. ("call to lock()", 'AssertionError', 'only once', bad18 ),
  143. ))
  144. qmsg('OK')
  145. return True