11596Szelenkov@nginx.comimport re 2*1842Szelenkov@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', 471596Szelenkov@nginx.com 'Server-Protocol': 'HTTP/1.1', 481596Szelenkov@nginx.com 'Custom-Header': 'blah', 491596Szelenkov@nginx.com 'Rack-Version': '13', 501596Szelenkov@nginx.com 'Rack-Url-Scheme': 'http', 511596Szelenkov@nginx.com 'Rack-Multithread': 'false', 521596Szelenkov@nginx.com 'Rack-Multiprocess': 'true', 531596Szelenkov@nginx.com 'Rack-Run-Once': 'false', 541596Szelenkov@nginx.com 'Rack-Hijack-Q': 'false', 551596Szelenkov@nginx.com 'Rack-Hijack': '', 561596Szelenkov@nginx.com 'Rack-Hijack-IO': '', 571596Szelenkov@nginx.com }, 'headers' 581596Szelenkov@nginx.com assert resp['body'] == body, 'body' 59585Szelenkov@nginx.com 60585Szelenkov@nginx.com def test_ruby_application_query_string(self): 61585Szelenkov@nginx.com self.load('query_string') 62585Szelenkov@nginx.com 63585Szelenkov@nginx.com resp = self.get(url='/?var1=val1&var2=val2') 64585Szelenkov@nginx.com 651596Szelenkov@nginx.com assert ( 661596Szelenkov@nginx.com resp['headers']['Query-String'] == 'var1=val1&var2=val2' 671596Szelenkov@nginx.com ), 'Query-String header' 68585Szelenkov@nginx.com 69894Szelenkov@nginx.com def test_ruby_application_query_string_empty(self): 70894Szelenkov@nginx.com self.load('query_string') 71894Szelenkov@nginx.com 72894Szelenkov@nginx.com resp = self.get(url='/?') 73894Szelenkov@nginx.com 741596Szelenkov@nginx.com assert resp['status'] == 200, 'query string empty status' 751596Szelenkov@nginx.com assert resp['headers']['Query-String'] == '', 'query string empty' 76894Szelenkov@nginx.com 77894Szelenkov@nginx.com def test_ruby_application_query_string_absent(self): 78894Szelenkov@nginx.com self.load('query_string') 79894Szelenkov@nginx.com 80894Szelenkov@nginx.com resp = self.get() 81894Szelenkov@nginx.com 821596Szelenkov@nginx.com assert resp['status'] == 200, 'query string absent status' 831596Szelenkov@nginx.com assert resp['headers']['Query-String'] == '', 'query string absent' 84894Szelenkov@nginx.com 851596Szelenkov@nginx.com @pytest.mark.skip('not yet') 86585Szelenkov@nginx.com def test_ruby_application_server_port(self): 87585Szelenkov@nginx.com self.load('server_port') 88585Szelenkov@nginx.com 891596Szelenkov@nginx.com assert ( 901596Szelenkov@nginx.com self.get()['headers']['Server-Port'] == '7080' 911596Szelenkov@nginx.com ), 'Server-Port header' 92585Szelenkov@nginx.com 93585Szelenkov@nginx.com def test_ruby_application_status_int(self): 94585Szelenkov@nginx.com self.load('status_int') 95585Szelenkov@nginx.com 961596Szelenkov@nginx.com assert self.get()['status'] == 200, 'status int' 97585Szelenkov@nginx.com 98585Szelenkov@nginx.com def test_ruby_application_input_read_empty(self): 99585Szelenkov@nginx.com self.load('input_read_empty') 100585Szelenkov@nginx.com 1011596Szelenkov@nginx.com assert self.get()['body'] == '', 'read empty' 102585Szelenkov@nginx.com 103585Szelenkov@nginx.com def test_ruby_application_input_read_parts(self): 104585Szelenkov@nginx.com self.load('input_read_parts') 105585Szelenkov@nginx.com 1061596Szelenkov@nginx.com assert ( 1071596Szelenkov@nginx.com self.post(body='0123456789')['body'] == '012345678' 1081596Szelenkov@nginx.com ), 'input read parts' 109585Szelenkov@nginx.com 110585Szelenkov@nginx.com def test_ruby_application_input_read_buffer(self): 111585Szelenkov@nginx.com self.load('input_read_buffer') 112585Szelenkov@nginx.com 1131596Szelenkov@nginx.com assert ( 1141596Szelenkov@nginx.com self.post(body='0123456789')['body'] == '0123456789' 1151596Szelenkov@nginx.com ), 'input read buffer' 116585Szelenkov@nginx.com 117585Szelenkov@nginx.com def test_ruby_application_input_read_buffer_not_empty(self): 118585Szelenkov@nginx.com self.load('input_read_buffer_not_empty') 119585Szelenkov@nginx.com 1201596Szelenkov@nginx.com assert ( 1211596Szelenkov@nginx.com self.post(body='0123456789')['body'] == '0123456789' 1221596Szelenkov@nginx.com ), 'input read buffer not empty' 123585Szelenkov@nginx.com 124585Szelenkov@nginx.com def test_ruby_application_input_gets(self): 125585Szelenkov@nginx.com self.load('input_gets') 126585Szelenkov@nginx.com 127585Szelenkov@nginx.com body = '0123456789' 128585Szelenkov@nginx.com 1291596Szelenkov@nginx.com assert self.post(body=body)['body'] == body, 'input gets' 130585Szelenkov@nginx.com 131585Szelenkov@nginx.com def test_ruby_application_input_gets_2(self): 132585Szelenkov@nginx.com self.load('input_gets') 133585Szelenkov@nginx.com 1341596Szelenkov@nginx.com assert ( 1351596Szelenkov@nginx.com self.post(body='01234\n56789\n')['body'] == '01234\n' 1361596Szelenkov@nginx.com ), 'input gets 2' 137585Szelenkov@nginx.com 138585Szelenkov@nginx.com def test_ruby_application_input_gets_all(self): 139585Szelenkov@nginx.com self.load('input_gets_all') 140585Szelenkov@nginx.com 141585Szelenkov@nginx.com body = '\n01234\n56789\n\n' 142585Szelenkov@nginx.com 1431596Szelenkov@nginx.com assert self.post(body=body)['body'] == body, 'input gets all' 144585Szelenkov@nginx.com 145585Szelenkov@nginx.com def test_ruby_application_input_each(self): 146585Szelenkov@nginx.com self.load('input_each') 147585Szelenkov@nginx.com 148585Szelenkov@nginx.com body = '\n01234\n56789\n\n' 149585Szelenkov@nginx.com 1501596Szelenkov@nginx.com assert self.post(body=body)['body'] == body, 'input each' 151585Szelenkov@nginx.com 1521596Szelenkov@nginx.com @pytest.mark.skip('not yet') 153585Szelenkov@nginx.com def test_ruby_application_input_rewind(self): 154585Szelenkov@nginx.com self.load('input_rewind') 155585Szelenkov@nginx.com 156585Szelenkov@nginx.com body = '0123456789' 157585Szelenkov@nginx.com 1581596Szelenkov@nginx.com assert self.post(body=body)['body'] == body, 'input rewind' 159585Szelenkov@nginx.com 1601596Szelenkov@nginx.com @pytest.mark.skip('not yet') 1611736Szelenkov@nginx.com def test_ruby_application_syntax_error(self, skip_alert): 1621596Szelenkov@nginx.com skip_alert( 1631596Szelenkov@nginx.com r'Failed to parse rack script', 1641596Szelenkov@nginx.com r'syntax error', 1651596Szelenkov@nginx.com r'new_from_string', 1661596Szelenkov@nginx.com r'parse_file', 1671017Szelenkov@nginx.com ) 168585Szelenkov@nginx.com self.load('syntax_error') 169585Szelenkov@nginx.com 1701596Szelenkov@nginx.com assert self.get()['status'] == 500, 'syntax error' 171585Szelenkov@nginx.com 172585Szelenkov@nginx.com def test_ruby_application_errors_puts(self): 173585Szelenkov@nginx.com self.load('errors_puts') 174585Szelenkov@nginx.com 175585Szelenkov@nginx.com self.get() 176585Szelenkov@nginx.com 1771596Szelenkov@nginx.com assert ( 1781596Szelenkov@nginx.com self.wait_for_record(r'\[error\].+Error in application') 1791596Szelenkov@nginx.com 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 ( 1971596Szelenkov@nginx.com self.wait_for_record(r'\[error\].+Error in application') 1981596Szelenkov@nginx.com is not None 1991596Szelenkov@nginx.com ), 'errors write' 200585Szelenkov@nginx.com 201585Szelenkov@nginx.com def test_ruby_application_errors_write_to_s_custom(self): 202585Szelenkov@nginx.com self.load('errors_write_to_s_custom') 203585Szelenkov@nginx.com 2041596Szelenkov@nginx.com assert self.get()['status'] == 200, 'errors write to_s custom' 205585Szelenkov@nginx.com 206585Szelenkov@nginx.com def test_ruby_application_errors_write_int(self): 207585Szelenkov@nginx.com self.load('errors_write_int') 208585Szelenkov@nginx.com 209585Szelenkov@nginx.com self.get() 210585Szelenkov@nginx.com 211585Szelenkov@nginx.com 2121596Szelenkov@nginx.com assert ( 2131596Szelenkov@nginx.com self.wait_for_record(r'\[error\].+1234567890') is not None 2141596Szelenkov@nginx.com ), 'errors write int' 215585Szelenkov@nginx.com 216585Szelenkov@nginx.com def test_ruby_application_at_exit(self): 217585Szelenkov@nginx.com self.load('at_exit') 218585Szelenkov@nginx.com 219585Szelenkov@nginx.com self.get() 220585Szelenkov@nginx.com 2211775Szelenkov@nginx.com assert 'success' in self.conf({"listeners": {}, "applications": {}}) 222585Szelenkov@nginx.com 2231596Szelenkov@nginx.com assert ( 2241596Szelenkov@nginx.com self.wait_for_record(r'\[error\].+At exit called\.') is not None 2251596Szelenkov@nginx.com ), 'at exit' 226585Szelenkov@nginx.com 227*1842Szelenkov@nginx.com def test_ruby_application_encoding(self): 228*1842Szelenkov@nginx.com self.load('encoding') 229*1842Szelenkov@nginx.com 230*1842Szelenkov@nginx.com try: 231*1842Szelenkov@nginx.com locales = subprocess.check_output( 232*1842Szelenkov@nginx.com ['locale', '-a'], stderr=subprocess.STDOUT, 233*1842Szelenkov@nginx.com ).decode().split('\n') 234*1842Szelenkov@nginx.com 235*1842Szelenkov@nginx.com except (FileNotFoundError, subprocess.CalledProcessError): 236*1842Szelenkov@nginx.com pytest.skip('require locale') 237*1842Szelenkov@nginx.com 238*1842Szelenkov@nginx.com def get_locale(pattern): 239*1842Szelenkov@nginx.com return next( 240*1842Szelenkov@nginx.com ( 241*1842Szelenkov@nginx.com l 242*1842Szelenkov@nginx.com for l in locales 243*1842Szelenkov@nginx.com if re.match(pattern, l.upper()) is not None 244*1842Szelenkov@nginx.com ), 245*1842Szelenkov@nginx.com None, 246*1842Szelenkov@nginx.com ) 247*1842Szelenkov@nginx.com 248*1842Szelenkov@nginx.com utf8 = get_locale(r'.*UTF[-_]?8') 249*1842Szelenkov@nginx.com iso88591 = get_locale(r'.*ISO[-_]?8859[-_]?1') 250*1842Szelenkov@nginx.com 251*1842Szelenkov@nginx.com def check_locale(enc): 252*1842Szelenkov@nginx.com assert 'success' in self.conf( 253*1842Szelenkov@nginx.com {"LC_CTYPE": enc}, '/config/applications/encoding/environment', 254*1842Szelenkov@nginx.com ) 255*1842Szelenkov@nginx.com 256*1842Szelenkov@nginx.com resp = self.get() 257*1842Szelenkov@nginx.com assert resp['status'] == 200, 'status' 258*1842Szelenkov@nginx.com 259*1842Szelenkov@nginx.com enc_default = re.sub(r'[-_]', '', resp['headers']['X-Enc']).upper() 260*1842Szelenkov@nginx.com assert ( 261*1842Szelenkov@nginx.com enc_default == re.sub(r'[-_]', '', enc.split('.')[-1]).upper() 262*1842Szelenkov@nginx.com ) 263*1842Szelenkov@nginx.com 264*1842Szelenkov@nginx.com if utf8: 265*1842Szelenkov@nginx.com check_locale(utf8) 266*1842Szelenkov@nginx.com 267*1842Szelenkov@nginx.com if iso88591: 268*1842Szelenkov@nginx.com check_locale(iso88591) 269*1842Szelenkov@nginx.com 270*1842Szelenkov@nginx.com if not utf8 and not iso88591: 271*1842Szelenkov@nginx.com pytest.skip('no available locales') 272*1842Szelenkov@nginx.com 273585Szelenkov@nginx.com def test_ruby_application_header_custom(self): 274585Szelenkov@nginx.com self.load('header_custom') 275585Szelenkov@nginx.com 276585Szelenkov@nginx.com resp = self.post(body="\ntc=one,two\ntc=three,four,\n\n") 277585Szelenkov@nginx.com 2781596Szelenkov@nginx.com assert resp['headers']['Custom-Header'] == [ 2791596Szelenkov@nginx.com '', 2801596Szelenkov@nginx.com 'tc=one,two', 2811596Szelenkov@nginx.com 'tc=three,four,', 2821596Szelenkov@nginx.com '', 2831596Szelenkov@nginx.com '', 2841596Szelenkov@nginx.com ], 'header custom' 285585Szelenkov@nginx.com 2861596Szelenkov@nginx.com @pytest.mark.skip('not yet') 287585Szelenkov@nginx.com def test_ruby_application_header_custom_non_printable(self): 288585Szelenkov@nginx.com self.load('header_custom') 289585Szelenkov@nginx.com 2901596Szelenkov@nginx.com assert ( 2911596Szelenkov@nginx.com self.post(body='\b')['status'] == 500 2921596Szelenkov@nginx.com ), 'header custom non printable' 293585Szelenkov@nginx.com 294585Szelenkov@nginx.com def test_ruby_application_header_status(self): 295585Szelenkov@nginx.com self.load('header_status') 296585Szelenkov@nginx.com 2971596Szelenkov@nginx.com assert self.get()['status'] == 200, 'header status' 298585Szelenkov@nginx.com 2991596Szelenkov@nginx.com @pytest.mark.skip('not yet') 300585Szelenkov@nginx.com def test_ruby_application_header_rack(self): 301585Szelenkov@nginx.com self.load('header_rack') 302585Szelenkov@nginx.com 3031596Szelenkov@nginx.com assert self.get()['status'] == 500, 'header rack' 304585Szelenkov@nginx.com 305585Szelenkov@nginx.com def test_ruby_application_body_empty(self): 306585Szelenkov@nginx.com self.load('body_empty') 307585Szelenkov@nginx.com 3081596Szelenkov@nginx.com assert self.get()['body'] == '', 'body empty' 309585Szelenkov@nginx.com 310585Szelenkov@nginx.com def test_ruby_application_body_array(self): 311585Szelenkov@nginx.com self.load('body_array') 312585Szelenkov@nginx.com 3131596Szelenkov@nginx.com assert self.get()['body'] == '0123456789', 'body array' 314585Szelenkov@nginx.com 315585Szelenkov@nginx.com def test_ruby_application_body_large(self): 316585Szelenkov@nginx.com self.load('mirror') 317585Szelenkov@nginx.com 318585Szelenkov@nginx.com body = '0123456789' * 1000 319585Szelenkov@nginx.com 3201596Szelenkov@nginx.com assert self.post(body=body)['body'] == body, 'body large' 321585Szelenkov@nginx.com 3221596Szelenkov@nginx.com @pytest.mark.skip('not yet') 323585Szelenkov@nginx.com def test_ruby_application_body_each_error(self): 324585Szelenkov@nginx.com self.load('body_each_error') 325585Szelenkov@nginx.com 3261596Szelenkov@nginx.com assert self.get()['status'] == 500, 'body each error status' 327585Szelenkov@nginx.com 3281596Szelenkov@nginx.com assert ( 3291596Szelenkov@nginx.com self.wait_for_record(r'\[error\].+Failed to run ruby script') 3301596Szelenkov@nginx.com is not None 3311596Szelenkov@nginx.com ), 'body each error' 332585Szelenkov@nginx.com 333585Szelenkov@nginx.com def test_ruby_application_body_file(self): 334585Szelenkov@nginx.com self.load('body_file') 335585Szelenkov@nginx.com 3361596Szelenkov@nginx.com assert self.get()['body'] == 'body\n', 'body file' 337585Szelenkov@nginx.com 338585Szelenkov@nginx.com def test_ruby_keepalive_body(self): 339585Szelenkov@nginx.com self.load('mirror') 340585Szelenkov@nginx.com 3411596Szelenkov@nginx.com assert self.get()['status'] == 200, 'init' 3421029Szelenkov@nginx.com 3431453Szelenkov@nginx.com body = '0123456789' * 500 3441017Szelenkov@nginx.com (resp, sock) = self.post( 3451017Szelenkov@nginx.com headers={ 3461017Szelenkov@nginx.com 'Host': 'localhost', 3471017Szelenkov@nginx.com 'Connection': 'keep-alive', 3481017Szelenkov@nginx.com 'Content-Type': 'text/html', 3491017Szelenkov@nginx.com }, 3501017Szelenkov@nginx.com start=True, 3511453Szelenkov@nginx.com body=body, 3521029Szelenkov@nginx.com read_timeout=1, 3531017Szelenkov@nginx.com ) 354585Szelenkov@nginx.com 3551596Szelenkov@nginx.com assert resp['body'] == body, 'keep-alive 1' 356585Szelenkov@nginx.com 3571453Szelenkov@nginx.com body = '0123456789' 3581017Szelenkov@nginx.com resp = self.post( 3591017Szelenkov@nginx.com headers={ 3601017Szelenkov@nginx.com 'Host': 'localhost', 3611017Szelenkov@nginx.com 'Connection': 'close', 3621017Szelenkov@nginx.com 'Content-Type': 'text/html', 3631017Szelenkov@nginx.com }, 3641017Szelenkov@nginx.com sock=sock, 3651453Szelenkov@nginx.com body=body, 3661017Szelenkov@nginx.com ) 367585Szelenkov@nginx.com 3681596Szelenkov@nginx.com assert resp['body'] == body, 'keep-alive 2' 369585Szelenkov@nginx.com 3701259Szelenkov@nginx.com def test_ruby_application_constants(self): 3711259Szelenkov@nginx.com self.load('constants') 3721259Szelenkov@nginx.com 3731259Szelenkov@nginx.com resp = self.get() 3741259Szelenkov@nginx.com 3751596Szelenkov@nginx.com assert resp['status'] == 200, 'status' 3761259Szelenkov@nginx.com 3771259Szelenkov@nginx.com headers = resp['headers'] 3781596Szelenkov@nginx.com assert len(headers['X-Copyright']) > 0, 'RUBY_COPYRIGHT' 3791596Szelenkov@nginx.com assert len(headers['X-Description']) > 0, 'RUBY_DESCRIPTION' 3801596Szelenkov@nginx.com assert len(headers['X-Engine']) > 0, 'RUBY_ENGINE' 3811596Szelenkov@nginx.com assert len(headers['X-Engine-Version']) > 0, 'RUBY_ENGINE_VERSION' 3821596Szelenkov@nginx.com assert len(headers['X-Patchlevel']) > 0, 'RUBY_PATCHLEVEL' 3831596Szelenkov@nginx.com assert len(headers['X-Platform']) > 0, 'RUBY_PLATFORM' 3841596Szelenkov@nginx.com assert len(headers['X-Release-Date']) > 0, 'RUBY_RELEASE_DATE' 3851596Szelenkov@nginx.com assert len(headers['X-Revision']) > 0, 'RUBY_REVISION' 3861596Szelenkov@nginx.com assert len(headers['X-Version']) > 0, 'RUBY_VERSION' 3871688Smax.romanov@nginx.com 3881688Smax.romanov@nginx.com def test_ruby_application_threads(self): 3891688Smax.romanov@nginx.com self.load('threads') 3901688Smax.romanov@nginx.com 3911688Smax.romanov@nginx.com assert 'success' in self.conf( 3921688Smax.romanov@nginx.com '4', 'applications/threads/threads' 3931688Smax.romanov@nginx.com ), 'configure 4 threads' 3941688Smax.romanov@nginx.com 3951688Smax.romanov@nginx.com socks = [] 3961688Smax.romanov@nginx.com 3971688Smax.romanov@nginx.com for i in range(4): 3981688Smax.romanov@nginx.com (_, sock) = self.get( 3991688Smax.romanov@nginx.com headers={ 4001688Smax.romanov@nginx.com 'Host': 'localhost', 4011688Smax.romanov@nginx.com 'X-Delay': '2', 4021688Smax.romanov@nginx.com 'Connection': 'close', 4031688Smax.romanov@nginx.com }, 4041688Smax.romanov@nginx.com no_recv=True, 4051688Smax.romanov@nginx.com start=True, 4061688Smax.romanov@nginx.com ) 4071688Smax.romanov@nginx.com 4081688Smax.romanov@nginx.com socks.append(sock) 4091688Smax.romanov@nginx.com 4101688Smax.romanov@nginx.com threads = set() 4111688Smax.romanov@nginx.com 4121688Smax.romanov@nginx.com for sock in socks: 4131688Smax.romanov@nginx.com resp = self.recvall(sock).decode('utf-8') 4141688Smax.romanov@nginx.com 4151688Smax.romanov@nginx.com self.log_in(resp) 4161688Smax.romanov@nginx.com 4171688Smax.romanov@nginx.com resp = self._resp_to_dict(resp) 4181688Smax.romanov@nginx.com 4191688Smax.romanov@nginx.com assert resp['status'] == 200, 'status' 4201688Smax.romanov@nginx.com 4211688Smax.romanov@nginx.com threads.add(resp['headers']['X-Thread']) 4221688Smax.romanov@nginx.com 4231688Smax.romanov@nginx.com assert resp['headers']['Rack-Multithread'] == 'true', 'multithread' 4241688Smax.romanov@nginx.com 4251688Smax.romanov@nginx.com sock.close() 4261688Smax.romanov@nginx.com 4271688Smax.romanov@nginx.com assert len(socks) == len(threads), 'threads differs' 428