8 import socket as _orig_sock
12 from nose.tools import eq_
14 from eventlet import event, greenio, debug
15 from eventlet.hubs import get_hub
16 from eventlet.green import select, socket, time, ssl
17 from eventlet.support import capture_stderr, get_errno, six
25 def bufsized(sock, size=1):
26 """ Resize both send and receive buffers on a socket.
27 Useful for testing trampoline. Returns the socket.
30 >>> sock = bufsized(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
32 sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, size)
33 sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, size)
38 """Return the minimum buffer size that the platform supports."""
39 test_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
40 test_sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 1)
41 return test_sock.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF)
44 def using_epoll_hub(_f):
46 return 'epolls' in type(get_hub()).__module__
51 def using_kqueue_hub(_f):
53 return 'kqueue' in type(get_hub()).__module__
58 class TestGreenSocket(tests.LimitedTestCase):
59 def assertWriteToClosedFileRaises(self, fd):
60 if sys.version_info[0] < 3:
61 # 2.x socket._fileobjects are odd: writes don't check
62 # whether the socket is closed or not, and you get an
63 # AttributeError during flush if it is closed
65 self.assertRaises(Exception, fd.flush)
67 # 3.x io write to closed file-like pbject raises ValueError
68 self.assertRaises(ValueError, fd.write, b'a')
70 def test_connect_timeout(self):
71 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
73 gs = greenio.GreenSocket(s)
75 gs.connect(('192.0.2.1', 80))
76 self.fail("socket.timeout not raised")
77 except socket.timeout as e:
78 assert hasattr(e, 'args')
79 self.assertEqual(e.args[0], 'timed out')
80 except socket.error as e:
81 # unreachable is also a valid outcome
82 if not get_errno(e) in (errno.EHOSTUNREACH, errno.ENETUNREACH):
85 def test_accept_timeout(self):
86 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
91 gs = greenio.GreenSocket(s)
94 self.fail("socket.timeout not raised")
95 except socket.timeout as e:
96 assert hasattr(e, 'args')
97 self.assertEqual(e.args[0], 'timed out')
99 def test_connect_ex_timeout(self):
100 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
102 gs = greenio.GreenSocket(s)
103 e = gs.connect_ex(('192.0.2.1', 80))
104 if e not in (errno.EHOSTUNREACH, errno.ENETUNREACH):
105 self.assertEqual(e, errno.EAGAIN)
107 def test_recv_timeout(self):
108 listener = greenio.GreenSocket(socket.socket())
109 listener.bind(('', 0))
115 # accept the connection in another greenlet
116 sock, addr = listener.accept()
119 gt = eventlet.spawn(server)
121 addr = listener.getsockname()
123 client = greenio.GreenSocket(socket.socket())
124 client.settimeout(0.1)
130 self.fail("socket.timeout not raised")
131 except socket.timeout as e:
132 assert hasattr(e, 'args')
133 self.assertEqual(e.args[0], 'timed out')
138 def test_recvfrom_timeout(self):
139 gs = greenio.GreenSocket(
140 socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
146 self.fail("socket.timeout not raised")
147 except socket.timeout as e:
148 assert hasattr(e, 'args')
149 self.assertEqual(e.args[0], 'timed out')
151 def test_recvfrom_into_timeout(self):
152 buf = array.array('B')
154 gs = greenio.GreenSocket(
155 socket.socket(socket.AF_INET, socket.SOCK_DGRAM))
160 gs.recvfrom_into(buf)
161 self.fail("socket.timeout not raised")
162 except socket.timeout as e:
163 assert hasattr(e, 'args')
164 self.assertEqual(e.args[0], 'timed out')
166 def test_recv_into_timeout(self):
167 buf = array.array('B')
169 listener = greenio.GreenSocket(socket.socket())
170 listener.bind(('', 0))
176 # accept the connection in another greenlet
177 sock, addr = listener.accept()
180 gt = eventlet.spawn(server)
182 addr = listener.getsockname()
184 client = greenio.GreenSocket(socket.socket())
185 client.settimeout(0.1)
190 client.recv_into(buf)
191 self.fail("socket.timeout not raised")
192 except socket.timeout as e:
193 assert hasattr(e, 'args')
194 self.assertEqual(e.args[0], 'timed out')
199 def test_send_timeout(self):
200 self.reset_timeout(2)
201 listener = bufsized(eventlet.listen(('', 0)))
206 # accept the connection in another greenlet
207 sock, addr = listener.accept()
208 sock = bufsized(sock)
211 gt = eventlet.spawn(server)
213 addr = listener.getsockname()
215 client = bufsized(greenio.GreenSocket(socket.socket()))
218 client.settimeout(0.00001)
219 msg = b"A" * 100000 # large enough number to overwhelm most buffers
222 # want to exceed the size of the OS buffer so it'll block in a
225 total_sent += client.send(msg)
226 self.fail("socket.timeout not raised")
227 except socket.timeout as e:
228 assert hasattr(e, 'args')
229 self.assertEqual(e.args[0], 'timed out')
234 def test_sendall_timeout(self):
235 listener = greenio.GreenSocket(socket.socket())
236 listener.bind(('', 0))
242 # accept the connection in another greenlet
243 sock, addr = listener.accept()
246 gt = eventlet.spawn(server)
248 addr = listener.getsockname()
250 client = greenio.GreenSocket(socket.socket())
251 client.settimeout(0.1)
255 msg = b"A" * (8 << 20)
257 # want to exceed the size of the OS buffer so it'll block
259 self.fail("socket.timeout not raised")
260 except socket.timeout as e:
261 assert hasattr(e, 'args')
262 self.assertEqual(e.args[0], 'timed out')
267 def test_close_with_makefile(self):
268 def accept_close_early(listener):
269 # verify that the makefile and the socket are truly independent
270 # by closing the socket prior to using the made file
272 conn, addr = listener.accept()
273 fd = conn.makefile('wb')
277 self.assertWriteToClosedFileRaises(fd)
278 self.assertRaises(socket.error, conn.send, b'b')
282 def accept_close_late(listener):
283 # verify that the makefile and the socket are truly independent
284 # by closing the made file and then sending a character
286 conn, addr = listener.accept()
287 fd = conn.makefile('wb')
292 self.assertWriteToClosedFileRaises(fd)
293 self.assertRaises(socket.error, conn.send, b'b')
297 def did_it_work(server):
298 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
299 client.connect(('127.0.0.1', server.getsockname()[1]))
300 fd = client.makefile('rb')
302 assert fd.readline() == b'hello\n'
303 assert fd.read() == b''
306 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
307 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
308 server.bind(('0.0.0.0', 0))
310 killer = eventlet.spawn(accept_close_early, server)
314 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
315 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
316 server.bind(('0.0.0.0', 0))
318 killer = eventlet.spawn(accept_close_late, server)
322 def test_del_closes_socket(self):
323 def accept_once(listener):
324 # delete/overwrite the original conn
325 # object, only keeping the file object around
326 # closing the file object should close everything
328 conn, addr = listener.accept()
329 conn = conn.makefile('wb')
330 conn.write(b'hello\n')
333 self.assertWriteToClosedFileRaises(conn)
337 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
338 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
339 server.bind(('127.0.0.1', 0))
341 killer = eventlet.spawn(accept_once, server)
342 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
343 client.connect(('127.0.0.1', server.getsockname()[1]))
344 fd = client.makefile('rb')
346 assert fd.read() == b'hello\n'
347 assert fd.read() == b''
351 def test_full_duplex(self):
352 large_data = b'*' * 10 * min_buf_size()
353 listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
354 listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
355 listener.bind(('127.0.0.1', 0))
359 def send_large(sock):
360 sock.sendall(large_data)
362 def read_large(sock):
363 result = sock.recv(len(large_data))
364 while len(result) < len(large_data):
365 result += sock.recv(len(large_data))
366 self.assertEqual(result, large_data)
369 (sock, addr) = listener.accept()
370 sock = bufsized(sock)
371 send_large_coro = eventlet.spawn(send_large, sock)
373 result = sock.recv(10)
374 expected = b'hello world'
375 while len(result) < len(expected):
376 result += sock.recv(10)
377 self.assertEqual(result, expected)
378 send_large_coro.wait()
380 server_evt = eventlet.spawn(server)
381 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
382 client.connect(('127.0.0.1', listener.getsockname()[1]))
384 large_evt = eventlet.spawn(read_large, client)
386 client.sendall(b'hello world')
391 def test_sendall(self):
392 # test adapted from Marcus Cavanaugh's email
393 # it may legitimately take a while, but will eventually complete
397 def test_sendall_impl(many_bytes):
398 bufsize = max(many_bytes // 15, 2)
400 def sender(listener):
401 (sock, addr) = listener.accept()
402 sock = bufsized(sock, size=bufsize)
403 sock.sendall(b'x' * many_bytes)
404 sock.sendall(b'y' * second_bytes)
406 listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
407 listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
408 listener.bind(("", 0))
410 sender_coro = eventlet.spawn(sender, listener)
411 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
412 client.connect(('127.0.0.1', listener.getsockname()[1]))
413 bufsized(client, size=bufsize)
415 while total < many_bytes:
416 data = client.recv(min(many_bytes - total, many_bytes // 10))
422 while total < second_bytes:
423 data = client.recv(second_bytes)
431 for how_many in (1000, 10000, 100000, 1000000):
432 test_sendall_impl(how_many)
434 def test_wrap_socket(self):
435 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
436 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
437 sock.bind(('127.0.0.1', 0))
439 ssl.wrap_socket(sock)
441 def test_timeout_and_final_write(self):
442 # This test verifies that a write on a socket that we've
443 # stopped listening for doesn't result in an incorrect switch
444 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
445 server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
446 server.bind(('127.0.0.1', 0))
448 bound_port = server.getsockname()[1]
451 s2, addr = server.accept()
452 wrap_wfile = s2.makefile('wb')
455 wrap_wfile.write(b'hi')
457 evt.send(b'sent via event')
460 eventlet.spawn(sender, evt)
461 # lets the socket enter accept mode, which
462 # is necessary for connect to succeed on windows
465 # try and get some data off of this pipe
466 # but bail before any is sent
467 eventlet.Timeout(0.01)
468 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
469 client.connect(('127.0.0.1', bound_port))
470 wrap_rfile = client.makefile()
473 except eventlet.TimeoutError:
477 self.assertEqual(result, b'sent via event')
481 @tests.skip_with_pyevent
482 def test_raised_multiple_readers(self):
483 debug.hub_prevent_multiple_readers(True)
485 def handle(sock, addr):
488 raise eventlet.StopServe()
490 listener = eventlet.listen(('127.0.0.1', 0))
491 eventlet.spawn(eventlet.serve, listener, handle)
496 s = eventlet.connect(('127.0.0.1', listener.getsockname()[1]))
497 a = eventlet.spawn(reader, s)
499 self.assertRaises(RuntimeError, s.recv, 1)
503 @tests.skip_with_pyevent
504 @tests.skip_if(using_epoll_hub)
505 @tests.skip_if(using_kqueue_hub)
506 def test_closure(self):
507 def spam_to_me(address):
508 sock = eventlet.connect(address)
511 sock.sendall(b'hello world')
512 except socket.error as e:
513 if get_errno(e) == errno.EPIPE:
517 server = eventlet.listen(('127.0.0.1', 0))
518 sender = eventlet.spawn(spam_to_me, server.getsockname())
519 client, address = server.accept()
525 data = client.recv(1024)
527 except socket.error as e:
528 # we get an EBADF because client is closed in the same process
529 # (but a different greenthread)
530 if get_errno(e) != errno.EBADF:
536 reader = eventlet.spawn(reader)
537 eventlet.spawn_n(closer)
541 def test_invalid_connection(self):
542 # find an unused port by creating a socket then closing it
543 listening_socket = eventlet.listen(('127.0.0.1', 0))
544 port = listening_socket.getsockname()[1]
545 listening_socket.close()
546 self.assertRaises(socket.error, eventlet.connect, ('127.0.0.1', port))
548 def test_zero_timeout_and_back(self):
549 listen = eventlet.listen(('', 0))
550 # Keep reference to server side of socket
551 server = eventlet.spawn(listen.accept)
552 client = eventlet.connect(listen.getsockname())
554 client.settimeout(0.05)
555 # Now must raise socket.timeout
556 self.assertRaises(socket.timeout, client.recv, 1)
559 # Now must raise socket.error with EAGAIN
563 except socket.error as e:
564 assert get_errno(e) == errno.EAGAIN
566 client.settimeout(0.05)
567 # Now socket.timeout again
568 self.assertRaises(socket.timeout, client.recv, 1)
571 def test_default_nonblocking(self):
572 sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
573 flags = fcntl.fcntl(sock1.fd.fileno(), fcntl.F_GETFL)
574 assert flags & os.O_NONBLOCK
576 sock2 = socket.socket(sock1.fd)
577 flags = fcntl.fcntl(sock2.fd.fileno(), fcntl.F_GETFL)
578 assert flags & os.O_NONBLOCK
580 def test_dup_nonblocking(self):
581 sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
582 flags = fcntl.fcntl(sock1.fd.fileno(), fcntl.F_GETFL)
583 assert flags & os.O_NONBLOCK
586 flags = fcntl.fcntl(sock2.fd.fileno(), fcntl.F_GETFL)
587 assert flags & os.O_NONBLOCK
589 def test_skip_nonblocking(self):
590 sock1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
591 fd = sock1.fd.fileno()
592 flags = fcntl.fcntl(fd, fcntl.F_GETFL)
593 flags = fcntl.fcntl(fd, fcntl.F_SETFL, flags & ~os.O_NONBLOCK)
594 assert flags & os.O_NONBLOCK == 0
596 sock2 = socket.socket(sock1.fd, set_nonblocking=False)
597 flags = fcntl.fcntl(sock2.fd.fileno(), fcntl.F_GETFL)
598 assert flags & os.O_NONBLOCK == 0
600 def test_sockopt_interface(self):
601 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
602 assert sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) == 0
603 assert sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) == b'\000'
604 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
606 def test_socketpair_select(self):
607 # https://github.com/eventlet/eventlet/pull/25
608 s1, s2 = socket.socketpair()
609 assert select.select([], [s1], [], 0) == ([], [s1], [])
610 assert select.select([], [s1], [], 0) == ([], [s1], [])
612 def test_shutdown_safe(self):
613 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
616 greenio.shutdown_safe(sock)
619 def test_get_fileno_of_a_socket_works():
620 class DummySocket(object):
623 assert select.get_fileno(DummySocket()) == 123
626 def test_get_fileno_of_an_int_works():
627 assert select.get_fileno(123) == 123
630 expected_get_fileno_type_error_message = (
631 'Expected int or long, got <%s \'str\'>' % ('type' if six.PY2 else 'class'))
634 def test_get_fileno_of_wrong_type_fails():
636 select.get_fileno('foo')
637 except TypeError as ex:
638 assert str(ex) == expected_get_fileno_type_error_message
640 assert False, 'Expected TypeError not raised'
643 def test_get_fileno_of_a_socket_with_fileno_returning_wrong_type_fails():
644 class DummySocket(object):
648 select.get_fileno(DummySocket())
649 except TypeError as ex:
650 assert str(ex) == expected_get_fileno_type_error_message
652 assert False, 'Expected TypeError not raised'
655 class TestGreenPipe(tests.LimitedTestCase):
656 @tests.skip_on_windows
658 super(self.__class__, self).setUp()
659 self.tempdir = tempfile.mkdtemp('_green_pipe_test')
662 shutil.rmtree(self.tempdir)
663 super(self.__class__, self).tearDown()
667 rf = greenio.GreenPipe(r, 'rb')
668 wf = greenio.GreenPipe(w, 'wb', 0)
670 def sender(f, content):
671 for ch in map(six.int2byte, six.iterbytes(content)):
672 eventlet.sleep(0.0001)
676 one_line = b"12345\n"
677 eventlet.spawn(sender, wf, one_line * 5)
681 self.assertEqual(line, one_line)
682 self.assertEqual(rf.readline(), b'')
684 def test_pipe_read(self):
685 # ensure that 'readline' works properly on GreenPipes when data is not
686 # immediately available (fd is nonblocking, was raising EAGAIN)
687 # also ensures that readline() terminates on '\n' and '\r\n'
690 r = greenio.GreenPipe(r, 'rb')
691 w = greenio.GreenPipe(w, 'wb')
702 gt = eventlet.spawn(writer)
707 self.assertEqual(line, b'line\n')
710 self.assertEqual(line, b'line\r\n')
714 def test_pipe_writes_large_messages(self):
717 r = greenio.GreenPipe(r, 'rb')
718 w = greenio.GreenPipe(w, 'wb')
720 large_message = b"".join([1024 * six.int2byte(i) for i in range(65)])
723 w.write(large_message)
726 gt = eventlet.spawn(writer)
730 expected = 1024 * six.int2byte(i)
733 "expected=%r..%r, found=%r..%r iter=%d"
734 % (expected[:4], expected[-4:], buf[:4], buf[-4:], i))
737 def test_seek_on_buffered_pipe(self):
738 f = greenio.GreenPipe(self.tempdir + "/TestFile", 'wb+', 1024)
739 self.assertEqual(f.tell(), 0)
741 self.assertEqual(f.tell(), 0)
742 f.write(b'1234567890')
744 self.assertEqual(f.tell(), 10)
747 self.assertEqual(value, b'1')
748 self.assertEqual(f.tell(), 1)
750 self.assertEqual(value, b'2')
751 self.assertEqual(f.tell(), 2)
753 self.assertEqual(f.readline(), b'34567890')
755 self.assertEqual(f.readline(), b'67890')
757 self.assertEqual(f.readline(), b'1234567890')
759 self.assertEqual(f.readline(), b'')
761 def test_truncate(self):
762 f = greenio.GreenPipe(self.tempdir + "/TestFile", 'wb+', 1024)
763 f.write(b'1234567890')
765 self.assertEqual(f.tell(), 9)
768 class TestGreenIoLong(tests.LimitedTestCase):
769 TEST_TIMEOUT = 10 # the test here might take a while depending on the OS
771 @tests.skip_with_pyevent
772 def test_multiple_readers(self, clibufsize=False):
773 debug.hub_prevent_multiple_readers(False)
774 recvsize = 2 * min_buf_size()
775 sendsize = 10 * recvsize
777 # test that we can have multiple coroutines reading
778 # from the same fd. We make no guarantees about which one gets which
779 # bytes, but they should both get at least some
780 def reader(sock, results):
782 data = sock.recv(recvsize)
789 listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
790 listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
791 listener.bind(('127.0.0.1', 0))
795 (sock, addr) = listener.accept()
796 sock = bufsized(sock)
798 c1 = eventlet.spawn(reader, sock, results1)
799 c2 = eventlet.spawn(reader, sock, results2)
809 server_coro = eventlet.spawn(server)
810 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
811 client.connect(('127.0.0.1', listener.getsockname()[1]))
813 bufsized(client, size=sendsize)
816 client.sendall(b'*' * sendsize)
820 assert len(results1) > 0
821 assert len(results2) > 0
822 debug.hub_prevent_multiple_readers()
824 @tests.skipped # by rdw because it fails but it's not clear how to make it pass
825 @tests.skip_with_pyevent
826 def test_multiple_readers2(self):
827 self.test_multiple_readers(clibufsize=True)
830 class TestGreenIoStarvation(tests.LimitedTestCase):
831 # fixme: this doesn't succeed, because of eventlet's predetermined
832 # ordering. two processes, one with server, one with client eventlets
833 # might be more reliable?
835 TEST_TIMEOUT = 300 # the test here might take a while depending on the OS
837 @tests.skipped # by rdw, because it fails but it's not clear how to make it pass
838 @tests.skip_with_pyevent
839 def test_server_starvation(self, sendloops=15):
840 recvsize = 2 * min_buf_size()
841 sendsize = 10000 * recvsize
843 results = [[] for i in range(5)]
845 listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
846 listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
847 listener.bind(('127.0.0.1', 0))
848 port = listener.getsockname()[1]
851 base_time = time.time()
853 def server(my_results):
854 sock, addr = listener.accept()
862 data = sock.recv(recvsize)
864 t1 = time.time() - base_time
866 t2 = time.time() - base_time
867 my_results.append(datasize)
868 my_results.append((t1, t2))
870 datasize += len(data)
879 client = _orig_sock.socket(socket.AF_INET, socket.SOCK_STREAM)
880 client.connect(('127.0.0.1', port))
882 bufsized(client, size=sendsize)
884 for i in range(sendloops):
885 client.sendall(b'*' * sendsize)
892 servers.append(eventlet.spawn(server, r))
894 clients.append(client())
903 # now test that all of the server receive intervals overlap, and
904 # that there were no errors.
906 assert len(r) == 2, "length is %d not 2!: %s\n%s" % (len(r), r, results)
907 assert r[0] == sendsize * sendloops
908 assert len(r[1]) == 2
909 assert r[1][0] is not None
910 assert r[1][1] is not None
912 starttimes = sorted(r[1][0] for r in results)
913 endtimes = sorted(r[1][1] for r in results)
914 runlengths = sorted(r[1][1] - r[1][0] for r in results)
916 # assert that the last task started before the first task ended
917 # (our no-starvation condition)
918 assert starttimes[-1] < endtimes[0], \
919 "Not overlapping: starts %s ends %s" % (starttimes, endtimes)
921 maxstartdiff = starttimes[-1] - starttimes[0]
923 assert maxstartdiff * 2 < runlengths[0], \
924 "Largest difference in starting times more than twice the shortest running time!"
925 assert runlengths[0] * 2 > runlengths[-1], \
926 "Longest runtime more than twice as long as shortest!"
929 def test_set_nonblocking():
930 sock = _orig_sock.socket(socket.AF_INET, socket.SOCK_DGRAM)
931 fileno = sock.fileno()
932 orig_flags = fcntl.fcntl(fileno, fcntl.F_GETFL)
933 assert orig_flags & os.O_NONBLOCK == 0
934 greenio.set_nonblocking(sock)
935 new_flags = fcntl.fcntl(fileno, fcntl.F_GETFL)
936 assert new_flags == (orig_flags | os.O_NONBLOCK)
939 def test_socket_del_fails_gracefully_when_not_fully_initialized():
940 # Regression introduced in da87716714689894f23d0db7b003f26d97031e83, reported in:
941 # * GH #137 https://github.com/eventlet/eventlet/issues/137
942 # * https://bugs.launchpad.net/oslo.messaging/+bug/1369999
944 class SocketSubclass(socket.socket):
949 with capture_stderr() as err:
952 assert err.getvalue() == ''
955 def test_double_close_219():
956 tests.run_isolated('greenio_double_close_219.py')