test_terminals.py 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. # coding: utf-8
  2. import time
  3. import pytest
  4. from synergine2.config import Config
  5. from synergine2.core import Core
  6. from synergine2.cycle import CycleManager
  7. from synergine2.log import SynergineLogger
  8. from synergine2.share import shared
  9. from synergine2.simulation import Event
  10. from synergine2.simulation import Simulation
  11. from synergine2.simulation import Subjects
  12. from synergine2.terminals import Terminal
  13. from synergine2.terminals import TerminalPackage
  14. from synergine2.terminals import TerminalManager
  15. from tests import BaseTest
  16. class ValueTerminalPackage(TerminalPackage):
  17. def __init__(self, value, *args, **kwargs):
  18. super().__init__(*args, **kwargs)
  19. self.value = value
  20. class MultiplyTerminal(Terminal):
  21. def receive(self, package: ValueTerminalPackage):
  22. self.send(ValueTerminalPackage(value=package.value * 2))
  23. self.send(ValueTerminalPackage(value=package.value * 4))
  24. class DivideTerminal(Terminal):
  25. def receive(self, package: ValueTerminalPackage):
  26. self.send(ValueTerminalPackage(value=package.value / 2))
  27. self.send(ValueTerminalPackage(value=package.value / 4))
  28. class AnEvent(Event):
  29. pass
  30. class AnOtherEvent(Event):
  31. pass
  32. class SendBackTerminal(Terminal):
  33. def receive(self, package: ValueTerminalPackage):
  34. self.send(package)
  35. class TestTerminals(BaseTest):
  36. def test_terminal_communications(self):
  37. terminals_manager = TerminalManager(
  38. Config(),
  39. SynergineLogger('test'),
  40. terminals=[
  41. MultiplyTerminal(Config(), SynergineLogger('test')),
  42. ]
  43. )
  44. terminals_manager.start()
  45. terminals_manager.send(ValueTerminalPackage(value=42))
  46. # We wait max 2s (see time.sleep) to consider
  47. # process have finished. If not, it will fail
  48. packages = []
  49. for i in range(200):
  50. packages.extend(terminals_manager.receive())
  51. if len(packages) == 2:
  52. break
  53. time.sleep(0.01)
  54. assert 2 == len(packages)
  55. values = [p.value for p in packages]
  56. assert 84 in values
  57. assert 168 in values
  58. terminals_manager.stop() # pytest must execute this if have fail
  59. def test_terminals_communications(self):
  60. terminals_manager = TerminalManager(
  61. Config(),
  62. SynergineLogger('test'),
  63. terminals=[
  64. MultiplyTerminal(Config(), SynergineLogger('test')),
  65. DivideTerminal(Config(), SynergineLogger('test')),
  66. ]
  67. )
  68. terminals_manager.start()
  69. terminals_manager.send(ValueTerminalPackage(value=42))
  70. # We wait max 2s (see time.sleep) to consider
  71. # process have finished. If not, it will fail
  72. packages = []
  73. for i in range(200):
  74. packages.extend(terminals_manager.receive())
  75. if len(packages) == 4:
  76. break
  77. time.sleep(0.01)
  78. assert 4 == len(packages)
  79. values = [p.value for p in packages]
  80. assert 84 in values
  81. assert 168 in values
  82. assert 21 in values
  83. assert 10.5 in values
  84. terminals_manager.stop() # TODO pytest must execute this if have fail
  85. def test_event_listen_everything(self):
  86. class ListenEverythingTerminal(SendBackTerminal):
  87. pass
  88. terminals_manager = TerminalManager(
  89. Config(),
  90. SynergineLogger('test'),
  91. terminals=[ListenEverythingTerminal(Config(), SynergineLogger('test'))]
  92. )
  93. terminals_manager.start()
  94. terminals_manager.send(ValueTerminalPackage(value=42))
  95. an_event = AnEvent()
  96. terminals_manager.send(TerminalPackage(events=[an_event]))
  97. # We wait max 2s (see time.sleep) to consider
  98. # process have finished. If not, it will fail
  99. packages = []
  100. for i in range(200):
  101. packages.extend(terminals_manager.receive())
  102. if len(packages) == 2:
  103. break
  104. time.sleep(0.01)
  105. assert 2 == len(packages)
  106. assert 42 == packages[0].value
  107. assert AnEvent == type(packages[1].events[0])
  108. terminals_manager.stop() # TODO pytest must execute this if have fail
  109. def test_event_listen_specified(self):
  110. class ListenAnEventTerminal(SendBackTerminal):
  111. subscribed_events = [AnOtherEvent]
  112. terminals_manager = TerminalManager(
  113. Config(),
  114. SynergineLogger('test'),
  115. terminals=[ListenAnEventTerminal(Config(), SynergineLogger('test'))]
  116. )
  117. terminals_manager.start()
  118. terminals_manager.send(ValueTerminalPackage(value=42))
  119. an_event = AnEvent()
  120. an_other_event = AnOtherEvent()
  121. terminals_manager.send(TerminalPackage(events=[an_event, an_other_event]))
  122. # We wait max 10s (see time.sleep) to consider
  123. # process have finished. If not, it will fail
  124. packages = []
  125. for i in range(1000):
  126. packages.extend(terminals_manager.receive())
  127. if len(packages) == 2:
  128. break
  129. time.sleep(0.01)
  130. assert 2 == len(packages)
  131. assert AnOtherEvent == type(packages[1].events[0])
  132. terminals_manager.stop() # TODO pytest must execute this if have fail
  133. @pytest.mark.skip(reason="Buggy ! Never terminate, all processes closed ?")
  134. def test_terminal_as_main_process(self):
  135. shared.reset()
  136. config = Config()
  137. logger = SynergineLogger('test')
  138. simulation = Simulation(config)
  139. simulation.subjects = Subjects(simulation=simulation)
  140. cycle_manager = CycleManager(
  141. config=config,
  142. logger=logger,
  143. simulation=simulation,
  144. )
  145. class MyMainTerminal(Terminal):
  146. main_process = True
  147. terminal = MyMainTerminal(config, logger)
  148. class Terminated(Exception):
  149. pass
  150. class MyCore(Core):
  151. def _end_cycle(self):
  152. self._continue = False
  153. core = MyCore(
  154. config=config,
  155. logger=logger,
  156. simulation=simulation,
  157. cycle_manager=cycle_manager,
  158. terminal_manager=TerminalManager(
  159. config=config,
  160. logger=logger,
  161. terminals=[terminal],
  162. ),
  163. )
  164. core.run()
  165. pass