From cf3baed5db8d5ae759c5150df3bdc877926d965a Mon Sep 17 00:00:00 2001 From: Zanie Date: Mon, 18 Dec 2023 14:51:08 -0600 Subject: [PATCH] Improve readability; commit tests :) --- tests/__snapshots__/test_index.ambr | 150 ++++++++++++++++++++++++++++ tests/common.py | 18 ++-- tests/test_build.py | 12 ++- tests/test_index.py | 117 ++++++++++++++++++++++ tests/test_publish.py | 2 +- tests/test_scenarios.py | 4 +- 6 files changed, 289 insertions(+), 14 deletions(-) create mode 100644 tests/__snapshots__/test_index.ambr create mode 100644 tests/test_index.py diff --git a/tests/__snapshots__/test_index.ambr b/tests/__snapshots__/test_index.ambr new file mode 100644 index 00000000..f67b0110 --- /dev/null +++ b/tests/__snapshots__/test_index.ambr @@ -0,0 +1,150 @@ +# serializer version: 1 +# name: test_index_down + dict({ + 'exit_code': 0, + 'stderr': ''' + Stopping server with pid [PID]... + Stopped server! + + ''', + 'stdout': '', + }) +# --- +# name: test_index_down_no_server_found + dict({ + 'exit_code': 1, + 'stderr': ''' + No server detected! + + ''', + 'stdout': '', + }) +# --- +# name: test_index_down_server_stopped + dict({ + 'exit_code': 1, + 'stderr': ''' + Server looks shutdown already. + + ''', + 'stdout': '', + }) +# --- +# name: test_index_down_with_storage_path + dict({ + 'exit_code': 0, + 'stderr': ''' + Stopping server with pid [PID]... + Stopped server! + + ''', + 'stdout': '', + }) +# --- +# name: test_index_up_background + dict({ + 'exit_code': 0, + 'stderr': ''' + Storing data at [PWD]/.packse + Initializing server... + Starting server at http://localhost:3141... + Configuring client... + Generating password... + Creating user 'packages'... + Logging in... + Creating package index 'packages/all'... + Index available at http://localhost:3141/packages/all + Running in background with pid [PID] + Stop index server with `packse index down`. + + ''', + 'stdout': ''' + [TIMESTAMP] INFO NOCTX Loading node info from [PWD]/.packse/server/.nodeinfo + [TIMESTAMP] INFO NOCTX wrote nodeinfo to: [PWD]/.packse/server/.nodeinfo + [TIMESTAMP] INFO NOCTX running with role 'standalone' + [TIMESTAMP] WARNI NOCTX No secret file provided, creating a new random secret. Login tokens issued before are invalid. Use --secretfile option to provide a persistent secret. You can create a proper secret with the devpi-gen-secret command. + [TIMESTAMP] INFO NOCTX Found plugin devpi-web-4.2.1. + [TIMESTAMP] INFO NOCTX Using [PWD]/.packse/server/.indices for Whoosh index files. + [TIMESTAMP] INFO [ASYN] Starting asyncio event loop + [TIMESTAMP] INFO [NOTI] [Rtx0] triggering load of initial projectnames for root/pypi + [TIMESTAMP] INFO NOCTX devpi-server version: 6.9.2 + [TIMESTAMP] INFO NOCTX serverdir: [PWD]/.packse/server + [TIMESTAMP] INFO NOCTX uuid: [UUID] + [TIMESTAMP] INFO NOCTX serving at url: http://localhost:3141 (might be http://[localhost]:3141 for IPv6) + [TIMESTAMP] INFO NOCTX using 50 threads + [TIMESTAMP] INFO NOCTX bug tracker: https://github.com/devpi/devpi/issues + [TIMESTAMP] INFO NOCTX Hit Ctrl-C to quit. + [TIMESTAMP] INFO Serving on http://[::1]:3141 + http://localhost:3141/packages/all + + ''', + }) +# --- +# name: test_index_up_foreground + dict({ + 'exit_code': '', + 'stderr': ''' + Storing data at /var/folders/bc/qlsk3t6x7c9fhhbvvcg68k9c0000gp/T/packse-serve-vzr40ky7 + Initializing server... + Starting server at http://localhost:3141... + Configuring client... + Generating password... + Creating user 'packages'... + Logging in... + Creating package index 'packages/all'... + Index available at http://localhost:3141/packages/all + Ready! [Stop with Ctrl-C] + Interrupted! + + ''', + 'stdout': ''' + [TIMESTAMP] INFO NOCTX Loading node info from /var/folders/bc/qlsk3t6x7c9fhhbvvcg68k9c0000gp/T/packse-serve-vzr40ky7/server/.nodeinfo + [TIMESTAMP] INFO NOCTX wrote nodeinfo to: /var/folders/bc/qlsk3t6x7c9fhhbvvcg68k9c0000gp/T/packse-serve-vzr40ky7/server/.nodeinfo + [TIMESTAMP] INFO NOCTX running with role 'standalone' + [TIMESTAMP] WARNI NOCTX No secret file provided, creating a new random secret. Login tokens issued before are invalid. Use --secretfile option to provide a persistent secret. You can create a proper secret with the devpi-gen-secret command. + [TIMESTAMP] INFO NOCTX Found plugin devpi-web-4.2.1. + [TIMESTAMP] INFO NOCTX Using /var/folders/bc/qlsk3t6x7c9fhhbvvcg68k9c0000gp/T/packse-serve-vzr40ky7/server/.indices for Whoosh index files. + [TIMESTAMP] INFO [ASYN] Starting asyncio event loop + [TIMESTAMP] INFO [NOTI] [Rtx0] triggering load of initial projectnames for root/pypi + [TIMESTAMP] INFO NOCTX devpi-server version: 6.9.2 + [TIMESTAMP] INFO NOCTX serverdir: /var/folders/bc/qlsk3t6x7c9fhhbvvcg68k9c0000gp/T/packse-serve-vzr40ky7/server + [TIMESTAMP] INFO NOCTX uuid: [UUID] + [TIMESTAMP] INFO NOCTX serving at url: http://localhost:3141 (might be http://[localhost]:3141 for IPv6) + [TIMESTAMP] INFO NOCTX using 50 threads + [TIMESTAMP] INFO NOCTX bug tracker: https://github.com/devpi/devpi/issues + [TIMESTAMP] INFO NOCTX Hit Ctrl-C to quit. + [TIMESTAMP] INFO Serving on http://[::1]:3141 + [TIMESTAMP] INFO Serving on http://127.0.0.1:3141 + [TIMESTAMP] INFO [req0] GET /+api + [TIMESTAMP] INFO [req1] PUT /packages + [TIMESTAMP] INFO [req1] [Wtx0] setting password for user 'packages' + [TIMESTAMP] INFO [req1] [Wtx0] created user 'packages' with email 'null' + [TIMESTAMP] INFO [req1] [Wtx0] fswriter1: committed at 1 + [TIMESTAMP] INFO [req2] POST /+login + [TIMESTAMP] INFO [req3] PUT /packages/all + [TIMESTAMP] INFO [req3] [Wtx1] created index packages/all: {'acl_upload': [':ANONYMOUS:'], 'bases': ('root/pypi',), 'volatile': False, 'mirror_whitelist': [], 'mirror_whitelist_inheritance': 'intersection', 'acl_toxresult_upload': [':ANONYMOUS:'], 'type': 'stage'} + [TIMESTAMP] INFO [req3] [Wtx1] fswriter2: committed at 2 + [TIMESTAMP] INFO [req4] GET /packages/all + + ''', + }) +# --- +# name: test_index_up_with_storage_path + dict({ + 'exit_code': 0, + 'stderr': ''' + Initializing server... + Starting server at http://localhost:3141... + Configuring client... + Creating package index 'packages/all'... + Index available at http://localhost:3141/packages/all + Running in background with pid [PID] + Stop index server with `packse index down`. + + ''', + 'stdout': ''' + http://localhost:3141/packages/all + + ''', + }) +# --- diff --git a/tests/common.py b/tests/common.py index bfb4bc28..ecb18778 100644 --- a/tests/common.py +++ b/tests/common.py @@ -24,10 +24,10 @@ def snapshot_command( command: list[str], working_directory: Path | None = None, snapshot_filesystem: bool = False, - stderr: bool = True, - stdout: bool = True, + snapshot_stderr: bool = True, + snapshot_stdout: bool = True, extra_filters: list[tuple[str, str]] | None = None, - stop_after: float = None, + interrupt_after: float = None, ) -> dict: # By default, filter out absolute references to the working directory filters = [ @@ -51,22 +51,22 @@ def snapshot_command( env=os.environ, ) try: - result_stdout, result_stderr = process.communicate(timeout=stop_after) + stdout, stderr = process.communicate(timeout=interrupt_after) except subprocess.TimeoutExpired: process.send_signal(signal.SIGINT) - result_stdout, result_stderr = process.communicate() + stdout, stderr = process.communicate() killed = True result = { "exit_code": process.returncode if not killed else "", "stdout": ( - apply_filters(result_stdout.decode(), filters) - if stdout + apply_filters(stdout.decode(), filters) + if snapshot_stdout else "" ), "stderr": ( - apply_filters(result_stderr.decode(), filters) - if stderr + apply_filters(stderr.decode(), filters) + if snapshot_stderr else "" ), } diff --git a/tests/test_build.py b/tests/test_build.py index 59069dd8..3096cf4c 100644 --- a/tests/test_build.py +++ b/tests/test_build.py @@ -26,7 +26,9 @@ def test_build_invalid_target(snapshot, tmpcwd): def test_build_example(snapshot): target = __development_base_path__ / "scenarios" / "example.json" assert ( - snapshot_command(["build", str(target)], snapshot_filesystem=True, stderr=False) + snapshot_command( + ["build", str(target)], snapshot_filesystem=True, snapshot_stderr=False + ) == snapshot ) @@ -37,7 +39,9 @@ def test_build_example_with_seed(snapshot): target = __development_base_path__ / "scenarios" / "example.json" os.environ["PACKSE_VERSION_SEED"] = "foo" assert ( - snapshot_command(["build", str(target)], snapshot_filesystem=True, stderr=False) + snapshot_command( + ["build", str(target)], snapshot_filesystem=True, snapshot_stderr=False + ) == snapshot ) @@ -55,4 +59,6 @@ def test_build_example_already_exists(snapshot): def test_build_example_already_exists_with_rm_flag(snapshot): target = __development_base_path__ / "scenarios" / "example.json" (Path(".") / "build").mkdir() - assert snapshot_command(["build", target, "--rm"], stderr=False) == snapshot + assert ( + snapshot_command(["build", target, "--rm"], snapshot_stderr=False) == snapshot + ) diff --git a/tests/test_index.py b/tests/test_index.py new file mode 100644 index 00000000..32a45081 --- /dev/null +++ b/tests/test_index.py @@ -0,0 +1,117 @@ +import subprocess + +import psutil +import pytest +from packse.index import write_server_pid + +from .common import snapshot_command + +FILTERS = [ + (r"pid \d+", "pid [PID]"), + (r"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d,\d\d\d", "[TIMESTAMP]"), + ("uuid: .*", "uuid: [UUID]"), +] + + +@pytest.fixture(autouse=True) +def check_for_leaked_servers(): + yield + + leak = False + for p in psutil.process_iter(): + try: + if "devpi" in p.name() or "devpi" in " ".join(p.cmdline()): + print("Killing devpi server with pid", p.pid) + p.terminate() + p.wait() + leak = True + except (psutil.AccessDenied, psutil.NoSuchProcess): + pass + + if leak: + raise RuntimeError("Leaked package index server(s)") + + +def test_index_up_background(snapshot, tmpcwd, tmpenviron): + tmpenviron["HOME"] = str(tmpcwd) + + try: + assert ( + snapshot_command( + ["index", "up", "--bg", "-v"], + extra_filters=FILTERS, + ) + == snapshot + ) + finally: + subprocess.call(["packse", "index", "down"]) + + +def test_index_up_foreground(snapshot, tmpcwd, tmpenviron): + tmpenviron["HOME"] = str(tmpcwd) + + assert ( + snapshot_command( + ["index", "up", "-v"], extra_filters=FILTERS, interrupt_after=5 + ) + == snapshot + ) + + +def test_index_down(snapshot, tmpcwd, tmpenviron): + tmpenviron["HOME"] = str(tmpcwd) + subprocess.check_call(["packse", "index", "up", "--bg"]) + assert ( + snapshot_command( + ["index", "down"], + extra_filters=FILTERS, + ) + == snapshot + ) + + +def test_index_up_with_storage_path(snapshot, tmpcwd): + try: + assert ( + snapshot_command( + ["index", "up", "--storage-path", str(tmpcwd), "--bg"], + extra_filters=FILTERS, + ) + == snapshot + ) + finally: + subprocess.call(["packse", "index", "down", "--storage-path", str(tmpcwd)]) + + +def test_index_down_with_storage_path(snapshot, tmpcwd): + subprocess.check_call( + ["packse", "index", "up", "--storage-path", str(tmpcwd), "--bg"] + ) + assert ( + snapshot_command( + ["index", "down", "--storage-path", str(tmpcwd)], + extra_filters=FILTERS, + ) + == snapshot + ) + + +def test_index_down_no_server_found(snapshot, tmpcwd): + assert ( + snapshot_command( + ["index", "down", "--storage-path", str(tmpcwd)], + extra_filters=FILTERS, + ) + == snapshot + ) + + +def test_index_down_server_stopped(snapshot, tmpcwd): + write_server_pid(tmpcwd, 99999) + assert ( + snapshot_command( + ["index", "down", "--storage-path", str(tmpcwd)], + extra_filters=FILTERS, + ) + == snapshot + ) diff --git a/tests/test_publish.py b/tests/test_publish.py index 22071e72..ac81a2aa 100644 --- a/tests/test_publish.py +++ b/tests/test_publish.py @@ -115,7 +115,7 @@ def test_publish_example_twine_succeeds_parallel( ["publish", scenario_dist, "-v"], extra_filters=[(re.escape(str(scenario_dist.resolve())), "[DISTDIR]")], # Cannot record stderr when running in parallel - stderr=False, + snapshot_stderr=False, ) == snapshot ) diff --git a/tests/test_scenarios.py b/tests/test_scenarios.py index 47d1fd8e..858c125d 100644 --- a/tests/test_scenarios.py +++ b/tests/test_scenarios.py @@ -26,7 +26,9 @@ @pytest.mark.usefixtures("tmpcwd") def test_build_all_scenarios(snapshot, target): assert ( - snapshot_command(["build", str(target)], stderr=False, snapshot_filesystem=True) + snapshot_command( + ["build", str(target)], snapshot_stderr=False, snapshot_filesystem=True + ) == snapshot )