test_win32_shim.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. from __future__ import print_function
  2. import os
  3. import time
  4. import sys
  5. from functools import wraps
  6. from pytest import mark
  7. from zmq.tests import BaseZMQTestCase
  8. from zmq.utils.win32 import allow_interrupt
  9. def count_calls(f):
  10. @wraps(f)
  11. def _(*args, **kwds):
  12. try:
  13. return f(*args, **kwds)
  14. finally:
  15. _.__calls__ += 1
  16. _.__calls__ = 0
  17. return _
  18. @mark.new_console
  19. class TestWindowsConsoleControlHandler(BaseZMQTestCase):
  20. @mark.new_console
  21. @mark.skipif(
  22. not sys.platform.startswith('win'),
  23. reason='Windows only test')
  24. def test_handler(self):
  25. @count_calls
  26. def interrupt_polling():
  27. print('Caught CTRL-C!')
  28. from ctypes import windll
  29. from ctypes.wintypes import BOOL, DWORD
  30. kernel32 = windll.LoadLibrary('kernel32')
  31. # <http://msdn.microsoft.com/en-us/library/ms683155.aspx>
  32. GenerateConsoleCtrlEvent = kernel32.GenerateConsoleCtrlEvent
  33. GenerateConsoleCtrlEvent.argtypes = (DWORD, DWORD)
  34. GenerateConsoleCtrlEvent.restype = BOOL
  35. # Simulate CTRL-C event while handler is active.
  36. try:
  37. with allow_interrupt(interrupt_polling) as context:
  38. result = GenerateConsoleCtrlEvent(0, 0)
  39. # Sleep so that we give time to the handler to
  40. # capture the Ctrl-C event.
  41. time.sleep(0.5)
  42. except KeyboardInterrupt:
  43. pass
  44. else:
  45. if result == 0:
  46. raise WindowsError()
  47. else:
  48. self.fail('Expecting `KeyboardInterrupt` exception!')
  49. # Make sure our handler was called.
  50. self.assertEqual(interrupt_polling.__calls__, 1)