def test_timeout(self): _, library = dist.load() e1 = CreateEvent(True, False) self.addCleanup(CloseHandle, e1) e2 = CreateEvent(True, False) self.addCleanup(CloseHandle, e2) result = MsgWaitForMultipleObjects([e1, e2], False, 0, library.QS_ALLEVENTS) self.assertEqual(result, library.WAIT_TIMEOUT)
def test_triggered(self): _, library = dist.load() e1 = CreateEvent(True, False) self.addCleanup(CloseHandle, e1) e2 = CreateEvent(True, True) self.addCleanup(CloseHandle, e2) # The result here should be 1 because the e2 # event is triggered by e1 is not. result = MsgWaitForMultipleObjects([e1, e2], False, 0, library.QS_ALLEVENTS) self.assertEqual(result, 1)
def test_creating_duplicate_event_does_not_raise_error(self): if sys.version_info[0:2] == (3, 4): self.skipTest("Not compatible with Python 3.4") # Windows raises set the last error to ERROR_ALREADY_EXISTS # if an event object with the same name already exists. The # pywincffi API ignores this error and returns the handle # object. name = u"pywincffi-%s" % self.random_string(5) handle1 = CreateEvent(False, False, lpName=name) self.addCleanup(CloseHandle, handle1) handle2 = CreateEvent(False, False, lpName=name) self.addCleanup(CloseHandle, handle2) _, library = dist.load() self.assert_last_error(library.ERROR_ALREADY_EXISTS)
def test_raises_non_error_already_exists(self): def raise_(*_): raise WindowsAPIError("CreateEvent", "", -1) with patch.object(events, "error_check", side_effect=raise_): with self.assertRaises(WindowsAPIError): CreateEvent(False, False)
def test_type_check_on_pHandles_input_not_list(self): _, library = dist.load() e1 = CreateEvent(True, False) self.addCleanup(CloseHandle, e1) with self.assertRaises(InputError): MsgWaitForMultipleObjects(e1, False, 0, library.QS_ALLEVENTS)
def test_resets_event(self): handle = CreateEvent(True, True) self.addCleanup(CloseHandle, handle) ResetEvent(handle) _, library = dist.load() self.assertEqual(WaitForSingleObject(handle, 0), library.WAIT_TIMEOUT)
def test_can_retrieve_named_event(self): if sys.version_info[0:2] == (3, 4): self.skipTest("Not compatible with Python 3.4") _, library = dist.load() name = u"pywincffi-%s" % self.random_string(5) handle = CreateEvent(False, False, lpName=name) self.addCleanup(CloseHandle, handle) opened_event = OpenEvent(library.EVENT_ALL_ACCESS, True, name) self.addCleanup(CloseHandle, opened_event)
def test_duplication(self): event = CreateEvent(bManualReset=False, bInitialState=False) self.addCleanup(CloseHandle, event) _, library = dist.load() handle = DuplicateHandle(GetCurrentProcess(), event, GetCurrentProcess(), 0, True, library.DUPLICATE_SAME_ACCESS) self.addCleanup(CloseHandle, handle) info = GetHandleInformation(handle) self.assertEqual(info, library.HANDLE_FLAG_INHERIT)
def test_overlapped_write_file(self): # Test outline: # - Create a temp dir. # - CreateFile for writing with FILE_FLAG_OVERLAPPED. # - WriteFile in overlapped mode. # - Use GetOverlappedResult to wait for IO completion. temp_dir = tempfile.mkdtemp(prefix="pywincffi-test-ovr-") self.addCleanup(shutil.rmtree, temp_dir, ignore_errors=True) filename = text_type(os.path.join(temp_dir, "overlapped-write-file")) file_contents = b"hello overlapped world" _, lib = dist.load() handle = CreateFile( lpFileName=filename, dwDesiredAccess=lib.GENERIC_WRITE, dwCreationDisposition=lib.CREATE_NEW, dwFlagsAndAttributes=lib.FILE_FLAG_OVERLAPPED, ) # Prepare overlapped write ovr = OVERLAPPED() ovr.hEvent = CreateEvent(bManualReset=True, bInitialState=False) # Go for overlapped WriteFile. Should result in: # - num_bytes_written == 0 # - GetLastError() == ERROR_IO_PENDING # HOWEVER, https://msdn.microsoft.com/en-us/library/aa365683 states: # "Further, the WriteFile function will sometimes return TRUE with a # GetLastError value of ERROR_SUCCESS, even though it is using an # asynchronous handle (which can also return FALSE with # ERROR_IO_PENDING). # Test strategy: # - Disregard WriteFile return result. # - Assert GetLastError is either ERROR_IO_PENDING or ERROR_SUCCESS. # - Later validate that the correct number of bytes was written. _ = WriteFile(handle, file_contents, lpOverlapped=ovr) self.maybe_assert_last_error(lib.ERROR_IO_PENDING) # Block until async write is completed. num_bytes_written = GetOverlappedResult(handle, ovr, bWait=True) self.assertEqual(num_bytes_written, len(file_contents)) CloseHandle(handle)
def test_wait_failed(self): _, library = dist.load() events = [] for _ in range(library.MAXIMUM_WAIT_OBJECTS + 1): event = CreateEvent(True, False) self.addCleanup(CloseHandle, event) events.append(event) with self.assertRaises(WindowsAPIError) as error: MsgWaitForMultipleObjects(events, False, 0, library.QS_ALLEVENTS) # The maximum number of events that MsgWaitForMultipleObjects can # wait on is MAXIMUM_WAIT_OBJECTS - 1. Anything else should cause # ERROR_INVALID_PARAMETER to be raised via WindowsAPIError. self.assertEqual(error.exception.errno, library.ERROR_INVALID_PARAMETER) self.SetLastError(0)
def test_basic_reset(self): handle = CreateEvent(True, True) self.addCleanup(CloseHandle, handle) ResetEvent(handle)
def test_check_lpeventattributes_type(self): with self.assertRaises(InputError): CreateEvent(False, False, lpEventAttributes="")
def test_basic_reset(self): handle = CreateEvent(bManualReset=True, bInitialState=True) self.addCleanup(CloseHandle, handle) ResetEvent(handle)
def test_create_event_valid_handle(self): handle = CreateEvent(bManualReset=False, bInitialState=False) CloseHandle(handle) # will raise exception if the handle is invalid
def test_signaled(self): handle = CreateEvent(False, True) self.addCleanup(CloseHandle, handle) _, library = dist.load() self.assertEqual(WaitForSingleObject(handle, 0), library.WAIT_OBJECT_0)
def test_create_event_valid_handle(self): handle = CreateEvent(False, False) CloseHandle(handle) # will raise exception if the handle is invalid
def test_non_signaled(self): handle = CreateEvent(bManualReset=False, bInitialState=False) self.addCleanup(CloseHandle, handle) _, library = dist.load() self.assertEqual(WaitForSingleObject(handle, 0), library.WAIT_TIMEOUT)
def test_check_lpeventattributes_type(self): with self.assertRaises(InputError): CreateEvent(bManualReset=False, bInitialState=False, lpEventAttributes="")