1import re 2 3import pytest 4 5from unit.applications.lang.node import ApplicationNode 6from unit.utils import waitforfiles 7 8prerequisites = {'modules': {'node': 'all'}} 9 10client = ApplicationNode() 11 12 13def assert_basic_application(): 14 resp = client.get() 15 assert resp['headers']['Content-Type'] == 'text/plain', 'basic header' 16 assert resp['body'] == 'Hello World\n', 'basic body' 17 18 19def test_node_application_basic(): 20 client.load('basic') 21 22 assert_basic_application() 23 24def test_node_application_options(wait_for_record): 25 client.load('options') 26 27 assert_basic_application() 28 assert wait_for_record(r'constructor was called with unsupported') is not None 29 30 31def test_node_application_loader_unit_http(): 32 client.load('loader/unit_http') 33 34 assert_basic_application() 35 36 37def test_node_application_loader_transitive_dependency(): 38 client.load('loader/transitive_dependency') 39 40 assert_basic_application() 41 42 43def test_node_application_seq(): 44 client.load('basic') 45 46 assert client.get()['status'] == 200, 'seq' 47 assert client.get()['status'] == 200, 'seq 2' 48 49 50def test_node_application_variables(date_to_sec_epoch, sec_epoch): 51 client.load('variables') 52 53 body = 'Test body string.' 54 55 resp = client.post( 56 headers={ 57 'Host': 'localhost', 58 'Content-Type': 'text/html', 59 'Custom-Header': 'blah', 60 'Connection': 'close', 61 }, 62 body=body, 63 ) 64 65 assert resp['status'] == 200, 'status' 66 headers = resp['headers'] 67 header_server = headers.pop('Server') 68 assert re.search(r'Unit/[\d\.]+', header_server), 'server header' 69 70 date = headers.pop('Date') 71 assert date[-4:] == ' GMT', 'date header timezone' 72 assert abs(date_to_sec_epoch(date) - sec_epoch) < 5, 'date header' 73 74 raw_headers = headers.pop('Request-Raw-Headers') 75 assert re.search( 76 r'^(?:Host|localhost|Content-Type|' 77 r'text\/html|Custom-Header|blah|Content-Length|17|Connection|' 78 r'close|,)+$', 79 raw_headers, 80 ), 'raw headers' 81 82 assert headers == { 83 'Connection': 'close', 84 'Content-Length': str(len(body)), 85 'Content-Type': 'text/html', 86 'Request-Method': 'POST', 87 'Request-Uri': '/', 88 'Http-Host': 'localhost', 89 'Server-Protocol': '1.1', 90 'Custom-Header': 'blah', 91 }, 'headers' 92 assert resp['body'] == body, 'body' 93 94 95def test_node_application_get_variables(): 96 client.load('get_variables') 97 98 resp = client.get(url='/?var1=val1&var2=&var3') 99 assert resp['headers']['X-Var-1'] == 'val1', 'GET variables' 100 assert resp['headers']['X-Var-2'] == '', 'GET variables 2' 101 assert resp['headers']['X-Var-3'] == '', 'GET variables 3' 102 103 104def test_node_application_post_variables(): 105 client.load('post_variables') 106 107 resp = client.post( 108 headers={ 109 'Content-Type': 'application/x-www-form-urlencoded', 110 'Host': 'localhost', 111 'Connection': 'close', 112 }, 113 body='var1=val1&var2=&var3', 114 ) 115 116 assert resp['headers']['X-Var-1'] == 'val1', 'POST variables' 117 assert resp['headers']['X-Var-2'] == '', 'POST variables 2' 118 assert resp['headers']['X-Var-3'] == '', 'POST variables 3' 119 120 121def test_node_application_404(): 122 client.load('404') 123 124 resp = client.get() 125 126 assert resp['status'] == 404, '404 status' 127 assert re.search(r'<title>404 Not Found</title>', resp['body']), '404 body' 128 129 130def test_node_keepalive_body(): 131 client.load('mirror') 132 133 assert client.get()['status'] == 200, 'init' 134 135 body = '0123456789' * 500 136 (resp, sock) = client.post( 137 headers={ 138 'Host': 'localhost', 139 'Connection': 'keep-alive', 140 }, 141 start=True, 142 body=body, 143 read_timeout=1, 144 ) 145 146 assert resp['body'] == '0123456789' * 500, 'keep-alive 1' 147 148 body = '0123456789' 149 resp = client.post(sock=sock, body=body) 150 151 assert resp['body'] == body, 'keep-alive 2' 152 153 154def test_node_application_write_buffer(): 155 client.load('write_buffer') 156 157 assert client.get()['body'] == 'buffer', 'write buffer' 158 159 160def test_node_application_write_array(): 161 client.load('write_array') 162 163 assert client.get()['body'] == 'array', 'write array' 164 165 166def test_node_application_write_callback(temp_dir): 167 client.load('write_callback') 168 169 assert client.get()['body'] == 'helloworld', 'write callback order' 170 assert waitforfiles(f'{temp_dir}/node/callback'), 'write callback' 171 172 173def test_node_application_write_before_write_head(): 174 client.load('write_before_write_head') 175 176 assert client.get()['status'] == 200, 'write before writeHead' 177 178 179def test_node_application_double_end(): 180 client.load('double_end') 181 182 assert client.get()['status'] == 200, 'double end' 183 assert client.get()['status'] == 200, 'double end 2' 184 185 186def test_node_application_write_return(): 187 client.load('write_return') 188 189 assert client.get()['body'] == 'bodytrue', 'write return' 190 191 192def test_node_application_remove_header(): 193 client.load('remove_header') 194 195 resp = client.get( 196 headers={ 197 'Host': 'localhost', 198 'X-Remove': 'X-Header', 199 'Connection': 'close', 200 } 201 ) 202 assert resp['headers']['Was-Header'] == 'true', 'was header' 203 assert resp['headers']['Has-Header'] == 'false', 'has header' 204 assert not ('X-Header' in resp['headers']), 'remove header' 205 206 207def test_node_application_remove_header_nonexisting(): 208 client.load('remove_header') 209 210 assert ( 211 client.get( 212 headers={ 213 'Host': 'localhost', 214 'X-Remove': 'blah', 215 'Connection': 'close', 216 } 217 )['headers']['Has-Header'] 218 == 'true' 219 ), 'remove header nonexisting' 220 221 222def test_node_application_update_header(): 223 client.load('update_header') 224 225 assert client.get()['headers']['X-Header'] == 'new', 'update header' 226 227 228def test_node_application_set_header_array(): 229 client.load('set_header_array') 230 231 assert client.get()['headers']['Set-Cookie'] == [ 232 'tc=one,two,three', 233 'tc=four,five,six', 234 ], 'set header array' 235 236 237@pytest.mark.skip('not yet') 238def test_node_application_status_message(): 239 client.load('status_message') 240 241 assert re.search(r'200 blah', client.get(raw_resp=True)), 'status message' 242 243 244def test_node_application_get_header_type(): 245 client.load('get_header_type') 246 247 assert client.get()['headers']['X-Type'] == 'number', 'get header type' 248 249 250def test_node_application_header_name_case(): 251 client.load('header_name_case') 252 253 headers = client.get()['headers'] 254 255 assert headers['X-HEADER'] == '3', 'header value' 256 assert 'X-Header' not in headers, 'insensitive' 257 assert 'X-header' not in headers, 'insensitive 2' 258 259 260def test_node_application_promise_handler_write_after_end(): 261 client.load('promise_handler') 262 263 assert ( 264 client.post( 265 headers={ 266 'Host': 'localhost', 267 'Content-Type': 'text/html', 268 'X-Write-Call': '1', 269 'Connection': 'close', 270 }, 271 body='callback', 272 )['status'] 273 == 200 274 ), 'promise handler request write after end' 275 276 277def test_node_application_promise_end(temp_dir): 278 client.load('promise_end') 279 280 assert ( 281 client.post( 282 headers={ 283 'Host': 'localhost', 284 'Content-Type': 'text/html', 285 'Connection': 'close', 286 }, 287 body='end', 288 )['status'] 289 == 200 290 ), 'promise end request' 291 assert waitforfiles(f'{temp_dir}/node/callback'), 'promise end' 292 293 294@pytest.mark.skip('not yet') 295def test_node_application_header_name_valid(): 296 client.load('header_name_valid') 297 298 assert 'status' not in client.get(), 'header name valid' 299 300 301def test_node_application_header_value_object(): 302 client.load('header_value_object') 303 304 assert 'X-Header' in client.get()['headers'], 'header value object' 305 306 307def test_node_application_get_header_names(): 308 client.load('get_header_names') 309 310 assert client.get()['headers']['X-Names'] == [ 311 'date', 312 'x-header', 313 ], 'get header names' 314 315 316def test_node_application_flush_headers(): 317 client.load('flush_headers') 318 319 assert client.get()['headers']['X-Header'] == 'blah' 320 321 322def test_node_application_has_header(): 323 client.load('has_header') 324 325 assert ( 326 client.get( 327 headers={ 328 'Host': 'localhost', 329 'X-Header': 'length', 330 'Connection': 'close', 331 } 332 )['headers']['X-Has-Header'] 333 == 'false' 334 ), 'has header length' 335 336 assert ( 337 client.get( 338 headers={ 339 'Host': 'localhost', 340 'X-Header': 'Date', 341 'Connection': 'close', 342 } 343 )['headers']['X-Has-Header'] 344 == 'false' 345 ), 'has header date' 346 347 348def test_node_application_write_multiple(): 349 client.load('write_multiple') 350 351 assert client.get()['body'] == 'writewrite2end', 'write multiple' 352