Use a condition variable (threading.Event) rather than sleeps and checking a
global to determine when the server is ready to be used. This slows the test down, but should make it correct. There was a race condition before where the server could have assigned a port, yet it wasn't ready to serve requests. If the client sent a request before the server was completely ready, it would get an exception. There was machinery to try to handle this condition. All of that should be unnecessary and removed if this change works. A NOTE was added as a comment about what needs to be fixed. The buildbots will tell us if there are more errors or if this test is now stable.
This commit is contained in:
parent
5be3067742
commit
653272f0cf
|
@ -296,6 +296,9 @@ class BinaryTestCase(unittest.TestCase):
|
||||||
|
|
||||||
PORT = None
|
PORT = None
|
||||||
|
|
||||||
|
# The evt is set twice. First when the server is ready to serve.
|
||||||
|
# Second when the server has been shutdown. The user must clear
|
||||||
|
# the event after it has been set the first time to catch the second set.
|
||||||
def http_server(evt, numrequests):
|
def http_server(evt, numrequests):
|
||||||
class TestInstanceClass:
|
class TestInstanceClass:
|
||||||
def div(self, x, y):
|
def div(self, x, y):
|
||||||
|
@ -323,6 +326,7 @@ def http_server(evt, numrequests):
|
||||||
serv.register_function(lambda x,y: x+y, 'add')
|
serv.register_function(lambda x,y: x+y, 'add')
|
||||||
serv.register_function(my_function)
|
serv.register_function(my_function)
|
||||||
serv.register_instance(TestInstanceClass())
|
serv.register_instance(TestInstanceClass())
|
||||||
|
evt.set()
|
||||||
|
|
||||||
# handle up to 'numrequests' requests
|
# handle up to 'numrequests' requests
|
||||||
while numrequests > 0:
|
while numrequests > 0:
|
||||||
|
@ -336,10 +340,19 @@ def http_server(evt, numrequests):
|
||||||
PORT = None
|
PORT = None
|
||||||
evt.set()
|
evt.set()
|
||||||
|
|
||||||
|
# TODO(nnorwitz): 25-Jan-2008 since we now notify the test when the server
|
||||||
|
# is totally ready to serve, this function should not be necessary.
|
||||||
|
# It is disabled by returning False. If the buildbots don't show any
|
||||||
|
# failures for this test over the next week, all the code associated
|
||||||
|
# with this function should be removed. The code that needs to be removed
|
||||||
|
# is this function, the NOTE below, and the entire except body that
|
||||||
|
# calls this function.
|
||||||
def is_unavailable_exception(e):
|
def is_unavailable_exception(e):
|
||||||
'''Returns True if the given ProtocolError is the product of a server-side
|
'''Returns True if the given ProtocolError is the product of a server-side
|
||||||
exception caused by the 'temporarily unavailable' response sometimes
|
exception caused by the 'temporarily unavailable' response sometimes
|
||||||
given by operations on non-blocking sockets.'''
|
given by operations on non-blocking sockets.'''
|
||||||
|
return False
|
||||||
|
|
||||||
# sometimes we get a -1 error code and/or empty headers
|
# sometimes we get a -1 error code and/or empty headers
|
||||||
if e.errcode == -1 or e.headers is None:
|
if e.errcode == -1 or e.headers is None:
|
||||||
return True
|
return True
|
||||||
|
@ -367,13 +380,9 @@ class SimpleServerTestCase(unittest.TestCase):
|
||||||
serv_args = (self.evt, 1)
|
serv_args = (self.evt, 1)
|
||||||
threading.Thread(target=http_server, args=serv_args).start()
|
threading.Thread(target=http_server, args=serv_args).start()
|
||||||
|
|
||||||
# wait for port to be assigned to server
|
# wait for the server to be ready
|
||||||
n = 1000
|
self.evt.wait()
|
||||||
while n > 0 and PORT is None:
|
self.evt.clear()
|
||||||
time.sleep(0.001)
|
|
||||||
n -= 1
|
|
||||||
|
|
||||||
time.sleep(0.5)
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
# wait on the server thread to terminate
|
# wait on the server thread to terminate
|
||||||
|
@ -518,13 +527,9 @@ class FailingServerTestCase(unittest.TestCase):
|
||||||
serv_args = (self.evt, 2)
|
serv_args = (self.evt, 2)
|
||||||
threading.Thread(target=http_server, args=serv_args).start()
|
threading.Thread(target=http_server, args=serv_args).start()
|
||||||
|
|
||||||
# wait for port to be assigned to server
|
# wait for the server to be ready
|
||||||
n = 1000
|
self.evt.wait()
|
||||||
while n > 0 and PORT is None:
|
self.evt.clear()
|
||||||
time.sleep(0.001)
|
|
||||||
n -= 1
|
|
||||||
|
|
||||||
time.sleep(0.5)
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
# wait on the server thread to terminate
|
# wait on the server thread to terminate
|
||||||
|
|
Loading…
Reference in New Issue