From: Antoine Pitrou Date: Sun, 1 Apr 2012 15:25:49 +0000 (+0200) Subject: Issue #14151: Raise a ValueError, not a NameError, when trying to create X-Git-Tag: v3.3.0a3~341 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=93bba8fb8a9c6c6d5df33fed8ca9a17975b45c34;p=python Issue #14151: Raise a ValueError, not a NameError, when trying to create a multiprocessing Client or Listener with an AF_PIPE type address under non-Windows platforms. Patch by Popa Claudiu. --- 93bba8fb8a9c6c6d5df33fed8ca9a17975b45c34 diff --cc Lib/test/test_multiprocessing.py index d65cf6e1af,8de7a8d1d0..b4f511ccf8 --- a/Lib/test/test_multiprocessing.py +++ b/Lib/test/test_multiprocessing.py @@@ -2483,163 -2320,19 +2483,175 @@@ class TestStdinBadfiledescriptor(unitte assert sio.getvalue() == 'foo' +class TestWait(unittest.TestCase): + + @classmethod + def _child_test_wait(cls, w, slow): + for i in range(10): + if slow: + time.sleep(random.random()*0.1) + w.send((i, os.getpid())) + w.close() + + def test_wait(self, slow=False): + from multiprocessing.connection import wait + readers = [] + procs = [] + messages = [] + + for i in range(4): + r, w = multiprocessing.Pipe(duplex=False) + p = multiprocessing.Process(target=self._child_test_wait, args=(w, slow)) + p.daemon = True + p.start() + w.close() + readers.append(r) + procs.append(p) + self.addCleanup(p.join) + + while readers: + for r in wait(readers): + try: + msg = r.recv() + except EOFError: + readers.remove(r) + r.close() + else: + messages.append(msg) + + messages.sort() + expected = sorted((i, p.pid) for i in range(10) for p in procs) + self.assertEqual(messages, expected) + + @classmethod + def _child_test_wait_socket(cls, address, slow): + s = socket.socket() + s.connect(address) + for i in range(10): + if slow: + time.sleep(random.random()*0.1) + s.sendall(('%s\n' % i).encode('ascii')) + s.close() + + def test_wait_socket(self, slow=False): + from multiprocessing.connection import wait + l = socket.socket() + l.bind(('', 0)) + l.listen(4) + addr = ('localhost', l.getsockname()[1]) + readers = [] + procs = [] + dic = {} + + for i in range(4): + p = multiprocessing.Process(target=self._child_test_wait_socket, + args=(addr, slow)) + p.daemon = True + p.start() + procs.append(p) + self.addCleanup(p.join) + + for i in range(4): + r, _ = l.accept() + readers.append(r) + dic[r] = [] + l.close() + + while readers: + for r in wait(readers): + msg = r.recv(32) + if not msg: + readers.remove(r) + r.close() + else: + dic[r].append(msg) + + expected = ''.join('%s\n' % i for i in range(10)).encode('ascii') + for v in dic.values(): + self.assertEqual(b''.join(v), expected) + + def test_wait_slow(self): + self.test_wait(True) + + def test_wait_socket_slow(self): + self.test_wait(True) + + def test_wait_timeout(self): + from multiprocessing.connection import wait + + expected = 1 + a, b = multiprocessing.Pipe() + + start = time.time() + res = wait([a, b], 1) + delta = time.time() - start + + self.assertEqual(res, []) + self.assertLess(delta, expected + 0.5) + self.assertGreater(delta, expected - 0.5) + + b.send(None) + + start = time.time() + res = wait([a, b], 1) + delta = time.time() - start + + self.assertEqual(res, [a]) + self.assertLess(delta, 0.4) + + def test_wait_integer(self): + from multiprocessing.connection import wait + + expected = 5 + a, b = multiprocessing.Pipe() + p = multiprocessing.Process(target=time.sleep, args=(expected,)) + + p.start() + self.assertIsInstance(p.sentinel, int) + + start = time.time() + res = wait([a, p.sentinel, b], expected + 20) + delta = time.time() - start + + self.assertEqual(res, [p.sentinel]) + self.assertLess(delta, expected + 2) + self.assertGreater(delta, expected - 2) + + a.send(None) + + start = time.time() + res = wait([a, p.sentinel, b], 20) + delta = time.time() - start + + self.assertEqual(res, [p.sentinel, b]) + self.assertLess(delta, 0.4) + + b.send(None) + + start = time.time() + res = wait([a, p.sentinel, b], 20) + delta = time.time() - start + + self.assertEqual(res, [a, p.sentinel, b]) + self.assertLess(delta, 0.4) + + p.join() + + + # + # Issue 14151: Test invalid family on invalid environment + # + + class TestInvalidFamily(unittest.TestCase): + + @unittest.skipIf(WIN32, "skipped on Windows") + def test_invalid_family(self): + with self.assertRaises(ValueError): + multiprocessing.connection.Listener(r'\\.\test') + ++ testcases_other = [OtherTest, TestInvalidHandle, TestInitializers, - TestStdinBadfiledescriptor, TestWait] - TestStdinBadfiledescriptor, TestInvalidFamily] ++ TestStdinBadfiledescriptor, TestWait, TestInvalidFamily] # # diff --cc Misc/NEWS index 12ca91bf17,2fa911e4bb..fa3660c64b --- a/Misc/NEWS +++ b/Misc/NEWS @@@ -40,9 -34,10 +40,13 @@@ Core and Builtin Library ------- + - Issue #14151: Raise a ValueError, not a NameError, when trying to create + a multiprocessing Client or Listener with an AF_PIPE type address under + non-Windows platforms. Patch by Popa Claudiu. + +- Issue #14300: Under Windows, sockets created using socket.dup() now allow + overlapped I/O. Patch by sbt. + - Issue #13872: socket.detach() now marks the socket closed (as mirrored in the socket repr()). Patch by Matt Joiner.