Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
testing_test.py341 linesDownload Raw Back to test
1from tornado import gen, ioloop
2from tornado.httpserver import HTTPServer
3from tornado.locks import Event
4from tornado.testing import AsyncHTTPTestCase, AsyncTestCase, bind_unused_port, gen_test
5from tornado.web import Application
6import asyncio
7import contextlib
8import gc
9import os
10import platform
11import sys
12import traceback
13import unittest
14import warnings
15
16
17@contextlib.contextmanager
18def set_environ(name, value):
19    old_value = os.environ.get(name)
20    os.environ[name] = value
21
22    try:
23        yield
24    finally:
25        if old_value is None:
26            del os.environ[name]
27        else:
28            os.environ[name] = old_value
29
30
31class AsyncTestCaseTest(AsyncTestCase):
32    def test_wait_timeout(self):
33        time = self.io_loop.time
34
35        # Accept default 5-second timeout, no error
36        self.io_loop.add_timeout(time() + 0.01, self.stop)
37        self.wait()
38
39        # Timeout passed to wait()
40        self.io_loop.add_timeout(time() + 1, self.stop)
41        with self.assertRaises(self.failureException):
42            self.wait(timeout=0.01)
43
44        # Timeout set with environment variable
45        self.io_loop.add_timeout(time() + 1, self.stop)
46        with set_environ("ASYNC_TEST_TIMEOUT", "0.01"):
47            with self.assertRaises(self.failureException):
48                self.wait()
49
50    def test_subsequent_wait_calls(self):
51        """
52        This test makes sure that a second call to wait()
53        clears the first timeout.
54        """
55        # The first wait ends with time left on the clock
56        self.io_loop.add_timeout(self.io_loop.time() + 0.00, self.stop)
57        self.wait(timeout=0.1)
58        # The second wait has enough time for itself but would fail if the
59        # first wait's deadline were still in effect.
60        self.io_loop.add_timeout(self.io_loop.time() + 0.2, self.stop)
61        self.wait(timeout=0.4)
62
63
64class LeakTest(AsyncTestCase):
65    def tearDown(self):
66        super().tearDown()
67        # Trigger a gc to make warnings more deterministic.
68        gc.collect()
69
70    def test_leaked_coroutine(self):
71        # This test verifies that "leaked" coroutines are shut down
72        # without triggering warnings like "task was destroyed but it
73        # is pending". If this test were to fail, it would fail
74        # because runtests.py detected unexpected output to stderr.
75        event = Event()
76
77        async def callback():
78            try:
79                await event.wait()
80            except asyncio.CancelledError:
81                pass
82
83        self.io_loop.add_callback(callback)
84        self.io_loop.add_callback(self.stop)
85        self.wait()
86
87
88class AsyncHTTPTestCaseTest(AsyncHTTPTestCase):
89    def setUp(self):
90        super().setUp()
91        # Bind a second port.
92        sock, port = bind_unused_port()
93        app = Application()
94        server = HTTPServer(app, **self.get_httpserver_options())
95        server.add_socket(sock)
96        self.second_port = port
97        self.second_server = server
98
99    def get_app(self):
100        return Application()
101
102    def test_fetch_segment(self):
103        path = "/path"
104        response = self.fetch(path)
105        self.assertEqual(response.request.url, self.get_url(path))
106
107    def test_fetch_full_http_url(self):
108        # Ensure that self.fetch() recognizes absolute urls and does
109        # not transform them into references to our main test server.
110        path = "http://127.0.0.1:%d/path" % self.second_port
111
112        response = self.fetch(path)
113        self.assertEqual(response.request.url, path)
114
115    def tearDown(self):
116        self.second_server.stop()
117        super().tearDown()
118
119
120class AsyncTestCaseReturnAssertionsTest(unittest.TestCase):
121    # These tests verify that tests that return non-None values (without being decorated with
122    # @gen_test) raise errors instead of incorrectly succeeding. These tests should be removed or
123    # updated when the _callTestMethod method is removed from AsyncTestCase (the same checks will
124    # still happen, but they'll be performed in the stdlib as DeprecationWarnings)
125    def test_undecorated_generator(self):
126        class Test(AsyncTestCase):
127            def test_gen(self):
128                yield
129
130        test = Test("test_gen")
131        result = unittest.TestResult()
132        test.run(result)
133        self.assertEqual(len(result.errors), 1)
134        self.assertIn("should be decorated", result.errors[0][1])
135
136    @unittest.skipIf(
137        platform.python_implementation() == "PyPy",
138        "pypy destructor warnings cannot be silenced",
139    )
140    @unittest.skipIf(
141        # This check actually exists in 3.11 but it changed in 3.12 in a way that breaks
142        # this test.
143        sys.version_info >= (3, 12),
144        "py312 has its own check for test case returns",
145    )
146    def test_undecorated_coroutine(self):
147        class Test(AsyncTestCase):
148            async def test_coro(self):
149                pass
150
151        test = Test("test_coro")
152        result = unittest.TestResult()
153
154        # Silence "RuntimeWarning: coroutine 'test_coro' was never awaited".
155        with warnings.catch_warnings():
156            warnings.simplefilter("ignore")
157            test.run(result)
158
159        self.assertEqual(len(result.errors), 1)
160        self.assertIn("should be decorated", result.errors[0][1])
161
162    def test_undecorated_generator_with_skip(self):
163        class Test(AsyncTestCase):
164            @unittest.skip("don't run this")
165            def test_gen(self):
166                yield
167
168        test = Test("test_gen")
169        result = unittest.TestResult()
170        test.run(result)
171        self.assertEqual(len(result.errors), 0)
172        self.assertEqual(len(result.skipped), 1)
173
174    def test_other_return(self):
175        class Test(AsyncTestCase):
176            def test_other_return(self):
177                return 42
178
179        test = Test("test_other_return")
180        result = unittest.TestResult()
181        test.run(result)
182        self.assertEqual(len(result.errors), 1)
183        self.assertIn("Return value from test method ignored", result.errors[0][1])
184
185
186class SetUpTearDownTest(unittest.TestCase):
187    def test_set_up_tear_down(self):
188        """
189        This test makes sure that AsyncTestCase calls super methods for
190        setUp and tearDown.
191
192        InheritBoth is a subclass of both AsyncTestCase and
193        SetUpTearDown, with the ordering so that the super of
194        AsyncTestCase will be SetUpTearDown.
195        """
196        events = []
197        result = unittest.TestResult()
198
199        class SetUpTearDown(unittest.TestCase):
200            def setUp(self):
201                events.append("setUp")
202
203            def tearDown(self):
204                events.append("tearDown")
205
206        class InheritBoth(AsyncTestCase, SetUpTearDown):
207            def test(self):
208                events.append("test")
209
210        InheritBoth("test").run(result)
211        expected = ["setUp", "test", "tearDown"]
212        self.assertEqual(expected, events)
213
214
215class AsyncHTTPTestCaseSetUpTearDownTest(unittest.TestCase):
216    def test_tear_down_releases_app_and_http_server(self):
217        result = unittest.TestResult()
218
219        class SetUpTearDown(AsyncHTTPTestCase):
220            def get_app(self):
221                return Application()
222
223            def test(self):
224                self.assertTrue(hasattr(self, "_app"))
225                self.assertTrue(hasattr(self, "http_server"))
226
227        test = SetUpTearDown("test")
228        test.run(result)
229        self.assertFalse(hasattr(test, "_app"))
230        self.assertFalse(hasattr(test, "http_server"))
231
232
233class GenTest(AsyncTestCase):
234    def setUp(self):
235        super().setUp()
236        self.finished = False
237
238    def tearDown(self):
239        self.assertTrue(self.finished)
240        super().tearDown()
241
242    @gen_test
243    def test_sync(self):
244        self.finished = True
245
246    @gen_test
247    def test_async(self):
248        yield gen.moment
249        self.finished = True
250
251    def test_timeout(self):
252        # Set a short timeout and exceed it.
253        @gen_test(timeout=0.1)
254        def test(self):
255            yield gen.sleep(1)
256
257        # This can't use assertRaises because we need to inspect the
258        # exc_info triple (and not just the exception object)
259        try:
260            test(self)
261            self.fail("did not get expected exception")
262        except ioloop.TimeoutError:
263            # The stack trace should blame the add_timeout line, not just
264            # unrelated IOLoop/testing internals.
265            self.assertIn("gen.sleep(1)", traceback.format_exc())
266
267        self.finished = True
268
269    def test_no_timeout(self):
270        # A test that does not exceed its timeout should succeed.
271        @gen_test(timeout=1)
272        def test(self):
273            yield gen.sleep(0.1)
274
275        test(self)
276        self.finished = True
277
278    def test_timeout_environment_variable(self):
279        @gen_test(timeout=0.5)
280        def test_long_timeout(self):
281            yield gen.sleep(0.25)
282
283        # Uses provided timeout of 0.5 seconds, doesn't time out.
284        with set_environ("ASYNC_TEST_TIMEOUT", "0.1"):
285            test_long_timeout(self)
286
287        self.finished = True
288
289    def test_no_timeout_environment_variable(self):
290        @gen_test(timeout=0.01)
291        def test_short_timeout(self):
292            yield gen.sleep(1)
293
294        # Uses environment-variable timeout of 0.1, times out.
295        with set_environ("ASYNC_TEST_TIMEOUT", "0.1"):
296            with self.assertRaises(ioloop.TimeoutError):
297                test_short_timeout(self)
298
299        self.finished = True
300
301    def test_with_method_args(self):
302        @gen_test
303        def test_with_args(self, *args):
304            self.assertEqual(args, ("test",))
305            yield gen.moment
306
307        test_with_args(self, "test")
308        self.finished = True
309
310    def test_with_method_kwargs(self):
311        @gen_test
312        def test_with_kwargs(self, **kwargs):
313            self.assertDictEqual(kwargs, {"test": "test"})
314            yield gen.moment
315
316        test_with_kwargs(self, test="test")
317        self.finished = True
318
319    def test_native_coroutine(self):
320        @gen_test
321        async def test(self):
322            self.finished = True
323
324        test(self)
325
326    def test_native_coroutine_timeout(self):
327        # Set a short timeout and exceed it.
328        @gen_test(timeout=0.1)
329        async def test(self):
330            await gen.sleep(1)
331
332        try:
333            test(self)
334            self.fail("did not get expected exception")
335        except ioloop.TimeoutError:
336            self.finished = True
337
338
339if __name__ == "__main__":
340    unittest.main()
341 
codekingpro/portable-devtools · Team Ai