4 from twisted.python.log import err
5 from twisted.internet.interfaces import IReactorSocket
6 from twisted.internet.error import (
7 UnsupportedAddressFamily, UnsupportedSocketType)
8 from twisted.internet.protocol import ServerFactory
9 from twisted.internet.test.reactormixins import (
10 ReactorBuilder, needsRunningReactor)
13 class AdoptStreamPortErrorsTestsBuilder(ReactorBuilder):
15 Builder for testing L{IReactorSocket} implementations.
17 Generally only tests for failure cases are found here. Success cases for
18 this interface are tested elsewhere. For example, the success case for
19 I{AF_INET} is in L{twisted.internet.test.test_tcp}, since that case should
20 behave exactly the same as L{IReactorTCP.listenTCP}.
22 requiredInterfaces = [IReactorSocket]
24 def test_invalidDescriptor(self):
26 An implementation of L{IReactorSocket.adoptStreamPort} raises
27 L{socket.error} if passed an integer which is not associated with a
30 reactor = self.buildReactor()
32 probe = socket.socket()
33 fileno = probe.fileno()
36 exc = self.assertRaises(
38 reactor.adoptStreamPort, fileno, socket.AF_INET, ServerFactory())
39 self.assertEqual(exc.args[0], errno.EBADF)
42 def test_invalidAddressFamily(self):
44 An implementation of L{IReactorSocket.adoptStreamPort} raises
45 L{UnsupportedAddressFamily} if passed an address family it does not
48 reactor = self.buildReactor()
50 port = socket.socket()
52 self.addCleanup(port.close)
54 arbitrary = 2 ** 16 + 7
57 UnsupportedAddressFamily,
58 reactor.adoptStreamPort, port.fileno(), arbitrary, ServerFactory())
61 def test_stopOnlyCloses(self):
63 When the L{IListeningPort} returned by L{IReactorSocket.adoptStreamPort}
64 is stopped using C{stopListening}, the underlying socket is closed but
65 not shutdown. This allows another process which still has a reference
66 to it to continue accepting connections over it.
68 reactor = self.buildReactor()
70 portSocket = socket.socket()
71 self.addCleanup(portSocket.close)
74 portSocket.setblocking(False)
76 # The file descriptor is duplicated by adoptStreamPort
77 port = reactor.adoptStreamPort(
78 portSocket.fileno(), portSocket.family, ServerFactory())
79 d = port.stopListening()
81 # Should still be possible to accept a connection on portSocket. If
82 # it was shutdown, the exception would be EINVAL instead.
83 exc = self.assertRaises(socket.error, portSocket.accept)
84 self.assertEqual(exc.args[0], errno.EAGAIN)
85 d.addCallback(stopped)
86 d.addErrback(err, "Failed to accept on original port.")
90 lambda: d.addCallback(lambda ignored: reactor.stop()))
96 globals().update(AdoptStreamPortErrorsTestsBuilder.makeTestCaseClasses())