11596Szelenkov@nginx.comimport re 21842Szelenkov@nginx.comimport subprocess 31477Szelenkov@nginx.com 41635Szelenkov@nginx.comimport pytest 51019Szelenkov@nginx.comfrom unit.applications.lang.ruby import TestApplicationRuby 6585Szelenkov@nginx.com 71017Szelenkov@nginx.com 81019Szelenkov@nginx.comclass TestRubyApplication(TestApplicationRuby): 91467Szelenkov@nginx.com prerequisites = {'modules': {'ruby': 'all'}} 10585Szelenkov@nginx.com 11585Szelenkov@nginx.com def test_ruby_application(self): 12585Szelenkov@nginx.com self.load('variables') 13585Szelenkov@nginx.com 14585Szelenkov@nginx.com body = 'Test body string.' 15585Szelenkov@nginx.com 161017Szelenkov@nginx.com resp = self.post( 171017Szelenkov@nginx.com headers={ 181017Szelenkov@nginx.com 'Host': 'localhost', 191017Szelenkov@nginx.com 'Content-Type': 'text/html', 201017Szelenkov@nginx.com 'Custom-Header': 'blah', 211017Szelenkov@nginx.com 'Connection': 'close', 221017Szelenkov@nginx.com }, 231017Szelenkov@nginx.com body=body, 241017Szelenkov@nginx.com ) 25585Szelenkov@nginx.com 261596Szelenkov@nginx.com assert resp['status'] == 200, 'status' 27585Szelenkov@nginx.com headers = resp['headers'] 28674Szelenkov@nginx.com header_server = headers.pop('Server') 291596Szelenkov@nginx.com assert re.search(r'Unit/[\d\.]+', header_server), 'server header' 301596Szelenkov@nginx.com assert ( 311596Szelenkov@nginx.com headers.pop('Server-Software') == header_server 321596Szelenkov@nginx.com ), 'server software header' 33599Szelenkov@nginx.com 34599Szelenkov@nginx.com date = headers.pop('Date') 351596Szelenkov@nginx.com assert date[-4:] == ' GMT', 'date header timezone' 361596Szelenkov@nginx.com assert ( 371596Szelenkov@nginx.com abs(self.date_to_sec_epoch(date) - self.sec_epoch()) < 5 381596Szelenkov@nginx.com ), 'date header' 39599Szelenkov@nginx.com 401596Szelenkov@nginx.com assert headers == { 411596Szelenkov@nginx.com 'Connection': 'close', 421596Szelenkov@nginx.com 'Content-Length': str(len(body)), 431596Szelenkov@nginx.com 'Content-Type': 'text/html', 441596Szelenkov@nginx.com 'Request-Method': 'POST', 451596Szelenkov@nginx.com 'Request-Uri': '/', 461596Szelenkov@nginx.com 'Http-Host': 'localhost', 47*2088Szelenkov@nginx.com 'Script-Name': 'config.ru', 481596Szelenkov@nginx.com 'Server-Protocol': 'HTTP/1.1', 491596Szelenkov@nginx.com 'Custom-Header': 'blah', 501596Szelenkov@nginx.com 'Rack-Version': '13', 511596Szelenkov@nginx.com 'Rack-Url-Scheme': 'http', 521596Szelenkov@nginx.com 'Rack-Multithread': 'false', 531596Szelenkov@nginx.com 'Rack-Multiprocess': 'true', 541596Szelenkov@nginx.com 'Rack-Run-Once': 'false', 551596Szelenkov@nginx.com 'Rack-Hijack-Q': 'false', 561596Szelenkov@nginx.com 'Rack-Hijack': '', 571596Szelenkov@nginx.com 'Rack-Hijack-IO': '', 581596Szelenkov@nginx.com }, 'headers' 591596Szelenkov@nginx.com assert resp['body'] == body, 'body' 60585Szelenkov@nginx.com 61585Szelenkov@nginx.com def test_ruby_application_query_string(self): 62585Szelenkov@nginx.com self.load('query_string') 63585Szelenkov@nginx.com 64585Szelenkov@nginx.com resp = self.get(url='/?var1=val1&var2=val2') 65585Szelenkov@nginx.com 661596Szelenkov@nginx.com assert ( 671596Szelenkov@nginx.com resp['headers']['Query-String'] == 'var1=val1&var2=val2' 681596Szelenkov@nginx.com ), 'Query-String header' 69585Szelenkov@nginx.com 70894Szelenkov@nginx.com def test_ruby_application_query_string_empty(self): 71894Szelenkov@nginx.com self.load('query_string') 72894Szelenkov@nginx.com 73894Szelenkov@nginx.com resp = self.get(url='/?') 74894Szelenkov@nginx.com 751596Szelenkov@nginx.com assert resp['status'] == 200, 'query string empty status' 761596Szelenkov@nginx.com assert resp['headers']['Query-String'] == '', 'query string empty' 77894Szelenkov@nginx.com 78894Szelenkov@nginx.com def test_ruby_application_query_string_absent(self): 79894Szelenkov@nginx.com self.load('query_string') 80894Szelenkov@nginx.com 81894Szelenkov@nginx.com resp = self.get() 82894Szelenkov@nginx.com 831596Szelenkov@nginx.com assert resp['status'] == 200, 'query string absent status' 841596Szelenkov@nginx.com assert resp['headers']['Query-String'] == '', 'query string absent' 85894Szelenkov@nginx.com 861596Szelenkov@nginx.com @pytest.mark.skip('not yet') 87585Szelenkov@nginx.com def test_ruby_application_server_port(self): 88585Szelenkov@nginx.com self.load('server_port') 89585Szelenkov@nginx.com 901596Szelenkov@nginx.com assert ( 911596Szelenkov@nginx.com self.get()['headers']['Server-Port'] == '7080' 921596Szelenkov@nginx.com ), 'Server-Port header' 93585Szelenkov@nginx.com 94585Szelenkov@nginx.com def test_ruby_application_status_int(self): 95585Szelenkov@nginx.com self.load('status_int') 96585Szelenkov@nginx.com 971596Szelenkov@nginx.com assert self.get()['status'] == 200, 'status int' 98585Szelenkov@nginx.com 99585Szelenkov@nginx.com def test_ruby_application_input_read_empty(self): 100585Szelenkov@nginx.com self.load('input_read_empty') 101585Szelenkov@nginx.com 1021596Szelenkov@nginx.com assert self.get()['body'] == '', 'read empty' 103585Szelenkov@nginx.com 104585Szelenkov@nginx.com def test_ruby_application_input_read_parts(self): 105585Szelenkov@nginx.com self.load('input_read_parts') 106585Szelenkov@nginx.com 1071596Szelenkov@nginx.com assert ( 1081596Szelenkov@nginx.com self.post(body='0123456789')['body'] == '012345678' 1091596Szelenkov@nginx.com ), 'input read parts' 110585Szelenkov@nginx.com 111585Szelenkov@nginx.com def test_ruby_application_input_read_buffer(self): 112585Szelenkov@nginx.com self.load('input_read_buffer') 113585Szelenkov@nginx.com 1141596Szelenkov@nginx.com assert ( 1151596Szelenkov@nginx.com self.post(body='0123456789')['body'] == '0123456789' 1161596Szelenkov@nginx.com ), 'input read buffer' 117585Szelenkov@nginx.com 118585Szelenkov@nginx.com def test_ruby_application_input_read_buffer_not_empty(self): 119585Szelenkov@nginx.com self.load('input_read_buffer_not_empty') 120585Szelenkov@nginx.com 1211596Szelenkov@nginx.com assert ( 1221596Szelenkov@nginx.com self.post(body='0123456789')['body'] == '0123456789' 1231596Szelenkov@nginx.com ), 'input read buffer not empty' 124585Szelenkov@nginx.com 125585Szelenkov@nginx.com def test_ruby_application_input_gets(self): 126585Szelenkov@nginx.com self.load('input_gets') 127585Szelenkov@nginx.com 128585Szelenkov@nginx.com body = '0123456789' 129585Szelenkov@nginx.com 1301596Szelenkov@nginx.com assert self.post(body=body)['body'] == body, 'input gets' 131585Szelenkov@nginx.com 132585Szelenkov@nginx.com def test_ruby_application_input_gets_2(self): 133585Szelenkov@nginx.com self.load('input_gets') 134585Szelenkov@nginx.com 1351596Szelenkov@nginx.com assert ( 1361596Szelenkov@nginx.com self.post(body='01234\n56789\n')['body'] == '01234\n' 1371596Szelenkov@nginx.com ), 'input gets 2' 138585Szelenkov@nginx.com 139585Szelenkov@nginx.com def test_ruby_application_input_gets_all(self): 140585Szelenkov@nginx.com self.load('input_gets_all') 141585Szelenkov@nginx.com 142585Szelenkov@nginx.com body = '\n01234\n56789\n\n' 143585Szelenkov@nginx.com 1441596Szelenkov@nginx.com assert self.post(body=body)['body'] == body, 'input gets all' 145585Szelenkov@nginx.com 146585Szelenkov@nginx.com def test_ruby_application_input_each(self): 147585Szelenkov@nginx.com self.load('input_each') 148585Szelenkov@nginx.com 149585Szelenkov@nginx.com body = '\n01234\n56789\n\n' 150585Szelenkov@nginx.com 1511596Szelenkov@nginx.com assert self.post(body=body)['body'] == body, 'input each' 152585Szelenkov@nginx.com 1531596Szelenkov@nginx.com @pytest.mark.skip('not yet') 154585Szelenkov@nginx.com def test_ruby_application_input_rewind(self): 155585Szelenkov@nginx.com self.load('input_rewind') 156585Szelenkov@nginx.com 157585Szelenkov@nginx.com body = '0123456789' 158585Szelenkov@nginx.com 1591596Szelenkov@nginx.com assert self.post(body=body)['body'] == body, 'input rewind' 160585Szelenkov@nginx.com 1611596Szelenkov@nginx.com @pytest.mark.skip('not yet') 1621736Szelenkov@nginx.com def test_ruby_application_syntax_error(self, skip_alert): 1631596Szelenkov@nginx.com skip_alert( 1641596Szelenkov@nginx.com r'Failed to parse rack script', 1651596Szelenkov@nginx.com r'syntax error', 1661596Szelenkov@nginx.com r'new_from_string', 1671596Szelenkov@nginx.com r'parse_file', 1681017Szelenkov@nginx.com ) 169585Szelenkov@nginx.com self.load('syntax_error') 170585Szelenkov@nginx.com 1711596Szelenkov@nginx.com assert self.get()['status'] == 500, 'syntax error' 172585Szelenkov@nginx.com 173585Szelenkov@nginx.com def test_ruby_application_errors_puts(self): 174585Szelenkov@nginx.com self.load('errors_puts') 175585Szelenkov@nginx.com 176585Szelenkov@nginx.com self.get() 177585Szelenkov@nginx.com 1781596Szelenkov@nginx.com assert ( 1792073Szelenkov@nginx.com self.wait_for_record(r'\[error\].+Error in application') is not None 1801596Szelenkov@nginx.com ), 'errors puts' 181585Szelenkov@nginx.com 182585Szelenkov@nginx.com def test_ruby_application_errors_puts_int(self): 183585Szelenkov@nginx.com self.load('errors_puts_int') 184585Szelenkov@nginx.com 185585Szelenkov@nginx.com self.get() 186585Szelenkov@nginx.com 1871596Szelenkov@nginx.com assert ( 1881596Szelenkov@nginx.com self.wait_for_record(r'\[error\].+1234567890') is not None 1891596Szelenkov@nginx.com ), 'errors puts int' 190585Szelenkov@nginx.com 191585Szelenkov@nginx.com def test_ruby_application_errors_write(self): 192585Szelenkov@nginx.com self.load('errors_write') 193585Szelenkov@nginx.com 194585Szelenkov@nginx.com self.get() 195585Szelenkov@nginx.com 1961596Szelenkov@nginx.com assert ( 1972073Szelenkov@nginx.com self.wait_for_record(r'\[error\].+Error in application') is not None 1981596Szelenkov@nginx.com ), 'errors write' 199585Szelenkov@nginx.com 200585Szelenkov@nginx.com def test_ruby_application_errors_write_to_s_custom(self): 201585Szelenkov@nginx.com self.load('errors_write_to_s_custom') 202585Szelenkov@nginx.com 2031596Szelenkov@nginx.com assert self.get()['status'] == 200, 'errors write to_s custom' 204585Szelenkov@nginx.com 205585Szelenkov@nginx.com def test_ruby_application_errors_write_int(self): 206585Szelenkov@nginx.com self.load('errors_write_int') 207585Szelenkov@nginx.com 208585Szelenkov@nginx.com self.get() 209585Szelenkov@nginx.com 2101596Szelenkov@nginx.com assert ( 2111596Szelenkov@nginx.com self.wait_for_record(r'\[error\].+1234567890') is not None 2121596Szelenkov@nginx.com ), 'errors write int' 213585Szelenkov@nginx.com 214585Szelenkov@nginx.com def test_ruby_application_at_exit(self): 215585Szelenkov@nginx.com self.load('at_exit') 216585Szelenkov@nginx.com 217585Szelenkov@nginx.com self.get() 218585Szelenkov@nginx.com 2191775Szelenkov@nginx.com assert 'success' in self.conf({"listeners": {}, "applications": {}}) 220585Szelenkov@nginx.com 2211596Szelenkov@nginx.com assert ( 2221596Szelenkov@nginx.com self.wait_for_record(r'\[error\].+At exit called\.') is not None 2231596Szelenkov@nginx.com ), 'at exit' 224585Szelenkov@nginx.com 2251842Szelenkov@nginx.com def test_ruby_application_encoding(self): 2261842Szelenkov@nginx.com self.load('encoding') 2271842Szelenkov@nginx.com 2281842Szelenkov@nginx.com try: 2291848Szelenkov@nginx.com locales = ( 2301848Szelenkov@nginx.com subprocess.check_output( 2312073Szelenkov@nginx.com ['locale', '-a'], 2322073Szelenkov@nginx.com stderr=subprocess.STDOUT, 2331848Szelenkov@nginx.com ) 2341848Szelenkov@nginx.com .decode() 2351848Szelenkov@nginx.com .split('\n') 2361848Szelenkov@nginx.com ) 2371842Szelenkov@nginx.com 2381842Szelenkov@nginx.com except (FileNotFoundError, subprocess.CalledProcessError): 2391842Szelenkov@nginx.com pytest.skip('require locale') 2401842Szelenkov@nginx.com 2411842Szelenkov@nginx.com def get_locale(pattern): 2421842Szelenkov@nginx.com return next( 2431842Szelenkov@nginx.com ( 2441842Szelenkov@nginx.com l 2451842Szelenkov@nginx.com for l in locales 2461842Szelenkov@nginx.com if re.match(pattern, l.upper()) is not None 2471842Szelenkov@nginx.com ), 2481842Szelenkov@nginx.com None, 2491842Szelenkov@nginx.com ) 2501842Szelenkov@nginx.com 2511842Szelenkov@nginx.com utf8 = get_locale(r'.*UTF[-_]?8') 2521842Szelenkov@nginx.com iso88591 = get_locale(r'.*ISO[-_]?8859[-_]?1') 2531842Szelenkov@nginx.com 2541842Szelenkov@nginx.com def check_locale(enc): 2551842Szelenkov@nginx.com assert 'success' in self.conf( 2561847Szelenkov@nginx.com {"LC_CTYPE": enc, "LC_ALL": ""}, 2571847Szelenkov@nginx.com '/config/applications/encoding/environment', 2581842Szelenkov@nginx.com ) 2591842Szelenkov@nginx.com 2601842Szelenkov@nginx.com resp = self.get() 2611842Szelenkov@nginx.com assert resp['status'] == 200, 'status' 2621842Szelenkov@nginx.com 2631842Szelenkov@nginx.com enc_default = re.sub(r'[-_]', '', resp['headers']['X-Enc']).upper() 2641842Szelenkov@nginx.com assert ( 2651842Szelenkov@nginx.com enc_default == re.sub(r'[-_]', '', enc.split('.')[-1]).upper() 2661842Szelenkov@nginx.com ) 2671842Szelenkov@nginx.com 2681842Szelenkov@nginx.com if utf8: 2691842Szelenkov@nginx.com check_locale(utf8) 2701842Szelenkov@nginx.com 2711842Szelenkov@nginx.com if iso88591: 2721842Szelenkov@nginx.com check_locale(iso88591) 2731842Szelenkov@nginx.com 2741842Szelenkov@nginx.com if not utf8 and not iso88591: 2751842Szelenkov@nginx.com pytest.skip('no available locales') 2761842Szelenkov@nginx.com 277585Szelenkov@nginx.com def test_ruby_application_header_custom(self): 278585Szelenkov@nginx.com self.load('header_custom') 279585Szelenkov@nginx.com 280585Szelenkov@nginx.com resp = self.post(body="\ntc=one,two\ntc=three,four,\n\n") 281585Szelenkov@nginx.com 2821596Szelenkov@nginx.com assert resp['headers']['Custom-Header'] == [ 2831596Szelenkov@nginx.com '', 2841596Szelenkov@nginx.com 'tc=one,two', 2851596Szelenkov@nginx.com 'tc=three,four,', 2861596Szelenkov@nginx.com '', 2871596Szelenkov@nginx.com '', 2881596Szelenkov@nginx.com ], 'header custom' 289585Szelenkov@nginx.com 2901596Szelenkov@nginx.com @pytest.mark.skip('not yet') 291585Szelenkov@nginx.com def test_ruby_application_header_custom_non_printable(self): 292585Szelenkov@nginx.com self.load('header_custom') 293585Szelenkov@nginx.com 2941596Szelenkov@nginx.com assert ( 2951596Szelenkov@nginx.com self.post(body='\b')['status'] == 500 2961596Szelenkov@nginx.com ), 'header custom non printable' 297585Szelenkov@nginx.com 298585Szelenkov@nginx.com def test_ruby_application_header_status(self): 299585Szelenkov@nginx.com self.load('header_status') 300585Szelenkov@nginx.com 3011596Szelenkov@nginx.com assert self.get()['status'] == 200, 'header status' 302585Szelenkov@nginx.com 3031596Szelenkov@nginx.com @pytest.mark.skip('not yet') 304585Szelenkov@nginx.com def test_ruby_application_header_rack(self): 305585Szelenkov@nginx.com self.load('header_rack') 306585Szelenkov@nginx.com 3071596Szelenkov@nginx.com assert self.get()['status'] == 500, 'header rack' 308585Szelenkov@nginx.com 309585Szelenkov@nginx.com def test_ruby_application_body_empty(self): 310585Szelenkov@nginx.com self.load('body_empty') 311585Szelenkov@nginx.com 3121596Szelenkov@nginx.com assert self.get()['body'] == '', 'body empty' 313585Szelenkov@nginx.com 314585Szelenkov@nginx.com def test_ruby_application_body_array(self): 315585Szelenkov@nginx.com self.load('body_array') 316585Szelenkov@nginx.com 3171596Szelenkov@nginx.com assert self.get()['body'] == '0123456789', 'body array' 318585Szelenkov@nginx.com 319585Szelenkov@nginx.com def test_ruby_application_body_large(self): 320585Szelenkov@nginx.com self.load('mirror') 321585Szelenkov@nginx.com 322585Szelenkov@nginx.com body = '0123456789' * 1000 323585Szelenkov@nginx.com 3241596Szelenkov@nginx.com assert self.post(body=body)['body'] == body, 'body large' 325585Szelenkov@nginx.com 3261596Szelenkov@nginx.com @pytest.mark.skip('not yet') 327585Szelenkov@nginx.com def test_ruby_application_body_each_error(self): 328585Szelenkov@nginx.com self.load('body_each_error') 329585Szelenkov@nginx.com 3301596Szelenkov@nginx.com assert self.get()['status'] == 500, 'body each error status' 331585Szelenkov@nginx.com 3321596Szelenkov@nginx.com assert ( 3331596Szelenkov@nginx.com self.wait_for_record(r'\[error\].+Failed to run ruby script') 3341596Szelenkov@nginx.com is not None 3351596Szelenkov@nginx.com ), 'body each error' 336585Szelenkov@nginx.com 337585Szelenkov@nginx.com def test_ruby_application_body_file(self): 338585Szelenkov@nginx.com self.load('body_file') 339585Szelenkov@nginx.com 3401596Szelenkov@nginx.com assert self.get()['body'] == 'body\n', 'body file' 341585Szelenkov@nginx.com 342585Szelenkov@nginx.com def test_ruby_keepalive_body(self): 343585Szelenkov@nginx.com self.load('mirror') 344585Szelenkov@nginx.com 3451596Szelenkov@nginx.com assert self.get()['status'] == 200, 'init' 3461029Szelenkov@nginx.com 3471453Szelenkov@nginx.com body = '0123456789' * 500 3481017Szelenkov@nginx.com (resp, sock) = self.post( 3491017Szelenkov@nginx.com headers={ 3501017Szelenkov@nginx.com 'Host': 'localhost', 3511017Szelenkov@nginx.com 'Connection': 'keep-alive', 3521017Szelenkov@nginx.com 'Content-Type': 'text/html', 3531017Szelenkov@nginx.com }, 3541017Szelenkov@nginx.com start=True, 3551453Szelenkov@nginx.com body=body, 3561029Szelenkov@nginx.com read_timeout=1, 3571017Szelenkov@nginx.com ) 358585Szelenkov@nginx.com 3591596Szelenkov@nginx.com assert resp['body'] == body, 'keep-alive 1' 360585Szelenkov@nginx.com 3611453Szelenkov@nginx.com body = '0123456789' 3621017Szelenkov@nginx.com resp = self.post( 3631017Szelenkov@nginx.com headers={ 3641017Szelenkov@nginx.com 'Host': 'localhost', 3651017Szelenkov@nginx.com 'Connection': 'close', 3661017Szelenkov@nginx.com 'Content-Type': 'text/html', 3671017Szelenkov@nginx.com }, 3681017Szelenkov@nginx.com sock=sock, 3691453Szelenkov@nginx.com body=body, 3701017Szelenkov@nginx.com ) 371585Szelenkov@nginx.com 3721596Szelenkov@nginx.com assert resp['body'] == body, 'keep-alive 2' 373585Szelenkov@nginx.com 3741259Szelenkov@nginx.com def test_ruby_application_constants(self): 3751259Szelenkov@nginx.com self.load('constants') 3761259Szelenkov@nginx.com 3771259Szelenkov@nginx.com resp = self.get() 3781259Szelenkov@nginx.com 3791596Szelenkov@nginx.com assert resp['status'] == 200, 'status' 3801259Szelenkov@nginx.com 3811259Szelenkov@nginx.com headers = resp['headers'] 3821596Szelenkov@nginx.com assert len(headers['X-Copyright']) > 0, 'RUBY_COPYRIGHT' 3831596Szelenkov@nginx.com assert len(headers['X-Description']) > 0, 'RUBY_DESCRIPTION' 3841596Szelenkov@nginx.com assert len(headers['X-Engine']) > 0, 'RUBY_ENGINE' 3851596Szelenkov@nginx.com assert len(headers['X-Engine-Version']) > 0, 'RUBY_ENGINE_VERSION' 3861596Szelenkov@nginx.com assert len(headers['X-Patchlevel']) > 0, 'RUBY_PATCHLEVEL' 3871596Szelenkov@nginx.com assert len(headers['X-Platform']) > 0, 'RUBY_PLATFORM' 3881596Szelenkov@nginx.com assert len(headers['X-Release-Date']) > 0, 'RUBY_RELEASE_DATE' 3891596Szelenkov@nginx.com assert len(headers['X-Revision']) > 0, 'RUBY_REVISION' 3901596Szelenkov@nginx.com assert len(headers['X-Version']) > 0, 'RUBY_VERSION' 3911688Smax.romanov@nginx.com 3921688Smax.romanov@nginx.com def test_ruby_application_threads(self): 3931688Smax.romanov@nginx.com self.load('threads') 3941688Smax.romanov@nginx.com 3951688Smax.romanov@nginx.com assert 'success' in self.conf( 3961688Smax.romanov@nginx.com '4', 'applications/threads/threads' 3971688Smax.romanov@nginx.com ), 'configure 4 threads' 3981688Smax.romanov@nginx.com 3991688Smax.romanov@nginx.com socks = [] 4001688Smax.romanov@nginx.com 4011688Smax.romanov@nginx.com for i in range(4): 4021688Smax.romanov@nginx.com (_, sock) = self.get( 4031688Smax.romanov@nginx.com headers={ 4041688Smax.romanov@nginx.com 'Host': 'localhost', 4051688Smax.romanov@nginx.com 'X-Delay': '2', 4061688Smax.romanov@nginx.com 'Connection': 'close', 4071688Smax.romanov@nginx.com }, 4081688Smax.romanov@nginx.com no_recv=True, 4091688Smax.romanov@nginx.com start=True, 4101688Smax.romanov@nginx.com ) 4111688Smax.romanov@nginx.com 4121688Smax.romanov@nginx.com socks.append(sock) 4131688Smax.romanov@nginx.com 4141688Smax.romanov@nginx.com threads = set() 4151688Smax.romanov@nginx.com 4161688Smax.romanov@nginx.com for sock in socks: 4171688Smax.romanov@nginx.com resp = self.recvall(sock).decode('utf-8') 4181688Smax.romanov@nginx.com 4191688Smax.romanov@nginx.com self.log_in(resp) 4201688Smax.romanov@nginx.com 4211688Smax.romanov@nginx.com resp = self._resp_to_dict(resp) 4221688Smax.romanov@nginx.com 4231688Smax.romanov@nginx.com assert resp['status'] == 200, 'status' 4241688Smax.romanov@nginx.com 4251688Smax.romanov@nginx.com threads.add(resp['headers']['X-Thread']) 4261688Smax.romanov@nginx.com 4271688Smax.romanov@nginx.com assert resp['headers']['Rack-Multithread'] == 'true', 'multithread' 4281688Smax.romanov@nginx.com 4291688Smax.romanov@nginx.com sock.close() 4301688Smax.romanov@nginx.com 4311688Smax.romanov@nginx.com assert len(socks) == len(threads), 'threads differs' 432