test_win32pipe.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import unittest
  2. import time
  3. import threading
  4. from pywin32_testutil import str2bytes # py3k-friendly helper
  5. import win32pipe
  6. import win32file
  7. import win32event
  8. import pywintypes
  9. import winerror
  10. import win32con
  11. class PipeTests(unittest.TestCase):
  12. pipename = "\\\\.\\pipe\\python_test_pipe"
  13. def _serverThread(self, pipe_handle, event, wait_time):
  14. # just do one connection and terminate.
  15. hr = win32pipe.ConnectNamedPipe(pipe_handle)
  16. self.failUnless(hr in (0, winerror.ERROR_PIPE_CONNECTED), "Got error code 0x%x" % (hr,))
  17. hr, got = win32file.ReadFile(pipe_handle, 100)
  18. self.failUnlessEqual(got, str2bytes("foo\0bar"))
  19. time.sleep(wait_time)
  20. win32file.WriteFile(pipe_handle, str2bytes("bar\0foo"))
  21. pipe_handle.Close()
  22. event.set()
  23. def startPipeServer(self, event, wait_time = 0):
  24. openMode = win32pipe.PIPE_ACCESS_DUPLEX
  25. pipeMode = win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT
  26. sa = pywintypes.SECURITY_ATTRIBUTES()
  27. sa.SetSecurityDescriptorDacl ( 1, None, 0 )
  28. pipe_handle = win32pipe.CreateNamedPipe(self.pipename,
  29. openMode,
  30. pipeMode,
  31. win32pipe.PIPE_UNLIMITED_INSTANCES,
  32. 0,
  33. 0,
  34. 2000,
  35. sa)
  36. threading.Thread(target=self._serverThread, args=(pipe_handle, event, wait_time)).start()
  37. def testCallNamedPipe(self):
  38. event = threading.Event()
  39. self.startPipeServer(event)
  40. got = win32pipe.CallNamedPipe(self.pipename,str2bytes("foo\0bar"), 1024, win32pipe.NMPWAIT_WAIT_FOREVER)
  41. self.failUnlessEqual(got, str2bytes("bar\0foo"))
  42. event.wait(5)
  43. self.failUnless(event.isSet(), "Pipe server thread didn't terminate")
  44. def testTransactNamedPipeBlocking(self):
  45. event = threading.Event()
  46. self.startPipeServer(event)
  47. open_mode = win32con.GENERIC_READ | win32con.GENERIC_WRITE
  48. hpipe = win32file.CreateFile(self.pipename,
  49. open_mode,
  50. 0, # no sharing
  51. None, # default security
  52. win32con.OPEN_EXISTING,
  53. 0, # win32con.FILE_FLAG_OVERLAPPED,
  54. None)
  55. # set to message mode.
  56. win32pipe.SetNamedPipeHandleState(
  57. hpipe, win32pipe.PIPE_READMODE_MESSAGE, None, None)
  58. hr, got = win32pipe.TransactNamedPipe(hpipe, str2bytes("foo\0bar"), 1024, None)
  59. self.failUnlessEqual(got, str2bytes("bar\0foo"))
  60. event.wait(5)
  61. self.failUnless(event.isSet(), "Pipe server thread didn't terminate")
  62. def testTransactNamedPipeBlockingBuffer(self):
  63. # Like testTransactNamedPipeBlocking, but a pre-allocated buffer is
  64. # passed (not really that useful, but it exercises the code path)
  65. event = threading.Event()
  66. self.startPipeServer(event)
  67. open_mode = win32con.GENERIC_READ | win32con.GENERIC_WRITE
  68. hpipe = win32file.CreateFile(self.pipename,
  69. open_mode,
  70. 0, # no sharing
  71. None, # default security
  72. win32con.OPEN_EXISTING,
  73. 0, # win32con.FILE_FLAG_OVERLAPPED,
  74. None)
  75. # set to message mode.
  76. win32pipe.SetNamedPipeHandleState(
  77. hpipe, win32pipe.PIPE_READMODE_MESSAGE, None, None)
  78. buffer = win32file.AllocateReadBuffer(1024)
  79. hr, got = win32pipe.TransactNamedPipe(hpipe, str2bytes("foo\0bar"), buffer, None)
  80. self.failUnlessEqual(got, str2bytes("bar\0foo"))
  81. event.wait(5)
  82. self.failUnless(event.isSet(), "Pipe server thread didn't terminate")
  83. def testTransactNamedPipeAsync(self):
  84. event = threading.Event()
  85. overlapped = pywintypes.OVERLAPPED()
  86. overlapped.hEvent = win32event.CreateEvent(None, 0, 0, None)
  87. self.startPipeServer(event, 0.5)
  88. open_mode = win32con.GENERIC_READ | win32con.GENERIC_WRITE
  89. hpipe = win32file.CreateFile(self.pipename,
  90. open_mode,
  91. 0, # no sharing
  92. None, # default security
  93. win32con.OPEN_EXISTING,
  94. win32con.FILE_FLAG_OVERLAPPED,
  95. None)
  96. # set to message mode.
  97. win32pipe.SetNamedPipeHandleState(
  98. hpipe, win32pipe.PIPE_READMODE_MESSAGE, None, None)
  99. buffer = win32file.AllocateReadBuffer(1024)
  100. hr, got = win32pipe.TransactNamedPipe(hpipe, str2bytes("foo\0bar"), buffer, overlapped)
  101. self.failUnlessEqual(hr, winerror.ERROR_IO_PENDING)
  102. nbytes = win32file.GetOverlappedResult(hpipe, overlapped, True)
  103. got = buffer[:nbytes]
  104. self.failUnlessEqual(got, str2bytes("bar\0foo"))
  105. event.wait(5)
  106. self.failUnless(event.isSet(), "Pipe server thread didn't terminate")
  107. if __name__ == '__main__':
  108. unittest.main()