diff options
author | Konstantin Pavlov <thresh@nginx.com> | 2023-05-10 10:29:16 -0700 |
---|---|---|
committer | Konstantin Pavlov <thresh@nginx.com> | 2023-05-10 10:29:16 -0700 |
commit | 69235c513277c64b513447d9b92c3c03d616f577 (patch) | |
tree | 0780c92ba28d92b547c85ea0bee5e3040e14dee2 /test | |
parent | b9bc222021e77bbdfb12576b3e315b962cf6b399 (diff) | |
parent | faf97dc06058de1c929af33a68adb34d3932b374 (diff) | |
download | unit-69235c513277c64b513447d9b92c3c03d616f577.tar.gz unit-69235c513277c64b513447d9b92c3c03d616f577.tar.bz2 |
Merged with the default branch.1.30.0-1
Diffstat (limited to '')
82 files changed, 1315 insertions, 859 deletions
diff --git a/test/conftest.py b/test/conftest.py index 4a1aa7cc..926d83f8 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -107,7 +107,7 @@ def pytest_configure(config): option.current_dir = os.path.abspath( os.path.join(os.path.dirname(__file__), os.pardir) ) - option.test_dir = option.current_dir + '/test' + option.test_dir = f'{option.current_dir}/test' option.architecture = platform.architecture()[0] option.system = platform.system() @@ -148,8 +148,8 @@ def pytest_generate_tests(metafunc): for version in versions: option.generated_tests[ - metafunc.function.__name__ + '[{}]'.format(version) - ] = (type + ' ' + version) + f'{metafunc.function.__name__} [{version}]' + ] = f'{type} {version}' # take available module from option and generate tests for each version @@ -161,18 +161,17 @@ def pytest_generate_tests(metafunc): generate_tests(available_versions) elif prereq_version == 'any': - option.generated_tests[metafunc.function.__name__] = ( - type + ' ' + available_versions[0] - ) + option.generated_tests[ + metafunc.function.__name__ + ] = f'{type} {available_versions[0]}' elif callable(prereq_version): generate_tests(list(filter(prereq_version, available_versions))) else: raise ValueError( - """ -Unexpected prerequisite version "%s" for module "%s" in %s. -'all', 'any' or callable expected.""" - % (str(prereq_version), module, str(cls)) + f''' +Unexpected prerequisite version "{prereq_version}" for module "{module}" in +{cls}. 'all', 'any' or callable expected.''' ) @@ -225,7 +224,7 @@ def pytest_sessionstart(session): check_isolation() check_unix_abstract() - _clear_conf(unit['temp_dir'] + '/control.unit.sock') + _clear_conf(f'{unit["temp_dir"]}/control.unit.sock') unit_stop() @@ -233,6 +232,8 @@ def pytest_sessionstart(session): if option.restart: shutil.rmtree(unit_instance['temp_dir']) + else: + _clear_temp_dir() @pytest.hookimpl(tryfirst=True, hookwrapper=True) @@ -244,7 +245,7 @@ def pytest_runtest_makereport(item, call): # set a report attribute for each phase of a call, which can # be "setup", "call", "teardown" - setattr(item, "rep_" + rep.when, rep) + setattr(item, f'rep_{rep.when}', rep) @pytest.fixture(scope='class', autouse=True) @@ -264,7 +265,7 @@ def check_prerequisites(request): missed.append(module) if missed: - pytest.skip('Unit has no ' + ', '.join(missed) + ' module(s)') + pytest.skip(f'Unit has no {", ".join(missed)} module(s)') # check features @@ -278,7 +279,7 @@ def check_prerequisites(request): missed.append(feature) if missed: - pytest.skip(', '.join(missed) + ' feature(s) not supported') + pytest.skip(f'{", ".join(missed)} feature(s) not supported') @pytest.fixture(autouse=True) @@ -316,33 +317,8 @@ def run(request): # clean temp_dir before the next test if not option.restart: - _clear_conf(unit['temp_dir'] + '/control.unit.sock', log=log) - - if is_findmnt and not waitforunmount(unit['temp_dir'], timeout=600): - exit('Could not unmount some filesystems in tmp dir.') - - for item in os.listdir(unit['temp_dir']): - if item not in [ - 'control.unit.sock', - 'state', - 'unit.pid', - 'unit.log', - ]: - path = os.path.join(unit['temp_dir'], item) - - public_dir(path) - - if os.path.isfile(path) or stat.S_ISSOCK(os.stat(path).st_mode): - os.remove(path) - else: - for attempt in range(10): - try: - shutil.rmtree(path) - break - except OSError as err: - if err.errno != 16: - raise - time.sleep(1) + _clear_conf(f'{unit["temp_dir"]}/control.unit.sock', log=log) + _clear_temp_dir() # check descriptors @@ -374,8 +350,11 @@ def unit_run(state_dir=None): if not option.restart and 'unitd' in unit_instance: return unit_instance - build_dir = option.current_dir + '/build' - unitd = build_dir + '/unitd' + builddir = f'{option.current_dir}/build' + libdir = f'{builddir}/lib' + modulesdir = f'{libdir}/unit/modules' + sbindir = f'{builddir}/sbin' + unitd = f'{sbindir}/unitd' if not os.path.isfile(unitd): exit('Could not find unit') @@ -383,53 +362,55 @@ def unit_run(state_dir=None): temp_dir = tempfile.mkdtemp(prefix='unit-test-') public_dir(temp_dir) - if oct(stat.S_IMODE(os.stat(build_dir).st_mode)) != '0o777': - public_dir(build_dir) + if oct(stat.S_IMODE(os.stat(builddir).st_mode)) != '0o777': + public_dir(builddir) - state = temp_dir + '/state' if state_dir is None else state_dir - if not os.path.isdir(state): - os.mkdir(state) + statedir = f'{temp_dir}/state' if state_dir is None else state_dir + if not os.path.isdir(statedir): + os.mkdir(statedir) + + control_sock = f'{temp_dir}/control.unit.sock' unitd_args = [ unitd, '--no-daemon', - '--modules', - build_dir, - '--state', - state, + '--modulesdir', + modulesdir, + '--statedir', + statedir, '--pid', - temp_dir + '/unit.pid', + f'{temp_dir}/unit.pid', '--log', - temp_dir + '/unit.log', + f'{temp_dir}/unit.log', '--control', - 'unix:' + temp_dir + '/control.unit.sock', - '--tmp', + f'unix:{temp_dir}/control.unit.sock', + '--tmpdir', temp_dir, ] if option.user: unitd_args.extend(['--user', option.user]) - with open(temp_dir + '/unit.log', 'w') as log: + with open(f'{temp_dir}/unit.log', 'w') as log: unit_instance['process'] = subprocess.Popen(unitd_args, stderr=log) Log.temp_dir = temp_dir - if not waitforfiles(temp_dir + '/control.unit.sock'): + if not waitforfiles(control_sock): _print_log() exit('Could not start unit') unit_instance['temp_dir'] = temp_dir - unit_instance['control_sock'] = temp_dir + '/control.unit.sock' + unit_instance['control_sock'] = control_sock unit_instance['unitd'] = unitd option.temp_dir = temp_dir - with open(temp_dir + '/unit.pid', 'r') as f: + with open(f'{temp_dir}/unit.pid', 'r') as f: unit_instance['pid'] = f.read().rstrip() if state_dir is None: - _clear_conf(unit_instance['temp_dir'] + '/control.unit.sock') + _clear_conf(control_sock) _fds_info['main']['fds'] = _count_fds(unit_instance['pid']) @@ -473,7 +454,7 @@ def unit_stop(): try: retcode = p.wait(15) if retcode: - return 'Child process terminated with code ' + str(retcode) + return f'Child process terminated with code {retcode}' except KeyboardInterrupt: p.kill() @@ -518,7 +499,7 @@ def _check_alerts(*, log=None): def _print_log(log=None): path = Log.get_path() - print('Path to unit.log:\n' + path + '\n') + print(f'Path to unit.log:\n{path}\n') if option.print_log: os.set_blocking(sys.stdout.fileno(), True) @@ -542,25 +523,58 @@ def _clear_conf(sock, *, log=None): assert 'success' in resp, 'clear conf' - if 'openssl' not in option.available['modules']: - return + def get(url): + return http.get(url=url, sock_type='unix', addr=sock)['body'] - try: - certs = json.loads( - http.get(url='/certificates', sock_type='unix', addr=sock)['body'] - ).keys() + def delete(url): + return http.delete(url=url, sock_type='unix', addr=sock)['body'] - except json.JSONDecodeError: - pytest.fail('Can\'t parse certificates list.') + if 'openssl' in option.available['modules']: + try: + certs = json.loads(get('/certificates')).keys() - for cert in certs: - resp = http.delete( - url='/certificates/' + cert, - sock_type='unix', - addr=sock, - )['body'] + except json.JSONDecodeError: + pytest.fail("Can't parse certificates list.") - assert 'success' in resp, 'remove certificate' + for cert in certs: + assert 'success' in delete(f'/certificates/{cert}'), 'delete cert' + + if 'njs' in option.available['modules']: + try: + scripts = json.loads(get('/js_modules')).keys() + + except json.JSONDecodeError: + pytest.fail("Can't parse njs modules list.") + + for script in scripts: + assert 'success' in delete(f'/js_modules/{script}'), 'delete script' + +def _clear_temp_dir(): + temp_dir = unit_instance['temp_dir'] + + if is_findmnt and not waitforunmount(temp_dir, timeout=600): + exit('Could not unmount some filesystems in tmpdir ({temp_dir}).') + + for item in os.listdir(temp_dir): + if item not in [ + 'control.unit.sock', + 'state', + 'unit.pid', + 'unit.log', + ]: + path = os.path.join(temp_dir, item) + public_dir(path) + if os.path.isfile(path) or stat.S_ISSOCK(os.stat(path).st_mode): + os.remove(path) + else: + for attempt in range(10): + try: + shutil.rmtree(path) + break + except OSError as err: + if err.errno != 16: + raise + time.sleep(1) def _check_processes(): @@ -595,17 +609,14 @@ def _check_processes(): out = [ l for l in out - if re.search(router_pid + r'\s+' + unit_pid + r'.*unit: router', l) - is None + if re.search(fr'{router_pid}\s+{unit_pid}.*unit: router', l) is None ] assert len(out) == 1, 'one router' out = [ l for l in out - if re.search( - controller_pid + r'\s+' + unit_pid + r'.*unit: controller', l - ) + if re.search(fr'{controller_pid}\s+{unit_pid}.*unit: controller', l) is None ] assert len(out) == 0, 'one controller' @@ -646,18 +657,16 @@ def _check_fds(*, log=None): ps['fds'] += fds_diff if not option.restart: - assert ps['pid'] == ps_pid, 'same pid %s' % name + assert ps['pid'] == ps_pid, f'same pid {name}' - assert fds_diff <= option.fds_threshold, ( - 'descriptors leak %s' % name - ) + assert fds_diff <= option.fds_threshold, f'descriptors leak {name}' else: ps['fds'] = _count_fds(ps['pid']) def _count_fds(pid): - procfile = '/proc/%s/fd' % pid + procfile = f'/proc/{pid}/fd' if os.path.isdir(procfile): return len(os.listdir(procfile)) @@ -712,14 +721,12 @@ def stop_processes(): def pid_by_name(name): output = subprocess.check_output(['ps', 'ax', '-O', 'ppid']).decode() - m = re.search( - r'\s*(\d+)\s*' + str(unit_instance['pid']) + r'.*' + name, output - ) + m = re.search(fr'\s*(\d+)\s*{unit_instance["pid"]}.*{name}', output) return None if m is None else m.group(1) def find_proc(name, ps_output): - return re.findall(str(unit_instance['pid']) + r'.*' + name, ps_output) + return re.findall(f'{unit_instance["pid"]}.*{name}', ps_output) @pytest.fixture() @@ -762,7 +769,7 @@ def unit_pid(request): def pytest_sessionfinish(session): if not option.restart and option.save_log: - print('Path to unit.log:\n' + Log.get_path() + '\n') + print(f'Path to unit.log:\n{Log.get_path()}\n') option.restart = True diff --git a/test/njs/global_this/script.js b/test/njs/global_this/script.js new file mode 100644 index 00000000..cf9bc078 --- /dev/null +++ b/test/njs/global_this/script.js @@ -0,0 +1,3 @@ +export default { + "str" : function () {return typeof globalThis.njs.version} +} diff --git a/test/njs/import_from/script.js b/test/njs/import_from/script.js new file mode 100644 index 00000000..99d1b80e --- /dev/null +++ b/test/njs/import_from/script.js @@ -0,0 +1,5 @@ +import cr from 'crypto'; + +export default { + "num" : function () {return typeof cr.createHash('md5').digest().length} +} diff --git a/test/njs/invalid/script.js b/test/njs/invalid/script.js new file mode 100644 index 00000000..a9d79797 --- /dev/null +++ b/test/njs/invalid/script.js @@ -0,0 +1,3 @@ +export default { + "route": function() {blah 'next'} +} diff --git a/test/njs/next/script.js b/test/njs/next/script.js new file mode 100644 index 00000000..86e49e82 --- /dev/null +++ b/test/njs/next/script.js @@ -0,0 +1,3 @@ +export default { + "route": function() {return 'next'} +} diff --git a/test/perl/streaming_body_multiple_responses/psgi.pl b/test/perl/streaming_body_multiple_responses/psgi.pl new file mode 100644 index 00000000..ffd026bd --- /dev/null +++ b/test/perl/streaming_body_multiple_responses/psgi.pl @@ -0,0 +1,11 @@ +my $counter = 2; + +my $app = sub { + my $env = shift; + + return sub { + my $responder = shift; + $responder->([200, ['Content-Type'=>'text/plain'], [$counter++]]); + $responder->([200, ['Content-Type'=>'text/plain'], [$counter++]]); + }; +}; diff --git a/test/python/environment/wsgi.py b/test/python/environment/wsgi.py index d1564f29..91e0ba49 100644 --- a/test/python/environment/wsgi.py +++ b/test/python/environment/wsgi.py @@ -2,13 +2,10 @@ import os def application(env, start_response): - body = '' vars = env.get('HTTP_X_VARIABLES').split(',') - for var in vars: - if var in os.environ: - body += str(os.environ[var]) + ',' - + body = ','.join([str(os.environ[var]) for var in vars if var in os.environ]) body = body.encode() + start_response('200', [('Content-Length', str(len(body)))]) return body diff --git a/test/python/input_readline_size/wsgi.py b/test/python/input_readline_size/wsgi.py index 36cf07b0..bde8c0d4 100644 --- a/test/python/input_readline_size/wsgi.py +++ b/test/python/input_readline_size/wsgi.py @@ -9,7 +9,7 @@ def application(environ, start_response): body.append(l) if len(l) > 9: - body.append(b'len(l) > 9: ' + l) + body.append(f'len(l) > 9: {l}'.encode()) break start_response('200', [('X-Lines-Count', str(len(body)))]) diff --git a/test/python/lifespan/empty/asgi.py b/test/python/lifespan/empty/asgi.py index 8ceecc2f..27395a28 100644 --- a/test/python/lifespan/empty/asgi.py +++ b/test/python/lifespan/empty/asgi.py @@ -3,17 +3,17 @@ import os async def handler(prefix, scope, receive, send): if scope['type'] == 'lifespan': - with open(prefix + 'version', 'w+') as f: + with open(f'{prefix}version', 'w+') as f: f.write( - scope['asgi']['version'] + ' ' + scope['asgi']['spec_version'] + f"{scope['asgi']['version']} {scope['asgi']['spec_version']}" ) while True: message = await receive() if message['type'] == 'lifespan.startup': - os.remove(prefix + 'startup') + os.remove(f'{prefix}startup') await send({'type': 'lifespan.startup.complete'}) elif message['type'] == 'lifespan.shutdown': - os.remove(prefix + 'shutdown') + os.remove(f'{prefix}shutdown') await send({'type': 'lifespan.shutdown.complete'}) return @@ -22,7 +22,9 @@ async def handler(prefix, scope, receive, send): { 'type': 'http.response.start', 'status': 204, - 'headers': [(b'content-length', b'0'),], + 'headers': [ + (b'content-length', b'0'), + ], } ) diff --git a/test/python/targets/wsgi.py b/test/python/targets/wsgi.py index 3f3d4b27..30a50efd 100644 --- a/test/python/targets/wsgi.py +++ b/test/python/targets/wsgi.py @@ -9,9 +9,6 @@ def wsgi_target_b(env, start_response): def wsgi_target_prefix(env, start_response): - data = u'%s %s' % ( - env.get('SCRIPT_NAME', 'No Script Name'), - env['PATH_INFO'], - ) - start_response('200', [('Content-Length', '%d' % len(data))]) + data = f"{env.get('SCRIPT_NAME', 'No Script Name')} {env['PATH_INFO']}" + start_response('200', [('Content-Length', f'{data}')]) return [data.encode('utf-8')] diff --git a/test/python/threading/asgi.py b/test/python/threading/asgi.py index fed6fcce..aa9b76cf 100644 --- a/test/python/threading/asgi.py +++ b/test/python/threading/asgi.py @@ -11,9 +11,7 @@ class Foo(threading.Thread): threading.Thread.__init__(self) def log_index(self, index): - sys.stderr.write( - "(" + str(index) + ") Thread: " + str(self.__x) + "\n" - ) + sys.stderr.write(f'({index}) Thread: {self.__x}\n') sys.stderr.flush() def run(self): diff --git a/test/python/threading/wsgi.py b/test/python/threading/wsgi.py index 48a73afd..afba674b 100644 --- a/test/python/threading/wsgi.py +++ b/test/python/threading/wsgi.py @@ -11,9 +11,7 @@ class Foo(threading.Thread): threading.Thread.__init__(self) def log_index(self, index): - sys.stderr.write( - "(" + str(index) + ") Thread: " + str(self.__x) + "\n" - ) + sys.stderr.write(f'({index}) Thread: {self.__x}\n') sys.stderr.flush() def run(self): diff --git a/test/python/unicode/wsgi.py b/test/python/unicode/wsgi.py index 40043af9..f2f85f5d 100644 --- a/test/python/unicode/wsgi.py +++ b/test/python/unicode/wsgi.py @@ -1,7 +1,7 @@ def application(environ, start_response): temp_dir = environ.get('HTTP_TEMP_DIR') - with open(temp_dir + '/tempfile', 'w') as f: + with open(f'{temp_dir}/tempfile', 'w') as f: f.write('\u26a0\ufe0f') start_response('200', [('Content-Length', '0')]) diff --git a/test/test_access_log.py b/test/test_access_log.py index a072858b..c29638a3 100644 --- a/test/test_access_log.py +++ b/test/test_access_log.py @@ -12,13 +12,13 @@ class TestAccessLog(TestApplicationPython): super().load(script) assert 'success' in self.conf( - '"' + option.temp_dir + '/access.log"', 'access_log' + f'"{option.temp_dir}/access.log"', 'access_log' ), 'access_log configure' def set_format(self, format): assert 'success' in self.conf( { - 'path': option.temp_dir + '/access.log', + 'path': f'{option.temp_dir}/access.log', 'format': format, }, 'access_log', @@ -103,13 +103,13 @@ Connection: close is not None ), 'ipv6' - def test_access_log_unix(self): + def test_access_log_unix(self, temp_dir): self.load('empty') - addr = option.temp_dir + '/sock' + addr = f'{temp_dir}/sock' assert 'success' in self.conf( - {"unix:" + addr: {"pass": "applications/empty"}}, 'listeners' + {f'unix:{addr}': {"pass": "applications/empty"}}, 'listeners' ) self.get(sock_type='unix', addr=addr) @@ -174,7 +174,7 @@ Connection: close time.sleep(1) assert ( - self.wait_for_record(r'"GE" 400 0 "-" "-"') is not None + self.wait_for_record(r'"-" 400 0 "-" "-"') is not None ), 'partial' def test_access_log_partial_2(self): @@ -185,7 +185,7 @@ Connection: close self.http(b"""GET /\n""", raw=True) assert ( - self.wait_for_record(r'"GET /" 400 \d+ "-" "-"') is not None + self.wait_for_record(r'"-" 400 \d+ "-" "-"') is not None ), 'partial 2' def test_access_log_partial_3(self): @@ -198,7 +198,7 @@ Connection: close time.sleep(1) assert ( - self.wait_for_record(r'"GET /" 400 0 "-" "-"') is not None + self.wait_for_record(r'"-" 400 0 "-" "-"') is not None ), 'partial 3' def test_access_log_partial_4(self): @@ -211,7 +211,7 @@ Connection: close time.sleep(1) assert ( - self.wait_for_record(r'"GET / HTTP/1.1" 400 0 "-" "-"') is not None + self.wait_for_record(r'"-" 400 0 "-" "-"') is not None ), 'partial 4' @pytest.mark.skip('not yet') @@ -248,14 +248,12 @@ Connection: close assert self.search_in_log(r'/delete', 'access.log') is None, 'delete' - def test_access_log_change(self): + def test_access_log_change(self, temp_dir): self.load('empty') self.get() - assert 'success' in self.conf( - '"' + option.temp_dir + '/new.log"', 'access_log' - ) + assert 'success' in self.conf(f'"{temp_dir}/new.log"', 'access_log') self.get() @@ -286,19 +284,20 @@ Connection: close body = '0123456789' * 50 self.post(url='/bbs', body=body, read_timeout=1) assert ( - self.wait_for_record(r'^\/bbs ' + str(len(body)) + r'$') is not None + self.wait_for_record(fr'^\/bbs {len(body)}$') is not None ), '$body_bytes_sent' - def test_access_log_incorrect(self, skip_alert): + def test_access_log_incorrect(self, temp_dir, skip_alert): skip_alert(r'failed to apply new conf') assert 'error' in self.conf( - option.temp_dir + '/blah/access.log' 'access_log/path', + f'{option.temp_dir}/blah/access.log', + 'access_log/path', ), 'access_log path incorrect' assert 'error' in self.conf( { - 'path': option.temp_dir + '/access.log', + 'path': f'{temp_dir}/access.log', 'format': '$remote_add', }, 'access_log', diff --git a/test/test_asgi_application.py b/test/test_asgi_application.py index 121a2fbc..5ce82cb2 100644 --- a/test/test_asgi_application.py +++ b/test/test_asgi_application.py @@ -20,17 +20,16 @@ class TestASGIApplication(TestApplicationPython): body = 'Test body string.' resp = self.http( - b"""POST / HTTP/1.1 + f"""POST / HTTP/1.1 Host: localhost -Content-Length: %d +Content-Length: {len(body)} Custom-Header: blah Custom-hEader: Blah Content-Type: text/html Connection: close custom-header: BLAH -%s""" - % (len(body), body.encode()), +{body}""".encode(), raw=True, ) @@ -63,9 +62,9 @@ custom-header: BLAH def test_asgi_application_unix(self, temp_dir): self.load('empty') - addr = temp_dir + '/sock' + addr = f'{temp_dir}/sock' assert 'success' in self.conf( - {"unix:" + addr: {"pass": "applications/empty"}}, 'listeners' + {f"unix:{addr}": {"pass": "applications/empty"}}, 'listeners' ) assert self.get(sock_type='unix', addr=addr)['status'] == 200 @@ -83,7 +82,7 @@ custom-header: BLAH self.load('prefix', prefix='/api/rest') def set_prefix(prefix): - self.conf('"' + prefix + '"', 'applications/prefix/prefix') + self.conf(f'"{prefix}"', 'applications/prefix/prefix') def check_prefix(url, prefix): resp = self.get(url=url) @@ -190,7 +189,7 @@ custom-header: BLAH max_body_size = 12 * 1024 * 1024 assert 'success' in self.conf( - '{"http":{"max_body_size": ' + str(max_body_size) + ' }}', + f'{{"http":{{"max_body_size": {max_body_size} }}}}', 'settings', ) diff --git a/test/test_asgi_application_unix_abstract.py b/test/test_asgi_application_unix_abstract.py index c4ec812f..2ca7839f 100644 --- a/test/test_asgi_application_unix_abstract.py +++ b/test/test_asgi_application_unix_abstract.py @@ -16,7 +16,7 @@ class TestASGIApplicationUnixAbstract(TestApplicationPython): addr = '\0sock' assert 'success' in self.conf( - {"unix:@" + addr[1:]: {"pass": "applications/empty"}}, + {f"unix:@{addr[1:]}": {"pass": "applications/empty"}}, 'listeners', ) diff --git a/test/test_asgi_lifespan.py b/test/test_asgi_lifespan.py index e295f7fa..84e9fea4 100644 --- a/test/test_asgi_lifespan.py +++ b/test/test_asgi_lifespan.py @@ -15,25 +15,25 @@ class TestASGILifespan(TestApplicationPython): load_module = 'asgi' def setup_cookies(self, prefix): - base_dir = option.test_dir + '/python/lifespan/empty' + base_dir = f'{option.test_dir}/python/lifespan/empty' os.chmod(base_dir, 0o777) for name in ['startup', 'shutdown', 'version']: - path = option.test_dir + '/python/lifespan/empty/' + prefix + name + path = f'{option.test_dir}/python/lifespan/empty/{prefix}{name}' open(path, 'a').close() os.chmod(path, 0o777) def assert_cookies(self, prefix): for name in ['startup', 'shutdown']: - path = option.test_dir + '/python/lifespan/empty/' + prefix + name + path = f'{option.test_dir}/python/lifespan/empty/{prefix}{name}' exists = os.path.isfile(path) if exists: os.remove(path) assert not exists, name - path = option.test_dir + '/python/lifespan/empty/' + prefix + 'version' + path = f'{option.test_dir}/python/lifespan/empty/{prefix}version' with open(path, 'r') as f: version = f.read() @@ -54,6 +54,8 @@ class TestASGILifespan(TestApplicationPython): self.assert_cookies('') def test_asgi_lifespan_targets(self): + path = f'{option.test_dir}/python/lifespan/empty' + assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, @@ -71,9 +73,8 @@ class TestASGILifespan(TestApplicationPython): "targets": { "type": self.get_application_type(), "processes": {"spare": 0}, - "working_directory": option.test_dir - + "/python/lifespan/empty", - "path": option.test_dir + '/python/lifespan/empty', + "working_directory": path, + "path": path, "targets": { "1": {"module": "asgi", "callable": "application"}, "2": { diff --git a/test/test_asgi_targets.py b/test/test_asgi_targets.py index 84d7b3b0..5afc7079 100644 --- a/test/test_asgi_targets.py +++ b/test/test_asgi_targets.py @@ -14,6 +14,8 @@ class TestASGITargets(TestApplicationPython): @pytest.fixture(autouse=True) def setup_method_fixture(self): + path = f'{option.test_dir}/python/targets/' + assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, @@ -31,9 +33,8 @@ class TestASGITargets(TestApplicationPython): "targets": { "type": self.get_application_type(), "processes": {"spare": 0}, - "working_directory": option.test_dir - + "/python/targets/", - "path": option.test_dir + '/python/targets/', + "working_directory": path, + "path": path, "protocol": "asgi", "targets": { "1": { diff --git a/test/test_asgi_websockets.py b/test/test_asgi_websockets.py index 975be90a..b15bee43 100644 --- a/test/test_asgi_websockets.py +++ b/test/test_asgi_websockets.py @@ -151,7 +151,7 @@ class TestASGIWebsockets(TestApplicationPython): frame = self.ws.frame_read(sock) - assert message + ' ' + message == frame['data'].decode( + assert f'{message} {message}' == frame['data'].decode( 'utf-8' ), 'mirror framing' @@ -527,21 +527,21 @@ class TestASGIWebsockets(TestApplicationPython): _, sock, _ = self.ws.upgrade() for i in range(0, 10): - self.ws.frame_write(sock, self.ws.OP_PING, 'payload-%d' % i) + self.ws.frame_write(sock, self.ws.OP_PING, f'payload-{i}') for i in range(0, 10): frame = self.ws.frame_read(sock) - self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i) + self.check_frame(frame, True, self.ws.OP_PONG, f'payload-{i}') # 2_11 for i in range(0, 10): opcode = self.ws.OP_PING - self.ws.frame_write(sock, opcode, 'payload-%d' % i, chopsize=1) + self.ws.frame_write(sock, opcode, f'payload-{i}', chopsize=1) for i in range(0, 10): frame = self.ws.frame_read(sock) - self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i) + self.check_frame(frame, True, self.ws.OP_PONG, f'payload-{i}') self.close_connection(sock) diff --git a/test/test_client_ip.py b/test/test_client_ip.py index 50aa6afc..6520d5e2 100644 --- a/test/test_client_ip.py +++ b/test/test_client_ip.py @@ -16,9 +16,7 @@ class TestClientIP(TestApplicationPython): "client_ip": options, "pass": "applications/client_ip", }, - "unix:" - + option.temp_dir - + "/sock": { + f"unix:{option.temp_dir}/sock": { "client_ip": options, "pass": "applications/client_ip", }, @@ -30,7 +28,7 @@ class TestClientIP(TestApplicationPython): address = { 'ipv4': ('127.0.0.1', 7081), 'ipv6': ('::1', 7082), - 'unix': (option.temp_dir + '/sock', None), + 'unix': (f'{option.temp_dir}/sock', None), } (addr, port) = address[sock_type] diff --git a/test/test_configuration.py b/test/test_configuration.py index 9c27222c..e3ddc891 100644 --- a/test/test_configuration.py +++ b/test/test_configuration.py @@ -283,7 +283,7 @@ class TestConfiguration(TestControl): assert 'success' in self.conf( { - "listeners": {"*:7080": {"pass": "applications/" + name}}, + "listeners": {"*:7080": {"pass": f"applications/{name}"}}, "applications": { name: { "type": "python", @@ -301,8 +301,7 @@ class TestConfiguration(TestControl): conf = { "applications": { - "app-" - + str(a): { + f"app-{a}": { "type": "python", "processes": {"spare": 0}, "path": "/app", @@ -311,7 +310,7 @@ class TestConfiguration(TestControl): for a in range(apps) }, "listeners": { - "*:" + str(7000 + a): {"pass": "applications/app-" + str(a)} + f"*:{(7000 + a)}": {"pass": f"applications/app-{a}"} for a in range(apps) }, } @@ -407,8 +406,7 @@ class TestConfiguration(TestControl): def test_json_application_many2(self): conf = { "applications": { - "app-" - + str(a): { + f"app-{a}": { "type": "python", "processes": {"spare": 0}, "path": "/app", diff --git a/test/test_go_application.py b/test/test_go_application.py index a746c6f4..9034d5aa 100644 --- a/test/test_go_application.py +++ b/test/test_go_application.py @@ -139,15 +139,15 @@ class TestGoApplication(TestApplicationGo): self.load('command_line_arguments') arg1 = '--cc=gcc-7.2.0' - arg2 = '--cc-opt=\'-O0 -DNXT_DEBUG_MEMORY=1 -fsanitize=address\'' + arg2 = "--cc-opt='-O0 -DNXT_DEBUG_MEMORY=1 -fsanitize=address'" arg3 = '--debug' assert 'success' in self.conf( - '["' + arg1 + '", "' + arg2 + '", "' + arg3 + '"]', + f'["{arg1}", "{arg2}", "{arg3}"]', 'applications/command_line_arguments/arguments', ) - assert self.get()['body'] == arg1 + ',' + arg2 + ',' + arg3, 'arguments' + assert self.get()['body'] == f'{arg1},{arg2},{arg3}', 'arguments' def test_go_application_command_line_arguments_change(self): self.load('command_line_arguments') diff --git a/test/test_go_isolation.py b/test/test_go_isolation.py index c3f92679..f063f987 100644 --- a/test/test_go_isolation.py +++ b/test/test_go_isolation.py @@ -37,7 +37,7 @@ class TestGoIsolation(TestApplicationGo): for ns, ns_value in option.available['features']['isolation'].items(): if ns.upper() in obj['NS']: - assert obj['NS'][ns.upper()] == ns_value, '%s match' % ns + assert obj['NS'][ns.upper()] == ns_value, f'{ns} match' def test_isolation_unpriv_user(self, is_su): if not self.isolation_key('unprivileged_userns_clone'): @@ -60,7 +60,7 @@ class TestGoIsolation(TestApplicationGo): # unprivileged unit map itself to nobody in the container by default assert obj['UID'] == nobody_uid, 'uid of nobody' - assert obj['GID'] == nogroup_gid, 'gid of %s' % nogroup + assert obj['GID'] == nogroup_gid, f'gid of {nogroup}' self.load( 'ns_inspect', @@ -200,7 +200,7 @@ class TestGoIsolation(TestApplicationGo): assert ( obj['NS'][ns.upper()] == option.available['features']['isolation'][ns] - ), ('%s match' % ns) + ), f'{ns} match' assert obj['NS']['MNT'] != getns('mnt'), 'mnt set' assert obj['NS']['USER'] != getns('user'), 'user set' @@ -260,7 +260,7 @@ class TestGoIsolation(TestApplicationGo): assert ( obj['NS'][ns.upper()] == option.available['features']['isolation'][ns] - ), ('%s match' % ns) + ), f'{ns} match' def test_go_isolation_rootfs_container(self, is_su, temp_dir): if not is_su: diff --git a/test/test_http_header.py b/test/test_http_header.py index 6773c44f..cae5e9b8 100644 --- a/test/test_http_header.py +++ b/test/test_http_header.py @@ -107,7 +107,7 @@ class TestHTTPHeader(TestApplicationPython): resp = self.get( headers={ 'Host': 'localhost', - 'Custom-Header': r'(),/:;<=>?@[\]{}\t !#$%&\'*+-.^_`|~', + 'Custom-Header': r"(),/:;<=>?@[\]{}\t !#$%&'*+-.^_`|~", 'Connection': 'close', } ) @@ -115,7 +115,7 @@ class TestHTTPHeader(TestApplicationPython): assert resp['status'] == 200, 'value chars status' assert ( resp['headers']['Custom-Header'] - == r'(),/:;<=>?@[\]{}\t !#$%&\'*+-.^_`|~' + == r"(),/:;<=>?@[\]{}\t !#$%&'*+-.^_`|~" ), 'value chars custom header' def test_http_header_value_chars_edge(self): diff --git a/test/test_java_application.py b/test/test_java_application.py index b825d925..6ff556a8 100644 --- a/test/test_java_application.py +++ b/test/test_java_application.py @@ -24,9 +24,9 @@ class TestJavaApplication(TestApplicationJava): "app": { "type": self.get_application_type(), "processes": 1, - "working_directory": option.test_dir + "/java/empty", - "webapp": temp_dir + "/java", - "unit_jars": temp_dir + "/no_such_dir", + "working_directory": f"{option.test_dir}/java/empty", + "webapp": f"{temp_dir}/java", + "unit_jars": f"{temp_dir}/no_such_dir", } }, } @@ -36,7 +36,7 @@ class TestJavaApplication(TestApplicationJava): self.load('empty_war') assert 'success' in self.conf( - '"' + temp_dir + '/java/empty.war"', + f'"{temp_dir}/java/empty.war"', '/config/applications/empty_war/webapp', ), 'configure war' @@ -118,7 +118,7 @@ class TestJavaApplication(TestApplicationJava): headers = self.get( headers={ 'Host': 'localhost', - 'Cookie': 'JSESSIONID=' + session_id, + 'Cookie': f'JSESSIONID={session_id}', 'Connection': 'close', }, url='/?var1=val2', @@ -157,7 +157,7 @@ class TestJavaApplication(TestApplicationJava): resp = self.get( headers={ 'Host': 'localhost', - 'Cookie': 'JSESSIONID=' + session_id, + 'Cookie': f'JSESSIONID={session_id}', 'Connection': 'close', } ) @@ -171,7 +171,7 @@ class TestJavaApplication(TestApplicationJava): resp = self.get( headers={ 'Host': 'localhost', - 'Cookie': 'JSESSIONID=' + session_id, + 'Cookie': f'JSESSIONID={session_id}', 'Connection': 'close', } ) @@ -183,7 +183,7 @@ class TestJavaApplication(TestApplicationJava): resp = self.get( headers={ 'Host': 'localhost', - 'Cookie': 'JSESSIONID=' + session_id, + 'Cookie': f'JSESSIONID={session_id}', 'Connection': 'close', } ) @@ -207,7 +207,7 @@ class TestJavaApplication(TestApplicationJava): resp = self.get( headers={ 'Host': 'localhost', - 'Cookie': 'JSESSIONID=' + session_id, + 'Cookie': f'JSESSIONID={session_id}', 'Connection': 'close', } ) @@ -223,7 +223,7 @@ class TestJavaApplication(TestApplicationJava): resp = self.get( headers={ 'Host': 'localhost', - 'Cookie': 'JSESSIONID=' + session_id, + 'Cookie': f'JSESSIONID={session_id}', 'Connection': 'close', } ) @@ -244,7 +244,7 @@ class TestJavaApplication(TestApplicationJava): headers = self.get( headers={ 'Host': 'localhost', - 'Cookie': 'JSESSIONID=' + session_id, + 'Cookie': f'JSESSIONID={session_id}', 'Connection': 'close', }, url='/?var1=val2', @@ -256,7 +256,7 @@ class TestJavaApplication(TestApplicationJava): headers = self.get( headers={ 'Host': 'localhost', - 'Cookie': 'JSESSIONID=' + session_id, + 'Cookie': f'JSESSIONID={session_id}', 'Connection': 'close', }, url='/', @@ -770,7 +770,7 @@ class TestJavaApplication(TestApplicationJava): assert headers['X-Path-Info'] == '/test', 'the rest of the path' assert ( headers['X-Path-Translated'] - == headers['X-Real-Path'] + headers['X-Path-Info'] + == f"{headers['X-Real-Path']}{headers['X-Path-Info']}" ), 'translated path is the app root + path info' assert ( headers['X-Resource-Paths'].endswith('/WEB-INF/, /index.html]') @@ -956,7 +956,7 @@ class TestJavaApplication(TestApplicationJava): self.load('multipart') reldst = '/uploads' - fulldst = temp_dir + reldst + fulldst = f'{temp_dir}{reldst}' os.mkdir(fulldst) public_dir(fulldst) @@ -989,7 +989,7 @@ class TestJavaApplication(TestApplicationJava): assert re.search(r'sample\.txt created', resp['body']), 'multipart body' assert ( self.search_in_log( - r'^Data from sample file$', name=reldst + '/sample.txt' + r'^Data from sample file$', name=f'{reldst}/sample.txt' ) is not None ), 'file created' diff --git a/test/test_java_isolation_rootfs.py b/test/test_java_isolation_rootfs.py index 3c6a45a3..28668997 100644 --- a/test/test_java_isolation_rootfs.py +++ b/test/test_java_isolation_rootfs.py @@ -13,17 +13,17 @@ class TestJavaIsolationRootfs(TestApplicationJava): if not is_su: pytest.skip('require root') - os.makedirs(option.temp_dir + '/jars') - os.makedirs(option.temp_dir + '/tmp') - os.chmod(option.temp_dir + '/tmp', 0o777) + os.makedirs(f'{option.temp_dir}/jars') + os.makedirs(f'{option.temp_dir}/tmp') + os.chmod(f'{option.temp_dir}/tmp', 0o777) try: subprocess.run( [ "mount", "--bind", - option.current_dir + "/build", - option.temp_dir + "/jars", + f'{option.current_dir}/build', + f'{option.temp_dir}/jars', ], stderr=subprocess.STDOUT, ) @@ -32,7 +32,7 @@ class TestJavaIsolationRootfs(TestApplicationJava): raise except subprocess.CalledProcessError: - pytest.fail('Can\'t run mount process.') + pytest.fail("Can't run mount process.") def teardown_method(self, is_su): if not is_su: @@ -40,7 +40,7 @@ class TestJavaIsolationRootfs(TestApplicationJava): try: subprocess.run( - ["umount", "--lazy", option.temp_dir + "/jars"], + ["umount", "--lazy", f"{option.temp_dir}/jars"], stderr=subprocess.STDOUT, ) @@ -48,7 +48,7 @@ class TestJavaIsolationRootfs(TestApplicationJava): raise except subprocess.CalledProcessError: - pytest.fail('Can\'t run umount process.') + pytest.fail("Can't run umount process.") def test_java_isolation_rootfs_chroot_war(self, is_su, temp_dir): if not is_su: diff --git a/test/test_java_websockets.py b/test/test_java_websockets.py index 362c8619..8de45a06 100644 --- a/test/test_java_websockets.py +++ b/test/test_java_websockets.py @@ -109,7 +109,7 @@ class TestJavaWebsockets(TestApplicationJava): frame = self.ws.frame_read(sock) - assert message + ' ' + message == frame['data'].decode( + assert f'{message} {message}' == frame['data'].decode( 'utf-8' ), 'mirror framing' @@ -454,21 +454,21 @@ class TestJavaWebsockets(TestApplicationJava): _, sock, _ = self.ws.upgrade() for i in range(0, 10): - self.ws.frame_write(sock, self.ws.OP_PING, 'payload-%d' % i) + self.ws.frame_write(sock, self.ws.OP_PING, f'payload-{i}') for i in range(0, 10): frame = self.ws.frame_read(sock) - self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i) + self.check_frame(frame, True, self.ws.OP_PONG, f'payload-{i}') # 2_11 for i in range(0, 10): opcode = self.ws.OP_PING - self.ws.frame_write(sock, opcode, 'payload-%d' % i, chopsize=1) + self.ws.frame_write(sock, opcode, f'payload-{i}', chopsize=1) for i in range(0, 10): frame = self.ws.frame_read(sock) - self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i) + self.check_frame(frame, True, self.ws.OP_PONG, f'payload-{i}') self.close_connection(sock) diff --git a/test/test_njs.py b/test/test_njs.py index 2cbded5b..a7261290 100644 --- a/test/test_njs.py +++ b/test/test_njs.py @@ -2,75 +2,77 @@ import os from unit.applications.proto import TestApplicationProto from unit.option import option +from unit.utils import waitforfiles class TestNJS(TestApplicationProto): prerequisites = {'modules': {'njs': 'any'}} def setup_method(self): - os.makedirs(option.temp_dir + '/assets') - open(option.temp_dir + '/assets/index.html', 'a') - open(option.temp_dir + '/assets/localhost', 'a') - open(option.temp_dir + '/assets/`string`', 'a') - open(option.temp_dir + '/assets/`backtick', 'a') - open(option.temp_dir + '/assets/l1\nl2', 'a') - open(option.temp_dir + '/assets/127.0.0.1', 'a') - assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, "routes": [ - {"action": {"share": option.temp_dir + "/assets$uri"}} + {"action": {"share": f"{option.temp_dir}/assets$uri"}} ], } ) + def create_files(self, *files): + assets_dir = f'{option.temp_dir}/assets/' + os.makedirs(assets_dir) + + [open(assets_dir + f, 'a') for f in files] + waitforfiles(*[assets_dir + f for f in files]) + def set_share(self, share): assert 'success' in self.conf(share, 'routes/0/action/share') - def test_njs_template_string(self, temp_dir): - self.set_share('"`' + temp_dir + '/assets/index.html`"') - assert self.get()['status'] == 200, 'string' + def check_expression(self, expression, url='/'): + self.set_share(f'"`{option.temp_dir}/assets{expression}`"') + assert self.get(url=url)['status'] == 200 - self.set_share('"' + temp_dir + '/assets/`string`"') - assert self.get()['status'] == 200, 'string 2' + def test_njs_template_string(self, temp_dir): + self.create_files('str', '`string`', '`backtick', 'l1\nl2') - self.set_share('"`' + temp_dir + '/assets/\\\\`backtick`"') - assert self.get()['status'] == 200, 'escape' + self.check_expression('/str') + self.check_expression('/\\\\`backtick') + self.check_expression('/l1\\nl2') - self.set_share('"`' + temp_dir + '/assets/l1\\nl2`"') - assert self.get()['status'] == 200, 'multiline' + self.set_share(f'"{temp_dir}/assets/`string`"') + assert self.get()['status'] == 200 def test_njs_template_expression(self, temp_dir): - def check_expression(expression): - self.set_share(expression) - assert self.get()['status'] == 200 + self.create_files('str', 'localhost') - check_expression('"`' + temp_dir + '/assets${uri}`"') - check_expression('"`' + temp_dir + '/assets${uri}${host}`"') - check_expression('"`' + temp_dir + '/assets${uri + host}`"') - check_expression('"`' + temp_dir + '/assets${uri + `${host}`}`"') + self.check_expression('${uri}', '/str') + self.check_expression('${uri}${host}') + self.check_expression('${uri + host}') + self.check_expression('${uri + `${host}`}') - def test_njs_variables(self, temp_dir): - self.set_share('"`' + temp_dir + '/assets/${host}`"') - assert self.get()['status'] == 200, 'host' + def test_njs_iteration(self, temp_dir): + self.create_files('Connection,Host', 'close,localhost') - self.set_share('"`' + temp_dir + '/assets/${remoteAddr}`"') - assert self.get()['status'] == 200, 'remoteAddr' + self.check_expression('/${Object.keys(headers).sort().join()}') + self.check_expression('/${Object.values(headers).sort().join()}') + + def test_njs_variables(self, temp_dir): + self.create_files('str', 'localhost', '127.0.0.1') - self.set_share('"`' + temp_dir + '/assets/${headers.Host}`"') - assert self.get()['status'] == 200, 'headers' + self.check_expression('/${host}') + self.check_expression('/${remoteAddr}') + self.check_expression('/${headers.Host}') - self.set_share('"`' + temp_dir + '/assets/${cookies.foo}`"') + self.set_share(f'"`{temp_dir}/assets/${{cookies.foo}}`"') assert ( - self.get( - headers={'Cookie': 'foo=localhost', 'Connection': 'close'} - )['status'] + self.get(headers={'Cookie': 'foo=str', 'Connection': 'close'})[ + 'status' + ] == 200 ), 'cookies' - self.set_share('"`' + temp_dir + '/assets/${args.foo}`"') - assert self.get(url='/?foo=localhost')['status'] == 200, 'args' + self.set_share(f'"`{temp_dir}/assets/${{args.foo}}`"') + assert self.get(url='/?foo=str')['status'] == 200, 'args' def test_njs_invalid(self, temp_dir, skip_alert): skip_alert(r'js exception:') diff --git a/test/test_njs_modules.py b/test/test_njs_modules.py new file mode 100644 index 00000000..ce592fe4 --- /dev/null +++ b/test/test_njs_modules.py @@ -0,0 +1,99 @@ +from unit.applications.proto import TestApplicationProto +from unit.option import option + + +class TestNJSModules(TestApplicationProto): + prerequisites = {'modules': {'njs': 'any'}} + + def njs_script_load(self, module, name=None, expect='success'): + if name is None: + name = module + + with open(f'{option.test_dir}/njs/{module}/script.js', 'rb') as s: + assert expect in self.conf(s.read(), f'/js_modules/{name}') + + def test_njs_modules(self): + self.njs_script_load('next') + + assert 'export' in self.conf_get('/js_modules/next') + assert 'error' in self.conf_post('"blah"', '/js_modules/next') + + assert 'success' in self.conf( + { + "settings": {"js_module": "next"}, + "listeners": {"*:7080": {"pass": "routes/first"}}, + "routes": { + "first": [{"action": {"pass": "`routes/${next.route()}`"}}], + "next": [{"action": {"return": 200}}], + }, + } + ) + assert self.get()['status'] == 200, 'string' + + assert 'success' in self.conf({"js_module": ["next"]}, 'settings') + assert self.get()['status'] == 200, 'array' + + # add one more value to array + + assert len(self.conf_get('/js_modules').keys()) == 1 + + self.njs_script_load('next', 'next_2') + + assert len(self.conf_get('/js_modules').keys()) == 2 + + assert 'success' in self.conf_post('"next_2"', 'settings/js_module') + assert self.get()['status'] == 200, 'array len 2' + + assert 'success' in self.conf( + '"`routes/${next_2.route()}`"', 'routes/first/0/action/pass' + ) + assert self.get()['status'] == 200, 'array new' + + # can't update exsisting script + + self.njs_script_load('global_this', 'next', expect='error') + + # delete modules + + assert 'error' in self.conf_delete('/js_modules/next_2') + assert 'success' in self.conf_delete('settings/js_module') + assert 'success' in self.conf_delete('/js_modules/next_2') + + def test_njs_modules_import(self): + self.njs_script_load('import_from') + + assert 'success' in self.conf( + { + "settings": {"js_module": "import_from"}, + "listeners": {"*:7080": {"pass": "routes/first"}}, + "routes": { + "first": [ + {"action": {"pass": "`routes/${import_from.num()}`"}} + ], + "number": [{"action": {"return": 200}}], + }, + } + ) + assert self.get()['status'] == 200 + + def test_njs_modules_this(self): + self.njs_script_load('global_this') + + assert 'success' in self.conf( + { + "settings": {"js_module": "global_this"}, + "listeners": {"*:7080": {"pass": "routes/first"}}, + "routes": { + "first": [ + {"action": {"pass": "`routes/${global_this.str()}`"}} + ], + "string": [{"action": {"return": 200}}], + }, + } + ) + assert self.get()['status'] == 200 + + def test_njs_modules_invalid(self, skip_alert): + skip_alert(r'.*JS compile module.*failed.*') + + self.njs_script_load('invalid', expect='error') diff --git a/test/test_node_application.py b/test/test_node_application.py index c26c72d0..719afae8 100644 --- a/test/test_node_application.py +++ b/test/test_node_application.py @@ -146,7 +146,7 @@ class TestNodeApplication(TestApplicationNode): self.load('write_callback') assert self.get()['body'] == 'helloworld', 'write callback order' - assert waitforfiles(temp_dir + '/node/callback'), 'write callback' + assert waitforfiles(f'{temp_dir}/node/callback'), 'write callback' def test_node_application_write_before_write_head(self): self.load('write_before_write_head') @@ -255,7 +255,7 @@ class TestNodeApplication(TestApplicationNode): )['status'] == 200 ), 'promise end request' - assert waitforfiles(temp_dir + '/node/callback'), 'promise end' + assert waitforfiles(f'{temp_dir}/node/callback'), 'promise end' @pytest.mark.skip('not yet') def test_node_application_header_name_valid(self): diff --git a/test/test_node_websockets.py b/test/test_node_websockets.py index 1f9a2e6b..f1767cac 100644 --- a/test/test_node_websockets.py +++ b/test/test_node_websockets.py @@ -109,7 +109,7 @@ class TestNodeWebsockets(TestApplicationNode): frame = self.ws.frame_read(sock) - assert message + ' ' + message == frame['data'].decode( + assert f'{message} {message}' == frame['data'].decode( 'utf-8' ), 'mirror framing' @@ -473,21 +473,21 @@ class TestNodeWebsockets(TestApplicationNode): _, sock, _ = self.ws.upgrade() for i in range(0, 10): - self.ws.frame_write(sock, self.ws.OP_PING, 'payload-%d' % i) + self.ws.frame_write(sock, self.ws.OP_PING, f'payload-{i}') for i in range(0, 10): frame = self.ws.frame_read(sock) - self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i) + self.check_frame(frame, True, self.ws.OP_PONG, f'payload-{i}') # 2_11 for i in range(0, 10): opcode = self.ws.OP_PING - self.ws.frame_write(sock, opcode, 'payload-%d' % i, chopsize=1) + self.ws.frame_write(sock, opcode, f'payload-{i}', chopsize=1) for i in range(0, 10): frame = self.ws.frame_read(sock) - self.check_frame(frame, True, self.ws.OP_PONG, 'payload-%d' % i) + self.check_frame(frame, True, self.ws.OP_PONG, f'payload-{i}') self.close_connection(sock) diff --git a/test/test_perl_application.py b/test/test_perl_application.py index fe2db72e..3c327aa1 100644 --- a/test/test_perl_application.py +++ b/test/test_perl_application.py @@ -179,6 +179,11 @@ class TestPerlApplication(TestApplicationPerl): assert self.get()['body'] == 'body\n', 'body io file' + def test_perl_streaming_body_multiple_responses(self): + self.load('streaming_body_multiple_responses') + + assert self.get()['status'] == 200 + @pytest.mark.skip('not yet') def test_perl_application_syntax_error(self, skip_alert): skip_alert(r'PSGI: Failed to parse script') diff --git a/test/test_php_application.py b/test/test_php_application.py index f442f551..6e1d190a 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -33,28 +33,23 @@ class TestPHPApplication(TestApplicationPHP): def set_opcache(self, app, val): assert 'success' in self.conf( {"admin": {"opcache.enable": val, "opcache.enable_cli": val}}, - 'applications/' + app + '/options', + f'applications/{app}/options', ) r = self.check_opcache() assert r['headers']['X-OPcache'] == val, 'opcache value' def set_preload(self, preload): - with open(option.temp_dir + '/php.ini', 'w') as f: + with open(f'{option.temp_dir}/php.ini', 'w') as f: f.write( - """opcache.preload = %(test_dir)s/php/opcache/preload\ -/%(preload)s -opcache.preload_user = %(user)s + f"""opcache.preload = {option.test_dir}/php/opcache/preload\ +/{preload} +opcache.preload_user = {option.user or getpass.getuser()} """ - % { - 'test_dir': option.test_dir, - 'preload': preload, - 'user': option.user or getpass.getuser(), - } ) assert 'success' in self.conf( - {"file": option.temp_dir + "/php.ini"}, + {"file": f"{option.temp_dir}/php.ini"}, 'applications/opcache/options', ) @@ -295,7 +290,7 @@ opcache.preload_user = %(user)s assert ( self.get()['headers']['X-File'] - == option.test_dir + '/php/ini_precision/ini/php.ini' + == f'{option.test_dir}/php/ini_precision/ini/php.ini' ), 'ini file' assert self.get()['headers']['X-Precision'] == '4', 'ini value' @@ -318,7 +313,7 @@ opcache.preload_user = %(user)s assert ( self.get()['headers']['X-File'] - == option.test_dir + '/php/ini_precision/ini/php.ini' + == f'{option.test_dir}/php/ini_precision/ini/php.ini' ), 'ini file' assert self.get()['headers']['X-Precision'] == '5', 'ini value admin' @@ -332,7 +327,7 @@ opcache.preload_user = %(user)s assert ( self.get()['headers']['X-File'] - == option.test_dir + '/php/ini_precision/ini/php.ini' + == f'{option.test_dir}/php/ini_precision/ini/php.ini' ), 'ini file' assert self.get()['headers']['X-Precision'] == '5', 'ini value user' @@ -590,7 +585,7 @@ opcache.preload_user = %(user)s "script": { "type": self.get_application_type(), "processes": {"spare": 0}, - "root": option.test_dir + "/php/script", + "root": f"{option.test_dir}/php/script", "script": "phpinfo.php", } }, @@ -610,7 +605,7 @@ opcache.preload_user = %(user)s "phpinfo": { "type": self.get_application_type(), "processes": {"spare": 0}, - "root": option.test_dir + "/php/phpinfo", + "root": f"{option.test_dir}/php/phpinfo", } }, } @@ -622,18 +617,18 @@ opcache.preload_user = %(user)s assert resp['body'] != '', 'body not empty' def test_php_application_trailing_slash(self, temp_dir): - new_root = temp_dir + "/php-root" - os.makedirs(new_root + '/path') + new_root = f'{temp_dir}/php-root' + os.makedirs(f'{new_root}/path') - Path(new_root + '/path/index.php').write_text('<?php echo "OK\n"; ?>') + Path(f'{new_root}/path/index.php').write_text('<?php echo "OK\n"; ?>') - addr = temp_dir + '/sock' + addr = f'{temp_dir}/sock' assert 'success' in self.conf( { "listeners": { "*:7080": {"pass": "applications/php-path"}, - "unix:" + addr: {"pass": "applications/php-path"}, + f'unix:{addr}': {"pass": "applications/php-path"}, }, "applications": { "php-path": { @@ -664,14 +659,34 @@ opcache.preload_user = %(user)s 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 = temp_dir + "/php" + new_root = f'{temp_dir}/php' os.mkdir(new_root) - shutil.copy(option.test_dir + '/php/phpinfo/index.wrong', new_root) + shutil.copy(f'{option.test_dir}/php/phpinfo/index.wrong', new_root) assert 'success' in self.conf( { @@ -688,21 +703,21 @@ opcache.preload_user = %(user)s ), 'configure new root' resp = self.get() - assert str(resp['status']) + resp['body'] != '200', 'status new root' + assert f'{resp["status"]}{resp["body"]}' != '200', 'status new root' def run_php_application_cwd_root_tests(self): assert 'success' in self.conf_delete( 'applications/cwd/working_directory' ) - script_cwd = option.test_dir + '/php/cwd' + script_cwd = f'{option.test_dir}/php/cwd' resp = self.get() assert resp['status'] == 200, 'status ok' assert resp['body'] == script_cwd, 'default cwd' assert 'success' in self.conf( - '"' + option.test_dir + '"', + f'"{option.test_dir}"', 'applications/cwd/working_directory', ) @@ -721,7 +736,7 @@ opcache.preload_user = %(user)s assert resp['body'] == script_cwd, 'cwd restored' resp = self.get(url='/subdir/') - assert resp['body'] == script_cwd + '/subdir', 'cwd subdir' + assert resp['body'] == f'{script_cwd}/subdir', 'cwd subdir' def test_php_application_cwd_root(self): self.load('cwd') @@ -740,7 +755,7 @@ opcache.preload_user = %(user)s def run_php_application_cwd_script_tests(self): self.load('cwd') - script_cwd = option.test_dir + '/php/cwd' + script_cwd = f'{option.test_dir}/php/cwd' assert 'success' in self.conf_delete( 'applications/cwd/working_directory' diff --git a/test/test_php_targets.py b/test/test_php_targets.py index eec1846f..e74f2ec6 100644 --- a/test/test_php_targets.py +++ b/test/test_php_targets.py @@ -6,6 +6,7 @@ class TestPHPTargets(TestApplicationPHP): prerequisites = {'modules': {'php': 'any'}} def test_php_application_targets(self): + targets_dir = f"{option.test_dir}/php/targets" assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, @@ -27,15 +28,15 @@ class TestPHPTargets(TestApplicationPHP): "targets": { "1": { "script": "1.php", - "root": option.test_dir + "/php/targets", + "root": targets_dir, }, "2": { "script": "2.php", - "root": option.test_dir + "/php/targets/2", + "root": f'{targets_dir}/2', }, "default": { "index": "index.php", - "root": option.test_dir + "/php/targets", + "root": targets_dir, }, }, } @@ -45,7 +46,7 @@ class TestPHPTargets(TestApplicationPHP): assert self.get(url='/1')['body'] == '1' assert self.get(url='/2')['body'] == '2' - assert self.get(url='/blah')['status'] == 503 # TODO 404 + assert self.get(url='/blah')['status'] == 404 assert self.get(url='/')['body'] == 'index' assert self.get(url='/1.php?test=test.php/')['body'] == '1' @@ -72,7 +73,7 @@ class TestPHPTargets(TestApplicationPHP): "targets": { "default": { "index": "index.php", - "root": option.test_dir + "/php/targets", + "root": f"{option.test_dir}/php/targets", }, }, } @@ -85,7 +86,7 @@ class TestPHPTargets(TestApplicationPHP): {"pass": "applications/targets/blah"}, 'listeners/*:7080' ), 'invalid targets pass' assert 'error' in self.conf( - '"' + option.test_dir + '/php/targets\"', + f'"{option.test_dir}/php/targets"', 'applications/targets/root', ), 'invalid root' assert 'error' in self.conf( diff --git a/test/test_proxy.py b/test/test_proxy.py index ede91fd6..74e48ca1 100644 --- a/test/test_proxy.py +++ b/test/test_proxy.py @@ -63,6 +63,7 @@ Content-Length: 10 run_process(self.run_server, self.SERVER_PORT) waitforsocket(self.SERVER_PORT) + python_dir = f'{option.test_dir}/python' assert 'success' in self.conf( { "listeners": { @@ -74,24 +75,22 @@ Content-Length: 10 "mirror": { "type": self.get_application_type(), "processes": {"spare": 0}, - "path": option.test_dir + "/python/mirror", - "working_directory": option.test_dir + "/python/mirror", + "path": f'{python_dir}/mirror', + "working_directory": f'{python_dir}/mirror', "module": "wsgi", }, "custom_header": { "type": self.get_application_type(), "processes": {"spare": 0}, - "path": option.test_dir + "/python/custom_header", - "working_directory": option.test_dir - + "/python/custom_header", + "path": f'{python_dir}/custom_header', + "working_directory": f'{python_dir}/custom_header', "module": "wsgi", }, "delayed": { "type": self.get_application_type(), "processes": {"spare": 0}, - "path": option.test_dir + "/python/delayed", - "working_directory": option.test_dir - + "/python/delayed", + "path": f'{python_dir}/delayed', + "working_directory": f'{python_dir}/delayed', "module": "wsgi", }, }, @@ -124,8 +123,8 @@ Content-Length: 10 "mirror": { "type": self.get_application_type(), "processes": {"spare": 0}, - "path": option.test_dir + "/python/mirror", - "working_directory": option.test_dir + "/python/mirror", + "path": f'{option.test_dir}/python/mirror', + "working_directory": f'{option.test_dir}/python/mirror', "module": "wsgi", } }, @@ -186,7 +185,7 @@ Content-Length: 10 socks = [] for i in range(10): sock = self.post_http10( - body=payload + str(i), + body=f'{payload}{i}', no_recv=True, read_buffer_size=buff_size, ) @@ -199,7 +198,7 @@ Content-Length: 10 resp = self._resp_to_dict(resp) assert resp['status'] == 200, 'status' - assert resp['body'] == payload + str(i), 'body' + assert resp['body'] == f'{payload}{i}', 'body' def test_proxy_header(self): assert 'success' in self.conf( @@ -214,7 +213,7 @@ Content-Length: 10 == header_value ), 'custom header' - header_value = r'(),/:;<=>?@[\]{}\t !#$%&\'*+-.^_`|~' + header_value = r"(),/:;<=>?@[\]{}\t !#$%&'*+-.^_`|~" assert ( self.get_http10( headers={'Host': 'localhost', 'Custom-Header': header_value} @@ -336,18 +335,18 @@ Content-Length: 10 assert self.get_http10()['status'] == 200, 'status' def test_proxy_unix(self, temp_dir): - addr = temp_dir + '/sock' + addr = f'{temp_dir}/sock' assert 'success' in self.conf( { "*:7080": {"pass": "routes"}, - "unix:" + addr: {'application': 'mirror'}, + f'unix:{addr}': {'application': 'mirror'}, }, 'listeners', ), 'add unix listener configure' assert 'success' in self.conf( - [{"action": {"proxy": 'http://unix:' + addr}}], 'routes' + [{"action": {"proxy": f'http://unix:{addr}'}}], 'routes' ), 'proxy unix configure' assert self.get_http10()['status'] == 200, 'status' @@ -420,13 +419,7 @@ Content-Length: 10 @pytest.mark.skip('not yet') def test_proxy_content_length(self): assert 'success' in self.conf( - [ - { - "action": { - "proxy": "http://127.0.0.1:" + str(self.SERVER_PORT) - } - } - ], + [{"action": {"proxy": f'http://127.0.0.1:{self.SERVER_PORT}'}}], 'routes', ), 'proxy backend configure' @@ -484,8 +477,8 @@ Content-Length: 10 "mirror": { "type": self.get_application_type(), "processes": {"spare": 0}, - "path": option.test_dir + "/python/mirror", - "working_directory": option.test_dir + "/python/mirror", + "path": f'{option.test_dir}/python/mirror', + "working_directory": f'{option.test_dir}/python/mirror', "module": "wsgi", }, }, diff --git a/test/test_proxy_chunked.py b/test/test_proxy_chunked.py index f024eaf5..f31c976a 100644 --- a/test/test_proxy_chunked.py +++ b/test/test_proxy_chunked.py @@ -61,7 +61,7 @@ class TestProxyChunked(TestApplicationPython): else: add = line - req = req + add + '\r\n' + req = f'{req}{add}\r\n' for chunk in re.split(r'([@#])', req): if chunk == '@' or chunk == '#': @@ -77,9 +77,9 @@ class TestProxyChunked(TestApplicationPython): body = '\r\n\r\n' for l, c in chunks: - body = body + l + '\r\n' + c + '\r\n' + body = f'{body}{l}\r\n{c}\r\n' - return body + '0\r\n\r\n' + return f'{body}0\r\n\r\n' def get_http10(self, *args, **kwargs): return self.get(*args, http_10=True, **kwargs) @@ -96,7 +96,7 @@ class TestProxyChunked(TestApplicationPython): "routes": [ { "action": { - "proxy": "http://127.0.0.1:" + str(self.SERVER_PORT) + "proxy": f'http://127.0.0.1:{self.SERVER_PORT}' } } ], @@ -111,20 +111,20 @@ class TestProxyChunked(TestApplicationPython): part = '0123456789abcdef' assert ( - self.get_http10(body=self.chunks([('1000', part + ' X 256')]))[ + self.get_http10(body=self.chunks([('1000', f'{part} X 256')]))[ 'body' ] == part * 256 ) assert ( - self.get_http10(body=self.chunks([('100000', part + ' X 65536')]))[ + self.get_http10(body=self.chunks([('100000', f'{part} X 65536')]))[ 'body' ] == part * 65536 ) assert ( self.get_http10( - body=self.chunks([('1000000', part + ' X 1048576')]), + body=self.chunks([('1000000', f'{part} X 1048576')]), read_buffer_size=4096 * 4096, )['body'] == part * 1048576 @@ -133,7 +133,7 @@ class TestProxyChunked(TestApplicationPython): assert ( self.get_http10( body=self.chunks( - [('1000', part + ' X 256'), ('1000', part + ' X 256')] + [('1000', f'{part} X 256'), ('1000', f'{part} X 256')] ) )['body'] == part * 256 * 2 @@ -142,8 +142,8 @@ class TestProxyChunked(TestApplicationPython): self.get_http10( body=self.chunks( [ - ('100000', part + ' X 65536'), - ('100000', part + ' X 65536'), + ('100000', f'{part} X 65536'), + ('100000', f'{part} X 65536'), ] ) )['body'] @@ -153,8 +153,8 @@ class TestProxyChunked(TestApplicationPython): self.get_http10( body=self.chunks( [ - ('1000000', part + ' X 1048576'), - ('1000000', part + ' X 1048576'), + ('1000000', f'{part} X 1048576'), + ('1000000', f'{part} X 1048576'), ] ), read_buffer_size=4096 * 4096, diff --git a/test/test_python_application.py b/test/test_python_application.py index c9065eae..d412ac68 100644 --- a/test/test_python_application.py +++ b/test/test_python_application.py @@ -20,17 +20,16 @@ class TestPythonApplication(TestApplicationPython): body = 'Test body string.' resp = self.http( - b"""POST / HTTP/1.1 + f"""POST / HTTP/1.1 Host: localhost -Content-Length: %d +Content-Length: {len(body)} Custom-Header: blah Custom-hEader: Blah Content-Type: text/html Connection: close custom-header: BLAH -%s""" - % (len(body), body.encode()), +{body}""".encode(), raw=True, ) @@ -101,7 +100,7 @@ custom-header: BLAH self.load('prefix', prefix='/api/rest') def set_prefix(prefix): - self.conf('"' + prefix + '"', 'applications/prefix/prefix') + self.conf(f'"{prefix}"', 'applications/prefix/prefix') def check_prefix(url, script_name, path_info): resp = self.get(url=url) @@ -585,12 +584,12 @@ last line: 987654321 except version.InvalidVersion: pytest.skip('require python module version 3') - venv_path = temp_dir + '/venv' + venv_path = f'{temp_dir}/venv' venv.create(venv_path) self.load('unicode') assert 'success' in self.conf( - '"' + venv_path + '"', + f'"{venv_path}"', '/config/applications/unicode/home', ) assert ( @@ -640,7 +639,7 @@ last line: 987654321 assert self.wait_for_record(r'Traceback') is not None, 'traceback' assert ( - self.wait_for_record(r'raise Exception\(\'first exception\'\)') + self.wait_for_record(r"raise Exception\('first exception'\)") is not None ), 'first exception raise' assert len(self.findall(r'Traceback')) == 1, 'traceback count 1' @@ -659,7 +658,7 @@ last line: 987654321 ), 'error 2' assert ( - self.wait_for_record(r'raise Exception\(\'second exception\'\)') + self.wait_for_record(r"raise Exception\('second exception'\)") is not None ), 'exception raise second' assert len(self.findall(r'Traceback')) == 2, 'traceback count 2' @@ -676,7 +675,7 @@ last line: 987654321 ) assert ( - self.wait_for_record(r'raise Exception\(\'third exception\'\)') + self.wait_for_record(r"raise Exception\('third exception'\)") is not None ), 'exception raise third' assert len(self.findall(r'Traceback')) == 3, 'traceback count 3' @@ -711,7 +710,7 @@ last line: 987654321 ) assert ( - self.wait_for_record(r'raise Exception\(\'next exception\'\)') + self.wait_for_record(r"raise Exception\('next exception'\)") is not None ), 'exception raise next' assert len(self.findall(r'Traceback')) == 5, 'traceback count 5' @@ -747,7 +746,7 @@ last line: 987654321 ), 'error' assert ( - self.wait_for_record(r'raise Exception\(\'close exception\'\)') + self.wait_for_record(r"raise Exception\('close exception'\)") is not None ), 'exception raise close' assert len(self.findall(r'Traceback')) == 8, 'traceback count 8' @@ -781,18 +780,14 @@ last line: 987654321 self.load('user_group', user='nobody', group=group) obj = self.getjson()['body'] - assert obj['UID'] == nobody_uid, ( - 'nobody uid user=nobody group=%s' % group - ) - - assert obj['GID'] == group_id, 'nobody gid user=nobody group=%s' % group + assert obj['UID'] == nobody_uid, f'nobody uid user=nobody group={group}' + assert obj['GID'] == group_id, f'nobody gid user=nobody group={group}' self.load('user_group', group=group) obj = self.getjson()['body'] - assert obj['UID'] == nobody_uid, 'nobody uid group=%s' % group - - assert obj['GID'] == group_id, 'nobody gid group=%s' % group + assert obj['UID'] == nobody_uid, f'nobody uid group={group}' + assert obj['GID'] == group_id, f'nobody gid group={group}' self.load('user_group', user='root') diff --git a/test/test_python_environment.py b/test/test_python_environment.py index 2d7d1595..bce72c4d 100644 --- a/test/test_python_environment.py +++ b/test/test_python_environment.py @@ -38,7 +38,7 @@ class TestPythonEnvironment(TestApplicationPython): 'Connection': 'close', } )['body'] - == 'val1,' + == 'val1' ), 'set' self.conf({"var": "val2"}, 'applications/environment/environment') @@ -51,7 +51,7 @@ class TestPythonEnvironment(TestApplicationPython): 'Connection': 'close', } )['body'] - == 'val2,' + == 'val2' ), 'update' def test_python_environment_replace(self): @@ -67,7 +67,7 @@ class TestPythonEnvironment(TestApplicationPython): 'Connection': 'close', } )['body'] - == 'val1,' + == 'val1' ), 'set' self.conf({"var2": "val2"}, 'applications/environment/environment') @@ -80,7 +80,7 @@ class TestPythonEnvironment(TestApplicationPython): 'Connection': 'close', } )['body'] - == 'val2,' + == 'val2' ), 'replace' def test_python_environment_clear(self): @@ -99,7 +99,7 @@ class TestPythonEnvironment(TestApplicationPython): 'Connection': 'close', } )['body'] - == 'val1,val2,' + == 'val1,val2' ), 'set' self.conf({}, 'applications/environment/environment') @@ -138,7 +138,7 @@ class TestPythonEnvironment(TestApplicationPython): 'Connection': 'close', } )['body'] - == '/,' + == '/' ), 'replace default' self.conf({}, 'applications/environment/environment') diff --git a/test/test_python_isolation.py b/test/test_python_isolation.py index 6d4ffaf3..c524aea0 100644 --- a/test/test_python_isolation.py +++ b/test/test_python_isolation.py @@ -20,13 +20,13 @@ class TestPythonIsolation(TestApplicationPython): ).decode() pid = re.search( - r'(\d+)\s*unit: "' + app_name + '" application', output + fr'(\d+)\s*unit: "{app_name}" application', output ).group(1) - cgroup = '/proc/' + pid + '/cgroup' + cgroup = f'/proc/{pid}/cgroup' if not os.path.isfile(cgroup): - pytest.skip('no cgroup at ' + cgroup) + pytest.skip(f'no cgroup at {cgroup}') with open(cgroup, 'r') as f: return f.read().rstrip() @@ -59,7 +59,7 @@ class TestPythonIsolation(TestApplicationPython): self.load('ns_inspect', isolation=isolation) assert ( - self.getjson(url='/?path=' + temp_dir)['body']['FileExists'] + self.getjson(url=f'/?path={temp_dir}')['body']['FileExists'] == False ), 'temp_dir does not exists in rootfs' @@ -87,7 +87,7 @@ class TestPythonIsolation(TestApplicationPython): isolation = {'rootfs': temp_dir, 'automount': {'language_deps': False}} self.load('empty', isolation=isolation) - python_path = temp_dir + '/usr' + python_path = f'{temp_dir}/usr' assert findmnt().find(python_path) == -1 assert self.get()['status'] != 200, 'disabled language_deps' @@ -156,7 +156,7 @@ class TestPythonIsolation(TestApplicationPython): pytest.skip('cgroup is not supported') def set_two_cgroup_path(path, path2): - script_path = option.test_dir + '/python/empty' + script_path = f'{option.test_dir}/python/empty' assert 'success' in self.conf( { @@ -203,7 +203,7 @@ class TestPythonIsolation(TestApplicationPython): pytest.skip('cgroup is not supported') def check_invalid(path): - script_path = option.test_dir + '/python/empty' + script_path = f'{option.test_dir}/python/empty' assert 'error' in self.conf( { "listeners": {"*:7080": {"pass": "applications/empty"}}, diff --git a/test/test_python_isolation_chroot.py b/test/test_python_isolation_chroot.py index 8e5b5fce..349ec869 100644 --- a/test/test_python_isolation_chroot.py +++ b/test/test_python_isolation_chroot.py @@ -16,7 +16,7 @@ class TestPythonIsolation(TestApplicationPython): self.load('ns_inspect', isolation=isolation) assert ( - self.getjson(url='/?path=' + temp_dir)['body']['FileExists'] + self.getjson(url=f'/?path={temp_dir}')['body']['FileExists'] == False ), 'temp_dir does not exists in rootfs' diff --git a/test/test_python_procman.py b/test/test_python_procman.py index a25b84ec..d69123ef 100644 --- a/test/test_python_procman.py +++ b/test/test_python_procman.py @@ -12,8 +12,8 @@ class TestPythonProcman(TestApplicationPython): prerequisites = {'modules': {'python': 'any'}} def setup_method(self): - self.app_name = "app-" + option.temp_dir.split('/')[-1] - self.app_proc = 'applications/' + self.app_name + '/processes' + self.app_name = f'app-{option.temp_dir.split("/")[-1]}' + self.app_proc = f'applications/{self.app_name}/processes' self.load('empty', self.app_name) def pids_for_process(self): @@ -23,7 +23,7 @@ class TestPythonProcman(TestApplicationPython): pids = set() for m in re.findall( - '.*unit: "' + self.app_name + '" application', output.decode() + fr'.*unit: "{self.app_name}" application', output.decode() ): pids.add(re.search(r'^\s*(\d+)', m).group(1)) @@ -126,7 +126,7 @@ class TestPythonProcman(TestApplicationPython): assert len(pids_new) == 3, 'reconf 3' assert pids.issubset(pids_new), 'reconf 3 only 1 new' - self.conf_proc('6', self.app_proc + '/spare') + self.conf_proc('6', f'{self.app_proc}/spare') pids = self.pids_for_process() assert len(pids) == 6, 'reconf 6' @@ -176,10 +176,10 @@ class TestPythonProcman(TestApplicationPython): def test_python_processes_access(self): self.conf_proc('1') - path = '/' + self.app_proc - assert 'error' in self.conf_get(path + '/max') - assert 'error' in self.conf_get(path + '/spare') - assert 'error' in self.conf_get(path + '/idle_timeout') + path = f'/{self.app_proc}' + assert 'error' in self.conf_get(f'{path}/max') + assert 'error' in self.conf_get(f'{path}/spare') + assert 'error' in self.conf_get(f'{path}/idle_timeout') def test_python_processes_invalid(self): assert 'error' in self.conf( @@ -206,7 +206,7 @@ class TestPythonProcman(TestApplicationPython): def test_python_restart(self, temp_dir): shutil.copyfile( - option.test_dir + '/python/restart/v1.py', temp_dir + '/wsgi.py' + f'{option.test_dir}/python/restart/v1.py', f'{temp_dir}/wsgi.py' ) self.load( @@ -220,14 +220,14 @@ class TestPythonProcman(TestApplicationPython): assert b == "v1", 'process started' shutil.copyfile( - option.test_dir + '/python/restart/v2.py', temp_dir + '/wsgi.py' + f'{option.test_dir}/python/restart/v2.py', f'{temp_dir}/wsgi.py' ) b = self.get()['body'] assert b == "v1", 'still old process' assert 'success' in self.conf_get( - '/control/applications/' + self.app_name + '/restart' + f'/control/applications/{self.app_name}/restart' ), 'restart processes' b = self.get()['body'] @@ -238,7 +238,7 @@ class TestPythonProcman(TestApplicationPython): ), 'application incorrect' assert 'error' in self.conf_delete( - '/control/applications/' + self.app_name + '/restart' + f'/control/applications/{self.app_name}/restart' ), 'method incorrect' def test_python_restart_multi(self): @@ -248,7 +248,7 @@ class TestPythonProcman(TestApplicationPython): assert len(pids) == 2, 'restart 2 started' assert 'success' in self.conf_get( - '/control/applications/' + self.app_name + '/restart' + f'/control/applications/{self.app_name}/restart' ), 'restart processes' new_pids = self.pids_for_process() @@ -272,7 +272,7 @@ class TestPythonProcman(TestApplicationPython): assert len(pids) == 2, 'longstarts == 2' assert 'success' in self.conf_get( - '/control/applications/' + self.app_name + '/restart' + f'/control/applications/{self.app_name}/restart' ), 'restart processes' # wait for longstarted app diff --git a/test/test_python_targets.py b/test/test_python_targets.py index ae271b5f..f55609ba 100644 --- a/test/test_python_targets.py +++ b/test/test_python_targets.py @@ -6,6 +6,8 @@ class TestPythonTargets(TestApplicationPython): prerequisites = {'modules': {'python': 'all'}} def test_python_targets(self): + python_dir = f'{option.test_dir}/python' + assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, @@ -22,9 +24,8 @@ class TestPythonTargets(TestApplicationPython): "applications": { "targets": { "type": self.get_application_type(), - "working_directory": option.test_dir - + "/python/targets/", - "path": option.test_dir + '/python/targets/', + "working_directory": f'{python_dir}/targets/', + "path": f'{python_dir}/targets/', "targets": { "1": { "module": "wsgi", @@ -49,6 +50,8 @@ class TestPythonTargets(TestApplicationPython): assert resp['body'] == '2' def test_python_targets_prefix(self): + python_dir = f'{option.test_dir}/python' + assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, @@ -65,9 +68,8 @@ class TestPythonTargets(TestApplicationPython): "applications": { "targets": { "type": "python", - "working_directory": option.test_dir - + "/python/targets/", - "path": option.test_dir + '/python/targets/', + "working_directory": f'{python_dir}/targets/', + "path": f'{python_dir}/targets/', "protocol": "wsgi", "targets": { "app": { diff --git a/test/test_respawn.py b/test/test_respawn.py index 19d97d37..3d3dfac3 100644 --- a/test/test_respawn.py +++ b/test/test_respawn.py @@ -13,21 +13,21 @@ class TestRespawn(TestApplicationPython): PATTERN_CONTROLLER = 'unit: controller' def setup_method(self): - self.app_name = "app-" + option.temp_dir.split('/')[-1] + self.app_name = f'app-{option.temp_dir.split("/")[-1]}' self.load('empty', self.app_name) assert 'success' in self.conf( - '1', 'applications/' + self.app_name + '/processes' + '1', f'applications/{self.app_name}/processes' ) def pid_by_name(self, name, ppid): output = subprocess.check_output(['ps', 'ax', '-O', 'ppid']).decode() - m = re.search(r'\s*(\d+)\s*' + str(ppid) + r'.*' + name, output) + m = re.search(fr'\s*(\d+)\s*{ppid}.*{name}', output) return None if m is None else m.group(1) def kill_pids(self, *pids): - subprocess.call(['kill', '-9'] + list(pids)) + subprocess.call(['kill', '-9', *pids]) def wait_for_process(self, process, unit_pid): for i in range(50): @@ -41,11 +41,11 @@ class TestRespawn(TestApplicationPython): return found def find_proc(self, name, ppid, ps_output): - return re.findall(str(ppid) + r'.*' + name, ps_output) + return re.findall(fr'{ppid}.*{name}', ps_output) def smoke_test(self, unit_pid): for _ in range(10): - r = self.conf('1', 'applications/' + self.app_name + '/processes') + r = self.conf('1', f'applications/{self.app_name}/processes') if 'success' in r: break @@ -68,7 +68,7 @@ class TestRespawn(TestApplicationPython): pid = self.pid_by_name(self.PATTERN_ROUTER, unit_pid) self.kill_pids(pid) - skip_alert(r'process %s exited on signal 9' % pid) + skip_alert(fr'process {pid} exited on signal 9') assert self.wait_for_process(self.PATTERN_ROUTER, unit_pid) is not None @@ -79,7 +79,7 @@ class TestRespawn(TestApplicationPython): pid = self.pid_by_name(self.PATTERN_CONTROLLER, unit_pid) self.kill_pids(pid) - skip_alert(r'process %s exited on signal 9' % pid) + skip_alert(fr'process {pid} exited on signal 9') assert ( self.wait_for_process(self.PATTERN_CONTROLLER, unit_pid) is not None @@ -93,7 +93,7 @@ class TestRespawn(TestApplicationPython): pid = self.pid_by_name(self.app_name, unit_pid) self.kill_pids(pid) - skip_alert(r'process %s exited on signal 9' % pid) + skip_alert(fr'process {pid} exited on signal 9') assert self.wait_for_process(self.app_name, unit_pid) is not None diff --git a/test/test_return.py b/test/test_return.py index 82bf1e64..4b8bddc7 100644 --- a/test/test_return.py +++ b/test/test_return.py @@ -107,26 +107,26 @@ Connection: close check_location(reserved) # After first "?" all other "?" encoded. - check_location("/?" + reserved, "/?:/%3F#[]@!&'()*+,;=") + check_location(f'/?{reserved}', "/?:/%3F#[]@!&'()*+,;=") check_location("???", "?%3F%3F") # After first "#" all other "?" or "#" encoded. - check_location("/#" + reserved, "/#:/%3F%23[]@!&'()*+,;=") + check_location(f'/#{reserved}', "/#:/%3F%23[]@!&'()*+,;=") check_location("##?#?", "#%23%3F%23%3F") # After first "?" next "#" not encoded. - check_location("/?#" + reserved, "/?#:/%3F%23[]@!&'()*+,;=") + check_location(f'/?#{reserved}', "/?#:/%3F%23[]@!&'()*+,;=") check_location("??##", "?%3F#%23") check_location("/?##?", "/?#%23%3F") # Unreserved never encoded. check_location(unreserved) - check_location("/" + unreserved + "?" + unreserved + "#" + unreserved) + check_location(f'/{unreserved}?{unreserved}#{unreserved}') # Unsafe always encoded. check_location(unsafe, unsafe_enc) - check_location("?" + unsafe, "?" + unsafe_enc) - check_location("#" + unsafe, "#" + unsafe_enc) + check_location(f'?{unsafe}', f'?{unsafe_enc}') + check_location(f'#{unsafe}', f'#{unsafe_enc}') # %00-%20 and %7F-%FF always encoded. check_location(u"\u0000\u0018\u001F\u0020\u0021", "%00%18%1F%20!") diff --git a/test/test_rewrite.py b/test/test_rewrite.py new file mode 100644 index 00000000..3bc7df19 --- /dev/null +++ b/test/test_rewrite.py @@ -0,0 +1,219 @@ +import os + +import pytest +from unit.applications.proto import TestApplicationProto +from unit.option import option + + +class TestRewrite(TestApplicationProto): + prerequisites = {} + + def setup_method(self): + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes"}}, + "routes": [ + { + "match": {"uri": "/"}, + "action": {"rewrite": "/new", "pass": "routes"}, + }, + {"match": {"uri": "/new"}, "action": {"return": 200}}, + ], + "applications": {}, + "settings": {"http": {"log_route": True}}, + }, + ), 'set initial configuration' + + def set_rewrite(self, rewrite, uri): + assert 'success' in self.conf( + [ + { + "match": {"uri": "/"}, + "action": {"rewrite": rewrite, "pass": "routes"}, + }, + {"match": {"uri": uri}, "action": {"return": 200}}, + ], + 'routes', + ) + + def test_rewrite(self): + assert self.get()['status'] == 200 + assert ( + self.wait_for_record(rf'\[notice\].*"routes/1" selected') + is not None + ) + assert len(self.findall(rf'\[notice\].*URI rewritten to "/new"')) == 1 + assert len(self.findall(rf'\[notice\].*URI rewritten')) == 1 + + self.set_rewrite("", "") + assert self.get()['status'] == 200 + + def test_rewrite_variable(self): + self.set_rewrite("/$host", "/localhost") + assert self.get()['status'] == 200 + + self.set_rewrite("${uri}a", "/a") + assert self.get()['status'] == 200 + + def test_rewrite_encoded(self): + assert 'success' in self.conf( + [ + { + "match": {"uri": "/f"}, + "action": {"rewrite": "${request_uri}oo", "pass": "routes"}, + }, + {"match": {"uri": "/foo"}, "action": {"return": 200}}, + ], + 'routes', + ) + assert self.get(url='/%66')['status'] == 200 + + assert 'success' in self.conf( + [ + { + "match": {"uri": "/f"}, + "action": { + "rewrite": "${request_uri}o%6F", + "pass": "routes", + }, + }, + {"match": {"uri": "/foo"}, "action": {"return": 200}}, + ], + 'routes', + ) + assert self.get(url='/%66')['status'] == 200 + + def test_rewrite_arguments(self): + assert 'success' in self.conf( + [ + { + "match": {"uri": "/foo", "arguments": {"arg": "val"}}, + "action": {"rewrite": "/new?some", "pass": "routes"}, + }, + { + "match": {"uri": "/new", "arguments": {"arg": "val"}}, + "action": {"return": 200}, + }, + ], + 'routes', + ) + assert self.get(url='/foo?arg=val')['status'] == 200 + + def test_rewrite_njs(self): + if 'njs' not in option.available['modules'].keys(): + pytest.skip('NJS is not available') + + self.set_rewrite("`/${host}`", "/localhost") + assert self.get()['status'] == 200 + + def test_rewrite_location(self): + def check_location(rewrite, expect): + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes"}}, + "routes": [ + { + "action": { + "return": 301, + "location": "$uri", + "rewrite": rewrite, + } + } + ], + } + ) + assert self.get()['headers']['Location'] == expect + + check_location('/new', '/new') + check_location('${request_uri}new', '/new') + + def test_rewrite_share(self, temp_dir): + os.makedirs(f'{temp_dir}/dir') + os.makedirs(f'{temp_dir}/foo') + + with open(f'{temp_dir}/foo/index.html', 'w') as fooindex: + fooindex.write('fooindex') + + # same action block + + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes"}}, + "routes": [ + { + "action": { + "rewrite": "${request_uri}dir", + "share": f'{temp_dir}$uri', + } + } + ], + } + ) + + resp = self.get() + assert resp['status'] == 301, 'redirect status' + assert resp['headers']['Location'] == '/dir/', 'redirect Location' + + # request_uri + + index_path = f'{temp_dir}${{request_uri}}/index.html' + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes"}}, + "routes": [ + { + "match": {"uri": "/foo"}, + "action": { + "rewrite": "${request_uri}dir", + "pass": "routes", + }, + }, + {"action": {"share": index_path}}, + ], + } + ) + + assert self.get(url='/foo')['body'] == 'fooindex' + + # different action block + + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes"}}, + "routes": [ + { + "match": {"uri": "/foo"}, + "action": { + "rewrite": "${request_uri}dir", + "pass": "routes", + }, + }, + { + "action": { + "share": f'{temp_dir}/dir', + } + }, + ], + } + ) + resp = self.get(url='/foo') + assert resp['status'] == 301, 'redirect status 2' + assert resp['headers']['Location'] == '/foodir/', 'redirect Location 2' + + def test_rewrite_invalid(self, skip_alert): + skip_alert(r'failed to apply new conf') + + def check_rewrite(rewrite): + assert 'error' in self.conf( + [ + { + "match": {"uri": "/"}, + "action": {"rewrite": rewrite, "pass": "routes"}, + }, + {"action": {"return": 200}}, + ], + 'routes', + ) + + check_rewrite("/$blah") + check_rewrite(["/"]) diff --git a/test/test_routing.py b/test/test_routing.py index 9e872061..a4806d5c 100644 --- a/test/test_routing.py +++ b/test/test_routing.py @@ -286,17 +286,18 @@ class TestRouting(TestApplicationPython): assert self.get(url='/BLAH')['status'] == 200, '/BLAH' def test_routes_pass_encode(self): + python_dir = f'{option.test_dir}/python' + def check_pass(path, name): assert 'success' in self.conf( { - "listeners": {"*:7080": {"pass": "applications/" + path}}, + "listeners": {"*:7080": {"pass": f'applications/{path}'}}, "applications": { name: { "type": self.get_application_type(), "processes": {"spare": 0}, - "path": option.test_dir + '/python/empty', - "working_directory": option.test_dir - + '/python/empty', + "path": f'{python_dir}/empty', + "working_directory": f'{python_dir}/empty', "module": "wsgi", } }, @@ -313,14 +314,13 @@ class TestRouting(TestApplicationPython): def check_pass_error(path, name): assert 'error' in self.conf( { - "listeners": {"*:7080": {"pass": "applications/" + path}}, + "listeners": {"*:7080": {"pass": f'applications/{path}'}}, "applications": { name: { "type": self.get_application_type(), "processes": {"spare": 0}, - "path": option.test_dir + '/python/empty', - "working_directory": option.test_dir - + '/python/empty', + "path": f'{python_dir}/empty', + "working_directory": f'{python_dir}/empty', "module": "wsgi", } }, @@ -338,8 +338,8 @@ class TestRouting(TestApplicationPython): "empty": { "type": self.get_application_type(), "processes": {"spare": 0}, - "path": option.test_dir + '/python/empty', - "working_directory": option.test_dir + '/python/empty', + "path": f'{option.test_dir}/python/empty', + "working_directory": f'{option.test_dir}/python/empty', "module": "wsgi", } }, @@ -1109,21 +1109,21 @@ class TestRouting(TestApplicationPython): "E", "F", ]: - chars_enc += "%" + h1 + h2 + chars_enc += f'%{h1}{h2}' chars_enc = chars_enc[:-3] def check_args(args, query): self.route_match({"arguments": args}) - assert self.get(url='/?' + query)['status'] == 200 + assert self.get(url=f'/?{query}')['status'] == 200 - check_args({chars: chars}, chars + '=' + chars) - check_args({chars: chars}, chars + '=' + chars_enc) - check_args({chars: chars}, chars_enc + '=' + chars) - check_args({chars: chars}, chars_enc + '=' + chars_enc) - check_args({chars_enc: chars_enc}, chars + '=' + chars) - check_args({chars_enc: chars_enc}, chars + '=' + chars_enc) - check_args({chars_enc: chars_enc}, chars_enc + '=' + chars) - check_args({chars_enc: chars_enc}, chars_enc + '=' + chars_enc) + check_args({chars: chars}, f'{chars}={chars}') + check_args({chars: chars}, f'{chars}={chars_enc}') + check_args({chars: chars}, f'{chars_enc}={chars}') + check_args({chars: chars}, f'{chars_enc}={chars_enc}') + check_args({chars_enc: chars_enc}, f'{chars}={chars}') + check_args({chars_enc: chars_enc}, f'{chars}={chars_enc}') + check_args({chars_enc: chars_enc}, f'{chars_enc}={chars}') + check_args({chars_enc: chars_enc}, f'{chars_enc}={chars_enc}') def test_routes_match_arguments_empty(self): self.route_match({"arguments": {}}) @@ -1492,28 +1492,28 @@ class TestRouting(TestApplicationPython): sock, port = sock_port() sock2, port2 = sock_port() - self.route_match({"source": "127.0.0.1:" + str(port)}) + self.route_match({"source": f'127.0.0.1:{port}'}) assert self.get(sock=sock)['status'] == 200, 'exact' assert self.get(sock=sock2)['status'] == 404, 'exact 2' sock, port = sock_port() sock2, port2 = sock_port() - self.route_match({"source": "!127.0.0.1:" + str(port)}) + self.route_match({"source": f'!127.0.0.1:{port}'}) assert self.get(sock=sock)['status'] == 404, 'negative' assert self.get(sock=sock2)['status'] == 200, 'negative 2' sock, port = sock_port() sock2, port2 = sock_port() - self.route_match({"source": ["*:" + str(port), "!127.0.0.1"]}) + self.route_match({"source": [f'*:{port}', "!127.0.0.1"]}) assert self.get(sock=sock)['status'] == 404, 'negative 3' assert self.get(sock=sock2)['status'] == 404, 'negative 4' sock, port = sock_port() sock2, port2 = sock_port() - self.route_match({"source": "127.0.0.1:" + str(port) + "-" + str(port)}) + self.route_match({"source": f'127.0.0.1:{port}-{port}'}) assert self.get(sock=sock)['status'] == 200, 'range single' assert self.get(sock=sock2)['status'] == 404, 'range single 2' @@ -1526,14 +1526,7 @@ class TestRouting(TestApplicationPython): ] socks.sort(key=lambda sock: sock[1]) - self.route_match( - { - "source": "127.0.0.1:" - + str(socks[1][1]) # second port number - + "-" - + str(socks[3][1]) # fourth port number - } - ) + self.route_match({"source": f'127.0.0.1:{socks[1][1]}-{socks[3][1]}'}) assert self.get(sock=socks[0][0])['status'] == 404, 'range' assert self.get(sock=socks[1][0])['status'] == 200, 'range 2' assert self.get(sock=socks[2][0])['status'] == 200, 'range 3' @@ -1550,8 +1543,8 @@ class TestRouting(TestApplicationPython): self.route_match( { "source": [ - "127.0.0.1:" + str(socks[0][1]), - "127.0.0.1:" + str(socks[2][1]), + f'127.0.0.1:{socks[0][1]}', + f'127.0.0.1:{socks[2][1]}', ] } ) @@ -1734,12 +1727,12 @@ class TestRouting(TestApplicationPython): assert self.get(port=7081)['status'] == 404, '0 ipv4' def test_routes_source_unix(self, temp_dir): - addr = temp_dir + '/sock' + addr = f'{temp_dir}/sock' assert 'success' in self.conf( { "127.0.0.1:7081": {"pass": "routes"}, - "unix:" + addr: {"pass": "routes"}, + f'unix:{addr}': {"pass": "routes"}, }, 'listeners', ), 'source listeners configure' diff --git a/test/test_ruby_hooks.py b/test/test_ruby_hooks.py index b4a79ebb..078e5723 100644 --- a/test/test_ruby_hooks.py +++ b/test/test_ruby_hooks.py @@ -8,7 +8,7 @@ class TestRubyHooks(TestApplicationRuby): def _wait_cookie(self, pattern, count): return waitforglob( - option.temp_dir + '/ruby/hooks/cookie_' + pattern, count + f'{option.temp_dir}/ruby/hooks/cookie_{pattern}', count ) def test_ruby_hooks_eval(self): diff --git a/test/test_settings.py b/test/test_settings.py index ad8929f8..21ab22d9 100644 --- a/test/test_settings.py +++ b/test/test_settings.py @@ -44,7 +44,7 @@ class TestSettings(TestApplicationPython): headers = {'Host': 'localhost', 'Connection': 'close'} for i in range(headers_num): - headers['Custom-header-' + str(i)] = 'a' * 8000 + headers[f'Custom-header-{i}'] = 'a' * 8000 assert self.get(headers=headers)['status'] == expect @@ -229,15 +229,12 @@ Connection: close sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect(addr) - req = ( - """GET / HTTP/1.1 + req = f"""GET / HTTP/1.1 Host: localhost -X-Length: %d +X-Length: {data_len} Connection: close """ - % data_len - ) sock.sendall(req.encode()) @@ -259,10 +256,10 @@ Connection: close data_len = 1048576 if len(values) == 0 else 10 * max(values) - addr = temp_dir + '/sock' + addr = f'{temp_dir}/sock' assert 'success' in self.conf( - {"unix:" + addr: {'application': 'body_generate'}}, 'listeners' + {f'unix:{addr}': {'application': 'body_generate'}}, 'listeners' ) assert 'success' in self.conf({'http': {'send_timeout': 1}}, 'settings') @@ -396,3 +393,157 @@ Connection: close assert bool(resp), 'response from application 4' assert resp['status'] == 200, 'status 4' assert resp['body'] == body, 'body 4' + + def test_settings_log_route(self): + def count_fallbacks(): + return len(self.findall(r'"fallback" taken')) + + def check_record(template): + assert self.search_in_log(template) is not None + + def check_no_record(template): + assert self.search_in_log(template) is None + + def template_req_line(url): + return rf'\[notice\].*http request line "GET {url} HTTP/1\.1"' + + def template_selected(route): + return rf'\[notice\].*"{route}" selected' + + def template_discarded(route): + return rf'\[info\].*"{route}" discarded' + + def wait_for_request_log(status, uri, route): + assert self.get(url=uri)['status'] == status + assert self.wait_for_record(template_req_line(uri)) is not None + assert self.wait_for_record(template_selected(route)) is not None + + # routes array + + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes"}}, + "routes": [ + { + "match": { + "uri": "/zero", + }, + "action": {"return": 200}, + }, + { + "action": {"return": 201}, + }, + ], + "applications": {}, + "settings": {"http": {"log_route": True}}, + } + ) + + wait_for_request_log(200, '/zero', 'routes/0') + check_no_record(r'discarded') + + wait_for_request_log(201, '/one', 'routes/1') + check_record(template_discarded('routes/0')) + + # routes object + + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes/main"}}, + "routes": { + "main": [ + { + "match": { + "uri": "/named_route", + }, + "action": {"return": 200}, + }, + { + "action": {"return": 201}, + }, + ] + }, + "applications": {}, + "settings": {"http": {"log_route": True}}, + } + ) + + wait_for_request_log(200, '/named_route', 'routes/main/0') + check_no_record(template_discarded('routes/main')) + + wait_for_request_log(201, '/unnamed_route', 'routes/main/1') + check_record(template_discarded('routes/main/0')) + + # routes sequence + + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes/first"}}, + "routes": { + "first": [ + { + "action": {"pass": "routes/second"}, + }, + ], + "second": [ + { + "action": {"return": 200}, + }, + ], + }, + "applications": {}, + "settings": {"http": {"log_route": True}}, + } + ) + + wait_for_request_log(200, '/sequence', 'routes/second/0') + check_record(template_selected('routes/first/0')) + + # fallback + + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes/fall"}}, + "routes": { + "fall": [ + { + "action": { + "share": "/blah", + "fallback": {"pass": "routes/fall2"}, + }, + }, + ], + "fall2": [ + { + "action": {"return": 200}, + }, + ], + }, + "applications": {}, + "settings": {"http": {"log_route": True}}, + } + ) + + wait_for_request_log(200, '/', 'routes/fall2/0') + assert count_fallbacks() == 1 + check_record(template_selected('routes/fall/0')) + + assert self.head()['status'] == 200 + assert count_fallbacks() == 2 + + # disable log + + assert 'success' in self.conf({"log_route": False}, 'settings/http') + + url = '/disable_logging' + assert self.get(url=url)['status'] == 200 + + time.sleep(1) + + check_no_record(template_req_line(url)) + + # total + + assert len(self.findall(r'\[notice\].*http request line')) == 7 + assert len(self.findall(r'\[notice\].*selected')) == 10 + assert len(self.findall(r'\[info\].*discarded')) == 2 diff --git a/test/test_static.py b/test/test_static.py index 9013b5c0..f7eade7c 100644 --- a/test/test_static.py +++ b/test/test_static.py @@ -11,13 +11,13 @@ class TestStatic(TestApplicationProto): prerequisites = {} def setup_method(self): - os.makedirs(option.temp_dir + '/assets/dir') - with open(option.temp_dir + '/assets/index.html', 'w') as index, open( - option.temp_dir + '/assets/README', 'w' + os.makedirs(f'{option.temp_dir}/assets/dir') + with open(f'{option.temp_dir}/assets/index.html', 'w') as index, open( + f'{option.temp_dir}/assets/README', 'w' ) as readme, open( - option.temp_dir + '/assets/log.log', 'w' + f'{option.temp_dir}/assets/log.log', 'w' ) as log, open( - option.temp_dir + '/assets/dir/file', 'w' + f'{option.temp_dir}/assets/dir/file', 'w' ) as file: index.write('0123456789') readme.write('readme') @@ -28,7 +28,7 @@ class TestStatic(TestApplicationProto): { "listeners": {"*:7080": {"pass": "routes"}}, "routes": [ - {"action": {"share": option.temp_dir + "/assets$uri"}} + {"action": {"share": f'{option.temp_dir}/assets$uri'}} ], "settings": { "http": { @@ -40,10 +40,10 @@ class TestStatic(TestApplicationProto): } ) - def test_static_index(self): + def test_static_index(self, temp_dir): def set_index(index): assert 'success' in self.conf( - {"share": option.temp_dir + "/assets$uri", "index": index}, + {"share": f'{temp_dir}/assets$uri', "index": index}, 'routes/0/action', ), 'configure index' @@ -72,12 +72,12 @@ class TestStatic(TestApplicationProto): resp['headers']['Content-Type'] == 'text/html' ), 'index not found 2 Content-Type' - def test_static_index_invalid(self, skip_alert): + def test_static_index_invalid(self, skip_alert, temp_dir): skip_alert(r'failed to apply new conf') def check_index(index): assert 'error' in self.conf( - {"share": option.temp_dir + "/assets$uri", "index": index}, + {"share": f'{temp_dir}/assets$uri', "index": index}, 'routes/0/action', ) @@ -86,7 +86,7 @@ class TestStatic(TestApplicationProto): def test_static_large_file(self, temp_dir): file_size = 32 * 1024 * 1024 - with open(temp_dir + '/assets/large', 'wb') as f: + with open(f'{temp_dir}/assets/large', 'wb') as f: f.seek(file_size - 1) f.write(b'\0') @@ -102,7 +102,7 @@ class TestStatic(TestApplicationProto): assert etag != etag_2, 'different ETag' assert etag == self.get(url='/')['headers']['ETag'], 'same ETag' - with open(temp_dir + '/assets/index.html', 'w') as f: + with open(f'{temp_dir}/assets/index.html', 'w') as f: f.write('blah') assert etag != self.get(url='/')['headers']['ETag'], 'new ETag' @@ -114,19 +114,21 @@ class TestStatic(TestApplicationProto): assert 'Content-Type' not in resp['headers'], 'redirect Content-Type' def test_static_space_in_name(self, temp_dir): + assets_dir = f'{temp_dir}/assets' + os.rename( - temp_dir + '/assets/dir/file', - temp_dir + '/assets/dir/fi le', + f'{assets_dir}/dir/file', + f'{assets_dir}/dir/fi le', ) - assert waitforfiles(temp_dir + '/assets/dir/fi le') + assert waitforfiles(f'{assets_dir}/dir/fi le') assert self.get(url='/dir/fi le')['body'] == 'blah', 'file name' - os.rename(temp_dir + '/assets/dir', temp_dir + '/assets/di r') - assert waitforfiles(temp_dir + '/assets/di r/fi le') + os.rename(f'{assets_dir}/dir', f'{assets_dir}/di r') + assert waitforfiles(f'{assets_dir}/di r/fi le') assert self.get(url='/di r/fi le')['body'] == 'blah', 'dir name' - os.rename(temp_dir + '/assets/di r', temp_dir + '/assets/ di r ') - assert waitforfiles(temp_dir + '/assets/ di r /fi le') + os.rename(f'{assets_dir}/di r', f'{assets_dir}/ di r ') + assert waitforfiles(f'{assets_dir}/ di r /fi le') assert ( self.get(url='/ di r /fi le')['body'] == 'blah' ), 'dir name enclosing' @@ -147,16 +149,16 @@ class TestStatic(TestApplicationProto): ), 'encoded 2' os.rename( - temp_dir + '/assets/ di r /fi le', - temp_dir + '/assets/ di r / fi le ', + f'{assets_dir}/ di r /fi le', + f'{assets_dir}/ di r / fi le ', ) - assert waitforfiles(temp_dir + '/assets/ di r / fi le ') + assert waitforfiles(f'{assets_dir}/ di r / fi le ') assert ( self.get(url='/%20di%20r%20/%20fi%20le%20')['body'] == 'blah' ), 'file name enclosing' try: - open(temp_dir + '/ф а', 'a').close() + open(f'{temp_dir}/ф а', 'a').close() utf8 = True except KeyboardInterrupt: @@ -167,33 +169,33 @@ class TestStatic(TestApplicationProto): if utf8: os.rename( - temp_dir + '/assets/ di r / fi le ', - temp_dir + '/assets/ di r /фа йл', + f'{assets_dir}/ di r / fi le ', + f'{assets_dir}/ di r /фа йл', ) - assert waitforfiles(temp_dir + '/assets/ di r /фа йл') + assert waitforfiles(f'{assets_dir}/ di r /фа йл') assert ( self.get(url='/ di r /фа йл')['body'] == 'blah' ), 'file name 2' os.rename( - temp_dir + '/assets/ di r ', - temp_dir + '/assets/ди ректория', + f'{assets_dir}/ di r ', + f'{assets_dir}/ди ректория', ) - assert waitforfiles(temp_dir + '/assets/ди ректория/фа йл') + assert waitforfiles(f'{assets_dir}/ди ректория/фа йл') assert ( self.get(url='/ди ректория/фа йл')['body'] == 'blah' ), 'dir name 2' def test_static_unix_socket(self, temp_dir): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - sock.bind(temp_dir + '/assets/unix_socket') + sock.bind(f'{temp_dir}/assets/unix_socket') assert self.get(url='/unix_socket')['status'] == 404, 'socket' sock.close() def test_static_unix_fifo(self, temp_dir): - os.mkfifo(temp_dir + '/assets/fifo') + os.mkfifo(f'{temp_dir}/assets/fifo') assert self.get(url='/fifo')['status'] == 404, 'fifo' @@ -346,5 +348,5 @@ Content-Length: 6\r raw_resp=True, raw=True, sock_type='unix', - addr=temp_dir + '/control.unit.sock', + addr=f'{temp_dir}/control.unit.sock', ), 'mime_types invalid' diff --git a/test/test_static_chroot.py b/test/test_static_chroot.py index e33a181c..c5a35d82 100644 --- a/test/test_static_chroot.py +++ b/test/test_static_chroot.py @@ -3,6 +3,7 @@ from pathlib import Path import pytest from unit.applications.proto import TestApplicationProto +from unit.option import option class TestStaticChroot(TestApplicationProto): @@ -10,22 +11,22 @@ class TestStaticChroot(TestApplicationProto): @pytest.fixture(autouse=True) def setup_method_fixture(self, temp_dir): - os.makedirs(temp_dir + '/assets/dir') - Path(temp_dir + '/assets/index.html').write_text('0123456789') - Path(temp_dir + '/assets/dir/file').write_text('blah') + os.makedirs(f'{temp_dir}/assets/dir') + Path(f'{temp_dir}/assets/index.html').write_text('0123456789') + Path(f'{temp_dir}/assets/dir/file').write_text('blah') - self.test_path = '/' + os.path.relpath(Path(__file__)) + self.test_path = f'/{os.path.relpath(Path(__file__))}' self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], + "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], } ) - def update_action(self, share, chroot): + def update_action(self, chroot, share=f'{option.temp_dir}/assets$uri'): return self.conf( - {"share": share, "chroot": chroot}, + {'chroot': chroot, 'share': share}, 'routes/0/action', ) @@ -38,9 +39,7 @@ class TestStaticChroot(TestApplicationProto): assert self.get(url='/dir/file')['status'] == 200, 'default chroot' assert self.get(url='/index.html')['status'] == 200, 'default chroot 2' - assert 'success' in self.update_action( - temp_dir + "/assets$uri", temp_dir + "/assets/dir" - ) + assert 'success' in self.update_action(f'{temp_dir}/assets/dir') assert self.get(url='/dir/file')['status'] == 200, 'chroot' assert self.get(url='/index.html')['status'] == 403, 'chroot 403 2' @@ -48,101 +47,89 @@ class TestStaticChroot(TestApplicationProto): def test_share_chroot_array(self, temp_dir): assert 'success' in self.update_action( - ["/blah", temp_dir + "/assets$uri"], temp_dir + "/assets/dir" + f'{temp_dir}/assets/dir', ["/blah", f'{temp_dir}/assets$uri'] ) assert self.get(url='/dir/file')['status'] == 200, 'share array' assert 'success' in self.update_action( - ["/blah", temp_dir + '/assets$uri'], temp_dir + '/assets/$host' + f'{temp_dir}/assets/$host', + ['/blah', f'{temp_dir}/assets$uri'], ) assert self.get_custom('/dir/file', 'dir') == 200, 'array variable' assert 'success' in self.update_action( - ["/blah", "/blah2"], temp_dir + "/assets/dir" + f'{temp_dir}/assets/dir', ['/blah', '/blah2'] ) assert self.get()['status'] != 200, 'share array bad' def test_static_chroot_permission(self, is_su, temp_dir): if is_su: - pytest.skip('does\'t work under root') + pytest.skip("does't work under root") - os.chmod(temp_dir + '/assets/dir', 0o100) + os.chmod(f'{temp_dir}/assets/dir', 0o100) assert 'success' in self.update_action( - temp_dir + "/assets$uri", temp_dir + "/assets/dir" + f'{temp_dir}/assets/dir' ), 'configure chroot' assert self.get(url='/dir/file')['status'] == 200, 'chroot' def test_static_chroot_empty(self, temp_dir): - assert 'success' in self.update_action(temp_dir + "/assets$uri", "") + assert 'success' in self.update_action('') assert self.get(url='/dir/file')['status'] == 200, 'empty absolute' - assert 'success' in self.update_action(".$uri", "") + assert 'success' in self.update_action("", ".$uri") assert self.get(url=self.test_path)['status'] == 200, 'empty relative' def test_static_chroot_relative(self, is_su, temp_dir): if is_su: - pytest.skip('does\'t work under root') + pytest.skip("Does't work under root.") - assert 'success' in self.update_action(temp_dir + "/assets$uri", ".") + assert 'success' in self.update_action('.') assert self.get(url='/dir/file')['status'] == 403, 'relative chroot' assert 'success' in self.conf({"share": ".$uri"}, 'routes/0/action') assert self.get(url=self.test_path)['status'] == 200, 'relative share' - assert 'success' in self.update_action(".$uri", ".") + assert 'success' in self.update_action(".", ".$uri") assert self.get(url=self.test_path)['status'] == 200, 'relative' def test_static_chroot_variables(self, temp_dir): - assert 'success' in self.update_action( - temp_dir + '/assets$uri', temp_dir + '/assets/$host' - ) + assert 'success' in self.update_action(f'{temp_dir}/assets/$host') assert self.get_custom('/dir/file', 'dir') == 200 - assert 'success' in self.update_action( - temp_dir + '/assets$uri', temp_dir + '/assets/${host}' - ) + assert 'success' in self.update_action(f'{temp_dir}/assets/${{host}}') assert self.get_custom('/dir/file', 'dir') == 200 def test_static_chroot_variables_buildin_start(self, temp_dir): assert 'success' in self.update_action( - temp_dir + '/assets/dir/$host', '$uri/assets/dir' + '$uri/assets/dir', + f'{temp_dir}/assets/dir/$host', ) assert self.get_custom(temp_dir, 'file') == 200 def test_static_chroot_variables_buildin_mid(self, temp_dir): - assert 'success' in self.update_action( - temp_dir + '/assets$uri', temp_dir + '/$host/dir' - ) + assert 'success' in self.update_action(f'{temp_dir}/$host/dir') assert self.get_custom('/dir/file', 'assets') == 200 def test_static_chroot_variables_buildin_end(self, temp_dir): - assert 'success' in self.update_action( - temp_dir + '/assets$uri', temp_dir + '/assets/$host' - ) + assert 'success' in self.update_action(f'{temp_dir}/assets/$host') assert self.get_custom('/dir/file', 'dir') == 200 def test_static_chroot_slash(self, temp_dir): - assert 'success' in self.update_action( - temp_dir + "/assets$uri", temp_dir + "/assets/dir/" - ) + assert 'success' in self.update_action(f'{temp_dir}/assets/dir/') assert self.get(url='/dir/file')['status'] == 200, 'slash end' assert self.get(url='/dirxfile')['status'] == 403, 'slash end bad' - assert 'success' in self.update_action( - temp_dir + "/assets$uri", temp_dir + "/assets/dir" - ) + assert 'success' in self.update_action(f'{temp_dir}/assets/dir') assert self.get(url='/dir/file')['status'] == 200, 'no slash end' - assert 'success' in self.update_action( - temp_dir + "/assets$uri", temp_dir + "/assets/dir/" - ) + assert 'success' in self.update_action(f'{temp_dir}/assets/dir/') assert self.get(url='/dir/file')['status'] == 200, 'slash end 2' assert self.get(url='/dirxfile')['status'] == 403, 'slash end 2 bad' assert 'success' in self.update_action( - temp_dir + "///assets/////$uri", temp_dir + "//assets////dir///" + f'{temp_dir}//assets////dir///', f'{temp_dir}///assets/////$uri' ) assert self.get(url='/dir/file')['status'] == 200, 'multiple slashes' @@ -160,9 +147,5 @@ class TestStaticChroot(TestApplicationProto): 'routes/0/action', ), 'configure mount error' - assert 'error' in self.update_action( - temp_dir + '/assets$uri', temp_dir + '/assets/d$r$uri' - ) - assert 'error' in self.update_action( - temp_dir + '/assets$uri', temp_dir + '/assets/$$uri' - ) + assert 'error' in self.update_action(f'{temp_dir}/assets/d$r$uri') + assert 'error' in self.update_action(f'{temp_dir}/assets/$$uri') diff --git a/test/test_static_fallback.py b/test/test_static_fallback.py index 1f1a1df7..75012bbb 100644 --- a/test/test_static_fallback.py +++ b/test/test_static_fallback.py @@ -10,11 +10,12 @@ class TestStaticFallback(TestApplicationProto): @pytest.fixture(autouse=True) def setup_method_fixture(self, temp_dir): - os.makedirs(temp_dir + '/assets/dir') - Path(temp_dir + '/assets/index.html').write_text('0123456789') + assets_dir = f'{temp_dir}/assets' + os.makedirs(f'{assets_dir}/dir') + Path(f'{assets_dir}/index.html').write_text('0123456789') - os.makedirs(temp_dir + '/assets/403') - os.chmod(temp_dir + '/assets/403', 0o000) + os.makedirs(f'{assets_dir}/403') + os.chmod(f'{assets_dir}/403', 0o000) self._load_conf( { @@ -22,7 +23,7 @@ class TestStaticFallback(TestApplicationProto): "*:7080": {"pass": "routes"}, "*:7081": {"pass": "routes"}, }, - "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], + "routes": [{"action": {"share": f'{assets_dir}$uri'}}], "applications": {}, } ) @@ -30,7 +31,7 @@ class TestStaticFallback(TestApplicationProto): yield try: - os.chmod(temp_dir + '/assets/403', 0o777) + os.chmod(f'{assets_dir}/403', 0o777) except FileNotFoundError: pass @@ -49,7 +50,7 @@ class TestStaticFallback(TestApplicationProto): def test_static_fallback_valid_path(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets$uri", "fallback": {"return": 200}} + {"share": f"{temp_dir}/assets$uri", "fallback": {"return": 200}} ) resp = self.get() assert resp['status'] == 200, 'fallback status' @@ -84,7 +85,7 @@ class TestStaticFallback(TestApplicationProto): self.action_update( { "share": "/blah", - "fallback": {"share": temp_dir + "/assets$uri"}, + "fallback": {"share": f"{temp_dir}/assets$uri"}, } ) diff --git a/test/test_static_mount.py b/test/test_static_mount.py index 91cf836c..406922b1 100644 --- a/test/test_static_mount.py +++ b/test/test_static_mount.py @@ -14,20 +14,20 @@ class TestStaticMount(TestApplicationProto): if not is_su: pytest.skip('requires root') - os.makedirs(temp_dir + '/assets/dir/mount') - os.makedirs(temp_dir + '/assets/dir/dir') - os.makedirs(temp_dir + '/assets/mount') - Path(temp_dir + '/assets/index.html').write_text('index') - Path(temp_dir + '/assets/dir/dir/file').write_text('file') - Path(temp_dir + '/assets/mount/index.html').write_text('mount') + os.makedirs(f'{temp_dir}/assets/dir/mount') + os.makedirs(f'{temp_dir}/assets/dir/dir') + os.makedirs(f'{temp_dir}/assets/mount') + Path(f'{temp_dir}/assets/index.html').write_text('index') + Path(f'{temp_dir}/assets/dir/dir/file').write_text('file') + Path(f'{temp_dir}/assets/mount/index.html').write_text('mount') try: subprocess.check_output( [ "mount", "--bind", - temp_dir + "/assets/mount", - temp_dir + "/assets/dir/mount", + f'{temp_dir}/assets/mount', + f'{temp_dir}/assets/dir/mount', ], stderr=subprocess.STDOUT, ) @@ -36,12 +36,12 @@ class TestStaticMount(TestApplicationProto): raise except subprocess.CalledProcessError: - pytest.fail('Can\'t run mount process.') + pytest.fail("Can't run mount process.") self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": temp_dir + "/assets/dir$uri"}}], + "routes": [{"action": {"share": f'{temp_dir}/assets/dir$uri'}}], } ) @@ -49,7 +49,7 @@ class TestStaticMount(TestApplicationProto): try: subprocess.check_output( - ["umount", "--lazy", temp_dir + "/assets/dir/mount"], + ["umount", "--lazy", f'{temp_dir}/assets/dir/mount'], stderr=subprocess.STDOUT, ) @@ -57,7 +57,7 @@ class TestStaticMount(TestApplicationProto): raise except subprocess.CalledProcessError: - pytest.fail('Can\'t run umount process.') + pytest.fail("Can't run umount process.") def test_static_mount(self, temp_dir, skip_alert): skip_alert(r'opening.*failed') @@ -67,14 +67,14 @@ class TestStaticMount(TestApplicationProto): assert resp['body'] == 'mount' assert 'success' in self.conf( - {"share": temp_dir + "/assets/dir$uri", "traverse_mounts": False}, + {"share": f'{temp_dir}/assets/dir$uri', "traverse_mounts": False}, 'routes/0/action', ), 'configure mount disable' assert self.get(url='/mount/')['status'] == 403 assert 'success' in self.conf( - {"share": temp_dir + "/assets/dir$uri", "traverse_mounts": True}, + {"share": f'{temp_dir}/assets/dir$uri', "traverse_mounts": True}, 'routes/0/action', ), 'configure mount enable' @@ -85,21 +85,21 @@ class TestStaticMount(TestApplicationProto): def test_static_mount_two_blocks(self, temp_dir, skip_alert): skip_alert(r'opening.*failed') - os.symlink(temp_dir + '/assets/dir', temp_dir + '/assets/link') + os.symlink(f'{temp_dir}/assets/dir', f'{temp_dir}/assets/link') assert 'success' in self.conf( [ { "match": {"method": "HEAD"}, "action": { - "share": temp_dir + "/assets/dir$uri", + "share": f'{temp_dir}/assets/dir$uri', "traverse_mounts": False, }, }, { "match": {"method": "GET"}, "action": { - "share": temp_dir + "/assets/dir$uri", + "share": f'{temp_dir}/assets/dir$uri', "traverse_mounts": True, }, }, @@ -115,8 +115,8 @@ class TestStaticMount(TestApplicationProto): assert 'success' in self.conf( { - "share": temp_dir + "/assets/dir$uri", - "chroot": temp_dir + "/assets", + "share": f'{temp_dir}/assets/dir$uri', + "chroot": f'{temp_dir}/assets', }, 'routes/0/action', ), 'configure chroot mount default' @@ -125,8 +125,8 @@ class TestStaticMount(TestApplicationProto): assert 'success' in self.conf( { - "share": temp_dir + "/assets/dir$uri", - "chroot": temp_dir + "/assets", + "share": f'{temp_dir}/assets/dir$uri', + "chroot": f'{temp_dir}/assets', "traverse_mounts": False, }, 'routes/0/action', diff --git a/test/test_static_share.py b/test/test_static_share.py index 5384866e..0166f1f0 100644 --- a/test/test_static_share.py +++ b/test/test_static_share.py @@ -10,16 +10,16 @@ class TestStaticShare(TestApplicationProto): @pytest.fixture(autouse=True) def setup_method_fixture(self, temp_dir): - os.makedirs(temp_dir + '/assets/dir') - os.makedirs(temp_dir + '/assets/dir2') + os.makedirs(f'{temp_dir}/assets/dir') + os.makedirs(f'{temp_dir}/assets/dir2') - Path(temp_dir + '/assets/dir/file').write_text('1') - Path(temp_dir + '/assets/dir2/file2').write_text('2') + Path(f'{temp_dir}/assets/dir/file').write_text('1') + Path(f'{temp_dir}/assets/dir2/file2').write_text('2') assert 'success' in self.conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], + "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], "applications": {}, } ) @@ -31,7 +31,7 @@ class TestStaticShare(TestApplicationProto): assert self.get(url='/dir/file')['body'] == '1' assert self.get(url='/dir2/file2')['body'] == '2' - self.action_update({"share": [temp_dir + "/assets/dir$uri"]}) + self.action_update({"share": [f'{temp_dir}/assets/dir$uri']}) assert self.get(url='/file')['body'] == '1' assert self.get(url='/file2')['status'] == 404 @@ -39,8 +39,8 @@ class TestStaticShare(TestApplicationProto): self.action_update( { "share": [ - temp_dir + "/assets/dir$uri", - temp_dir + "/assets/dir2$uri", + f'{temp_dir}/assets/dir$uri', + f'{temp_dir}/assets/dir2$uri', ] } ) @@ -51,8 +51,8 @@ class TestStaticShare(TestApplicationProto): self.action_update( { "share": [ - temp_dir + "/assets/dir2$uri", - temp_dir + "/assets/dir3$uri", + f'{temp_dir}/assets/dir2$uri', + f'{temp_dir}/assets/dir3$uri', ] } ) diff --git a/test/test_static_symlink.py b/test/test_static_symlink.py index 24638e20..13d67bc7 100644 --- a/test/test_static_symlink.py +++ b/test/test_static_symlink.py @@ -10,21 +10,21 @@ class TestStaticSymlink(TestApplicationProto): @pytest.fixture(autouse=True) def setup_method_fixture(self, temp_dir): - os.makedirs(temp_dir + '/assets/dir/dir') - Path(temp_dir + '/assets/index.html').write_text('0123456789') - Path(temp_dir + '/assets/dir/file').write_text('blah') + os.makedirs(f'{temp_dir}/assets/dir/dir') + Path(f'{temp_dir}/assets/index.html').write_text('0123456789') + Path(f'{temp_dir}/assets/dir/file').write_text('blah') self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], + "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], } ) def test_static_symlink(self, temp_dir, skip_alert): skip_alert(r'opening.*failed') - os.symlink(temp_dir + '/assets/dir', temp_dir + '/assets/link') + os.symlink(f'{temp_dir}/assets/dir', f'{temp_dir}/assets/link') assert self.get(url='/dir')['status'] == 301, 'dir' assert self.get(url='/dir/file')['status'] == 200, 'file' @@ -32,14 +32,14 @@ class TestStaticSymlink(TestApplicationProto): assert self.get(url='/link/file')['status'] == 200, 'symlink file' assert 'success' in self.conf( - {"share": temp_dir + "/assets$uri", "follow_symlinks": False}, + {"share": f'{temp_dir}/assets$uri', "follow_symlinks": False}, 'routes/0/action', ), 'configure symlink disable' assert self.get(url='/link/file')['status'] == 403, 'symlink disabled' assert 'success' in self.conf( - {"share": temp_dir + "/assets$uri", "follow_symlinks": True}, + {"share": f'{temp_dir}/assets$uri', "follow_symlinks": True}, 'routes/0/action', ), 'configure symlink enable' @@ -48,21 +48,21 @@ class TestStaticSymlink(TestApplicationProto): def test_static_symlink_two_blocks(self, temp_dir, skip_alert): skip_alert(r'opening.*failed') - os.symlink(temp_dir + '/assets/dir', temp_dir + '/assets/link') + os.symlink(f'{temp_dir}/assets/dir', f'{temp_dir}/assets/link') assert 'success' in self.conf( [ { "match": {"method": "HEAD"}, "action": { - "share": temp_dir + "/assets$uri", + "share": f'{temp_dir}/assets$uri', "follow_symlinks": False, }, }, { "match": {"method": "GET"}, "action": { - "share": temp_dir + "/assets$uri", + "share": f'{temp_dir}/assets$uri', "follow_symlinks": True, }, }, @@ -77,15 +77,15 @@ class TestStaticSymlink(TestApplicationProto): skip_alert(r'opening.*failed') os.symlink( - temp_dir + '/assets/dir/file', temp_dir + '/assets/dir/dir/link' + f'{temp_dir}/assets/dir/file', f'{temp_dir}/assets/dir/dir/link' ) assert self.get(url='/dir/dir/link')['status'] == 200, 'default chroot' assert 'success' in self.conf( { - "share": temp_dir + "/assets$uri", - "chroot": temp_dir + "/assets/dir/dir", + "share": f'{temp_dir}/assets$uri', + "chroot": f'{temp_dir}/assets/dir/dir', }, 'routes/0/action', ), 'configure chroot' diff --git a/test/test_static_types.py b/test/test_static_types.py index 0e86517b..28ab28e6 100644 --- a/test/test_static_types.py +++ b/test/test_static_types.py @@ -9,11 +9,11 @@ class TestStaticTypes(TestApplicationProto): @pytest.fixture(autouse=True) def setup_method_fixture(self, temp_dir): - Path(temp_dir + '/assets').mkdir() + Path(f'{temp_dir}/assets').mkdir() for ext in ['.xml', '.mp4', '.php', '', '.txt', '.html', '.png']: - Path(temp_dir + '/assets/file' + ext).write_text(ext) + Path(f'{temp_dir}/assets/file{ext}').write_text(ext) - Path(temp_dir + '/assets/index.html').write_text('index') + Path(f'{temp_dir}/assets/index.html').write_text('index') self._load_conf( { @@ -21,7 +21,7 @@ class TestStaticTypes(TestApplicationProto): "*:7080": {"pass": "routes"}, "*:7081": {"pass": "routes"}, }, - "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], + "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], "applications": {}, } ) @@ -35,39 +35,39 @@ class TestStaticTypes(TestApplicationProto): assert resp['body'] == body, 'body' def test_static_types_basic(self, temp_dir): - self.action_update({"share": temp_dir + "/assets$uri"}) + self.action_update({"share": f'{temp_dir}/assets$uri'}) self.check_body('/index.html', 'index') self.check_body('/file.xml', '.xml') self.action_update( - {"share": temp_dir + "/assets$uri", "types": "application/xml"} + {"share": f'{temp_dir}/assets$uri', "types": "application/xml"} ) self.check_body('/file.xml', '.xml') self.action_update( - {"share": temp_dir + "/assets$uri", "types": ["application/xml"]} + {"share": f'{temp_dir}/assets$uri', "types": ["application/xml"]} ) self.check_body('/file.xml', '.xml') - self.action_update({"share": temp_dir + "/assets$uri", "types": [""]}) + self.action_update({"share": f'{temp_dir}/assets$uri', "types": [""]}) assert self.get(url='/file.xml')['status'] == 403, 'no mtype' def test_static_types_wildcard(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets$uri", "types": ["application/*"]} + {"share": f'{temp_dir}/assets$uri', "types": ["application/*"]} ) self.check_body('/file.xml', '.xml') assert self.get(url='/file.mp4')['status'] == 403, 'app * mtype mp4' self.action_update( - {"share": temp_dir + "/assets$uri", "types": ["video/*"]} + {"share": f'{temp_dir}/assets$uri', "types": ["video/*"]} ) assert self.get(url='/file.xml')['status'] == 403, 'video * mtype xml' self.check_body('/file.mp4', '.mp4') def test_static_types_negation(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets$uri", "types": ["!application/xml"]} + {"share": f'{temp_dir}/assets$uri', "types": ["!application/xml"]} ) assert self.get(url='/file.xml')['status'] == 403, 'forbidden negation' self.check_body('/file.mp4', '.mp4') @@ -75,7 +75,7 @@ class TestStaticTypes(TestApplicationProto): # sorting negation self.action_update( { - "share": temp_dir + "/assets$uri", + "share": f'{temp_dir}/assets$uri', "types": ["!video/*", "image/png", "!image/jpg"], } ) @@ -86,7 +86,7 @@ class TestStaticTypes(TestApplicationProto): def test_static_types_regex(self, temp_dir): self.action_update( { - "share": temp_dir + "/assets$uri", + "share": f'{temp_dir}/assets$uri', "types": ["~text/(html|plain)"], } ) @@ -96,7 +96,7 @@ class TestStaticTypes(TestApplicationProto): def test_static_types_case(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets$uri", "types": ["!APpliCaTiOn/xMl"]} + {"share": f'{temp_dir}/assets$uri', "types": ["!APpliCaTiOn/xMl"]} ) self.check_body('/file.mp4', '.mp4') assert ( @@ -104,7 +104,7 @@ class TestStaticTypes(TestApplicationProto): ), 'mixed case xml negation' self.action_update( - {"share": temp_dir + "/assets$uri", "types": ["vIdEo/mp4"]} + {"share": f'{temp_dir}/assets$uri', "types": ["vIdEo/mp4"]} ) assert self.get(url='/file.mp4')['status'] == 200, 'mixed case' assert ( @@ -112,7 +112,7 @@ class TestStaticTypes(TestApplicationProto): ), 'mixed case video negation' self.action_update( - {"share": temp_dir + "/assets$uri", "types": ["vIdEo/*"]} + {"share": f'{temp_dir}/assets$uri', "types": ["vIdEo/*"]} ) self.check_body('/file.mp4', '.mp4') assert ( @@ -128,7 +128,7 @@ class TestStaticTypes(TestApplicationProto): }, { "action": { - "share": temp_dir + "/assets$uri", + "share": f'{temp_dir}/assets$uri', "types": ["!application/x-httpd-php"], "fallback": {"proxy": "http://127.0.0.1:7081"}, } @@ -142,7 +142,7 @@ class TestStaticTypes(TestApplicationProto): def test_static_types_index(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets$uri", "types": "application/xml"} + {"share": f'{temp_dir}/assets$uri', "types": "application/xml"} ) self.check_body('/', 'index') self.check_body('/file.xml', '.xml') @@ -153,7 +153,7 @@ class TestStaticTypes(TestApplicationProto): self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], + "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], "applications": {}, "settings": { "http": { @@ -163,10 +163,10 @@ class TestStaticTypes(TestApplicationProto): } ) - self.action_update({"share": temp_dir + "/assets$uri", "types": [""]}) + self.action_update({"share": f'{temp_dir}/assets$uri', "types": [""]}) assert self.get(url='/file')['status'] == 403, 'forbidden custom mime' self.action_update( - {"share": temp_dir + "/assets$uri", "types": ["test/mime-type"]} + {"share": f'{temp_dir}/assets$uri', "types": ["test/mime-type"]} ) self.check_body('/file', '') diff --git a/test/test_static_variables.py b/test/test_static_variables.py index e7e1629c..370c3e6f 100644 --- a/test/test_static_variables.py +++ b/test/test_static_variables.py @@ -10,16 +10,16 @@ class TestStaticVariables(TestApplicationProto): @pytest.fixture(autouse=True) def setup_method_fixture(self, temp_dir): - os.makedirs(temp_dir + '/assets/dir') - os.makedirs(temp_dir + '/assets/d$r') - Path(temp_dir + '/assets/index.html').write_text('0123456789') - Path(temp_dir + '/assets/dir/file').write_text('file') - Path(temp_dir + '/assets/d$r/file').write_text('d$r') + os.makedirs(f'{temp_dir}/assets/dir') + os.makedirs(f'{temp_dir}/assets/d$r') + Path(f'{temp_dir}/assets/index.html').write_text('0123456789') + Path(f'{temp_dir}/assets/dir/file').write_text('file') + Path(f'{temp_dir}/assets/d$r/file').write_text('d$r') self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], + "routes": [{"action": {"share": f'{temp_dir}/assets$uri'}}], } ) @@ -27,37 +27,37 @@ class TestStaticVariables(TestApplicationProto): if isinstance(share, list): return self.conf(share, 'routes/0/action/share') - return self.conf('"' + share + '"', 'routes/0/action/share') + return self.conf(f'"{share}"', 'routes/0/action/share') def test_static_variables(self, temp_dir): assert self.get(url='/index.html')['status'] == 200 assert self.get(url='/d$r/file')['status'] == 200 assert 'success' in self.update_share('$uri') - assert self.get(url=temp_dir + '/assets/index.html')['status'] == 200 + assert self.get(url=f'{temp_dir}/assets/index.html')['status'] == 200 - assert 'success' in self.update_share(temp_dir + '/assets${uri}') + assert 'success' in self.update_share(f'{temp_dir}/assets${{uri}}') assert self.get(url='/index.html')['status'] == 200 def test_static_variables_array(self, temp_dir): assert 'success' in self.update_share( - [temp_dir + '/assets$uri', '$uri'] + [f'{temp_dir}/assets$uri', '$uri'] ) assert self.get(url='/dir/file')['status'] == 200 - assert self.get(url=temp_dir + '/assets/index.html')['status'] == 200 + assert self.get(url=f'{temp_dir}/assets/index.html')['status'] == 200 assert self.get(url='/blah')['status'] == 404 assert 'success' in self.conf( { - "share": [temp_dir + '/assets$uri', '$uri'], + "share": [f'{temp_dir}/assets$uri', '$uri'], "fallback": {"return": 201}, }, 'routes/0/action', ) assert self.get(url='/dir/file')['status'] == 200 - assert self.get(url=temp_dir + '/assets/index.html')['status'] == 200 + assert self.get(url=f'{temp_dir}/assets/index.html')['status'] == 200 assert self.get(url='/dir/blah')['status'] == 201 def test_static_variables_buildin_start(self, temp_dir): @@ -65,15 +65,15 @@ class TestStaticVariables(TestApplicationProto): assert self.get(url=temp_dir)['status'] == 200 def test_static_variables_buildin_mid(self, temp_dir): - assert 'success' in self.update_share(temp_dir + '$uri/index.html') + assert 'success' in self.update_share(f'{temp_dir}$uri/index.html') assert self.get(url='/assets')['status'] == 200 def test_static_variables_buildin_end(self): assert self.get(url='/index.html')['status'] == 200 def test_static_variables_invalid(self, temp_dir): - assert 'error' in self.update_share(temp_dir + '/assets/d$r$uri') - assert 'error' in self.update_share(temp_dir + '/assets/$$uri') + assert 'error' in self.update_share(f'{temp_dir}/assets/d$r$uri') + assert 'error' in self.update_share(f'{temp_dir}/assets/$$uri') assert 'error' in self.update_share( - [temp_dir + '/assets$uri', temp_dir + '/assets/dir', '$$uri'] + [f'{temp_dir}/assets$uri', f'{temp_dir}/assets/dir', '$$uri'] ) diff --git a/test/test_status.py b/test/test_status.py index 6c733474..d0901f42 100644 --- a/test/test_status.py +++ b/test/test_status.py @@ -18,11 +18,12 @@ class TestStatus(TestApplicationPython): } def app_default(self, name="empty", module="wsgi"): + name_dir = f'{option.test_dir}/python/{name}' return { "type": self.get_application_type(), "processes": {"spare": 0}, - "path": option.test_dir + "/python/" + name, - "working_directory": option.test_dir + "/python/" + name, + "path": name_dir, + "working_directory": name_dir, "module": module, } @@ -141,7 +142,7 @@ Connection: close assert apps == expert.sort() def check_application(name, running, starting, idle, active): - Status.get('/applications/' + name) == { + Status.get(f'/applications/{name}') == { 'processes': { 'running': running, 'starting': starting, diff --git a/test/test_tls.py b/test/test_tls.py index d4edcbd3..06c38d0b 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -17,19 +17,19 @@ class TestTLS(TestApplicationTLS): def add_tls(self, application='empty', cert='default', port=7080): assert 'success' in self.conf( { - "pass": "applications/" + application, + "pass": f"applications/{application}", "tls": {"certificate": cert}, }, - 'listeners/*:' + str(port), + f'listeners/*:{port}', ) def remove_tls(self, application='empty', port=7080): assert 'success' in self.conf( - {"pass": "applications/" + application}, 'listeners/*:' + str(port) + {"pass": f"applications/{application}"}, f'listeners/*:{port}' ) def req(self, name='localhost', subject=None, x509=False): - subj = subject if subject is not None else '/CN=' + name + '/' + subj = subject if subject is not None else f'/CN={name}/' subprocess.check_output( [ @@ -39,27 +39,27 @@ class TestTLS(TestApplicationTLS): '-subj', subj, '-config', - option.temp_dir + '/openssl.conf', + f'{option.temp_dir}/openssl.conf', '-out', - option.temp_dir + '/' + name + '.csr', + f'{option.temp_dir}/{name}.csr', '-keyout', - option.temp_dir + '/' + name + '.key', + f'{option.temp_dir}/{name}.key', ], stderr=subprocess.STDOUT, ) def generate_ca_conf(self): - with open(option.temp_dir + '/ca.conf', 'w') as f: + with open(f'{option.temp_dir}/ca.conf', 'w') as f: f.write( - """[ ca ] + f"""[ ca ] default_ca = myca [ myca ] -new_certs_dir = %(dir)s -database = %(database)s +new_certs_dir = {option.temp_dir} +database = {option.temp_dir}/certindex default_md = sha256 policy = myca_policy -serial = %(certserial)s +serial = {option.temp_dir}/certserial default_days = 1 x509_extensions = myca_extensions copy_extensions = copy @@ -69,20 +69,15 @@ commonName = optional [ myca_extensions ] basicConstraints = critical,CA:TRUE""" - % { - 'dir': option.temp_dir, - 'database': option.temp_dir + '/certindex', - 'certserial': option.temp_dir + '/certserial', - } ) - with open(option.temp_dir + '/certserial', 'w') as f: + with open(f'{option.temp_dir}/certserial', 'w') as f: f.write('1000') - with open(option.temp_dir + '/certindex', 'w') as f: + with open(f'{option.temp_dir}/certindex', 'w') as f: f.write('') - with open(option.temp_dir + '/certindex.attr', 'w') as f: + with open(f'{option.temp_dir}/certindex.attr', 'w') as f: f.write('') def ca(self, cert='root', out='localhost'): @@ -92,15 +87,15 @@ basicConstraints = critical,CA:TRUE""" 'ca', '-batch', '-config', - option.temp_dir + '/ca.conf', + f'{option.temp_dir}/ca.conf', '-keyfile', - option.temp_dir + '/' + cert + '.key', + f'{option.temp_dir}/{cert}.key', '-cert', - option.temp_dir + '/' + cert + '.crt', + f'{option.temp_dir}/{cert}.crt', '-in', - option.temp_dir + '/' + out + '.csr', + f'{option.temp_dir}/{out}.csr', '-out', - option.temp_dir + '/' + out + '.crt', + f'{option.temp_dir}/{out}.crt', ], stderr=subprocess.STDOUT, ) @@ -109,9 +104,7 @@ basicConstraints = critical,CA:TRUE""" self.context = ssl.create_default_context() self.context.check_hostname = False self.context.verify_mode = ssl.CERT_REQUIRED - self.context.load_verify_locations( - option.temp_dir + '/' + cert + '.crt' - ) + self.context.load_verify_locations(f'{option.temp_dir}/{cert}.crt') def test_tls_listener_option_add(self): self.load('empty') @@ -230,7 +223,7 @@ basicConstraints = critical,CA:TRUE""" '-noout', '-genkey', '-out', - temp_dir + '/ec.key', + f'{temp_dir}/ec.key', '-name', 'prime256v1', ], @@ -246,11 +239,11 @@ basicConstraints = critical,CA:TRUE""" '-subj', '/CN=ec/', '-config', - temp_dir + '/openssl.conf', + f'{temp_dir}/openssl.conf', '-key', - temp_dir + '/ec.key', + f'{temp_dir}/ec.key', '-out', - temp_dir + '/ec.crt', + f'{temp_dir}/ec.crt', ], stderr=subprocess.STDOUT, ) @@ -305,9 +298,9 @@ basicConstraints = critical,CA:TRUE""" self.ca(cert='root', out='int') self.ca(cert='int', out='end') - crt_path = temp_dir + '/end-int.crt' - end_path = temp_dir + '/end.crt' - int_path = temp_dir + '/int.crt' + crt_path = f'{temp_dir}/end-int.crt' + end_path = f'{temp_dir}/end.crt' + int_path = f'{temp_dir}/int.crt' with open(crt_path, 'wb') as crt, open(end_path, 'rb') as end, open( int_path, 'rb' @@ -400,22 +393,24 @@ basicConstraints = critical,CA:TRUE""" elif i == chain_length - 1: self.req('end') else: - self.req('int{}'.format(i)) + self.req(f'int{i}') for i in range(chain_length - 1): if i == 0: self.ca(cert='root', out='int1') elif i == chain_length - 2: - self.ca(cert='int{}'.format(chain_length - 2), out='end') + self.ca(cert=f'int{(chain_length - 2)}', out='end') else: - self.ca(cert='int{}'.format(i), out='int{}'.format(i + 1)) + self.ca(cert=f'int{i}', out=f'int{(i + 1)}') for i in range(chain_length - 1, 0, -1): - path = temp_dir + ( - '/end.crt' if i == chain_length - 1 else '/int{}.crt'.format(i) + path = ( + f'{temp_dir}/end.crt' + if i == chain_length - 1 + else f'{temp_dir}/int{i}.crt' ) - with open(temp_dir + '/all.crt', 'a') as chain, open(path) as cert: + with open(f'{temp_dir}/all.crt', 'a') as chain, open(path) as cert: chain.write(cert.read()) self.set_certificate_req_context() @@ -611,10 +606,10 @@ basicConstraints = critical,CA:TRUE""" subprocess.check_output(['kill', '-9', app_id]) - skip_alert(r'process %s exited on signal 9' % app_id) + skip_alert(fr'process {app_id} exited on signal 9') self.wait_for_record( - r' (?!' + app_id + r'#)(\d+)#\d+ "mirror" application started' + fr' (?!{app_id}#)(\d+)#\d+ "mirror" application started' ) resp = self.post_ssl(sock=sock, body='0123456789') @@ -673,7 +668,7 @@ basicConstraints = critical,CA:TRUE""" } ) assert res['status'] == 200, 'status ok' - assert res['body'] == filename + data + assert res['body'] == f'{filename}{data}' def test_tls_multi_listener(self): self.load('empty') diff --git a/test/test_tls_conf_command.py b/test/test_tls_conf_command.py index b414b5a0..605848ea 100644 --- a/test/test_tls_conf_command.py +++ b/test/test_tls_conf_command.py @@ -47,7 +47,7 @@ class TestTLSConfCommand(TestApplicationTLS): assert 'success' in self.conf( { "certificate": "default", - "conf_commands": {"protocol": '-' + protocol}, + "conf_commands": {"protocol": f'-{protocol}'}, }, 'listeners/*:7080/tls', ), 'protocol disabled' @@ -74,8 +74,8 @@ class TestTLSConfCommand(TestApplicationTLS): { "certificate": "default", "conf_commands": { - "protocol": '-' + protocol, - "cipherstring": cipher[1] + ":!" + cipher[0], + "protocol": f'-{protocol}', + "cipherstring": f"{cipher[1]}:!{cipher[0]}", }, }, 'listeners/*:7080/tls', diff --git a/test/test_tls_sni.py b/test/test_tls_sni.py index 44cc21e1..e918bb20 100644 --- a/test/test_tls_sni.py +++ b/test/test_tls_sni.py @@ -30,17 +30,17 @@ class TestTLSSNI(TestApplicationTLS): assert 'success' in self.conf({"pass": "routes"}, 'listeners/*:7080') def generate_ca_conf(self): - with open(option.temp_dir + '/ca.conf', 'w') as f: + with open(f'{option.temp_dir}/ca.conf', 'w') as f: f.write( - """[ ca ] + f"""[ ca ] default_ca = myca [ myca ] -new_certs_dir = %(dir)s -database = %(database)s +new_certs_dir = {option.temp_dir} +database = {option.temp_dir}/certindex default_md = sha256 policy = myca_policy -serial = %(certserial)s +serial = {option.temp_dir}/certserial default_days = 1 x509_extensions = myca_extensions copy_extensions = copy @@ -50,17 +50,12 @@ commonName = optional [ myca_extensions ] basicConstraints = critical,CA:TRUE""" - % { - 'dir': option.temp_dir, - 'database': option.temp_dir + '/certindex', - 'certserial': option.temp_dir + '/certserial', - } ) - with open(option.temp_dir + '/certserial', 'w') as f: + with open(f'{option.temp_dir}/certserial', 'w') as f: f.write('1000') - with open(option.temp_dir + '/certindex', 'w') as f: + with open(f'{option.temp_dir}/certindex', 'w') as f: f.write('') def config_bundles(self, bundles): @@ -68,11 +63,7 @@ basicConstraints = critical,CA:TRUE""" for b in bundles: self.openssl_conf(rewrite=True, alt_names=bundles[b]['alt_names']) - subj = ( - '/CN={}/'.format(bundles[b]['subj']) - if 'subj' in bundles[b] - else '/' - ) + subj = f'/CN={bundles[b]["subj"]}/' if 'subj' in bundles[b] else '/' subprocess.check_output( [ @@ -82,11 +73,11 @@ basicConstraints = critical,CA:TRUE""" '-subj', subj, '-config', - option.temp_dir + '/openssl.conf', + f'{option.temp_dir}/openssl.conf', '-out', - option.temp_dir + '/{}.csr'.format(b), + f'{option.temp_dir}/{b}.csr', '-keyout', - option.temp_dir + '/{}.key'.format(b), + f'{option.temp_dir}/{b}.key', ], stderr=subprocess.STDOUT, ) @@ -94,11 +85,7 @@ basicConstraints = critical,CA:TRUE""" self.generate_ca_conf() for b in bundles: - subj = ( - '/CN={}/'.format(bundles[b]['subj']) - if 'subj' in bundles[b] - else '/' - ) + subj = f'/CN={bundles[b]["subj"]}/' if 'subj' in bundles[b] else '/' subprocess.check_output( [ @@ -108,15 +95,15 @@ basicConstraints = critical,CA:TRUE""" '-subj', subj, '-config', - option.temp_dir + '/ca.conf', + f'{option.temp_dir}/ca.conf', '-keyfile', - option.temp_dir + '/root.key', + f'{option.temp_dir}/root.key', '-cert', - option.temp_dir + '/root.crt', + f'{option.temp_dir}/root.crt', '-in', - option.temp_dir + '/{}.csr'.format(b), + f'{option.temp_dir}/{b}.csr', '-out', - option.temp_dir + '/{}.crt'.format(b), + f'{option.temp_dir}/{b}.crt', ], stderr=subprocess.STDOUT, ) @@ -124,7 +111,7 @@ basicConstraints = critical,CA:TRUE""" self.context = ssl.create_default_context() self.context.check_hostname = False self.context.verify_mode = ssl.CERT_REQUIRED - self.context.load_verify_locations(option.temp_dir + '/root.crt') + self.context.load_verify_locations(f'{option.temp_dir}/root.crt') self.load_certs(bundles) @@ -132,7 +119,7 @@ basicConstraints = critical,CA:TRUE""" for bname, bvalue in bundles.items(): assert 'success' in self.certificate_load( bname, bname - ), 'certificate {} upload'.format(bvalue['subj']) + ), f'certificate {bvalue["subj"]} upload' def check_cert(self, host, expect): resp, sock = self.get_ssl( diff --git a/test/test_tls_tickets.py b/test/test_tls_tickets.py index 5399fae7..cca230f3 100644 --- a/test/test_tls_tickets.py +++ b/test/test_tls_tickets.py @@ -48,7 +48,7 @@ class TestTLSTicket(TestApplicationTLS): def set_tickets(self, tickets=True, port=7080): assert 'success' in self.conf( {"cache_size": 0, "tickets": tickets}, - 'listeners/*:' + str(port) + '/tls/session', + f'listeners/*:{port}/tls/session', ) def connect(self, ctx=None, session=None, port=7080): @@ -168,7 +168,7 @@ class TestTLSTicket(TestApplicationTLS): 'listeners/*:7080/tls/session/tickets/0' ), 'removed first ticket' assert 'success' in self.conf_post( - '"' + self.ticket + '"', 'listeners/*:7080/tls/session/tickets' + f'"{self.ticket}"', 'listeners/*:7080/tls/session/tickets' ), 'add new ticket to the end of array' sess, ctx, _ = self.connect() @@ -186,10 +186,10 @@ class TestTLSTicket(TestApplicationTLS): check_tickets({}) check_tickets('!?&^' * 16) - check_tickets(self.ticket[:-2] + '!' + self.ticket[3:]) + check_tickets(f'{self.ticket[:-2]}!{self.ticket[3:]}') check_tickets(self.ticket[:-1]) - check_tickets(self.ticket + 'b') - check_tickets(self.ticket + 'blah') + check_tickets(f'{self.ticket}b') + check_tickets(f'{self.ticket}blah') check_tickets([True, self.ticket, self.ticket2]) check_tickets([self.ticket, 'blah', self.ticket2]) check_tickets([self.ticket, self.ticket2, []]) diff --git a/test/test_unix_abstract.py b/test/test_unix_abstract.py index 195b0aa7..c562487b 100644 --- a/test/test_unix_abstract.py +++ b/test/test_unix_abstract.py @@ -13,14 +13,14 @@ class TestUnixAbstract(TestApplicationPython): def source(source): assert 'success' in self.conf( - '"' + source + '"', 'routes/0/match/source' + f'"{source}"', 'routes/0/match/source' ) assert 'success' in self.conf( { "listeners": { "127.0.0.1:7080": {"pass": "routes"}, - "unix:@" + addr[1:]: {"pass": "routes"}, + f"unix:@{addr[1:]}": {"pass": "routes"}, }, "routes": [ { @@ -61,6 +61,7 @@ class TestUnixAbstract(TestApplicationPython): headers={'Connection': 'close', 'X-Forwarded-For': xff}, )['body'] + client_ip_dir = f"{option.test_dir}/python/client_ip" assert 'success' in self.conf( { "listeners": { @@ -90,9 +91,8 @@ class TestUnixAbstract(TestApplicationPython): "client_ip": { "type": self.get_application_type(), "processes": {"spare": 0}, - "path": option.test_dir + "/python/client_ip", - "working_directory": option.test_dir - + "/python/client_ip", + "path": client_ip_dir, + "working_directory": client_ip_dir, "module": "wsgi", } }, diff --git a/test/test_upstreams_rr.py b/test/test_upstreams_rr.py index 71af3f5d..324c93cb 100644 --- a/test/test_upstreams_rr.py +++ b/test/test_upstreams_rr.py @@ -247,6 +247,7 @@ Connection: close assert abs(r_two[0] - r_two[1]) <= self.cpu_count, 'dep two mix' def test_upstreams_rr_delay(self): + delayed_dir = f'{option.test_dir}/python/delayed' assert 'success' in self.conf( { "listeners": { @@ -276,9 +277,8 @@ Connection: close "delayed": { "type": self.get_application_type(), "processes": {"spare": 0}, - "path": option.test_dir + "/python/delayed", - "working_directory": option.test_dir - + "/python/delayed", + "path": delayed_dir, + "working_directory": delayed_dir, "module": "wsgi", } }, @@ -389,20 +389,20 @@ Connection: close assert abs(resps[0] - resps[1]) <= self.cpu_count, 'post' def test_upstreams_rr_unix(self, temp_dir): - addr_0 = temp_dir + '/sock_0' - addr_1 = temp_dir + '/sock_1' + addr_0 = f'{temp_dir}/sock_0' + addr_1 = f'{temp_dir}/sock_1' assert 'success' in self.conf( { "*:7080": {"pass": "upstreams/one"}, - "unix:" + addr_0: {"pass": "routes/one"}, - "unix:" + addr_1: {"pass": "routes/two"}, + f"unix:{addr_0}": {"pass": "routes/one"}, + f"unix:{addr_1}": {"pass": "routes/two"}, }, 'listeners', ), 'configure listeners unix' assert 'success' in self.conf( - {"unix:" + addr_0: {}, "unix:" + addr_1: {}}, + {f"unix:{addr_0}": {}, f"unix:{addr_1}": {}}, 'upstreams/one/servers', ), 'configure servers unix' diff --git a/test/test_usr1.py b/test/test_usr1.py index 3d190935..4bff0242 100644 --- a/test/test_usr1.py +++ b/test/test_usr1.py @@ -14,15 +14,15 @@ class TestUSR1(TestApplicationPython): log = 'access.log' log_new = 'new.log' - log_path = temp_dir + '/' + log + log_path = f'{temp_dir}/{log}' assert 'success' in self.conf( - '"' + log_path + '"', 'access_log' + f'"{log_path}"', 'access_log' ), 'access log configure' assert waitforfiles(log_path), 'open' - os.rename(log_path, temp_dir + '/' + log_new) + os.rename(log_path, f'{temp_dir}/{log_new}') assert self.get()['status'] == 200 @@ -48,8 +48,8 @@ class TestUSR1(TestApplicationPython): self.load('log_body') log_new = 'new.log' - log_path = temp_dir + '/unit.log' - log_path_new = temp_dir + '/' + log_new + log_path = f'{temp_dir}/unit.log' + log_path_new = f'{temp_dir}/{log_new}' os.rename(log_path, log_path_new) diff --git a/test/test_variables.py b/test/test_variables.py index ecce5e6d..545d61e9 100644 --- a/test/test_variables.py +++ b/test/test_variables.py @@ -19,7 +19,7 @@ class TestVariables(TestApplicationProto): def set_format(self, format): assert 'success' in self.conf( { - 'path': option.temp_dir + '/access.log', + 'path': f'{option.temp_dir}/access.log', 'format': format, }, 'access_log', @@ -36,7 +36,7 @@ class TestVariables(TestApplicationProto): def check_dollar(location, expect): assert 'success' in self.conf( - '"' + location + '"', + f'"{location}"', 'routes/0/action/location', ) assert self.get()['headers']['Location'] == expect @@ -93,7 +93,7 @@ Connection: close self.set_format('$request_uri') def check_request_uri(req_uri): - reg = r'^' + re.escape(req_uri) + r'$' + reg = fr'^{re.escape(req_uri)}$' assert self.search_in_log(reg) is None assert self.get(url=req_uri)['status'] == 200 @@ -109,7 +109,7 @@ Connection: close def check_uri(uri, expect=None): expect = uri if expect is None else expect - reg = r'^' + re.escape(expect) + r'$' + reg = fr'^{re.escape(expect)}$' assert self.search_in_log(reg) is None assert self.get(url=uri)['status'] == 200 @@ -125,7 +125,7 @@ Connection: close def check_host(host, expect=None): expect = host if expect is None else expect - reg = r'^' + re.escape(expect) + r'$' + reg = fr'^{re.escape(expect)}$' assert self.search_in_log(reg) is None assert ( @@ -196,7 +196,7 @@ Connection: close self.set_format('$method $header_referer') def check_referer(referer): - reg = r'^GET ' + re.escape(referer) + r'$' + reg = fr'^GET {re.escape(referer)}$' assert self.search_in_log(reg) is None assert ( @@ -219,7 +219,7 @@ Connection: close self.set_format('$method $header_user_agent') def check_user_agent(user_agent): - reg = r'^GET ' + re.escape(user_agent) + r'$' + reg = fr'^GET {re.escape(user_agent)}$' assert self.search_in_log(reg) is None assert ( @@ -240,7 +240,7 @@ Connection: close def test_variables_many(self): def check_vars(uri, expect): - reg = r'^' + re.escape(expect) + r'$' + reg = fr'^{re.escape(expect)}$' assert self.search_in_log(reg) is None assert self.get(url=uri)['status'] == 200 @@ -273,7 +273,7 @@ Connection: close def test_variables_dynamic_arguments(self): def check_arg(url, expect=None): expect = url if expect is None else expect - reg = r'^' + re.escape(expect) + r'$' + reg = fr'^{re.escape(expect)}$' assert self.search_in_log(reg) is None assert self.get(url=url)['status'] == 200 @@ -304,7 +304,7 @@ Connection: close def test_variables_dynamic_headers(self): def check_header(header, value): - reg = r'^' + value + r'$' + reg = fr'^{value}$' assert self.search_in_log(reg) is None assert ( @@ -368,7 +368,7 @@ Connection: close def check_variables(format): assert 'error' in self.conf( { - 'path': option.temp_dir + '/access.log', + 'path': f'{option.temp_dir}/access.log', 'format': format, }, 'access_log', diff --git a/test/unit/applications/lang/go.py b/test/unit/applications/lang/go.py index 14e76362..557753a4 100644 --- a/test/unit/applications/lang/go.py +++ b/test/unit/applications/lang/go.py @@ -14,23 +14,21 @@ class TestApplicationGo(TestApplicationProto): except subprocess.CalledProcessError: return None - temp_dir = option.temp_dir + '/go/' + temp_dir = f'{option.temp_dir}/go/' if not os.path.exists(temp_dir): os.mkdir(temp_dir) - cache_dir = option.cache_dir + '/go-build' + cache_dir = f'{option.cache_dir}/go-build' if not os.path.exists(cache_dir): os.mkdir(cache_dir) env = os.environ.copy() - env['GOPATH'] = option.current_dir + '/build/go' + env['GOPATH'] = f'{option.current_dir}/build/go' env['GOCACHE'] = cache_dir - shutil.copy2( - option.test_dir + '/go/' + script + '/' + name + '.go', temp_dir - ) + shutil.copy2(f'{option.test_dir}/go/{script}/{name}.go', temp_dir) if static: args = [ @@ -41,21 +39,21 @@ class TestApplicationGo(TestApplicationProto): '-ldflags', '-extldflags "-static"', '-o', - temp_dir + name, - temp_dir + name + '.go', + f'{temp_dir}{name}', + f'{temp_dir}{name}.go', ] else: args = [ 'go', 'build', '-o', - temp_dir + name, - temp_dir + name + '.go', + f'{temp_dir}{name}', + f'{temp_dir}{name}.go', ] - replace_path = option.current_dir + '/build/go/src/unit.nginx.org/go' + replace_path = f'{option.current_dir}/build/go/src/unit.nginx.org/go' - with open(temp_dir + 'go.mod', 'w') as f: + with open(f'{temp_dir}go.mod', 'w') as f: f.write( f"""module test/app require unit.nginx.org/go v0.0.0 @@ -64,7 +62,7 @@ replace unit.nginx.org/go => {replace_path} ) if option.detailed: - print("\n$ GOPATH=" + env['GOPATH'] + " " + " ".join(args)) + print(f'\n$ GOPATH={env["GOPATH"]} {" ".join(args)}') try: output = subprocess.check_output( @@ -82,18 +80,18 @@ replace unit.nginx.org/go => {replace_path} def load(self, script, name='app', **kwargs): static_build = False - wdir = option.test_dir + "/go/" + script - executable = option.temp_dir + "/go/" + name + wdir = f'{option.test_dir}/go/{script}' + executable = f'{option.temp_dir}/go/{name}' if 'isolation' in kwargs and 'rootfs' in kwargs['isolation']: wdir = "/go/" - executable = "/go/" + name + executable = f"/go/{name}" static_build = True TestApplicationGo.prepare_env(script, name, static=static_build) conf = { - "listeners": {"*:7080": {"pass": "applications/" + script}}, + "listeners": {"*:7080": {"pass": f"applications/{script}"}}, "applications": { script: { "type": "external", diff --git a/test/unit/applications/lang/java.py b/test/unit/applications/lang/java.py index c8936274..b6382cfe 100644 --- a/test/unit/applications/lang/java.py +++ b/test/unit/applications/lang/java.py @@ -12,10 +12,10 @@ class TestApplicationJava(TestApplicationProto): application_type = "java" def prepare_env(self, script): - app_path = option.temp_dir + '/java' - web_inf_path = app_path + '/WEB-INF/' - classes_path = web_inf_path + 'classes/' - script_path = option.test_dir + '/java/' + script + '/' + app_path = f'{option.temp_dir}/java' + web_inf_path = f'{app_path}/WEB-INF/' + classes_path = f'{web_inf_path}classes/' + script_path = f'{option.test_dir}/java/{script}/' if not os.path.isdir(app_path): os.makedirs(app_path) @@ -23,7 +23,7 @@ class TestApplicationJava(TestApplicationProto): src = [] for f in os.listdir(script_path): - file_path = script_path + f + file_path = f'{script_path}{f}' if f.endswith('.java'): src.append(file_path) @@ -36,7 +36,7 @@ class TestApplicationJava(TestApplicationProto): if f == 'WEB-INF': continue - shutil.copytree(file_path, app_path + '/' + f) + shutil.copytree(file_path, f'{app_path}/{f}') continue if f == 'web.xml': @@ -52,11 +52,11 @@ class TestApplicationJava(TestApplicationProto): os.makedirs(classes_path) classpath = ( - option.current_dir + '/build/tomcat-servlet-api-9.0.70.jar' + f'{option.current_dir}/build/tomcat-servlet-api-9.0.70.jar' ) ws_jars = glob.glob( - option.current_dir + '/build/websocket-api-java-*.jar' + f'{option.current_dir}/build/websocket-api-java*.jar' ) if not ws_jars: @@ -74,12 +74,12 @@ class TestApplicationJava(TestApplicationProto): '-d', classes_path, '-classpath', - classpath + ':' + ws_jars[0], + f'{classpath}:{ws_jars[0]}', ] javac.extend(src) if option.detailed: - print("\n$ " + " ".join(javac)) + print(f'\n$ {" ".join(javac)}') try: subprocess.check_output(javac, stderr=subprocess.STDOUT) @@ -88,26 +88,24 @@ class TestApplicationJava(TestApplicationProto): raise except subprocess.CalledProcessError: - pytest.fail('Can\'t run javac process.') + pytest.fail("Can't run javac process.") def load(self, script, **kwargs): self.prepare_env(script) + script_path = f'{option.test_dir}/java/{script}/' self._load_conf( { - "listeners": {"*:7080": {"pass": "applications/" + script}}, + "listeners": {"*:7080": {"pass": f"applications/{script}"}}, "applications": { script: { - "unit_jars": option.current_dir + '/build', + "unit_jars": f'{option.current_dir}/build', "type": self.get_application_type(), "processes": {"spare": 0}, - "working_directory": option.test_dir - + '/java/' - + script - + '/', - "webapp": option.temp_dir + '/java', + "working_directory": script_path, + "webapp": f'{option.temp_dir}/java', } }, }, - **kwargs + **kwargs, ) diff --git a/test/unit/applications/lang/node.py b/test/unit/applications/lang/node.py index 5d05c70c..87d5a19c 100644 --- a/test/unit/applications/lang/node.py +++ b/test/unit/applications/lang/node.py @@ -13,16 +13,16 @@ class TestApplicationNode(TestApplicationProto): def prepare_env(self, script): # copy application shutil.copytree( - option.test_dir + '/node/' + script, option.temp_dir + '/node' + f'{option.test_dir}/node/{script}', f'{option.temp_dir}/node' ) # copy modules shutil.copytree( - option.current_dir + '/node/node_modules', - option.temp_dir + '/node/node_modules', + f'{option.current_dir}/node/node_modules', + f'{option.temp_dir}/node/node_modules', ) - public_dir(option.temp_dir + '/node') + public_dir(f'{option.temp_dir}/node') def load(self, script, name='app.js', **kwargs): self.prepare_env(script) @@ -43,17 +43,17 @@ class TestApplicationNode(TestApplicationProto): self._load_conf( { "listeners": { - "*:7080": {"pass": "applications/" + quote(script, '')} + "*:7080": {"pass": f"applications/{quote(script, '')}"} }, "applications": { script: { "type": "external", "processes": {"spare": 0}, - "working_directory": option.temp_dir + '/node', + "working_directory": f'{option.temp_dir}/node', "executable": '/usr/bin/env', "arguments": arguments, } }, }, - **kwargs + **kwargs, ) diff --git a/test/unit/applications/lang/perl.py b/test/unit/applications/lang/perl.py index 58b867f0..19852363 100644 --- a/test/unit/applications/lang/perl.py +++ b/test/unit/applications/lang/perl.py @@ -6,19 +6,19 @@ class TestApplicationPerl(TestApplicationProto): application_type = "perl" def load(self, script, name='psgi.pl', **kwargs): - script_path = option.test_dir + '/perl/' + script + script_path = f'{option.test_dir}/perl/{script}' self._load_conf( { - "listeners": {"*:7080": {"pass": "applications/" + script}}, + "listeners": {"*:7080": {"pass": f"applications/{script}"}}, "applications": { script: { "type": self.get_application_type(), "processes": {"spare": 0}, "working_directory": script_path, - "script": script_path + '/' + name, + "script": f'{script_path}/{name}', } }, }, - **kwargs + **kwargs, ) diff --git a/test/unit/applications/lang/php.py b/test/unit/applications/lang/php.py index 5319d2ca..1b94c3ae 100644 --- a/test/unit/applications/lang/php.py +++ b/test/unit/applications/lang/php.py @@ -9,18 +9,18 @@ class TestApplicationPHP(TestApplicationProto): application_type = "php" def load(self, script, index='index.php', **kwargs): - script_path = option.test_dir + '/php/' + script + script_path = f'{option.test_dir}/php/{script}' if kwargs.get('isolation') and kwargs['isolation'].get('rootfs'): rootfs = kwargs['isolation']['rootfs'] - if not os.path.exists(rootfs + '/app/php/'): - os.makedirs(rootfs + '/app/php/') + if not os.path.exists(f'{rootfs}/app/php/'): + os.makedirs(f'{rootfs}/app/php/') - if not os.path.exists(rootfs + '/app/php/' + script): - shutil.copytree(script_path, rootfs + '/app/php/' + script) + if not os.path.exists(f'{rootfs}/app/php/{script}'): + shutil.copytree(script_path, f'{rootfs}/app/php/{script}') - script_path = '/app/php/' + script + script_path = f'/app/php/{script}' app = { "type": self.get_application_type(), @@ -41,8 +41,8 @@ class TestApplicationPHP(TestApplicationProto): self._load_conf( { - "listeners": {"*:7080": {"pass": "applications/" + script}}, + "listeners": {"*:7080": {"pass": f"applications/{script}"}}, "applications": {script: app}, }, - **kwargs + **kwargs, ) diff --git a/test/unit/applications/lang/python.py b/test/unit/applications/lang/python.py index 3768cf07..0bb69992 100644 --- a/test/unit/applications/lang/python.py +++ b/test/unit/applications/lang/python.py @@ -20,18 +20,18 @@ class TestApplicationPython(TestApplicationProto): if script[0] == '/': script_path = script else: - script_path = option.test_dir + '/python/' + script + script_path = f'{option.test_dir}/python/{script}' if kwargs.get('isolation') and kwargs['isolation'].get('rootfs'): rootfs = kwargs['isolation']['rootfs'] - if not os.path.exists(rootfs + '/app/python/'): - os.makedirs(rootfs + '/app/python/') + if not os.path.exists(f'{rootfs}/app/python/'): + os.makedirs(f'{rootfs}/app/python/') - if not os.path.exists(rootfs + '/app/python/' + name): - shutil.copytree(script_path, rootfs + '/app/python/' + name) + if not os.path.exists(f'{rootfs}/app/python/{name}'): + shutil.copytree(script_path, f'{rootfs}/app/python/{name}') - script_path = '/app/python/' + name + script_path = f'/app/python/{name}' app = { "type": self.get_application_type(), @@ -58,9 +58,9 @@ class TestApplicationPython(TestApplicationProto): self._load_conf( { "listeners": { - "*:7080": {"pass": "applications/" + quote(name, '')} + "*:7080": {"pass": f"applications/{quote(name, '')}"} }, "applications": {name: app}, }, - **kwargs + **kwargs, ) diff --git a/test/unit/applications/lang/ruby.py b/test/unit/applications/lang/ruby.py index 824bfe7f..e0712fc6 100644 --- a/test/unit/applications/lang/ruby.py +++ b/test/unit/applications/lang/ruby.py @@ -10,22 +10,22 @@ class TestApplicationRuby(TestApplicationProto): def prepare_env(self, script): shutil.copytree( - option.test_dir + '/ruby/' + script, - option.temp_dir + '/ruby/' + script, + f'{option.test_dir}/ruby/{script}', + f'{option.temp_dir}/ruby/{script}', ) - public_dir(option.temp_dir + '/ruby/' + script) + public_dir(f'{option.temp_dir}/ruby/{script}') def load(self, script, name='config.ru', **kwargs): self.prepare_env(script) - script_path = option.temp_dir + '/ruby/' + script + script_path = f'{option.temp_dir}/ruby/{script}' app = { "type": self.get_application_type(), "processes": {"spare": 0}, "working_directory": script_path, - "script": script_path + '/' + name, + "script": f'{script_path}/{name}', } for key in [ @@ -36,8 +36,8 @@ class TestApplicationRuby(TestApplicationProto): self._load_conf( { - "listeners": {"*:7080": {"pass": "applications/" + script}}, + "listeners": {"*:7080": {"pass": f"applications/{script}"}}, "applications": {script: app}, }, - **kwargs + **kwargs, ) diff --git a/test/unit/applications/tls.py b/test/unit/applications/tls.py index 93400328..e5813312 100644 --- a/test/unit/applications/tls.py +++ b/test/unit/applications/tls.py @@ -22,13 +22,13 @@ class TestApplicationTLS(TestApplicationProto): '-x509', '-new', '-subj', - '/CN=' + name + '/', + f'/CN={name}/', '-config', - option.temp_dir + '/openssl.conf', + f'{option.temp_dir}/openssl.conf', '-out', - option.temp_dir + '/' + name + '.crt', + f'{option.temp_dir}/{name}.crt', '-keyout', - option.temp_dir + '/' + name + '.key', + f'{option.temp_dir}/{name}.key', ], stderr=subprocess.STDOUT, ) @@ -40,11 +40,11 @@ class TestApplicationTLS(TestApplicationProto): if key is None: key = crt - key_path = option.temp_dir + '/' + key + '.key' - crt_path = option.temp_dir + '/' + crt + '.crt' + key_path = f'{option.temp_dir}/{key}.key' + crt_path = f'{option.temp_dir}/{crt}.crt' with open(key_path, 'rb') as k, open(crt_path, 'rb') as c: - return self.conf(k.read() + c.read(), '/certificates/' + crt) + return self.conf(k.read() + c.read(), f'/certificates/{crt}') def get_ssl(self, **kwargs): return self.get(wrapper=self.context.wrap_socket, **kwargs) @@ -52,54 +52,50 @@ class TestApplicationTLS(TestApplicationProto): def post_ssl(self, **kwargs): return self.post(wrapper=self.context.wrap_socket, **kwargs) - def openssl_conf(self, rewrite=False, alt_names=[]): - conf_path = option.temp_dir + '/openssl.conf' + def openssl_conf(self, rewrite=False, alt_names=None): + alt_names = alt_names or [] + conf_path = f'{option.temp_dir}/openssl.conf' if not rewrite and os.path.exists(conf_path): return # Generates alt_names section with dns names - a_names = "[alt_names]\n" + a_names = '[alt_names]\n' for i, k in enumerate(alt_names, 1): k = k.split('|') if k[0] == 'IP': - a_names += "IP.%d = %s\n" % (i, k[1]) + a_names += f'IP.{i} = {k[1]}\n' else: - a_names += "DNS.%d = %s\n" % (i, k[0]) + a_names += f'DNS.{i} = {k[0]}\n' # Generates section for sign request extension - a_sec = """req_extensions = myca_req_extensions + a_sec = f'''req_extensions = myca_req_extensions [ myca_req_extensions ] subjectAltName = @alt_names -{a_names}""".format( - a_names=a_names - ) +{a_names}''' with open(conf_path, 'w') as f: f.write( - """[ req ] + f'''[ req ] default_bits = 2048 encrypt_key = no distinguished_name = req_distinguished_name -{a_sec} -[ req_distinguished_name ]""".format( - a_sec=a_sec if alt_names else "" - ) +{a_sec if alt_names else ""} +[ req_distinguished_name ]''' ) def load(self, script, name=None): if name is None: name = script - script_path = option.test_dir + '/python/' + script - + script_path = f'{option.test_dir}/python/{script}' self._load_conf( { - "listeners": {"*:7080": {"pass": "applications/" + name}}, + "listeners": {"*:7080": {"pass": f"applications/{name}"}}, "applications": { name: { "type": "python", diff --git a/test/unit/applications/websockets.py b/test/unit/applications/websockets.py index 15f212ff..a4b9287d 100644 --- a/test/unit/applications/websockets.py +++ b/test/unit/applications/websockets.py @@ -52,7 +52,7 @@ class TestApplicationWebsocket(TestApplicationProto): while True: rlist = select.select([sock], [], [], 60)[0] if not rlist: - pytest.fail('Can\'t read response from server.') + pytest.fail("Can't read response from server.") resp += sock.recv(4096).decode() @@ -77,7 +77,7 @@ class TestApplicationWebsocket(TestApplicationProto): # For all current cases if the "read_timeout" was changed # than test do not expect to get a response from server. if read_timeout == 60: - pytest.fail('Can\'t read response from server.') + pytest.fail("Can't read response from server.") break data += sock.recv(bytes - len(data)) diff --git a/test/unit/check/chroot.py b/test/unit/check/chroot.py index 40b75058..1b7aae90 100644 --- a/test/unit/check/chroot.py +++ b/test/unit/check/chroot.py @@ -12,7 +12,7 @@ def check_chroot(): resp = http.put( url='/config', sock_type='unix', - addr=option.temp_dir + '/control.unit.sock', + addr=f'{option.temp_dir}/control.unit.sock', body=json.dumps( { "listeners": {"*:7080": {"pass": "routes"}}, diff --git a/test/unit/check/isolation.py b/test/unit/check/isolation.py index 9bd835a3..4ebce893 100644 --- a/test/unit/check/isolation.py +++ b/test/unit/check/isolation.py @@ -27,8 +27,8 @@ def check_isolation(): "empty": { "type": "external", "processes": {"spare": 0}, - "working_directory": option.test_dir + "/go/empty", - "executable": option.temp_dir + "/go/app", + "working_directory": f"{option.test_dir}/go/empty", + "executable": f"{option.test_dir}/go/app", "isolation": {"namespaces": {"credential": True}}, }, }, @@ -41,8 +41,8 @@ def check_isolation(): "empty": { "type": "python", "processes": {"spare": 0}, - "path": option.test_dir + "/python/empty", - "working_directory": option.test_dir + "/python/empty", + "path": f"{option.test_dir}/python/empty", + "working_directory": f"{option.test_dir}/python/empty", "module": "wsgi", "isolation": {"namespaces": {"credential": True}}, } @@ -56,8 +56,8 @@ def check_isolation(): "phpinfo": { "type": "php", "processes": {"spare": 0}, - "root": option.test_dir + "/php/phpinfo", - "working_directory": option.test_dir + "/php/phpinfo", + "root": f"{option.test_dir}/php/phpinfo", + "working_directory": f"{option.test_dir}/php/phpinfo", "index": "index.php", "isolation": {"namespaces": {"credential": True}}, } @@ -73,8 +73,8 @@ def check_isolation(): "empty": { "type": "ruby", "processes": {"spare": 0}, - "working_directory": option.temp_dir + "/ruby/empty", - "script": option.temp_dir + "/ruby/empty/config.ru", + "working_directory": f"{option.temp_dir}/ruby/empty", + "script": f"{option.temp_dir}/ruby/empty/config.ru", "isolation": {"namespaces": {"credential": True}}, } }, @@ -87,11 +87,11 @@ def check_isolation(): "listeners": {"*:7080": {"pass": "applications/empty"}}, "applications": { "empty": { - "unit_jars": option.current_dir + "/build", + "unit_jars": f"{option.current_dir}/build", "type": "java", "processes": {"spare": 0}, - "working_directory": option.test_dir + "/java/empty/", - "webapp": option.temp_dir + "/java", + "working_directory": f"{option.temp_dir}/java/empty/", + "webapp": f"{option.temp_dir}/java", "isolation": {"namespaces": {"credential": True}}, } }, @@ -106,7 +106,7 @@ def check_isolation(): "basic": { "type": "external", "processes": {"spare": 0}, - "working_directory": option.temp_dir + "/node", + "working_directory": f"{option.temp_dir}/node", "executable": "app.js", "isolation": {"namespaces": {"credential": True}}, } @@ -120,8 +120,8 @@ def check_isolation(): "body_empty": { "type": "perl", "processes": {"spare": 0}, - "working_directory": option.test_dir + "/perl/body_empty", - "script": option.test_dir + "/perl/body_empty/psgi.pl", + "working_directory": f"{option.test_dir}/perl/body_empty", + "script": f"{option.test_dir}/perl/body_empty/psgi.pl", "isolation": {"namespaces": {"credential": True}}, } }, @@ -133,7 +133,7 @@ def check_isolation(): resp = http.put( url='/config', sock_type='unix', - addr=option.temp_dir + '/control.unit.sock', + addr=f'{option.temp_dir}/control.unit.sock', body=json.dumps(conf), ) diff --git a/test/unit/check/node.py b/test/unit/check/node.py index e053a749..dd59e7a4 100644 --- a/test/unit/check/node.py +++ b/test/unit/check/node.py @@ -3,7 +3,7 @@ import subprocess def check_node(current_dir): - if not os.path.exists(current_dir + '/node/node_modules'): + if not os.path.exists(f'{current_dir}/node/node_modules'): return None try: diff --git a/test/unit/check/unix_abstract.py b/test/unit/check/unix_abstract.py index 5d1f629e..aadde43a 100644 --- a/test/unit/check/unix_abstract.py +++ b/test/unit/check/unix_abstract.py @@ -12,7 +12,7 @@ def check_unix_abstract(): resp = http.put( url='/config', sock_type='unix', - addr=option.temp_dir + '/control.unit.sock', + addr=f'{option.temp_dir}/control.unit.sock', body=json.dumps( { "listeners": {"unix:@sock": {"pass": "routes"}}, diff --git a/test/unit/control.py b/test/unit/control.py index 99436ca0..61b6edf4 100644 --- a/test/unit/control.py +++ b/test/unit/control.py @@ -21,7 +21,7 @@ def args_handler(conf_func): url = args[1] if len(args) == 2 else url_default - url = url if url.startswith('/') else url_default + '/' + url + url = url if url.startswith('/') else f'{url_default}/{url}' arguments = (self, url) if conf is None else (self, conf, url) return json.loads(conf_func(*arguments)) @@ -50,7 +50,7 @@ class TestControl(TestHTTP): args = { 'url': url, 'sock_type': 'unix', - 'addr': option.temp_dir + '/control.unit.sock', + 'addr': f'{option.temp_dir}/control.unit.sock', } if conf is not None: diff --git a/test/unit/http.py b/test/unit/http.py index c48a720f..6a267e26 100644 --- a/test/unit/http.py +++ b/test/unit/http.py @@ -53,13 +53,13 @@ class TestHTTP: sock.connect(connect_args) except (ConnectionRefusedError, FileNotFoundError): sock.close() - pytest.fail('Client can\'t connect to the server.') + pytest.fail("Client can't connect to the server.") else: sock = kwargs['sock'] if 'raw' not in kwargs: - req = ' '.join([start_str, url, http]) + crlf + req = f'{start_str} {url} {http}{crlf}' if body != b'': if isinstance(body, str): @@ -75,10 +75,10 @@ class TestHTTP: for header, value in headers.items(): if isinstance(value, list): for v in value: - req += header + ': ' + str(v) + crlf + req += f'{header}: {v}{crlf}' else: - req += header + ': ' + str(value) + crlf + req += f'{header}: {value}{crlf}' req = (req + crlf).encode() + body @@ -151,12 +151,12 @@ class TestHTTP: len_log = len(log) if len_log > limit: log = log[:limit] - appendix = '(...logged %s of %s bytes)' % (limit, len_log) + appendix = f'(...logged {limit} of {len_log} bytes)' if isinstance(log, bytes): appendix = appendix.encode() - log = log + appendix + log = f'{log}{appendix}' return log @@ -188,7 +188,7 @@ class TestHTTP: # For all current cases if the "read_timeout" was changed # than test do not expect to get a response from server. if timeout == timeout_default: - pytest.fail('Can\'t read response from server.') + pytest.fail("Can't read response from server.") break try: @@ -263,7 +263,7 @@ class TestHTTP: size = int(chunks.pop(0), 16) except ValueError: - pytest.fail('Invalid chunk size %s' % str(size)) + pytest.fail(f'Invalid chunk size {size}') if size == 0: assert len(chunks) == 1, 'last zero size' @@ -310,7 +310,7 @@ class TestHTTP: def form_url_encode(self, fields): data = "&".join( - "%s=%s" % (name, value) for name, value in fields.items() + f'{name}={value}' for name, value in fields.items() ).encode() return data, 'application/x-www-form-urlencoded' @@ -341,21 +341,21 @@ class TestHTTP: else: pytest.fail('multipart requires a string or stream data') - body += ("--%s\r\nContent-Disposition: form-data; name=\"%s\"") % ( - boundary, - field, + body += ( + f'--{boundary}\r\nContent-Disposition: form-data;' + f'name="{field}"' ) if filename != '': - body += "; filename=\"%s\"" % filename + body += f'; filename="{filename}"' - body += "\r\n" + body += '\r\n' if datatype != '': - body += "Content-Type: %s\r\n" % datatype + body += f'Content-Type: {datatype}\r\n' - body += "\r\n%s\r\n" % data + body += f'\r\n{data}\r\n' - body += "--%s--\r\n" % boundary + body += f'--{boundary}--\r\n' - return body.encode(), "multipart/form-data; boundary=%s" % boundary + return body.encode(), f'multipart/form-data; boundary={boundary}' diff --git a/test/unit/log.py b/test/unit/log.py index 7263443d..f984d7a1 100644 --- a/test/unit/log.py +++ b/test/unit/log.py @@ -20,4 +20,4 @@ class Log: Log.pos[name] = pos def get_path(name=UNIT_LOG): - return Log.temp_dir + '/' + name + return f'{Log.temp_dir}/{name}' diff --git a/test/unit/utils.py b/test/unit/utils.py index d6590b97..985801e2 100644 --- a/test/unit/utils.py +++ b/test/unit/utils.py @@ -69,7 +69,7 @@ def waitforsocket(port): except KeyboardInterrupt: raise - pytest.fail('Can\'t connect to the 127.0.0.1:' + str(port)) + pytest.fail(f"Can't connect to the 127.0.0.1:{port}") def check_findmnt(): @@ -125,7 +125,7 @@ def getns(nstype): # read namespace id from symlink file: # it points to: '<nstype>:[<ns id>]' # # eg.: 'pid:[4026531836]' - nspath = '/proc/self/ns/' + nstype + nspath = f'/proc/self/ns/{nstype}' data = None if os.path.exists(nspath): |