diff options
author | Andrei Zeliankou <zelenkov@nginx.com> | 2023-06-14 18:20:09 +0100 |
---|---|---|
committer | Andrei Zeliankou <zelenkov@nginx.com> | 2023-06-14 18:20:09 +0100 |
commit | c183bd8749a19477390f8cb77efe5f6d223f0905 (patch) | |
tree | 4e821e9cb07be9a86bf2d442acb3ea6740ba5a99 /test/test_php_application.py | |
parent | c6d05191a069ac150cc8eb2bece75cf79c0a465a (diff) | |
download | unit-c183bd8749a19477390f8cb77efe5f6d223f0905.tar.gz unit-c183bd8749a19477390f8cb77efe5f6d223f0905.tar.bz2 |
Tests: get rid of classes in test files.
Class usage came from the unittest framework and it was always redundant
after migration to the pytest. This commit removes classes from files
containing tests to make them more readable and understandable.
Diffstat (limited to 'test/test_php_application.py')
-rw-r--r-- | test/test_php_application.py | 1275 |
1 files changed, 654 insertions, 621 deletions
diff --git a/test/test_php_application.py b/test/test_php_application.py index 548c0c9d..6c1f227b 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -7,820 +7,853 @@ import time from pathlib import Path import pytest -from unit.applications.lang.php import TestApplicationPHP +from unit.applications.lang.php import ApplicationPHP from unit.option import option prerequisites = {'modules': {'php': 'all'}} +client = ApplicationPHP() -class TestPHPApplication(TestApplicationPHP): - def before_disable_functions(self): - body = self.get()['body'] - assert re.search(r'time: \d+', body), 'disable_functions before time' - assert re.search(r'exec: \/\w+', body), 'disable_functions before exec' +def before_disable_functions(): + body = client.get()['body'] - def check_opcache(self): - resp = self.get() - assert resp['status'] == 200, 'status' + assert re.search(r'time: \d+', body), 'disable_functions before time' + assert re.search(r'exec: \/\w+', body), 'disable_functions before exec' - headers = resp['headers'] - if 'X-OPcache' in headers and headers['X-OPcache'] == '-1': - pytest.skip('opcache is not supported') - return resp +def check_opcache(): + resp = client.get() + assert resp['status'] == 200, 'status' - def set_opcache(self, app, val): - assert 'success' in self.conf( - {"admin": {"opcache.enable": val, "opcache.enable_cli": val}}, - f'applications/{app}/options', - ) + headers = resp['headers'] + if 'X-OPcache' in headers and headers['X-OPcache'] == '-1': + pytest.skip('opcache is not supported') - r = self.check_opcache() - assert r['headers']['X-OPcache'] == val, 'opcache value' + return resp - def set_preload(self, preload): - with open(f'{option.temp_dir}/php.ini', 'w') as f: - f.write( - f"""opcache.preload = {option.test_dir}/php/opcache/preload\ -/{preload} -opcache.preload_user = {option.user or getpass.getuser()} -""" - ) - assert 'success' in self.conf( - {"file": f"{option.temp_dir}/php.ini"}, - 'applications/opcache/options', - ) +def run_php_application_cwd_root_tests(): + assert 'success' in client.conf_delete('applications/cwd/working_directory') - def test_php_application_variables(self, date_to_sec_epoch, sec_epoch): - self.load('variables') + script_cwd = f'{option.test_dir}/php/cwd' - body = 'Test body string.' + resp = client.get() + assert resp['status'] == 200, 'status ok' + assert resp['body'] == script_cwd, 'default cwd' - resp = self.post( - headers={ - 'Host': 'localhost', - 'Content-Type': 'text/html', - 'Custom-Header': 'blah', - 'Connection': 'close', - }, - body=body, - url='/index.php/blah?var=val', - ) + assert 'success' in client.conf( + f'"{option.test_dir}"', + 'applications/cwd/working_directory', + ) - assert resp['status'] == 200, 'status' - headers = resp['headers'] - header_server = headers.pop('Server') - assert re.search(r'Unit/[\d\.]+', header_server), 'server header' - assert ( - headers.pop('Server-Software') == header_server - ), 'server software header' - - date = headers.pop('Date') - assert date[-4:] == ' GMT', 'date header timezone' - assert abs(date_to_sec_epoch(date) - sec_epoch) < 5, 'date header' - - if 'X-Powered-By' in headers: - headers.pop('X-Powered-By') - - headers.pop('Content-type') - assert headers == { - 'Connection': 'close', - 'Content-Length': str(len(body)), - 'Request-Method': 'POST', - 'Path-Info': '/blah', - 'Request-Uri': '/index.php/blah?var=val', - 'Http-Host': 'localhost', - 'Server-Protocol': 'HTTP/1.1', - 'Custom-Header': 'blah', - }, 'headers' - assert resp['body'] == body, 'body' + resp = client.get() + assert resp['status'] == 200, 'status ok' + assert resp['body'] == script_cwd, 'wdir cwd' - def test_php_application_query_string(self): - self.load('query_string') + resp = client.get(url='/?chdir=/') + assert resp['status'] == 200, 'status ok' + assert resp['body'] == '/', 'cwd after chdir' - resp = self.get(url='/?var1=val1&var2=val2') + # cwd must be restored - assert ( - resp['headers']['Query-String'] == 'var1=val1&var2=val2' - ), 'query string' + resp = client.get() + assert resp['status'] == 200, 'status ok' + assert resp['body'] == script_cwd, 'cwd restored' - def test_php_application_query_string_empty(self): - self.load('query_string') + resp = client.get(url='/subdir/') + assert resp['body'] == f'{script_cwd}/subdir', 'cwd subdir' - resp = self.get(url='/?') - assert resp['status'] == 200, 'query string empty status' - assert resp['headers']['Query-String'] == '', 'query string empty' +def run_php_application_cwd_script_tests(): + client.load('cwd') - def test_php_application_fastcgi_finish_request(self, findall, unit_pid): - self.load('fastcgi_finish_request') + script_cwd = f'{option.test_dir}/php/cwd' - assert 'success' in self.conf( - {"admin": {"auto_globals_jit": "1"}}, - 'applications/fastcgi_finish_request/options', - ) + assert 'success' in client.conf_delete('applications/cwd/working_directory') - assert self.get()['body'] == '0123' + assert 'success' in client.conf('"index.php"', 'applications/cwd/script') - os.kill(unit_pid, signal.SIGUSR1) + assert client.get()['body'] == script_cwd, 'default cwd' - errs = findall(r'Error in fastcgi_finish_request') + assert client.get(url='/?chdir=/')['body'] == '/', 'cwd after chdir' - assert len(errs) == 0, 'no error' + # cwd must be restored + assert client.get()['body'] == script_cwd, 'cwd restored' - def test_php_application_fastcgi_finish_request_2(self, findall, unit_pid): - self.load('fastcgi_finish_request') - assert 'success' in self.conf( - {"admin": {"auto_globals_jit": "1"}}, - 'applications/fastcgi_finish_request/options', +def set_opcache(app, val): + assert 'success' in client.conf( + {"admin": {"opcache.enable": val, "opcache.enable_cli": val}}, + f'applications/{app}/options', + ) + + r = check_opcache() + assert r['headers']['X-OPcache'] == val, 'opcache value' + + +def set_preload(preload): + with open(f'{option.temp_dir}/php.ini', 'w') as ini: + ini.write( + f"""opcache.preload = {option.test_dir}/php/opcache/preload\ +/{preload} +opcache.preload_user = {option.user or getpass.getuser()} +""" ) - resp = self.get(url='/?skip') - assert resp['status'] == 200 - assert resp['body'] == '' + assert 'success' in client.conf( + {"file": f"{option.temp_dir}/php.ini"}, + 'applications/opcache/options', + ) - os.kill(unit_pid, signal.SIGUSR1) - errs = findall(r'Error in fastcgi_finish_request') +def test_php_application_variables(date_to_sec_epoch, sec_epoch): + client.load('variables') - assert len(errs) == 0, 'no error' + body = 'Test body string.' - def test_php_application_query_string_absent(self): - self.load('query_string') + resp = client.post( + headers={ + 'Host': 'localhost', + 'Content-Type': 'text/html', + 'Custom-Header': 'blah', + 'Connection': 'close', + }, + body=body, + url='/index.php/blah?var=val', + ) - resp = self.get() + assert resp['status'] == 200, 'status' + headers = resp['headers'] + header_server = headers.pop('Server') + assert re.search(r'Unit/[\d\.]+', header_server), 'server header' + assert ( + headers.pop('Server-Software') == header_server + ), 'server software header' - assert resp['status'] == 200, 'query string absent status' - assert resp['headers']['Query-String'] == '', 'query string absent' + date = headers.pop('Date') + assert date[-4:] == ' GMT', 'date header timezone' + assert abs(date_to_sec_epoch(date) - sec_epoch) < 5, 'date header' - def test_php_application_phpinfo(self): - self.load('phpinfo') + if 'X-Powered-By' in headers: + headers.pop('X-Powered-By') - resp = self.get() + headers.pop('Content-type') + assert headers == { + 'Connection': 'close', + 'Content-Length': str(len(body)), + 'Request-Method': 'POST', + 'Path-Info': '/blah', + 'Request-Uri': '/index.php/blah?var=val', + 'Http-Host': 'localhost', + 'Server-Protocol': 'HTTP/1.1', + 'Custom-Header': 'blah', + }, 'headers' + assert resp['body'] == body, 'body' - assert resp['status'] == 200, 'status' - assert resp['body'] != '', 'body not empty' - def test_php_application_header_status(self): - self.load('header') +def test_php_application_query_string(): + client.load('query_string') - assert ( - self.get( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'X-Header': 'HTTP/1.1 404 Not Found', - } - )['status'] - == 404 - ), 'status' - - assert ( - self.get( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'X-Header': 'http/1.1 404 Not Found', - } - )['status'] - == 404 - ), 'status case insensitive' - - assert ( - self.get( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'X-Header': 'HTTP/ 404 Not Found', - } - )['status'] - == 404 - ), 'status version empty' + resp = client.get(url='/?var1=val1&var2=val2') - def test_php_application_404(self): - self.load('404') + assert ( + resp['headers']['Query-String'] == 'var1=val1&var2=val2' + ), 'query string' - resp = self.get() - assert resp['status'] == 404, '404 status' - assert re.search( - r'<title>404 Not Found</title>', resp['body'] - ), '404 body' +def test_php_application_query_string_empty(): + client.load('query_string') - def test_php_application_keepalive_body(self): - self.load('mirror') + resp = client.get(url='/?') - assert self.get()['status'] == 200, 'init' + assert resp['status'] == 200, 'query string empty status' + assert resp['headers']['Query-String'] == '', 'query string empty' + + +def test_php_application_fastcgi_finish_request(findall, unit_pid): + client.load('fastcgi_finish_request') + + assert 'success' in client.conf( + {"admin": {"auto_globals_jit": "1"}}, + 'applications/fastcgi_finish_request/options', + ) + + assert client.get()['body'] == '0123' + + os.kill(unit_pid, signal.SIGUSR1) + + errs = findall(r'Error in fastcgi_finish_request') + + assert len(errs) == 0, 'no error' - body = '0123456789' * 500 - (resp, sock) = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'keep-alive', - }, - start=True, - body=body, - read_timeout=1, - ) - assert resp['body'] == body, 'keep-alive 1' +def test_php_application_fastcgi_finish_request_2(findall, unit_pid): + client.load('fastcgi_finish_request') - body = '0123456789' - resp = self.post(sock=sock, body=body) + assert 'success' in client.conf( + {"admin": {"auto_globals_jit": "1"}}, + 'applications/fastcgi_finish_request/options', + ) - assert resp['body'] == body, 'keep-alive 2' + resp = client.get(url='/?skip') + assert resp['status'] == 200 + assert resp['body'] == '' - def test_php_application_conditional(self): - self.load('conditional') + os.kill(unit_pid, signal.SIGUSR1) - assert re.search(r'True', self.get()['body']), 'conditional true' - assert re.search(r'False', self.post()['body']), 'conditional false' + errs = findall(r'Error in fastcgi_finish_request') - def test_php_application_get_variables(self): - self.load('get_variables') + assert len(errs) == 0, 'no error' - resp = self.get(url='/?var1=val1&var2=&var3') - assert resp['headers']['X-Var-1'] == 'val1', 'GET variables' - assert resp['headers']['X-Var-2'] == '', 'GET variables 2' - assert resp['headers']['X-Var-3'] == '', 'GET variables 3' - assert resp['headers']['X-Var-4'] == 'not set', 'GET variables 4' - def test_php_application_post_variables(self): - self.load('post_variables') +def test_php_application_query_string_absent(): + client.load('query_string') - resp = self.post( + resp = client.get() + + assert resp['status'] == 200, 'query string absent status' + assert resp['headers']['Query-String'] == '', 'query string absent' + + +def test_php_application_phpinfo(): + client.load('phpinfo') + + resp = client.get() + + assert resp['status'] == 200, 'status' + assert resp['body'] != '', 'body not empty' + + +def test_php_application_header_status(): + client.load('header') + + assert ( + client.get( headers={ - 'Content-Type': 'application/x-www-form-urlencoded', 'Host': 'localhost', 'Connection': 'close', - }, - body='var1=val1&var2=', - ) - assert resp['headers']['X-Var-1'] == 'val1', 'POST variables' - assert resp['headers']['X-Var-2'] == '', 'POST variables 2' - assert resp['headers']['X-Var-3'] == 'not set', 'POST variables 3' + 'X-Header': 'HTTP/1.1 404 Not Found', + } + )['status'] + == 404 + ), 'status' - def test_php_application_cookies(self): - self.load('cookies') + assert ( + client.get( + headers={ + 'Host': 'localhost', + 'Connection': 'close', + 'X-Header': 'http/1.1 404 Not Found', + } + )['status'] + == 404 + ), 'status case insensitive' - resp = self.get( + assert ( + client.get( headers={ - 'Cookie': 'var=val; var2=val2', 'Host': 'localhost', 'Connection': 'close', + 'X-Header': 'HTTP/ 404 Not Found', } - ) + )['status'] + == 404 + ), 'status version empty' - assert resp['headers']['X-Cookie-1'] == 'val', 'cookie' - assert resp['headers']['X-Cookie-2'] == 'val2', 'cookie' - def test_php_application_ini_precision(self): - self.load('ini_precision') +def test_php_application_404(): + client.load('404') - assert self.get()['headers']['X-Precision'] != '4', 'ini value default' + resp = client.get() - assert 'success' in self.conf( - {"file": "ini/php.ini"}, 'applications/ini_precision/options' - ) + assert resp['status'] == 404, '404 status' + assert re.search(r'<title>404 Not Found</title>', resp['body']), '404 body' - assert ( - self.get()['headers']['X-File'] - == f'{option.test_dir}/php/ini_precision/ini/php.ini' - ), 'ini file' - assert self.get()['headers']['X-Precision'] == '4', 'ini value' - @pytest.mark.skip('not yet') - def test_php_application_ini_admin_user(self): - self.load('ini_precision') +def test_php_application_keepalive_body(): + client.load('mirror') - assert 'error' in self.conf( - {"user": {"precision": "4"}, "admin": {"precision": "5"}}, - 'applications/ini_precision/options', - ), 'ini admin user' + assert client.get()['status'] == 200, 'init' - def test_php_application_ini_admin(self): - self.load('ini_precision') + body = '0123456789' * 500 + (resp, sock) = client.post( + headers={ + 'Host': 'localhost', + 'Connection': 'keep-alive', + }, + start=True, + body=body, + read_timeout=1, + ) - assert 'success' in self.conf( - {"file": "ini/php.ini", "admin": {"precision": "5"}}, - 'applications/ini_precision/options', - ) + assert resp['body'] == body, 'keep-alive 1' - assert ( - self.get()['headers']['X-File'] - == f'{option.test_dir}/php/ini_precision/ini/php.ini' - ), 'ini file' - assert self.get()['headers']['X-Precision'] == '5', 'ini value admin' + body = '0123456789' + resp = client.post(sock=sock, body=body) - def test_php_application_ini_user(self): - self.load('ini_precision') + assert resp['body'] == body, 'keep-alive 2' - assert 'success' in self.conf( - {"file": "ini/php.ini", "user": {"precision": "5"}}, - 'applications/ini_precision/options', - ) - assert ( - self.get()['headers']['X-File'] - == f'{option.test_dir}/php/ini_precision/ini/php.ini' - ), 'ini file' - assert self.get()['headers']['X-Precision'] == '5', 'ini value user' +def test_php_application_conditional(): + client.load('conditional') - def test_php_application_ini_user_2(self): - self.load('ini_precision') + assert re.search(r'True', client.get()['body']), 'conditional true' + assert re.search(r'False', client.post()['body']), 'conditional false' - assert 'success' in self.conf( - {"file": "ini/php.ini"}, 'applications/ini_precision/options' - ) - assert self.get()['headers']['X-Precision'] == '4', 'ini user file' +def test_php_application_get_variables(): + client.load('get_variables') - assert 'success' in self.conf( - {"precision": "5"}, 'applications/ini_precision/options/user' - ) + resp = client.get(url='/?var1=val1&var2=&var3') + assert resp['headers']['X-Var-1'] == 'val1', 'GET variables' + assert resp['headers']['X-Var-2'] == '', 'GET variables 2' + assert resp['headers']['X-Var-3'] == '', 'GET variables 3' + assert resp['headers']['X-Var-4'] == 'not set', 'GET variables 4' - assert self.get()['headers']['X-Precision'] == '5', 'ini value user' - def test_php_application_ini_set_admin(self): - self.load('ini_precision') +def test_php_application_post_variables(): + client.load('post_variables') - assert 'success' in self.conf( - {"admin": {"precision": "5"}}, 'applications/ini_precision/options' - ) + resp = client.post( + headers={ + 'Content-Type': 'application/x-www-form-urlencoded', + 'Host': 'localhost', + 'Connection': 'close', + }, + body='var1=val1&var2=', + ) + assert resp['headers']['X-Var-1'] == 'val1', 'POST variables' + assert resp['headers']['X-Var-2'] == '', 'POST variables 2' + assert resp['headers']['X-Var-3'] == 'not set', 'POST variables 3' - assert ( - self.get(url='/?precision=6')['headers']['X-Precision'] == '5' - ), 'ini set admin' - def test_php_application_ini_set_user(self): - self.load('ini_precision') +def test_php_application_cookies(): + client.load('cookies') - assert 'success' in self.conf( - {"user": {"precision": "5"}}, 'applications/ini_precision/options' - ) + resp = client.get( + headers={ + 'Cookie': 'var=val; var2=val2', + 'Host': 'localhost', + 'Connection': 'close', + } + ) - assert ( - self.get(url='/?precision=6')['headers']['X-Precision'] == '6' - ), 'ini set user' + assert resp['headers']['X-Cookie-1'] == 'val', 'cookie' + assert resp['headers']['X-Cookie-2'] == 'val2', 'cookie' - def test_php_application_ini_repeat(self): - self.load('ini_precision') - assert 'success' in self.conf( - {"user": {"precision": "5"}}, 'applications/ini_precision/options' - ) +def test_php_application_ini_precision(): + client.load('ini_precision') - assert self.get()['headers']['X-Precision'] == '5', 'ini value' + assert client.get()['headers']['X-Precision'] != '4', 'ini value default' - assert self.get()['headers']['X-Precision'] == '5', 'ini value repeat' + assert 'success' in client.conf( + {"file": "ini/php.ini"}, 'applications/ini_precision/options' + ) - def test_php_application_disable_functions_exec(self): - self.load('time_exec') + assert ( + client.get()['headers']['X-File'] + == f'{option.test_dir}/php/ini_precision/ini/php.ini' + ), 'ini file' + assert client.get()['headers']['X-Precision'] == '4', 'ini value' - self.before_disable_functions() - assert 'success' in self.conf( - {"admin": {"disable_functions": "exec"}}, - 'applications/time_exec/options', - ) +@pytest.mark.skip('not yet') +def test_php_application_ini_admin_user(): + client.load('ini_precision') - body = self.get()['body'] + assert 'error' in client.conf( + {"user": {"precision": "4"}, "admin": {"precision": "5"}}, + 'applications/ini_precision/options', + ), 'ini admin user' - assert re.search(r'time: \d+', body), 'disable_functions time' - assert not re.search(r'exec: \/\w+', body), 'disable_functions exec' - def test_php_application_disable_functions_comma(self): - self.load('time_exec') +def test_php_application_ini_admin(): + client.load('ini_precision') - self.before_disable_functions() + assert 'success' in client.conf( + {"file": "ini/php.ini", "admin": {"precision": "5"}}, + 'applications/ini_precision/options', + ) - assert 'success' in self.conf( - {"admin": {"disable_functions": "exec,time"}}, - 'applications/time_exec/options', - ) + assert ( + client.get()['headers']['X-File'] + == f'{option.test_dir}/php/ini_precision/ini/php.ini' + ), 'ini file' + assert client.get()['headers']['X-Precision'] == '5', 'ini value admin' - body = self.get()['body'] - assert not re.search(r'time: \d+', body), 'disable_functions comma time' - assert not re.search( - r'exec: \/\w+', body - ), 'disable_functions comma exec' +def test_php_application_ini_user(): + client.load('ini_precision') - def test_php_application_auth(self): - self.load('auth') + assert 'success' in client.conf( + {"file": "ini/php.ini", "user": {"precision": "5"}}, + 'applications/ini_precision/options', + ) - resp = self.get() - assert resp['status'] == 200, 'status' - assert resp['headers']['X-Digest'] == 'not set', 'digest' - assert resp['headers']['X-User'] == 'not set', 'user' - assert resp['headers']['X-Password'] == 'not set', 'password' + assert ( + client.get()['headers']['X-File'] + == f'{option.test_dir}/php/ini_precision/ini/php.ini' + ), 'ini file' + assert client.get()['headers']['X-Precision'] == '5', 'ini value user' - resp = self.get( - headers={ - 'Host': 'localhost', - 'Authorization': 'Basic dXNlcjpwYXNzd29yZA==', - 'Connection': 'close', - } - ) - assert resp['status'] == 200, 'basic status' - assert resp['headers']['X-Digest'] == 'not set', 'basic digest' - assert resp['headers']['X-User'] == 'user', 'basic user' - assert resp['headers']['X-Password'] == 'password', 'basic password' - resp = self.get( +def test_php_application_ini_user_2(): + client.load('ini_precision') + + assert 'success' in client.conf( + {"file": "ini/php.ini"}, 'applications/ini_precision/options' + ) + + assert client.get()['headers']['X-Precision'] == '4', 'ini user file' + + assert 'success' in client.conf( + {"precision": "5"}, 'applications/ini_precision/options/user' + ) + + assert client.get()['headers']['X-Precision'] == '5', 'ini value user' + + +def test_php_application_ini_set_admin(): + client.load('ini_precision') + + assert 'success' in client.conf( + {"admin": {"precision": "5"}}, 'applications/ini_precision/options' + ) + + assert ( + client.get(url='/?precision=6')['headers']['X-Precision'] == '5' + ), 'ini set admin' + + +def test_php_application_ini_set_user(): + client.load('ini_precision') + + assert 'success' in client.conf( + {"user": {"precision": "5"}}, 'applications/ini_precision/options' + ) + + assert ( + client.get(url='/?precision=6')['headers']['X-Precision'] == '6' + ), 'ini set user' + + +def test_php_application_ini_repeat(): + client.load('ini_precision') + + assert 'success' in client.conf( + {"user": {"precision": "5"}}, 'applications/ini_precision/options' + ) + + assert client.get()['headers']['X-Precision'] == '5', 'ini value' + + assert client.get()['headers']['X-Precision'] == '5', 'ini value repeat' + + +def test_php_application_disable_functions_exec(): + client.load('time_exec') + + before_disable_functions() + + assert 'success' in client.conf( + {"admin": {"disable_functions": "exec"}}, + 'applications/time_exec/options', + ) + + body = client.get()['body'] + + assert re.search(r'time: \d+', body), 'disable_functions time' + assert not re.search(r'exec: \/\w+', body), 'disable_functions exec' + + +def test_php_application_disable_functions_comma(): + client.load('time_exec') + + before_disable_functions() + + assert 'success' in client.conf( + {"admin": {"disable_functions": "exec,time"}}, + 'applications/time_exec/options', + ) + + body = client.get()['body'] + + assert not re.search(r'time: \d+', body), 'disable_functions comma time' + assert not re.search(r'exec: \/\w+', body), 'disable_functions comma exec' + + +def test_php_application_auth(): + client.load('auth') + + resp = client.get() + assert resp['status'] == 200, 'status' + assert resp['headers']['X-Digest'] == 'not set', 'digest' + assert resp['headers']['X-User'] == 'not set', 'user' + assert resp['headers']['X-Password'] == 'not set', 'password' + + resp = client.get( + headers={ + 'Host': 'localhost', + 'Authorization': 'Basic dXNlcjpwYXNzd29yZA==', + 'Connection': 'close', + } + ) + assert resp['status'] == 200, 'basic status' + assert resp['headers']['X-Digest'] == 'not set', 'basic digest' + assert resp['headers']['X-User'] == 'user', 'basic user' + assert resp['headers']['X-Password'] == 'password', 'basic password' + + resp = client.get( + headers={ + 'Host': 'localhost', + 'Authorization': 'Digest username="blah", realm="", uri="/"', + 'Connection': 'close', + } + ) + assert resp['status'] == 200, 'digest status' + assert ( + resp['headers']['X-Digest'] == 'username="blah", realm="", uri="/"' + ), 'digest digest' + assert resp['headers']['X-User'] == 'not set', 'digest user' + assert resp['headers']['X-Password'] == 'not set', 'digest password' + + +def test_php_application_auth_invalid(): + client.load('auth') + + def check_auth(auth): + resp = client.get( headers={ 'Host': 'localhost', - 'Authorization': 'Digest username="blah", realm="", uri="/"', + 'Authorization': auth, 'Connection': 'close', } ) - assert resp['status'] == 200, 'digest status' - assert ( - resp['headers']['X-Digest'] == 'username="blah", realm="", uri="/"' - ), 'digest digest' - assert resp['headers']['X-User'] == 'not set', 'digest user' - assert resp['headers']['X-Password'] == 'not set', 'digest password' - - def test_php_application_auth_invalid(self): - self.load('auth') - - def check_auth(auth): - resp = self.get( - headers={ - 'Host': 'localhost', - 'Authorization': auth, - 'Connection': 'close', - } - ) - assert resp['status'] == 200, 'status' - assert resp['headers']['X-Digest'] == 'not set', 'Digest' - assert resp['headers']['X-User'] == 'not set', 'User' - assert resp['headers']['X-Password'] == 'not set', 'Password' + assert resp['status'] == 200, 'status' + assert resp['headers']['X-Digest'] == 'not set', 'Digest' + assert resp['headers']['X-User'] == 'not set', 'User' + assert resp['headers']['X-Password'] == 'not set', 'Password' - check_auth('Basic dXN%cjpwYXNzd29yZA==') - check_auth('Basic XNlcjpwYXNzd29yZA==') - check_auth('Basic DdXNlcjpwYXNzd29yZA==') - check_auth('Basic blah') - check_auth('Basic') - check_auth('Digest') - check_auth('blah') + check_auth('Basic dXN%cjpwYXNzd29yZA==') + check_auth('Basic XNlcjpwYXNzd29yZA==') + check_auth('Basic DdXNlcjpwYXNzd29yZA==') + check_auth('Basic blah') + check_auth('Basic') + check_auth('Digest') + check_auth('blah') - def test_php_application_disable_functions_space(self): - self.load('time_exec') - self.before_disable_functions() +def test_php_application_disable_functions_space(): + client.load('time_exec') - assert 'success' in self.conf( - {"admin": {"disable_functions": "exec time"}}, - 'applications/time_exec/options', - ) + before_disable_functions() - body = self.get()['body'] + assert 'success' in client.conf( + {"admin": {"disable_functions": "exec time"}}, + 'applications/time_exec/options', + ) - assert not re.search(r'time: \d+', body), 'disable_functions space time' - assert not re.search( - r'exec: \/\w+', body - ), 'disable_functions space exec' + body = client.get()['body'] - def test_php_application_disable_functions_user(self): - self.load('time_exec') + assert not re.search(r'time: \d+', body), 'disable_functions space time' + assert not re.search(r'exec: \/\w+', body), 'disable_functions space exec' - self.before_disable_functions() - assert 'success' in self.conf( - {"user": {"disable_functions": "exec"}}, - 'applications/time_exec/options', - ) +def test_php_application_disable_functions_user(): + client.load('time_exec') - body = self.get()['body'] + before_disable_functions() - assert re.search(r'time: \d+', body), 'disable_functions user time' - assert not re.search( - r'exec: \/\w+', body - ), 'disable_functions user exec' + assert 'success' in client.conf( + {"user": {"disable_functions": "exec"}}, + 'applications/time_exec/options', + ) - def test_php_application_disable_functions_nonexistent(self): - self.load('time_exec') + body = client.get()['body'] - self.before_disable_functions() + assert re.search(r'time: \d+', body), 'disable_functions user time' + assert not re.search(r'exec: \/\w+', body), 'disable_functions user exec' - assert 'success' in self.conf( - {"admin": {"disable_functions": "blah"}}, - 'applications/time_exec/options', - ) - body = self.get()['body'] +def test_php_application_disable_functions_nonexistent(): + client.load('time_exec') - assert re.search( - r'time: \d+', body - ), 'disable_functions nonexistent time' - assert re.search( - r'exec: \/\w+', body - ), 'disable_functions nonexistent exec' + before_disable_functions() - def test_php_application_disable_classes(self): - self.load('date_time') + assert 'success' in client.conf( + {"admin": {"disable_functions": "blah"}}, + 'applications/time_exec/options', + ) - assert re.search( - r'012345', self.get()['body'] - ), 'disable_classes before' + body = client.get()['body'] - assert 'success' in self.conf( - {"admin": {"disable_classes": "DateTime"}}, - 'applications/date_time/options', - ) + assert re.search(r'time: \d+', body), 'disable_functions nonexistent time' + assert re.search(r'exec: \/\w+', body), 'disable_functions nonexistent exec' - assert not re.search( - r'012345', self.get()['body'] - ), 'disable_classes before' - def test_php_application_disable_classes_user(self): - self.load('date_time') +def test_php_application_disable_classes(): + client.load('date_time') - assert re.search( - r'012345', self.get()['body'] - ), 'disable_classes before' + assert re.search(r'012345', client.get()['body']), 'disable_classes before' - assert 'success' in self.conf( - {"user": {"disable_classes": "DateTime"}}, - 'applications/date_time/options', - ) + assert 'success' in client.conf( + {"admin": {"disable_classes": "DateTime"}}, + 'applications/date_time/options', + ) - assert not re.search( - r'012345', self.get()['body'] - ), 'disable_classes before' + assert not re.search( + r'012345', client.get()['body'] + ), 'disable_classes before' - def test_php_application_error_log(self, findall, wait_for_record): - self.load('error_log') - assert self.get()['status'] == 200, 'status' +def test_php_application_disable_classes_user(): + client.load('date_time') - time.sleep(1) + assert re.search(r'012345', client.get()['body']), 'disable_classes before' - assert self.get()['status'] == 200, 'status 2' + assert 'success' in client.conf( + {"user": {"disable_classes": "DateTime"}}, + 'applications/date_time/options', + ) - pattern = r'\d{4}\/\d\d\/\d\d\s\d\d:.+\[notice\].+Error in application' + assert not re.search( + r'012345', client.get()['body'] + ), 'disable_classes before' - assert wait_for_record(pattern) is not None, 'errors print' - errs = findall(pattern) +def test_php_application_error_log(findall, wait_for_record): + client.load('error_log') - assert len(errs) == 2, 'error_log count' + assert client.get()['status'] == 200, 'status' - date = errs[0].split('[')[0] - date2 = errs[1].split('[')[0] - assert date != date2, 'date diff' + time.sleep(1) - def test_php_application_script(self): - assert 'success' in self.conf( - { - "listeners": {"*:7080": {"pass": "applications/script"}}, - "applications": { - "script": { - "type": self.get_application_type(), - "processes": {"spare": 0}, - "root": f"{option.test_dir}/php/script", - "script": "phpinfo.php", - } - }, - } - ), 'configure script' + assert client.get()['status'] == 200, 'status 2' - resp = self.get() + pattern = r'\d{4}\/\d\d\/\d\d\s\d\d:.+\[notice\].+Error in application' - assert resp['status'] == 200, 'status' - assert resp['body'] != '', 'body not empty' - - def test_php_application_index_default(self): - assert 'success' in self.conf( - { - "listeners": {"*:7080": {"pass": "applications/phpinfo"}}, - "applications": { - "phpinfo": { - "type": self.get_application_type(), - "processes": {"spare": 0}, - "root": f"{option.test_dir}/php/phpinfo", - } - }, - } - ), 'configure index default' + assert wait_for_record(pattern) is not None, 'errors print' - resp = self.get() + errs = findall(pattern) - assert resp['status'] == 200, 'status' - assert resp['body'] != '', 'body not empty' - - def test_php_application_trailing_slash(self, temp_dir): - new_root = f'{temp_dir}/php-root' - os.makedirs(f'{new_root}/path') - - Path(f'{new_root}/path/index.php').write_text('<?php echo "OK\n"; ?>') - - addr = f'{temp_dir}/sock' - - assert 'success' in self.conf( - { - "listeners": { - "*:7080": {"pass": "applications/php-path"}, - f'unix:{addr}': {"pass": "applications/php-path"}, - }, - "applications": { - "php-path": { - "type": self.get_application_type(), - "processes": {"spare": 0}, - "root": new_root, - } - }, - } - ), 'configure trailing slash' + assert len(errs) == 2, 'error_log count' - assert self.get(url='/path/')['status'] == 200, 'uri with trailing /' + date = errs[0].split('[')[0] + date2 = errs[1].split('[')[0] + assert date != date2, 'date diff' - resp = self.get(url='/path?q=a') - assert resp['status'] == 301, 'uri without trailing /' - assert ( - resp['headers']['Location'] == 'http://localhost:7080/path/?q=a' - ), 'Location with query string' - resp = self.get( - sock_type='unix', - addr=addr, - url='/path', - headers={'Host': 'foo', 'Connection': 'close'}, - ) - assert resp['status'] == 301, 'uri without trailing /' - assert ( - resp['headers']['Location'] == 'http://foo/path/' - ), 'Location with custom Host over UDS' - - def test_php_application_forbidden(self, temp_dir): - new_root = f'{temp_dir}/php-root/path' - os.makedirs(new_root) - os.chmod(new_root, 0o000) - - assert 'success' in self.conf( - { - "listeners": {"*:7080": {"pass": "applications/php-path"}}, - "applications": { - "php-path": { - "type": self.get_application_type(), - "processes": {"spare": 0}, - "root": f'{temp_dir}/php-root', - } - }, - } - ), 'forbidden directory' - - assert self.get(url='/path/')['status'] == 403, 'access forbidden' - - def test_php_application_extension_check(self, temp_dir): - self.load('phpinfo') - - assert self.get(url='/index.wrong')['status'] != 200, 'status' - - new_root = f'{temp_dir}/php' - os.mkdir(new_root) - shutil.copy(f'{option.test_dir}/php/phpinfo/index.wrong', new_root) - - assert 'success' in self.conf( - { - "listeners": {"*:7080": {"pass": "applications/phpinfo"}}, - "applications": { - "phpinfo": { - "type": self.get_application_type(), - "processes": {"spare": 0}, - "root": new_root, - "working_directory": new_root, - } - }, - } - ), 'configure new root' +def test_php_application_script(): + assert 'success' in client.conf( + { + "listeners": {"*:7080": {"pass": "applications/script"}}, + "applications": { + "script": { + "type": client.get_application_type(), + "processes": {"spare": 0}, + "root": f"{option.test_dir}/php/script", + "script": "phpinfo.php", + } + }, + } + ), 'configure script' - resp = self.get() - assert f'{resp["status"]}{resp["body"]}' != '200', 'status new root' + resp = client.get() - def run_php_application_cwd_root_tests(self): - assert 'success' in self.conf_delete( - 'applications/cwd/working_directory' - ) + assert resp['status'] == 200, 'status' + assert resp['body'] != '', 'body not empty' - script_cwd = f'{option.test_dir}/php/cwd' - resp = self.get() - assert resp['status'] == 200, 'status ok' - assert resp['body'] == script_cwd, 'default cwd' +def test_php_application_index_default(): + assert 'success' in client.conf( + { + "listeners": {"*:7080": {"pass": "applications/phpinfo"}}, + "applications": { + "phpinfo": { + "type": client.get_application_type(), + "processes": {"spare": 0}, + "root": f"{option.test_dir}/php/phpinfo", + } + }, + } + ), 'configure index default' - assert 'success' in self.conf( - f'"{option.test_dir}"', - 'applications/cwd/working_directory', - ) + resp = client.get() - resp = self.get() - assert resp['status'] == 200, 'status ok' - assert resp['body'] == script_cwd, 'wdir cwd' + assert resp['status'] == 200, 'status' + assert resp['body'] != '', 'body not empty' - resp = self.get(url='/?chdir=/') - assert resp['status'] == 200, 'status ok' - assert resp['body'] == '/', 'cwd after chdir' - # cwd must be restored +def test_php_application_trailing_slash(temp_dir): + new_root = f'{temp_dir}/php-root' + os.makedirs(f'{new_root}/path') - resp = self.get() - assert resp['status'] == 200, 'status ok' - assert resp['body'] == script_cwd, 'cwd restored' + Path(f'{new_root}/path/index.php').write_text('<?php echo "OK\n"; ?>') - resp = self.get(url='/subdir/') - assert resp['body'] == f'{script_cwd}/subdir', 'cwd subdir' + addr = f'{temp_dir}/sock' - def test_php_application_cwd_root(self): - self.load('cwd') - self.run_php_application_cwd_root_tests() + assert 'success' in client.conf( + { + "listeners": { + "*:7080": {"pass": "applications/php-path"}, + f'unix:{addr}': {"pass": "applications/php-path"}, + }, + "applications": { + "php-path": { + "type": client.get_application_type(), + "processes": {"spare": 0}, + "root": new_root, + } + }, + } + ), 'configure trailing slash' + + assert client.get(url='/path/')['status'] == 200, 'uri with trailing /' + + resp = client.get(url='/path?q=a') + assert resp['status'] == 301, 'uri without trailing /' + assert ( + resp['headers']['Location'] == 'http://localhost:7080/path/?q=a' + ), 'Location with query string' + + resp = client.get( + sock_type='unix', + addr=addr, + url='/path', + headers={'Host': 'foo', 'Connection': 'close'}, + ) + assert resp['status'] == 301, 'uri without trailing /' + assert ( + resp['headers']['Location'] == 'http://foo/path/' + ), 'Location with custom Host over UDS' + + +def test_php_application_forbidden(temp_dir): + new_root = f'{temp_dir}/php-root/path' + os.makedirs(new_root) + os.chmod(new_root, 0o000) + + assert 'success' in client.conf( + { + "listeners": {"*:7080": {"pass": "applications/php-path"}}, + "applications": { + "php-path": { + "type": client.get_application_type(), + "processes": {"spare": 0}, + "root": f'{temp_dir}/php-root', + } + }, + } + ), 'forbidden directory' - def test_php_application_cwd_opcache_disabled(self): - self.load('cwd') - self.set_opcache('cwd', '0') - self.run_php_application_cwd_root_tests() + assert client.get(url='/path/')['status'] == 403, 'access forbidden' - def test_php_application_cwd_opcache_enabled(self): - self.load('cwd') - self.set_opcache('cwd', '1') - self.run_php_application_cwd_root_tests() - def run_php_application_cwd_script_tests(self): - self.load('cwd') +def test_php_application_extension_check(temp_dir): + client.load('phpinfo') - script_cwd = f'{option.test_dir}/php/cwd' + assert client.get(url='/index.wrong')['status'] != 200, 'status' + + new_root = f'{temp_dir}/php' + os.mkdir(new_root) + shutil.copy(f'{option.test_dir}/php/phpinfo/index.wrong', new_root) + + assert 'success' in client.conf( + { + "listeners": {"*:7080": {"pass": "applications/phpinfo"}}, + "applications": { + "phpinfo": { + "type": client.get_application_type(), + "processes": {"spare": 0}, + "root": new_root, + "working_directory": new_root, + } + }, + } + ), 'configure new root' + + resp = client.get() + assert f'{resp["status"]}{resp["body"]}' != '200', 'status new root' + + +def test_php_application_cwd_root(): + client.load('cwd') + run_php_application_cwd_root_tests() + + +def test_php_application_cwd_opcache_disabled(): + client.load('cwd') + set_opcache('cwd', '0') + run_php_application_cwd_root_tests() + + +def test_php_application_cwd_opcache_enabled(): + client.load('cwd') + set_opcache('cwd', '1') + run_php_application_cwd_root_tests() + + +def test_php_application_cwd_script(): + client.load('cwd') + run_php_application_cwd_script_tests() - assert 'success' in self.conf_delete( - 'applications/cwd/working_directory' - ) - assert 'success' in self.conf('"index.php"', 'applications/cwd/script') +def test_php_application_cwd_script_opcache_disabled(): + client.load('cwd') + set_opcache('cwd', '0') + run_php_application_cwd_script_tests() - assert self.get()['body'] == script_cwd, 'default cwd' - assert self.get(url='/?chdir=/')['body'] == '/', 'cwd after chdir' +def test_php_application_cwd_script_opcache_enabled(): + client.load('cwd') + set_opcache('cwd', '1') + run_php_application_cwd_script_tests() - # cwd must be restored - assert self.get()['body'] == script_cwd, 'cwd restored' - def test_php_application_cwd_script(self): - self.load('cwd') - self.run_php_application_cwd_script_tests() +def test_php_application_path_relative(): + client.load('open') - def test_php_application_cwd_script_opcache_disabled(self): - self.load('cwd') - self.set_opcache('cwd', '0') - self.run_php_application_cwd_script_tests() + assert client.get()['body'] == 'test', 'relative path' - def test_php_application_cwd_script_opcache_enabled(self): - self.load('cwd') - self.set_opcache('cwd', '1') - self.run_php_application_cwd_script_tests() + assert ( + client.get(url='/?chdir=/')['body'] != 'test' + ), 'relative path w/ chdir' - def test_php_application_path_relative(self): - self.load('open') + assert client.get()['body'] == 'test', 'relative path 2' - assert self.get()['body'] == 'test', 'relative path' - assert ( - self.get(url='/?chdir=/')['body'] != 'test' - ), 'relative path w/ chdir' +def test_php_application_shared_opcache(): + client.load('opcache', limits={'requests': 1}) - assert self.get()['body'] == 'test', 'relative path 2' + r = check_opcache() + pid = r['headers']['X-Pid'] + assert r['headers']['X-Cached'] == '0', 'not cached' - def test_php_application_shared_opcache(self): - self.load('opcache', limits={'requests': 1}) + r = client.get() - r = self.check_opcache() - pid = r['headers']['X-Pid'] - assert r['headers']['X-Cached'] == '0', 'not cached' + assert r['headers']['X-Pid'] != pid, 'new instance' + assert r['headers']['X-Cached'] == '1', 'cached' - r = self.get() - assert r['headers']['X-Pid'] != pid, 'new instance' - assert r['headers']['X-Cached'] == '1', 'cached' +def test_php_application_opcache_preload_chdir(): + client.load('opcache') - def test_php_application_opcache_preload_chdir(self): - self.load('opcache') + check_opcache() - self.check_opcache() + set_preload('chdir.php') - self.set_preload('chdir.php') + assert client.get()['headers']['X-Cached'] == '0', 'not cached' + assert client.get()['headers']['X-Cached'] == '1', 'cached' - assert self.get()['headers']['X-Cached'] == '0', 'not cached' - assert self.get()['headers']['X-Cached'] == '1', 'cached' - def test_php_application_opcache_preload_ffr(self): - self.load('opcache') +def test_php_application_opcache_preload_ffr(): + client.load('opcache') - self.check_opcache() + check_opcache() - self.set_preload('fastcgi_finish_request.php') + set_preload('fastcgi_finish_request.php') - assert self.get()['headers']['X-Cached'] == '0', 'not cached' - assert self.get()['headers']['X-Cached'] == '1', 'cached' + assert client.get()['headers']['X-Cached'] == '0', 'not cached' + assert client.get()['headers']['X-Cached'] == '1', 'cached' |