Tornado is blocking while testing async method using AsyncHttpTastCase

I am new to python and tornado and am trying to write a unit test for a GET method with @ tornado.web.asynchronous. But it always blocks and prints the following error message:

Failure
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 327, in run
    testMethod()
File "/Developer/PycharmProjects/CanMusic/tornadotestcase.py", line 19, in test_gen
    response = self.fetch(r'/gen')
File "/Developer/python/canmusic_env/lib/python2.7/site-packages/tornado/testing.py", line 265, in fetch
    return self.wait()
File "/Developer/python/canmusic_env/lib/python2.7/site-packages/tornado/testing.py", line 205, in wait
    self.__rethrow()
File "/Developer/python/canmusic_env/lib/python2.7/site-packages/tornado/testing.py", line 149, in __rethrow
    raise_exc_info(failure)
File "/Developer/python/canmusic_env/lib/python2.7/site-packages/tornado/testing.py", line 186, in timeout_func
    timeout)
AssertionError: Async operation timed out after 5 seconds

      

I am writing the following code as an example. Run it as unit test (nose), get above error. while running it as a standalone app and accessing the url through a browser it works fine. I also use an asynchronous version of the callback (no @ tornado.gen.engine and yield), which results in the same.

Why? Did I miss something?

import tornado.web, tornado.gen, tornado.httpclient, tornado.testing

class GenHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        http = tornado.httpclient.AsyncHTTPClient()
        response = yield tornado.gen.Task(http.fetch, 'http://www.google.com')
        self.finish()

# code for run nose test
class GenTestCase(tornado.testing.AsyncHTTPTestCase):
    def get_app(self):
        return tornado.web.Application([(r'/gen', GenHandler)])
    def test_gen(self):
        response = self.fetch(r'/gen')
        assert response.code == 200

# code for run standalone
application = tornado.web.Application([(r'/gen', GenHandler),])
if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

      

+3


source to share


2 answers


What happens is the AsyncHTTPClient in your RequestHandler is running on a different IOLoop that never starts.

You can get around this by overriding get_new_ioloop

in your test case:



def get_new_ioloop(self):
    return tornado.ioloop.IOLoop.instance()

      

This is a little weird, but this is because each AsyncTestCase / AsyncHTTPTestCase generates its own IOLoop for more isolation.

+13


source


In my case, the default timeout is insufficient as I am doing an integration test hitting a remote service.

I am overwriting the default timeout in my setup method.



def setUp(self):
    super(AsyncHTTPTestCase, self).setUp()
    ## allow more time before timeout since we are doing remote access..
    os.environ["ASYNC_TEST_TIMEOUT"] = str(60)

      

+3


source







All Articles