Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Side by Side Diff: third_party/twisted_8_1/twisted/test/test_tcp_internals.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2006 Twisted Matrix Laboratories.
2 # See LICENSE for details.
3
4 """
5 Whitebox tests for TCP APIs.
6 """
7
8 import errno, socket, os
9
10 try:
11 import resource
12 except ImportError:
13 resource = None
14
15 from twisted.trial.unittest import TestCase
16
17 from twisted.python import log
18 from twisted.internet.tcp import ECONNABORTED, ENOMEM, ENFILE, EMFILE, ENOBUFS, EINPROGRESS, Port
19 from twisted.internet.protocol import ServerFactory
20 from twisted.python.runtime import platform
21 from twisted.internet.defer import maybeDeferred, gatherResults
22 from twisted.internet import reactor, interfaces
23
24
25 class PlatformAssumptionsTestCase(TestCase):
26 """
27 Test assumptions about platform behaviors.
28 """
29 socketLimit = 8192
30
31 def setUp(self):
32 self.openSockets = []
33 if resource is not None:
34 self.originalFileLimit = resource.getrlimit(resource.RLIMIT_NOFILE)
35 resource.setrlimit(resource.RLIMIT_NOFILE, (128, self.originalFileLi mit[1]))
36 self.socketLimit = 256
37
38
39 def tearDown(self):
40 while self.openSockets:
41 self.openSockets.pop().close()
42 if resource is not None:
43 # OS X implicitly lowers the hard limit in the setrlimit call
44 # above. Retrieve the new hard limit to pass in to this
45 # setrlimit call, so that it doesn't give us a permission denied
46 # error.
47 currentHardLimit = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
48 newSoftLimit = min(self.originalFileLimit[0], currentHardLimit)
49 resource.setrlimit(resource.RLIMIT_NOFILE, (newSoftLimit, currentHar dLimit))
50
51
52 def socket(self):
53 """
54 Create and return a new socket object, also tracking it so it can be
55 closed in the test tear down.
56 """
57 s = socket.socket()
58 self.openSockets.append(s)
59 return s
60
61
62 def test_acceptOutOfFiles(self):
63 """
64 Test that the platform accept(2) call fails with either L{EMFILE} or
65 L{ENOBUFS} when there are too many file descriptors open.
66 """
67 # Make a server to which to connect
68 port = self.socket()
69 port.bind(('127.0.0.1', 0))
70 serverPortNumber = port.getsockname()[1]
71 port.listen(5)
72
73 # Use up all the file descriptors
74 for i in xrange(self.socketLimit):
75 try:
76 self.socket()
77 except socket.error, e:
78 if e.args[0] in (EMFILE, ENOBUFS):
79 self.openSockets.pop().close()
80 break
81 else:
82 raise
83 else:
84 self.fail("Could provoke neither EMFILE nor ENOBUFS from platform.")
85
86 # Make a client to use to connect to the server
87 client = self.socket()
88 client.setblocking(False)
89
90 # Non-blocking connect is supposed to fail, but this is not true
91 # everywhere (e.g. freeBSD)
92 self.assertIn(client.connect_ex(('127.0.0.1', serverPortNumber)),
93 (0, EINPROGRESS))
94
95 # Make sure that the accept call fails in the way we expect.
96 exc = self.assertRaises(socket.error, port.accept)
97 self.assertIn(exc.args[0], (EMFILE, ENOBUFS))
98 if platform.getType() == "win32":
99 test_acceptOutOfFiles.skip = (
100 "Windows requires an unacceptably large amount of resources to "
101 "provoke this behavior in the naive manner.")
102
103
104
105 class SelectReactorTestCase(TestCase):
106 """
107 Tests for select-specific failure conditions.
108 """
109
110 def setUp(self):
111 self.ports = []
112 self.messages = []
113 log.addObserver(self.messages.append)
114
115
116 def tearDown(self):
117 log.removeObserver(self.messages.append)
118 return gatherResults([
119 maybeDeferred(p.stopListening)
120 for p in self.ports])
121
122
123 def port(self, portNumber, factory, interface):
124 """
125 Create, start, and return a new L{Port}, also tracking it so it can
126 be stopped in the test tear down.
127 """
128 p = Port(portNumber, factory, interface=interface)
129 p.startListening()
130 self.ports.append(p)
131 return p
132
133
134 def _acceptFailureTest(self, socketErrorNumber):
135 """
136 Test behavior in the face of an exception from C{accept(2)}.
137
138 On any exception which indicates the platform is unable or unwilling
139 to allocate further resources to us, the existing port should remain
140 listening, a message should be logged, and the exception should not
141 propagate outward from doRead.
142
143 @param socketErrorNumber: The errno to simulate from accept.
144 """
145 class FakeSocket(object):
146 """
147 Pretend to be a socket in an overloaded system.
148 """
149 def accept(self):
150 raise socket.error(
151 socketErrorNumber, os.strerror(socketErrorNumber))
152
153 factory = ServerFactory()
154 port = self.port(0, factory, interface='127.0.0.1')
155 originalSocket = port.socket
156 try:
157 port.socket = FakeSocket()
158
159 port.doRead()
160
161 expectedFormat = "Could not accept new connection (%s)"
162 expectedErrorCode = errno.errorcode[socketErrorNumber]
163 expectedMessage = expectedFormat % (expectedErrorCode,)
164 for msg in self.messages:
165 if msg.get('message') == (expectedMessage,):
166 break
167 else:
168 self.fail("Log event for failed accept not found in "
169 "%r" % (self.messages,))
170 finally:
171 port.socket = originalSocket
172
173
174 def test_tooManyFilesFromAccept(self):
175 """
176 C{accept(2)} can fail with C{EMFILE} when there are too many open file
177 descriptors in the process. Test that this doesn't negatively impact
178 any other existing connections.
179
180 C{EMFILE} mainly occurs on Linux when the open file rlimit is
181 encountered.
182 """
183 return self._acceptFailureTest(EMFILE)
184
185
186 def test_noBufferSpaceFromAccept(self):
187 """
188 Similar to L{test_tooManyFilesFromAccept}, but test the case where
189 C{accept(2)} fails with C{ENOBUFS}.
190
191 This mainly occurs on Windows and FreeBSD, but may be possible on
192 Linux and other platforms as well.
193 """
194 return self._acceptFailureTest(ENOBUFS)
195
196
197 def test_connectionAbortedFromAccept(self):
198 """
199 Similar to L{test_tooManyFilesFromAccept}, but test the case where
200 C{accept(2)} fails with C{ECONNABORTED}.
201
202 It is not clear whether this is actually possible for TCP
203 connections on modern versions of Linux.
204 """
205 return self._acceptFailureTest(ECONNABORTED)
206
207
208 def test_noFilesFromAccept(self):
209 """
210 Similar to L{test_tooManyFilesFromAccept}, but test the case where
211 C{accept(2)} fails with C{ENFILE}.
212
213 This can occur on Linux when the system has exhausted (!) its supply
214 of inodes.
215 """
216 return self._acceptFailureTest(ENFILE)
217 if platform.getType() == 'win32':
218 test_noFilesFromAccept.skip = "Windows accept(2) cannot generate ENFILE"
219
220
221 def test_noMemoryFromAccept(self):
222 """
223 Similar to L{test_tooManyFilesFromAccept}, but test the case where
224 C{accept(2)} fails with C{ENOMEM}.
225
226 On Linux at least, this can sensibly occur, even in a Python program
227 (which eats memory like no ones business), when memory has become
228 fragmented or low memory has been filled (d_alloc calls
229 kmem_cache_alloc calls kmalloc - kmalloc only allocates out of low
230 memory).
231 """
232 return self._acceptFailureTest(ENOMEM)
233 if platform.getType() == 'win32':
234 test_noMemoryFromAccept.skip = "Windows accept(2) cannot generate ENOMEM "
235
236 if not interfaces.IReactorFDSet.providedBy(reactor):
237 skipMsg = 'This test only applies to reactors that implement IReactorFDset'
238 PlatformAssumptionsTestCase.skip = skipMsg
239 SelectReactorTestCase.skip = skipMsg
240
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/test/test_tcp.py ('k') | third_party/twisted_8_1/twisted/test/test_text.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698