Busy wait loop for testing serve_forever2

This fixes race conditions, such as those in
https://travis-ci.org/letsencrypt/letsencrypt/jobs/84990239:

+ nosetests -c /dev/null --with-cover --cover-tests --cover-package acme --cover-min-percentage=100 acme
.......................................................................................................................................................................................................................................................................................................................................................Exception in thread Thread-5:
Traceback (most recent call last):
  File "/opt/python/2.7.9/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/opt/python/2.7.9/lib/python2.7/threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/opt/python/2.7.9/lib/python2.7/SocketServer.py", line 271, in handle_request
    timeout = self.socket.gettimeout()
  File "/opt/python/2.7.9/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
  File "/opt/python/2.7.9/lib/python2.7/socket.py", line 170, in _dummy
    raise error(EBADF, 'Bad file descriptor')
error: [Errno 9] Bad file descriptor
.127.0.0.1 - - [12/Oct/2015 20:08:23] "GET /foo HTTP/1.1" 404 -
.127.0.0.1 - - [12/Oct/2015 20:08:23] "GET / HTTP/1.1" 200 -
.127.0.0.1 - - [12/Oct/2015 20:08:23] "GET /.well-known/acme-challenge/eHh4eHh4eHh4eHh4eHh4eA HTTP/1.1" 200 -
.....
Name                           Stmts   Miss  Cover   Missing
------------------------------------------------------------
acme.py                            0      0   100%
acme/challenges.py               215      0   100%
acme/challenges_test.py          366      0   100%
acme/client.py                   215      0   100%
acme/client_test.py              308      0   100%
acme/crypto_util.py               92      0   100%
acme/crypto_util_test.py          53      0   100%
acme/errors.py                    19      0   100%
acme/errors_test.py               18      0   100%
acme/fields.py                    32      0   100%
acme/fields_test.py               41      0   100%
acme/jose.py                       8      0   100%
acme/jose/b64.py                  15      0   100%
acme/jose/b64_test.py             38      0   100%
acme/jose/errors.py               12      0   100%
acme/jose/errors_test.py           8      0   100%
acme/jose/interfaces.py           39      0   100%
acme/jose/interfaces_test.py      73      0   100%
acme/jose/json_util.py           170      0   100%
acme/jose/json_util_test.py      214      0   100%
acme/jose/jwa.py                 105      0   100%
acme/jose/jwa_test.py             58      0   100%
acme/jose/jwk.py                 114      0   100%
acme/jose/jwk_test.py             96      0   100%
acme/jose/jws.py                 205      0   100%
acme/jose/jws_test.py            145      0   100%
acme/jose/util.py                114      0   100%
acme/jose/util_test.py           126      0   100%
acme/jws.py                       17      0   100%
acme/jws_test.py                  27      0   100%
acme/messages.py                 184      0   100%
acme/messages_test.py            198      0   100%
acme/other.py                     21      0   100%
acme/other_test.py                48      0   100%
acme/standalone.py               102      1    99%   58
acme/standalone_test.py          109      0   100%
acme/test_util.py                 28      0   100%
acme/util.py                       3      0   100%
acme/util_test.py                  7      0   100%
------------------------------------------------------------
TOTAL                           3643      1    99%
nose.plugins.cover: ERROR: TOTAL Coverage did not reach minimum required: 100%
This commit is contained in:
Jakub Warmuz 2015-10-13 07:09:14 +00:00
parent 73ae361559
commit c4042e6ce8
No known key found for this signature in database
GPG key ID: 2A7BAD3A489B52EA

View file

@ -1,6 +1,7 @@
"""Tests for acme.standalone."""
import os
import shutil
import socket
import threading
import tempfile
import time
@ -40,9 +41,27 @@ class ACMEServerMixinTest(unittest.TestCase):
ACMEServerMixin.__init__(self)
self.server = _MockServer(("", 0), socketserver.BaseRequestHandler)
def _busy_wait(self): # pragma: no cover
# This function is used to avoid race coditions in tests, but
# not all of the functionality is always used, hence "no
# cover"
while True:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
# pylint: disable=no-member
sock.connect(self.server.socket.getsockname())
except socket.error:
pass
else:
break
finally:
sock.close()
time.sleep(1)
def test_serve_shutdown(self):
thread = threading.Thread(target=self.server.serve_forever2)
thread.start()
self._busy_wait()
self.server.shutdown2()
def test_shutdown2_not_running(self):