test_interpreter.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import queue
  2. import threading
  3. from sccd.test.static.syntax import TestVariant
  4. from sccd.controller.controller import *
  5. from sccd.util.debug import *
  6. import sys
  7. if sys.version_info.minor >= 7:
  8. QueueImplementation = queue.SimpleQueue
  9. else:
  10. QueueImplementation = queue.Queue
  11. def run_variant(test: TestVariant, unittest):
  12. print_debug('\n'+test.name)
  13. pipe = QueueImplementation()
  14. current_big_step = []
  15. def on_output(event: OutputEvent):
  16. nonlocal current_big_step
  17. if event.port == "trace":
  18. if event.name == "big_step_completed":
  19. if len(current_big_step) > 0:
  20. pipe.put(current_big_step)
  21. current_big_step = []
  22. else:
  23. current_big_step.append(event)
  24. controller = Controller(test.cd, on_output)
  25. for bag in test.input:
  26. controller.schedule(
  27. bag.timestamp.eval(None),
  28. bag.events,
  29. controller.all_instances()) # broadcast input events to all instances
  30. def controller_thread():
  31. try:
  32. # Run as-fast-as-possible, always advancing time to the next item in event queue, no sleeping.
  33. # The call returns when the event queue is empty and therefore the simulation is finished.
  34. controller.run_until(None)
  35. except Exception as e:
  36. print_debug(e)
  37. pipe.put(e, block=True, timeout=None)
  38. return
  39. # Signal end of output
  40. pipe.put(None, block=True, timeout=None)
  41. # start the controller
  42. thread = threading.Thread(target=controller_thread)
  43. thread.daemon = True # make controller thread exit when main thread exits
  44. thread.start()
  45. # check output
  46. expected = test.output
  47. actual = []
  48. def fail(msg):
  49. thread.join()
  50. def pretty(output):
  51. return '\n'.join("%d: %s" % (i, str(big_step)) for i, big_step in enumerate(output))
  52. unittest.fail('\n'+test.name + '\n'+msg + "\n\nActual:\n" + pretty(actual) + "\n\nExpected:\n" + pretty(expected))
  53. while True:
  54. data = pipe.get(block=True, timeout=None)
  55. if isinstance(data, Exception):
  56. raise data # Exception was caught in Controller thread, throw it here instead.
  57. elif data is None:
  58. # End of output
  59. break
  60. else:
  61. actual.append(data)
  62. if actual != expected:
  63. fail("Output differs from expected.")