1import getpass 2import os 3import re 4import shutil 5import signal 6import time 7from pathlib import Path 8 9import pytest 10 11from unit.applications.lang.php import ApplicationPHP 12from unit.option import option 13 14prerequisites = {'modules': {'php': 'all'}} 15 16client = ApplicationPHP() 17 18 19def before_disable_functions(): 20 body = client.get()['body'] 21 22 assert re.search(r'time: \d+', body), 'disable_functions before time' 23 assert re.search(r'exec: \/\w+', body), 'disable_functions before exec' 24 25 26def check_opcache(): 27 resp = client.get() 28 assert resp['status'] == 200, 'status' 29 30 headers = resp['headers'] 31 if 'X-OPcache' in headers and headers['X-OPcache'] == '-1': 32 pytest.skip('opcache is not supported') 33 34 return resp 35 36 37def run_php_application_cwd_root_tests(): 38 assert 'success' in client.conf_delete('applications/cwd/working_directory') 39 40 script_cwd = f'{option.test_dir}/php/cwd' 41 42 resp = client.get() 43 assert resp['status'] == 200, 'status ok' 44 assert resp['body'] == script_cwd, 'default cwd' 45 46 assert 'success' in client.conf( 47 f'"{option.test_dir}"', 48 'applications/cwd/working_directory', 49 ) 50 51 resp = client.get() 52 assert resp['status'] == 200, 'status ok' 53 assert resp['body'] == script_cwd, 'wdir cwd' 54 55 resp = client.get(url='/?chdir=/') 56 assert resp['status'] == 200, 'status ok' 57 assert resp['body'] == '/', 'cwd after chdir' 58 59 # cwd must be restored 60 61 resp = client.get() 62 assert resp['status'] == 200, 'status ok' 63 assert resp['body'] == script_cwd, 'cwd restored' 64 65 resp = client.get(url='/subdir/') 66 assert resp['body'] == f'{script_cwd}/subdir', 'cwd subdir' 67 68 69def run_php_application_cwd_script_tests(): 70 client.load('cwd') 71 72 script_cwd = f'{option.test_dir}/php/cwd' 73 74 assert 'success' in client.conf_delete('applications/cwd/working_directory') 75 76 assert 'success' in client.conf('"index.php"', 'applications/cwd/script') 77 78 assert client.get()['body'] == script_cwd, 'default cwd' 79 80 assert client.get(url='/?chdir=/')['body'] == '/', 'cwd after chdir' 81 82 # cwd must be restored 83 assert client.get()['body'] == script_cwd, 'cwd restored' 84 85 86def set_opcache(app, val): 87 assert 'success' in client.conf( 88 {"admin": {"opcache.enable": val, "opcache.enable_cli": val}}, 89 f'applications/{app}/options', 90 ) 91 92 r = check_opcache() 93 assert r['headers']['X-OPcache'] == val, 'opcache value' 94 95 96def set_preload(preload): 97 Path(f'{option.temp_dir}/php.ini').write_text( 98 f"""opcache.preload = {option.test_dir}/php/opcache/preload\ 99/{preload} 100opcache.preload_user = {option.user or getpass.getuser()} 101""", 102 encoding='utf-8', 103 ) 104 105 assert 'success' in client.conf( 106 {"file": f"{option.temp_dir}/php.ini"}, 107 'applications/opcache/options', 108 ) 109 110 111def test_php_application_variables(date_to_sec_epoch, sec_epoch): 112 client.load('variables') 113 114 body = 'Test body string.' 115 116 resp = client.post( 117 headers={ 118 'Host': 'localhost', 119 'Content-Type': 'text/html', 120 'Custom-Header': 'blah', 121 'Connection': 'close', 122 }, 123 body=body, 124 url='/index.php/blah?var=val', 125 ) 126 127 assert resp['status'] == 200, 'status' 128 headers = resp['headers'] 129 header_server = headers.pop('Server') 130 assert re.search(r'Unit/[\d\.]+', header_server), 'server header' 131 assert ( 132 headers.pop('Server-Software') == header_server 133 ), 'server software header' 134 135 date = headers.pop('Date') 136 assert date[-4:] == ' GMT', 'date header timezone' 137 assert abs(date_to_sec_epoch(date) - sec_epoch) < 5, 'date header' 138 139 if 'X-Powered-By' in headers: 140 headers.pop('X-Powered-By') 141 142 headers.pop('Content-type') 143 assert headers == { 144 'Connection': 'close', 145 'Content-Length': str(len(body)), 146 'Request-Method': 'POST', 147 'Path-Info': '/blah', 148 'Request-Uri': '/index.php/blah?var=val', 149 'Http-Host': 'localhost', 150 'Server-Protocol': 'HTTP/1.1', 151 'Custom-Header': 'blah', 152 }, 'headers' 153 assert resp['body'] == body, 'body' 154 155 156def test_php_application_query_string(): 157 client.load('query_string') 158 159 resp = client.get(url='/?var1=val1&var2=val2') 160 161 assert ( 162 resp['headers']['Query-String'] == 'var1=val1&var2=val2' 163 ), 'query string' 164 165 166def test_php_application_query_string_empty(): 167 client.load('query_string') 168 169 resp = client.get(url='/?') 170 171 assert resp['status'] == 200, 'query string empty status' 172 assert resp['headers']['Query-String'] == '', 'query string empty' 173 174 175def test_php_application_query_string_rewrite(): 176 assert 'success' in client.conf( 177 { 178 "listeners": {"*:8080": {"pass": "routes"}}, 179 "routes": [ 180 { 181 "action": { 182 "rewrite": "/new", 183 "pass": "applications/query_string", 184 }, 185 }, 186 ], 187 "applications": { 188 "query_string": { 189 "type": client.get_application_type(), 190 "processes": {"spare": 0}, 191 "root": f"{option.test_dir}/php/query_string", 192 "script": "index.php", 193 } 194 }, 195 }, 196 ) 197 198 assert client.get(url='/old')['status'] == 200 199 200 resp = client.get(url='/old?arg=val') 201 assert resp['status'] == 200 202 assert resp['headers']['Query-String'] == 'arg=val' 203 204 205def test_php_application_fastcgi_finish_request(findall, unit_pid): 206 client.load('fastcgi_finish_request') 207 208 assert 'success' in client.conf( 209 {"admin": {"auto_globals_jit": "1"}}, 210 'applications/fastcgi_finish_request/options', 211 ) 212 213 assert client.get()['body'] == '0123' 214 215 os.kill(unit_pid, signal.SIGUSR1) 216 217 errs = findall(r'Error in fastcgi_finish_request') 218 219 assert len(errs) == 0, 'no error' 220 221 222def test_php_application_fastcgi_finish_request_2(findall, unit_pid): 223 client.load('fastcgi_finish_request') 224 225 assert 'success' in client.conf( 226 {"admin": {"auto_globals_jit": "1"}}, 227 'applications/fastcgi_finish_request/options', 228 ) 229 230 resp = client.get(url='/?skip') 231 assert resp['status'] == 200 232 assert resp['body'] == '' 233 234 os.kill(unit_pid, signal.SIGUSR1) 235 236 errs = findall(r'Error in fastcgi_finish_request') 237 238 assert len(errs) == 0, 'no error' 239 240 241def test_php_application_query_string_absent(): 242 client.load('query_string') 243 244 resp = client.get() 245 246 assert resp['status'] == 200, 'query string absent status' 247 assert resp['headers']['Query-String'] == '', 'query string absent' 248 249 250def test_php_application_phpinfo(): 251 client.load('phpinfo') 252 253 resp = client.get() 254 255 assert resp['status'] == 200, 'status' 256 assert resp['body'] != '', 'body not empty' 257 258 259def test_php_application_header_status(): 260 client.load('header') 261 262 assert ( 263 client.get( 264 headers={ 265 'Host': 'localhost', 266 'Connection': 'close', 267 'X-Header': 'HTTP/1.1 404 Not Found', 268 } 269 )['status'] 270 == 404 271 ), 'status' 272 273 assert ( 274 client.get( 275 headers={ 276 'Host': 'localhost', 277 'Connection': 'close', 278 'X-Header': 'http/1.1 404 Not Found', 279 } 280 )['status'] 281 == 404 282 ), 'status case insensitive' 283 284 assert ( 285 client.get( 286 headers={ 287 'Host': 'localhost', 288 'Connection': 'close', 289 'X-Header': 'HTTP/ 404 Not Found', 290 } 291 )['status'] 292 == 404 293 ), 'status version empty' 294 295 296def test_php_application_404(): 297 client.load('404') 298 299 resp = client.get() 300 301 assert resp['status'] == 404, '404 status' 302 assert re.search(r'<title>404 Not Found</title>', resp['body']), '404 body' 303 304 305def test_php_application_keepalive_body(): 306 client.load('mirror') 307 308 assert client.get()['status'] == 200, 'init' 309 310 body = '0123456789' * 500 311 (resp, sock) = client.post( 312 headers={ 313 'Host': 'localhost', 314 'Connection': 'keep-alive', 315 }, 316 start=True, 317 body=body, 318 read_timeout=1, 319 ) 320 321 assert resp['body'] == body, 'keep-alive 1' 322 323 body = '0123456789' 324 resp = client.post(sock=sock, body=body) 325 326 assert resp['body'] == body, 'keep-alive 2' 327 328 329def test_php_application_conditional(): 330 client.load('conditional') 331 332 assert re.search(r'True', client.get()['body']), 'conditional true' 333 assert re.search(r'False', client.post()['body']), 'conditional false' 334 335 336def test_php_application_get_variables(): 337 client.load('get_variables') 338 339 resp = client.get(url='/?var1=val1&var2=&var3') 340 assert resp['headers']['X-Var-1'] == 'val1', 'GET variables' 341 assert resp['headers']['X-Var-2'] == '', 'GET variables 2' 342 assert resp['headers']['X-Var-3'] == '', 'GET variables 3' 343 assert resp['headers']['X-Var-4'] == 'not set', 'GET variables 4' 344 345 346def test_php_application_post_variables(): 347 client.load('post_variables') 348 349 resp = client.post( 350 headers={ 351 'Content-Type': 'application/x-www-form-urlencoded', 352 'Host': 'localhost', 353 'Connection': 'close', 354 }, 355 body='var1=val1&var2=', 356 ) 357 assert resp['headers']['X-Var-1'] == 'val1', 'POST variables' 358 assert resp['headers']['X-Var-2'] == '', 'POST variables 2' 359 assert resp['headers']['X-Var-3'] == 'not set', 'POST variables 3' 360 361 362def test_php_application_cookies(): 363 client.load('cookies') 364 365 resp = client.get( 366 headers={ 367 'Cookie': 'var=val; var2=val2', 368 'Host': 'localhost', 369 'Connection': 'close', 370 } 371 ) 372 373 assert resp['headers']['X-Cookie-1'] == 'val', 'cookie' 374 assert resp['headers']['X-Cookie-2'] == 'val2', 'cookie' 375 376 377def test_php_application_ini_precision(): 378 client.load('ini_precision') 379 380 assert client.get()['headers']['X-Precision'] != '4', 'ini value default' 381 382 assert 'success' in client.conf( 383 {"file": "ini/php.ini"}, 'applications/ini_precision/options' 384 ) 385 386 assert ( 387 client.get()['headers']['X-File'] 388 == f'{option.test_dir}/php/ini_precision/ini/php.ini' 389 ), 'ini file' 390 assert client.get()['headers']['X-Precision'] == '4', 'ini value' 391 392 393@pytest.mark.skip('not yet') 394def test_php_application_ini_admin_user(): 395 client.load('ini_precision') 396 397 assert 'error' in client.conf( 398 {"user": {"precision": "4"}, "admin": {"precision": "5"}}, 399 'applications/ini_precision/options', 400 ), 'ini admin user' 401 402 403def test_php_application_ini_admin(): 404 client.load('ini_precision') 405 406 assert 'success' in client.conf( 407 {"file": "ini/php.ini", "admin": {"precision": "5"}}, 408 'applications/ini_precision/options', 409 ) 410 411 assert ( 412 client.get()['headers']['X-File'] 413 == f'{option.test_dir}/php/ini_precision/ini/php.ini' 414 ), 'ini file' 415 assert client.get()['headers']['X-Precision'] == '5', 'ini value admin' 416 417 418def test_php_application_ini_user(): 419 client.load('ini_precision') 420 421 assert 'success' in client.conf( 422 {"file": "ini/php.ini", "user": {"precision": "5"}}, 423 'applications/ini_precision/options', 424 ) 425 426 assert ( 427 client.get()['headers']['X-File'] 428 == f'{option.test_dir}/php/ini_precision/ini/php.ini' 429 ), 'ini file' 430 assert client.get()['headers']['X-Precision'] == '5', 'ini value user' 431 432 433def test_php_application_ini_user_2(): 434 client.load('ini_precision') 435 436 assert 'success' in client.conf( 437 {"file": "ini/php.ini"}, 'applications/ini_precision/options' 438 ) 439 440 assert client.get()['headers']['X-Precision'] == '4', 'ini user file' 441 442 assert 'success' in client.conf( 443 {"precision": "5"}, 'applications/ini_precision/options/user' 444 ) 445 446 assert client.get()['headers']['X-Precision'] == '5', 'ini value user' 447 448 449def test_php_application_ini_set_admin(): 450 client.load('ini_precision') 451 452 assert 'success' in client.conf( 453 {"admin": {"precision": "5"}}, 'applications/ini_precision/options' 454 ) 455 456 assert ( 457 client.get(url='/?precision=6')['headers']['X-Precision'] == '5' 458 ), 'ini set admin' 459 460 461def test_php_application_ini_set_user(): 462 client.load('ini_precision') 463 464 assert 'success' in client.conf( 465 {"user": {"precision": "5"}}, 'applications/ini_precision/options' 466 ) 467 468 assert ( 469 client.get(url='/?precision=6')['headers']['X-Precision'] == '6' 470 ), 'ini set user' 471 472 473def test_php_application_ini_repeat(): 474 client.load('ini_precision') 475 476 assert 'success' in client.conf( 477 {"user": {"precision": "5"}}, 'applications/ini_precision/options' 478 ) 479 480 assert client.get()['headers']['X-Precision'] == '5', 'ini value' 481 482 assert client.get()['headers']['X-Precision'] == '5', 'ini value repeat' 483 484 485def test_php_application_disable_functions_exec(): 486 client.load('time_exec') 487 488 before_disable_functions() 489 490 assert 'success' in client.conf( 491 {"admin": {"disable_functions": "exec"}}, 492 'applications/time_exec/options', 493 ) 494 495 body = client.get()['body'] 496 497 assert re.search(r'time: \d+', body), 'disable_functions time' 498 assert not re.search(r'exec: \/\w+', body), 'disable_functions exec' 499 500 501def test_php_application_disable_functions_comma(): 502 client.load('time_exec') 503 504 before_disable_functions() 505 506 assert 'success' in client.conf( 507 {"admin": {"disable_functions": "exec,time"}}, 508 'applications/time_exec/options', 509 ) 510 511 body = client.get()['body'] 512 513 assert not re.search(r'time: \d+', body), 'disable_functions comma time' 514 assert not re.search(r'exec: \/\w+', body), 'disable_functions comma exec' 515 516 517def test_php_application_auth(): 518 client.load('auth') 519 520 resp = client.get() 521 assert resp['status'] == 200, 'status' 522 assert resp['headers']['X-Digest'] == 'not set', 'digest' 523 assert resp['headers']['X-User'] == 'not set', 'user' 524 assert resp['headers']['X-Password'] == 'not set', 'password' 525 526 resp = client.get( 527 headers={ 528 'Host': 'localhost', 529 'Authorization': 'Basic dXNlcjpwYXNzd29yZA==', 530 'Connection': 'close', 531 } 532 ) 533 assert resp['status'] == 200, 'basic status' 534 assert resp['headers']['X-Digest'] == 'not set', 'basic digest' 535 assert resp['headers']['X-User'] == 'user', 'basic user' 536 assert resp['headers']['X-Password'] == 'password', 'basic password' 537 538 resp = client.get( 539 headers={ 540 'Host': 'localhost', 541 'Authorization': 'Digest username="blah", realm="", uri="/"', 542 'Connection': 'close', 543 } 544 ) 545 assert resp['status'] == 200, 'digest status' 546 assert ( 547 resp['headers']['X-Digest'] == 'username="blah", realm="", uri="/"' 548 ), 'digest digest' 549 assert resp['headers']['X-User'] == 'not set', 'digest user' 550 assert resp['headers']['X-Password'] == 'not set', 'digest password' 551 552 553def test_php_application_auth_invalid(): 554 client.load('auth') 555 556 def check_auth(auth): 557 resp = client.get( 558 headers={ 559 'Host': 'localhost', 560 'Authorization': auth, 561 'Connection': 'close', 562 } 563 ) 564 565 assert resp['status'] == 200, 'status' 566 assert resp['headers']['X-Digest'] == 'not set', 'Digest' 567 assert resp['headers']['X-User'] == 'not set', 'User' 568 assert resp['headers']['X-Password'] == 'not set', 'Password' 569 570 check_auth('Basic dXN%cjpwYXNzd29yZA==') 571 check_auth('Basic XNlcjpwYXNzd29yZA==') 572 check_auth('Basic DdXNlcjpwYXNzd29yZA==') 573 check_auth('Basic blah') 574 check_auth('Basic') 575 check_auth('Digest') 576 check_auth('blah') 577 578 579def test_php_application_disable_functions_space(): 580 client.load('time_exec') 581 582 before_disable_functions() 583 584 assert 'success' in client.conf( 585 {"admin": {"disable_functions": "exec time"}}, 586 'applications/time_exec/options', 587 ) 588 589 body = client.get()['body'] 590 591 assert not re.search(r'time: \d+', body), 'disable_functions space time' 592 assert not re.search(r'exec: \/\w+', body), 'disable_functions space exec' 593 594 595def test_php_application_disable_functions_user(): 596 client.load('time_exec') 597 598 before_disable_functions() 599 600 assert 'success' in client.conf( 601 {"user": {"disable_functions": "exec"}}, 602 'applications/time_exec/options', 603 ) 604 605 body = client.get()['body'] 606 607 assert re.search(r'time: \d+', body), 'disable_functions user time' 608 assert not re.search(r'exec: \/\w+', body), 'disable_functions user exec' 609 610 611def test_php_application_disable_functions_nonexistent(): 612 client.load('time_exec') 613 614 before_disable_functions() 615 616 assert 'success' in client.conf( 617 {"admin": {"disable_functions": "blah"}}, 618 'applications/time_exec/options', 619 ) 620 621 body = client.get()['body'] 622 623 assert re.search(r'time: \d+', body), 'disable_functions nonexistent time' 624 assert re.search(r'exec: \/\w+', body), 'disable_functions nonexistent exec' 625 626 627def test_php_application_disable_classes(): 628 client.load('date_time') 629 630 assert re.search(r'012345', client.get()['body']), 'disable_classes before' 631 632 assert 'success' in client.conf( 633 {"admin": {"disable_classes": "DateTime"}}, 634 'applications/date_time/options', 635 ) 636 637 assert not re.search( 638 r'012345', client.get()['body'] 639 ), 'disable_classes before' 640 641 642def test_php_application_disable_classes_user(): 643 client.load('date_time') 644 645 assert re.search(r'012345', client.get()['body']), 'disable_classes before' 646 647 assert 'success' in client.conf( 648 {"user": {"disable_classes": "DateTime"}}, 649 'applications/date_time/options', 650 ) 651 652 assert not re.search( 653 r'012345', client.get()['body'] 654 ), 'disable_classes before' 655 656 657def test_php_application_error_log(findall, wait_for_record): 658 client.load('error_log') 659 660 assert client.get()['status'] == 200, 'status' 661 662 time.sleep(1) 663 664 assert client.get()['status'] == 200, 'status 2' 665 666 pattern = r'\d{4}\/\d\d\/\d\d\s\d\d:.+\[notice\].+Error in application' 667 668 assert wait_for_record(pattern) is not None, 'errors print' 669 670 errs = findall(pattern) 671 672 assert len(errs) == 2, 'error_log count' 673 674 date = errs[0].split('[')[0] 675 date2 = errs[1].split('[')[0] 676 assert date != date2, 'date diff' 677 678 679def test_php_application_script(): 680 assert 'success' in client.conf( 681 { 682 "listeners": {"*:8080": {"pass": "applications/script"}}, 683 "applications": { 684 "script": { 685 "type": client.get_application_type(), 686 "processes": {"spare": 0}, 687 "root": f"{option.test_dir}/php/script", 688 "script": "phpinfo.php", 689 } 690 }, 691 } 692 ), 'configure script' 693 694 resp = client.get() 695 696 assert resp['status'] == 200, 'status' 697 assert resp['body'] != '', 'body not empty' 698 699 700def test_php_application_index_default(): 701 assert 'success' in client.conf( 702 { 703 "listeners": {"*:8080": {"pass": "applications/phpinfo"}}, 704 "applications": { 705 "phpinfo": { 706 "type": client.get_application_type(), 707 "processes": {"spare": 0}, 708 "root": f"{option.test_dir}/php/phpinfo", 709 } 710 }, 711 } 712 ), 'configure index default' 713 714 resp = client.get() 715 716 assert resp['status'] == 200, 'status' 717 assert resp['body'] != '', 'body not empty' 718 719 720def test_php_application_trailing_slash(temp_dir): 721 new_root = f'{temp_dir}/php-root' 722 723 Path(f'{new_root}/path').mkdir(parents=True) 724 Path(f'{new_root}/path/index.php').write_text( 725 '<?php echo "OK\n"; ?>', encoding='utf-8' 726 ) 727 728 addr = f'{temp_dir}/sock' 729 730 assert 'success' in client.conf( 731 { 732 "listeners": { 733 "*:8080": {"pass": "applications/php-path"}, 734 f'unix:{addr}': {"pass": "applications/php-path"}, 735 }, 736 "applications": { 737 "php-path": { 738 "type": client.get_application_type(), 739 "processes": {"spare": 0}, 740 "root": new_root, 741 } 742 }, 743 } 744 ), 'configure trailing slash' 745 746 assert client.get(url='/path/')['status'] == 200, 'uri with trailing /' 747 748 resp = client.get(url='/path?q=a') 749 assert resp['status'] == 301, 'uri without trailing /' 750 assert ( 751 resp['headers']['Location'] == 'http://localhost:8080/path/?q=a' 752 ), 'Location with query string' 753 754 resp = client.get( 755 sock_type='unix', 756 addr=addr, 757 url='/path', 758 headers={'Host': 'foo', 'Connection': 'close'}, 759 ) 760 assert resp['status'] == 301, 'uri without trailing /' 761 assert ( 762 resp['headers']['Location'] == 'http://foo/path/' 763 ), 'Location with custom Host over UDS' 764 765 766def test_php_application_forbidden(temp_dir): 767 Path(f'{temp_dir}/php-root/path').mkdir(mode=0o000, parents=True) 768 769 assert 'success' in client.conf( 770 { 771 "listeners": {"*:8080": {"pass": "applications/php-path"}}, 772 "applications": { 773 "php-path": { 774 "type": client.get_application_type(), 775 "processes": {"spare": 0}, 776 "root": f'{temp_dir}/php-root', 777 } 778 }, 779 } 780 ), 'forbidden directory' 781 782 assert client.get(url='/path/')['status'] == 403, 'access forbidden' 783 784 785def test_php_application_extension_check(temp_dir): 786 client.load('phpinfo') 787 788 assert client.get(url='/index.wrong')['status'] != 200, 'status' 789 790 new_root = f'{temp_dir}/php' 791 Path(new_root).mkdir(parents=True) 792 shutil.copy(f'{option.test_dir}/php/phpinfo/index.wrong', new_root) 793 794 assert 'success' in client.conf( 795 { 796 "listeners": {"*:8080": {"pass": "applications/phpinfo"}}, 797 "applications": { 798 "phpinfo": { 799 "type": client.get_application_type(), 800 "processes": {"spare": 0}, 801 "root": new_root, 802 "working_directory": new_root, 803 } 804 }, 805 } 806 ), 'configure new root' 807 808 resp = client.get() 809 assert f'{resp["status"]}{resp["body"]}' != '200', 'status new root' 810 811 812def test_php_application_cwd_root(): 813 client.load('cwd') 814 run_php_application_cwd_root_tests() 815 816 817def test_php_application_cwd_opcache_disabled(): 818 client.load('cwd') 819 set_opcache('cwd', '0') 820 run_php_application_cwd_root_tests() 821 822 823def test_php_application_cwd_opcache_enabled(): 824 client.load('cwd') 825 set_opcache('cwd', '1') 826 run_php_application_cwd_root_tests() 827 828 829def test_php_application_cwd_script(): 830 client.load('cwd') 831 run_php_application_cwd_script_tests() 832 833 834def test_php_application_cwd_script_opcache_disabled(): 835 client.load('cwd') 836 set_opcache('cwd', '0') 837 run_php_application_cwd_script_tests() 838 839 840def test_php_application_cwd_script_opcache_enabled(): 841 client.load('cwd') 842 set_opcache('cwd', '1') 843 run_php_application_cwd_script_tests() 844 845 846def test_php_application_path_relative(): 847 client.load('open') 848 849 assert client.get()['body'] == 'test', 'relative path' 850 851 assert ( 852 client.get(url='/?chdir=/')['body'] != 'test' 853 ), 'relative path w/ chdir' 854 855 assert client.get()['body'] == 'test', 'relative path 2' 856 857 858def test_php_application_shared_opcache(): 859 client.load('opcache', limits={'requests': 1}) 860 861 r = check_opcache() 862 pid = r['headers']['X-Pid'] 863 assert r['headers']['X-Cached'] == '0', 'not cached' 864 865 r = client.get() 866 867 assert r['headers']['X-Pid'] != pid, 'new instance' 868 assert r['headers']['X-Cached'] == '1', 'cached' 869 870 871def test_php_application_opcache_preload_chdir(): 872 client.load('opcache') 873 874 check_opcache() 875 876 set_preload('chdir.php') 877 878 assert client.get()['headers']['X-Cached'] == '0', 'not cached' 879 assert client.get()['headers']['X-Cached'] == '1', 'cached' 880 881 882def test_php_application_opcache_preload_ffr(): 883 client.load('opcache') 884 885 check_opcache() 886 887 set_preload('fastcgi_finish_request.php') 888 889 assert client.get()['headers']['X-Cached'] == '0', 'not cached' 890 assert client.get()['headers']['X-Cached'] == '1', 'cached' 891