xref: /unit/test/test_asgi_application.py (revision 2066:242192963d93)
11626Smax.romanov@nginx.comimport re
21626Smax.romanov@nginx.comimport time
31626Smax.romanov@nginx.com
41635Szelenkov@nginx.comimport pytest
5*2066Szelenkov@nginx.comfrom packaging import version
61626Smax.romanov@nginx.comfrom unit.applications.lang.python import TestApplicationPython
71626Smax.romanov@nginx.com
81626Smax.romanov@nginx.com
91626Smax.romanov@nginx.comclass TestASGIApplication(TestApplicationPython):
101848Szelenkov@nginx.com    prerequisites = {
11*2066Szelenkov@nginx.com        'modules': {
12*2066Szelenkov@nginx.com            'python': lambda v: version.parse(v) >= version.parse('3.5')
13*2066Szelenkov@nginx.com        }
141848Szelenkov@nginx.com    }
151626Smax.romanov@nginx.com    load_module = 'asgi'
161626Smax.romanov@nginx.com
171635Szelenkov@nginx.com    def test_asgi_application_variables(self):
181626Smax.romanov@nginx.com        self.load('variables')
191626Smax.romanov@nginx.com
201626Smax.romanov@nginx.com        body = 'Test body string.'
211626Smax.romanov@nginx.com
221626Smax.romanov@nginx.com        resp = self.http(
231626Smax.romanov@nginx.com            b"""POST / HTTP/1.1
241626Smax.romanov@nginx.comHost: localhost
251626Smax.romanov@nginx.comContent-Length: %d
261626Smax.romanov@nginx.comCustom-Header: blah
271626Smax.romanov@nginx.comCustom-hEader: Blah
281626Smax.romanov@nginx.comContent-Type: text/html
291626Smax.romanov@nginx.comConnection: close
301626Smax.romanov@nginx.comcustom-header: BLAH
311626Smax.romanov@nginx.com
321848Szelenkov@nginx.com%s"""
331848Szelenkov@nginx.com            % (len(body), body.encode()),
341626Smax.romanov@nginx.com            raw=True,
351626Smax.romanov@nginx.com        )
361626Smax.romanov@nginx.com
371626Smax.romanov@nginx.com        assert resp['status'] == 200, 'status'
381626Smax.romanov@nginx.com        headers = resp['headers']
391626Smax.romanov@nginx.com        header_server = headers.pop('Server')
401626Smax.romanov@nginx.com        assert re.search(r'Unit/[\d\.]+', header_server), 'server header'
411626Smax.romanov@nginx.com
421626Smax.romanov@nginx.com        date = headers.pop('Date')
431626Smax.romanov@nginx.com        assert date[-4:] == ' GMT', 'date header timezone'
441626Smax.romanov@nginx.com        assert (
451626Smax.romanov@nginx.com            abs(self.date_to_sec_epoch(date) - self.sec_epoch()) < 5
461626Smax.romanov@nginx.com        ), 'date header'
471626Smax.romanov@nginx.com
481626Smax.romanov@nginx.com        assert headers == {
491626Smax.romanov@nginx.com            'Connection': 'close',
501626Smax.romanov@nginx.com            'content-length': str(len(body)),
511626Smax.romanov@nginx.com            'content-type': 'text/html',
521626Smax.romanov@nginx.com            'request-method': 'POST',
531626Smax.romanov@nginx.com            'request-uri': '/',
541626Smax.romanov@nginx.com            'http-host': 'localhost',
551626Smax.romanov@nginx.com            'http-version': '1.1',
561626Smax.romanov@nginx.com            'custom-header': 'blah, Blah, BLAH',
571626Smax.romanov@nginx.com            'asgi-version': '3.0',
581626Smax.romanov@nginx.com            'asgi-spec-version': '2.1',
591626Smax.romanov@nginx.com            'scheme': 'http',
601626Smax.romanov@nginx.com        }, 'headers'
611626Smax.romanov@nginx.com        assert resp['body'] == body, 'body'
621626Smax.romanov@nginx.com
631635Szelenkov@nginx.com    def test_asgi_application_query_string(self):
641626Smax.romanov@nginx.com        self.load('query_string')
651626Smax.romanov@nginx.com
661626Smax.romanov@nginx.com        resp = self.get(url='/?var1=val1&var2=val2')
671626Smax.romanov@nginx.com
681626Smax.romanov@nginx.com        assert (
691626Smax.romanov@nginx.com            resp['headers']['query-string'] == 'var1=val1&var2=val2'
701626Smax.romanov@nginx.com        ), 'query-string header'
711626Smax.romanov@nginx.com
721635Szelenkov@nginx.com    def test_asgi_application_query_string_space(self):
731626Smax.romanov@nginx.com        self.load('query_string')
741626Smax.romanov@nginx.com
751626Smax.romanov@nginx.com        resp = self.get(url='/ ?var1=val1&var2=val2')
761626Smax.romanov@nginx.com        assert (
771626Smax.romanov@nginx.com            resp['headers']['query-string'] == 'var1=val1&var2=val2'
781626Smax.romanov@nginx.com        ), 'query-string space'
791626Smax.romanov@nginx.com
801626Smax.romanov@nginx.com        resp = self.get(url='/ %20?var1=val1&var2=val2')
811626Smax.romanov@nginx.com        assert (
821626Smax.romanov@nginx.com            resp['headers']['query-string'] == 'var1=val1&var2=val2'
831626Smax.romanov@nginx.com        ), 'query-string space 2'
841626Smax.romanov@nginx.com
851626Smax.romanov@nginx.com        resp = self.get(url='/ %20 ?var1=val1&var2=val2')
861626Smax.romanov@nginx.com        assert (
871626Smax.romanov@nginx.com            resp['headers']['query-string'] == 'var1=val1&var2=val2'
881626Smax.romanov@nginx.com        ), 'query-string space 3'
891626Smax.romanov@nginx.com
901626Smax.romanov@nginx.com        resp = self.get(url='/blah %20 blah? var1= val1 & var2=val2')
911626Smax.romanov@nginx.com        assert (
921626Smax.romanov@nginx.com            resp['headers']['query-string'] == ' var1= val1 & var2=val2'
931626Smax.romanov@nginx.com        ), 'query-string space 4'
941626Smax.romanov@nginx.com
951635Szelenkov@nginx.com    def test_asgi_application_query_string_empty(self):
961626Smax.romanov@nginx.com        self.load('query_string')
971626Smax.romanov@nginx.com
981626Smax.romanov@nginx.com        resp = self.get(url='/?')
991626Smax.romanov@nginx.com
1001626Smax.romanov@nginx.com        assert resp['status'] == 200, 'query string empty status'
1011626Smax.romanov@nginx.com        assert resp['headers']['query-string'] == '', 'query string empty'
1021626Smax.romanov@nginx.com
1031635Szelenkov@nginx.com    def test_asgi_application_query_string_absent(self):
1041626Smax.romanov@nginx.com        self.load('query_string')
1051626Smax.romanov@nginx.com
1061626Smax.romanov@nginx.com        resp = self.get()
1071626Smax.romanov@nginx.com
1081626Smax.romanov@nginx.com        assert resp['status'] == 200, 'query string absent status'
1091626Smax.romanov@nginx.com        assert resp['headers']['query-string'] == '', 'query string absent'
1101626Smax.romanov@nginx.com
1111626Smax.romanov@nginx.com    @pytest.mark.skip('not yet')
1121635Szelenkov@nginx.com    def test_asgi_application_server_port(self):
1131626Smax.romanov@nginx.com        self.load('server_port')
1141626Smax.romanov@nginx.com
1151626Smax.romanov@nginx.com        assert (
1161626Smax.romanov@nginx.com            self.get()['headers']['Server-Port'] == '7080'
1171626Smax.romanov@nginx.com        ), 'Server-Port header'
1181626Smax.romanov@nginx.com
1191626Smax.romanov@nginx.com    @pytest.mark.skip('not yet')
1201635Szelenkov@nginx.com    def test_asgi_application_working_directory_invalid(self):
1211626Smax.romanov@nginx.com        self.load('empty')
1221626Smax.romanov@nginx.com
1231626Smax.romanov@nginx.com        assert 'success' in self.conf(
1241626Smax.romanov@nginx.com            '"/blah"', 'applications/empty/working_directory'
1251626Smax.romanov@nginx.com        ), 'configure invalid working_directory'
1261626Smax.romanov@nginx.com
1271626Smax.romanov@nginx.com        assert self.get()['status'] == 500, 'status'
1281626Smax.romanov@nginx.com
1291635Szelenkov@nginx.com    def test_asgi_application_204_transfer_encoding(self):
1301626Smax.romanov@nginx.com        self.load('204_no_content')
1311626Smax.romanov@nginx.com
1321626Smax.romanov@nginx.com        assert (
1331626Smax.romanov@nginx.com            'Transfer-Encoding' not in self.get()['headers']
1341626Smax.romanov@nginx.com        ), '204 header transfer encoding'
1351626Smax.romanov@nginx.com
1361635Szelenkov@nginx.com    def test_asgi_application_shm_ack_handle(self):
1371626Smax.romanov@nginx.com        # Minimum possible limit
1381626Smax.romanov@nginx.com        shm_limit = 10 * 1024 * 1024
1391626Smax.romanov@nginx.com
1401695Smax.romanov@nginx.com        self.load('mirror', limits={"shm": shm_limit})
1411626Smax.romanov@nginx.com
1421626Smax.romanov@nginx.com        # Should exceed shm_limit
1431626Smax.romanov@nginx.com        max_body_size = 12 * 1024 * 1024
1441626Smax.romanov@nginx.com
1451695Smax.romanov@nginx.com        assert 'success' in self.conf(
1461695Smax.romanov@nginx.com            '{"http":{"max_body_size": ' + str(max_body_size) + ' }}',
1471848Szelenkov@nginx.com            'settings',
1481626Smax.romanov@nginx.com        )
1491626Smax.romanov@nginx.com
1501626Smax.romanov@nginx.com        assert self.get()['status'] == 200, 'init'
1511626Smax.romanov@nginx.com
1521626Smax.romanov@nginx.com        body = '0123456789AB' * 1024 * 1024  # 12 Mb
1531626Smax.romanov@nginx.com        resp = self.post(
1541626Smax.romanov@nginx.com            headers={
1551626Smax.romanov@nginx.com                'Host': 'localhost',
1561626Smax.romanov@nginx.com                'Connection': 'close',
1571626Smax.romanov@nginx.com                'Content-Type': 'text/html',
1581626Smax.romanov@nginx.com            },
1591626Smax.romanov@nginx.com            body=body,
1601626Smax.romanov@nginx.com            read_buffer_size=1024 * 1024,
1611626Smax.romanov@nginx.com        )
1621626Smax.romanov@nginx.com
1631626Smax.romanov@nginx.com        assert resp['body'] == body, 'keep-alive 1'
1641626Smax.romanov@nginx.com
1651626Smax.romanov@nginx.com    def test_asgi_keepalive_body(self):
1661626Smax.romanov@nginx.com        self.load('mirror')
1671626Smax.romanov@nginx.com
1681626Smax.romanov@nginx.com        assert self.get()['status'] == 200, 'init'
1691626Smax.romanov@nginx.com
1701626Smax.romanov@nginx.com        body = '0123456789' * 500
1711626Smax.romanov@nginx.com        (resp, sock) = self.post(
1721626Smax.romanov@nginx.com            headers={
1731626Smax.romanov@nginx.com                'Host': 'localhost',
1741626Smax.romanov@nginx.com                'Connection': 'keep-alive',
1751626Smax.romanov@nginx.com                'Content-Type': 'text/html',
1761626Smax.romanov@nginx.com            },
1771626Smax.romanov@nginx.com            start=True,
1781626Smax.romanov@nginx.com            body=body,
1791626Smax.romanov@nginx.com            read_timeout=1,
1801626Smax.romanov@nginx.com        )
1811626Smax.romanov@nginx.com
1821626Smax.romanov@nginx.com        assert resp['body'] == body, 'keep-alive 1'
1831626Smax.romanov@nginx.com
1841626Smax.romanov@nginx.com        body = '0123456789'
1851626Smax.romanov@nginx.com        resp = self.post(
1861626Smax.romanov@nginx.com            headers={
1871626Smax.romanov@nginx.com                'Host': 'localhost',
1881626Smax.romanov@nginx.com                'Connection': 'close',
1891626Smax.romanov@nginx.com                'Content-Type': 'text/html',
1901626Smax.romanov@nginx.com            },
1911626Smax.romanov@nginx.com            sock=sock,
1921626Smax.romanov@nginx.com            body=body,
1931626Smax.romanov@nginx.com        )
1941626Smax.romanov@nginx.com
1951626Smax.romanov@nginx.com        assert resp['body'] == body, 'keep-alive 2'
1961626Smax.romanov@nginx.com
1971626Smax.romanov@nginx.com    def test_asgi_keepalive_reconfigure(self):
1981626Smax.romanov@nginx.com        self.load('mirror')
1991626Smax.romanov@nginx.com
2001626Smax.romanov@nginx.com        assert self.get()['status'] == 200, 'init'
2011626Smax.romanov@nginx.com
2021626Smax.romanov@nginx.com        body = '0123456789'
2031626Smax.romanov@nginx.com        conns = 3
2041626Smax.romanov@nginx.com        socks = []
2051626Smax.romanov@nginx.com
2061626Smax.romanov@nginx.com        for i in range(conns):
2071626Smax.romanov@nginx.com            (resp, sock) = self.post(
2081626Smax.romanov@nginx.com                headers={
2091626Smax.romanov@nginx.com                    'Host': 'localhost',
2101626Smax.romanov@nginx.com                    'Connection': 'keep-alive',
2111626Smax.romanov@nginx.com                    'Content-Type': 'text/html',
2121626Smax.romanov@nginx.com                },
2131626Smax.romanov@nginx.com                start=True,
2141626Smax.romanov@nginx.com                body=body,
2151626Smax.romanov@nginx.com                read_timeout=1,
2161626Smax.romanov@nginx.com            )
2171626Smax.romanov@nginx.com
2181626Smax.romanov@nginx.com            assert resp['body'] == body, 'keep-alive open'
2191695Smax.romanov@nginx.com
2201695Smax.romanov@nginx.com            self.load('mirror', processes=i + 1)
2211626Smax.romanov@nginx.com
2221626Smax.romanov@nginx.com            socks.append(sock)
2231626Smax.romanov@nginx.com
2241626Smax.romanov@nginx.com        for i in range(conns):
2251626Smax.romanov@nginx.com            (resp, sock) = self.post(
2261626Smax.romanov@nginx.com                headers={
2271626Smax.romanov@nginx.com                    'Host': 'localhost',
2281626Smax.romanov@nginx.com                    'Connection': 'keep-alive',
2291626Smax.romanov@nginx.com                    'Content-Type': 'text/html',
2301626Smax.romanov@nginx.com                },
2311626Smax.romanov@nginx.com                start=True,
2321626Smax.romanov@nginx.com                sock=socks[i],
2331626Smax.romanov@nginx.com                body=body,
2341626Smax.romanov@nginx.com                read_timeout=1,
2351626Smax.romanov@nginx.com            )
2361626Smax.romanov@nginx.com
2371626Smax.romanov@nginx.com            assert resp['body'] == body, 'keep-alive request'
2381695Smax.romanov@nginx.com
2391695Smax.romanov@nginx.com            self.load('mirror', processes=i + 1)
2401626Smax.romanov@nginx.com
2411626Smax.romanov@nginx.com        for i in range(conns):
2421626Smax.romanov@nginx.com            resp = self.post(
2431626Smax.romanov@nginx.com                headers={
2441626Smax.romanov@nginx.com                    'Host': 'localhost',
2451626Smax.romanov@nginx.com                    'Connection': 'close',
2461626Smax.romanov@nginx.com                    'Content-Type': 'text/html',
2471626Smax.romanov@nginx.com                },
2481626Smax.romanov@nginx.com                sock=socks[i],
2491626Smax.romanov@nginx.com                body=body,
2501626Smax.romanov@nginx.com            )
2511626Smax.romanov@nginx.com
2521626Smax.romanov@nginx.com            assert resp['body'] == body, 'keep-alive close'
2531695Smax.romanov@nginx.com
2541695Smax.romanov@nginx.com            self.load('mirror', processes=i + 1)
2551626Smax.romanov@nginx.com
2561626Smax.romanov@nginx.com    def test_asgi_keepalive_reconfigure_2(self):
2571626Smax.romanov@nginx.com        self.load('mirror')
2581626Smax.romanov@nginx.com
2591626Smax.romanov@nginx.com        assert self.get()['status'] == 200, 'init'
2601626Smax.romanov@nginx.com
2611626Smax.romanov@nginx.com        body = '0123456789'
2621626Smax.romanov@nginx.com
2631626Smax.romanov@nginx.com        (resp, sock) = self.post(
2641626Smax.romanov@nginx.com            headers={
2651626Smax.romanov@nginx.com                'Host': 'localhost',
2661626Smax.romanov@nginx.com                'Connection': 'keep-alive',
2671626Smax.romanov@nginx.com                'Content-Type': 'text/html',
2681626Smax.romanov@nginx.com            },
2691626Smax.romanov@nginx.com            start=True,
2701626Smax.romanov@nginx.com            body=body,
2711626Smax.romanov@nginx.com            read_timeout=1,
2721626Smax.romanov@nginx.com        )
2731626Smax.romanov@nginx.com
2741626Smax.romanov@nginx.com        assert resp['body'] == body, 'reconfigure 2 keep-alive 1'
2751626Smax.romanov@nginx.com
2761626Smax.romanov@nginx.com        self.load('empty')
2771626Smax.romanov@nginx.com
2781626Smax.romanov@nginx.com        assert self.get()['status'] == 200, 'init'
2791626Smax.romanov@nginx.com
2801626Smax.romanov@nginx.com        (resp, sock) = self.post(
2811626Smax.romanov@nginx.com            headers={
2821626Smax.romanov@nginx.com                'Host': 'localhost',
2831626Smax.romanov@nginx.com                'Connection': 'close',
2841626Smax.romanov@nginx.com                'Content-Type': 'text/html',
2851626Smax.romanov@nginx.com            },
2861626Smax.romanov@nginx.com            start=True,
2871626Smax.romanov@nginx.com            sock=sock,
2881626Smax.romanov@nginx.com            body=body,
2891626Smax.romanov@nginx.com        )
2901626Smax.romanov@nginx.com
2911626Smax.romanov@nginx.com        assert resp['status'] == 200, 'reconfigure 2 keep-alive 2'
2921626Smax.romanov@nginx.com        assert resp['body'] == '', 'reconfigure 2 keep-alive 2 body'
2931626Smax.romanov@nginx.com
2941626Smax.romanov@nginx.com        assert 'success' in self.conf(
2951626Smax.romanov@nginx.com            {"listeners": {}, "applications": {}}
2961626Smax.romanov@nginx.com        ), 'reconfigure 2 clear configuration'
2971626Smax.romanov@nginx.com
2981626Smax.romanov@nginx.com        resp = self.get(sock=sock)
2991626Smax.romanov@nginx.com
3001626Smax.romanov@nginx.com        assert resp == {}, 'reconfigure 2 keep-alive 3'
3011626Smax.romanov@nginx.com
3021626Smax.romanov@nginx.com    def test_asgi_keepalive_reconfigure_3(self):
3031626Smax.romanov@nginx.com        self.load('empty')
3041626Smax.romanov@nginx.com
3051626Smax.romanov@nginx.com        assert self.get()['status'] == 200, 'init'
3061626Smax.romanov@nginx.com
3071626Smax.romanov@nginx.com        (_, sock) = self.http(
3081626Smax.romanov@nginx.com            b"""GET / HTTP/1.1
3091626Smax.romanov@nginx.com""",
3101626Smax.romanov@nginx.com            start=True,
3111626Smax.romanov@nginx.com            raw=True,
3121626Smax.romanov@nginx.com            no_recv=True,
3131626Smax.romanov@nginx.com        )
3141626Smax.romanov@nginx.com
3151626Smax.romanov@nginx.com        assert self.get()['status'] == 200
3161626Smax.romanov@nginx.com
3171626Smax.romanov@nginx.com        assert 'success' in self.conf(
3181626Smax.romanov@nginx.com            {"listeners": {}, "applications": {}}
3191626Smax.romanov@nginx.com        ), 'reconfigure 3 clear configuration'
3201626Smax.romanov@nginx.com
3211626Smax.romanov@nginx.com        resp = self.http(
3221626Smax.romanov@nginx.com            b"""Host: localhost
3231626Smax.romanov@nginx.comConnection: close
3241626Smax.romanov@nginx.com
3251626Smax.romanov@nginx.com""",
3261626Smax.romanov@nginx.com            sock=sock,
3271626Smax.romanov@nginx.com            raw=True,
3281626Smax.romanov@nginx.com        )
3291626Smax.romanov@nginx.com
3301626Smax.romanov@nginx.com        assert resp['status'] == 200, 'reconfigure 3'
3311626Smax.romanov@nginx.com
3321626Smax.romanov@nginx.com    def test_asgi_process_switch(self):
3331695Smax.romanov@nginx.com        self.load('delayed', processes=2)
3341626Smax.romanov@nginx.com
3351626Smax.romanov@nginx.com        self.get(
3361626Smax.romanov@nginx.com            headers={
3371626Smax.romanov@nginx.com                'Host': 'localhost',
3381626Smax.romanov@nginx.com                'Content-Length': '0',
3391626Smax.romanov@nginx.com                'X-Delay': '5',
3401626Smax.romanov@nginx.com                'Connection': 'close',
3411626Smax.romanov@nginx.com            },
3421626Smax.romanov@nginx.com            no_recv=True,
3431626Smax.romanov@nginx.com        )
3441626Smax.romanov@nginx.com
3451626Smax.romanov@nginx.com        headers_delay_1 = {
3461626Smax.romanov@nginx.com            'Connection': 'close',
3471626Smax.romanov@nginx.com            'Host': 'localhost',
3481626Smax.romanov@nginx.com            'Content-Length': '0',
3491626Smax.romanov@nginx.com            'X-Delay': '1',
3501626Smax.romanov@nginx.com        }
3511626Smax.romanov@nginx.com
3521626Smax.romanov@nginx.com        self.get(headers=headers_delay_1, no_recv=True)
3531626Smax.romanov@nginx.com
3541626Smax.romanov@nginx.com        time.sleep(0.5)
3551626Smax.romanov@nginx.com
3561626Smax.romanov@nginx.com        for _ in range(10):
3571626Smax.romanov@nginx.com            self.get(headers=headers_delay_1, no_recv=True)
3581626Smax.romanov@nginx.com
3591626Smax.romanov@nginx.com        self.get(headers=headers_delay_1)
3601626Smax.romanov@nginx.com
3611736Szelenkov@nginx.com    def test_asgi_application_loading_error(self, skip_alert):
3621626Smax.romanov@nginx.com        skip_alert(r'Python failed to import module "blah"')
3631626Smax.romanov@nginx.com
3641695Smax.romanov@nginx.com        self.load('empty', module="blah")
3651626Smax.romanov@nginx.com
3661626Smax.romanov@nginx.com        assert self.get()['status'] == 503, 'loading error'
3671626Smax.romanov@nginx.com
3681635Szelenkov@nginx.com    def test_asgi_application_threading(self):
3691626Smax.romanov@nginx.com        """wait_for_record() timeouts after 5s while every thread works at
3701626Smax.romanov@nginx.com        least 3s.  So without releasing GIL test should fail.
3711626Smax.romanov@nginx.com        """
3721626Smax.romanov@nginx.com
3731626Smax.romanov@nginx.com        self.load('threading')
3741626Smax.romanov@nginx.com
3751626Smax.romanov@nginx.com        for _ in range(10):
3761626Smax.romanov@nginx.com            self.get(no_recv=True)
3771626Smax.romanov@nginx.com
3781626Smax.romanov@nginx.com        assert (
3791804Szelenkov@nginx.com            self.wait_for_record(r'\(5\) Thread: 100', wait=50) is not None
3801626Smax.romanov@nginx.com        ), 'last thread finished'
3811683Smax.romanov@nginx.com
3821683Smax.romanov@nginx.com    def test_asgi_application_threads(self):
3831695Smax.romanov@nginx.com        self.load('threads', threads=2)
3841683Smax.romanov@nginx.com
3851683Smax.romanov@nginx.com        socks = []
3861683Smax.romanov@nginx.com
3871692Smax.romanov@nginx.com        for i in range(2):
3881683Smax.romanov@nginx.com            (_, sock) = self.get(
3891683Smax.romanov@nginx.com                headers={
3901683Smax.romanov@nginx.com                    'Host': 'localhost',
3911692Smax.romanov@nginx.com                    'X-Delay': '3',
3921683Smax.romanov@nginx.com                    'Connection': 'close',
3931683Smax.romanov@nginx.com                },
3941683Smax.romanov@nginx.com                no_recv=True,
3951683Smax.romanov@nginx.com                start=True,
3961683Smax.romanov@nginx.com            )
3971683Smax.romanov@nginx.com
3981683Smax.romanov@nginx.com            socks.append(sock)
3991683Smax.romanov@nginx.com
4001848Szelenkov@nginx.com            time.sleep(1.0)  # required to avoid greedy request reading
4011683Smax.romanov@nginx.com
4021683Smax.romanov@nginx.com        threads = set()
4031683Smax.romanov@nginx.com
4041683Smax.romanov@nginx.com        for sock in socks:
4051683Smax.romanov@nginx.com            resp = self.recvall(sock).decode('utf-8')
4061683Smax.romanov@nginx.com
4071683Smax.romanov@nginx.com            self.log_in(resp)
4081683Smax.romanov@nginx.com
4091683Smax.romanov@nginx.com            resp = self._resp_to_dict(resp)
4101683Smax.romanov@nginx.com
4111683Smax.romanov@nginx.com            assert resp['status'] == 200, 'status'
4121683Smax.romanov@nginx.com
4131683Smax.romanov@nginx.com            threads.add(resp['headers']['x-thread'])
4141683Smax.romanov@nginx.com
4151683Smax.romanov@nginx.com            sock.close()
4161683Smax.romanov@nginx.com
4171683Smax.romanov@nginx.com        assert len(socks) == len(threads), 'threads differs'
4181697Smax.romanov@nginx.com
4191697Smax.romanov@nginx.com    def test_asgi_application_legacy(self):
4201697Smax.romanov@nginx.com        self.load('legacy')
4211697Smax.romanov@nginx.com
4221697Smax.romanov@nginx.com        resp = self.get(
4231697Smax.romanov@nginx.com            headers={
4241697Smax.romanov@nginx.com                'Host': 'localhost',
4251697Smax.romanov@nginx.com                'Content-Length': '0',
4261697Smax.romanov@nginx.com                'Connection': 'close',
4271697Smax.romanov@nginx.com            },
4281697Smax.romanov@nginx.com        )
4291697Smax.romanov@nginx.com
4301697Smax.romanov@nginx.com        assert resp['status'] == 200, 'status'
4311697Smax.romanov@nginx.com
4321697Smax.romanov@nginx.com    def test_asgi_application_legacy_force(self):
4331697Smax.romanov@nginx.com        self.load('legacy_force', protocol='asgi')
4341697Smax.romanov@nginx.com
4351697Smax.romanov@nginx.com        resp = self.get(
4361697Smax.romanov@nginx.com            headers={
4371697Smax.romanov@nginx.com                'Host': 'localhost',
4381697Smax.romanov@nginx.com                'Content-Length': '0',
4391697Smax.romanov@nginx.com                'Connection': 'close',
4401697Smax.romanov@nginx.com            },
4411697Smax.romanov@nginx.com        )
4421697Smax.romanov@nginx.com
4431697Smax.romanov@nginx.com        assert resp['status'] == 200, 'status'
444