You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
3.1 KiB

  1. import re
  2. import signal
  3. import unittest
  4. import time
  5. from gooey.gui.processor import ProcessController
  6. class TestProcessor(unittest.TestCase):
  7. def test_extract_progress(self):
  8. # should pull out a number based on the supplied
  9. # regex and expression
  10. processor = ProcessController(r"^progress: (\d+)%$", None, False, 'utf-8')
  11. self.assertEqual(processor._extract_progress(b'progress: 50%'), 50)
  12. processor = ProcessController(r"total: (\d+)%$", None, False, 'utf-8')
  13. self.assertEqual(processor._extract_progress(b'my cool total: 100%'), 100)
  14. def test_extract_progress_returns_none_if_no_regex_supplied(self):
  15. processor = ProcessController(None, None, False, 'utf-8')
  16. self.assertIsNone(processor._extract_progress(b'Total progress: 100%'))
  17. def test_extract_progress_returns_none_if_no_match_found(self):
  18. processor = ProcessController(r'(\d+)%$', None, False, 'utf-8')
  19. self.assertIsNone(processor._extract_progress(b'No match in dis string'))
  20. def test_eval_progress(self):
  21. # given a match in the string, should eval the result
  22. regex = r'(\d+)/(\d+)$'
  23. processor = ProcessController(regex, r'x[0] / x[1]', False,False, 'utf-8')
  24. match = re.search(regex, '50/50')
  25. self.assertEqual(processor._eval_progress(match), 1.0)
  26. def test_eval_progress_returns_none_on_failure(self):
  27. # given a match in the string, should eval the result
  28. regex = r'(\d+)/(\d+)$'
  29. processor = ProcessController(regex, r'x[0] *^/* x[1]', False, False,'utf-8')
  30. match = re.search(regex, '50/50')
  31. self.assertIsNone(processor._eval_progress(match))
  32. def test_all_interrupts_halt_process(self):
  33. """
  34. TODO: These tests are hella flaky. I'm confident that the feature works. However, getting
  35. signals, subprocesses and unittest to all play together reliably is proving tricky. It
  36. primarily seems to come down to how long the time.sleep() is before sending the shutdown
  37. signal.
  38. """
  39. import os
  40. cmd = 'python ' + os.path.join(os.getcwd(), 'files', 'infinite_loop.py')
  41. windows_signals = [signal.SIGTERM, signal.CTRL_BREAK_EVENT, signal.CTRL_C_EVENT]
  42. try:
  43. for sig in windows_signals:
  44. print('sig', sig)
  45. processor = ProcessController(None, None, False, 'utf-8', True, shutdown_signal=sig)
  46. import subprocess
  47. processor.run(cmd)
  48. self.assertTrue(processor.running())
  49. # super-duper important sleep so that the
  50. # signal is actually received by the child process
  51. # see: https://stackoverflow.com/questions/32023719/how-to-simulate-a-terminal-ctrl-c-event-from-a-unittest
  52. time.sleep(1)
  53. processor.stop()
  54. max_wait = time.time() + 4
  55. while processor.running() and time.time() < max_wait:
  56. time.sleep(0.1)
  57. self.assertFalse(processor.running())
  58. except KeyboardInterrupt:
  59. pass