hop3-testing 0.5.0.dev1__tar.gz → 0.5.0.dev3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/PKG-INFO +1 -1
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/pyproject.toml +1 -1
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/apps/deployment.py +9 -49
- hop3_testing-0.5.0.dev3/src/hop3_testing/bundle.py +691 -0
- hop3_testing-0.5.0.dev3/src/hop3_testing/bundle_ids.py +64 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/catalog/loader.py +66 -2
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/catalog/models.py +9 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/catalog/scanner.py +28 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/cli/commands/__init__.py +3 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/cli/commands/cloud.py +18 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/cli/commands/test.py +11 -1
- hop3_testing-0.5.0.dev3/src/hop3_testing/cli/commands/why.py +60 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/cli/runners.py +40 -6
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/results/__init__.py +10 -1
- hop3_testing-0.5.0.dev3/src/hop3_testing/results/compression.py +31 -0
- hop3_testing-0.5.0.dev3/src/hop3_testing/results/models.py +298 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/results/reporters.py +138 -20
- hop3_testing-0.5.0.dev3/src/hop3_testing/results/store.py +498 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/runners/base.py +8 -1
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/runners/demo.py +74 -71
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/runners/deployment.py +39 -12
- hop3_testing-0.5.0.dev3/src/hop3_testing/runtime_diagnostics.py +143 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/system_tests/config.py +23 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/system_tests/hetzner_cli.py +15 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/system_tests/orchestrator.py +6 -3
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/system_tests/runner.py +1 -1
- hop3_testing-0.5.0.dev3/src/hop3_testing/targets/adapter.py +53 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/targets/constants.py +16 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/targets/docker.py +9 -3
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/targets/helpers.py +24 -5
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/targets/remote.py +8 -3
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/util/__init__.py +2 -0
- hop3_testing-0.5.0.dev3/src/hop3_testing/util/timing.py +23 -0
- hop3_testing-0.5.0.dev1/src/hop3_testing/results/models.py +0 -142
- hop3_testing-0.5.0.dev1/src/hop3_testing/results/store.py +0 -136
- hop3_testing-0.5.0.dev1/src/hop3_testing/runtime_diagnostics.py +0 -103
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/README.md +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/__init__.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/apps/__init__.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/apps/catalog.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/apps/debug.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/apps/preparation.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/apps/verification.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/catalog/__init__.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/cli/__init__.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/cli/commands/catalog.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/cli/helpers.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/cli/logging.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/cli/reports.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/diagnostics.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/exceptions.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/runners/__init__.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/runners/tutorial.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/runners/validations.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/selector/__init__.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/selector/modes.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/selector/selector.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/system_tests/__init__.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/system_tests/deployment.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/system_tests/diagnostics.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/system_tests/hetzner.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/system_tests/multi_distro.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/targets/__init__.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/targets/base.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/targets/config.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/util/console.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/util/project.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/util/ssh.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/util/streaming.py +0 -0
- {hop3_testing-0.5.0.dev1 → hop3_testing-0.5.0.dev3}/src/hop3_testing/util/subprocess.py +0 -0
|
@@ -104,6 +104,7 @@ class DeploymentSession:
|
|
|
104
104
|
# Deployment state
|
|
105
105
|
self.deployed = False
|
|
106
106
|
self._last_deploy_error: str | None = None
|
|
107
|
+
self._last_deploy_output: str = ""
|
|
107
108
|
self._app_port: int | None = None
|
|
108
109
|
|
|
109
110
|
# Console setup
|
|
@@ -129,6 +130,11 @@ class DeploymentSession:
|
|
|
129
130
|
"""Get the last deployment error message."""
|
|
130
131
|
return self._last_deploy_error
|
|
131
132
|
|
|
133
|
+
@property
|
|
134
|
+
def last_deploy_output(self) -> str:
|
|
135
|
+
"""Full stdout of the last `hop3 deploy` (kept for every build)."""
|
|
136
|
+
return self._last_deploy_output
|
|
137
|
+
|
|
132
138
|
def _build_cli_env(self) -> dict[str, str]:
|
|
133
139
|
"""Build environment variables for hop3 CLI commands.
|
|
134
140
|
|
|
@@ -277,6 +283,9 @@ class DeploymentSession:
|
|
|
277
283
|
result = run_streaming(cmd, on_output=on_output, env=env, timeout=timeout)
|
|
278
284
|
stdout = result.stdout
|
|
279
285
|
returncode = result.returncode
|
|
286
|
+
# Keep the full deploy output for every build (success or failure), not
|
|
287
|
+
# just a one-line summary — so the per-build logs are actually useful.
|
|
288
|
+
self._last_deploy_output = stdout
|
|
280
289
|
|
|
281
290
|
if result.timed_out:
|
|
282
291
|
mins = timeout // 60
|
|
@@ -454,55 +463,6 @@ class DeploymentSession:
|
|
|
454
463
|
port, path, expected_status, max_retries, result,
|
|
455
464
|
)
|
|
456
465
|
|
|
457
|
-
def _test_http_local(
|
|
458
|
-
self,
|
|
459
|
-
host: str,
|
|
460
|
-
port: int,
|
|
461
|
-
path: str,
|
|
462
|
-
expected_status: int | Iterable[int],
|
|
463
|
-
max_retries: int,
|
|
464
|
-
result: dict[str, Any],
|
|
465
|
-
) -> dict[str, Any]:
|
|
466
|
-
"""Test HTTP by connecting directly from the test client."""
|
|
467
|
-
import httpx # noqa: PLC0415
|
|
468
|
-
|
|
469
|
-
url = f"http://{host}:{port}{path}"
|
|
470
|
-
result["details"]["url"] = url
|
|
471
|
-
|
|
472
|
-
for attempt in range(max_retries):
|
|
473
|
-
try:
|
|
474
|
-
response = httpx.get(url, timeout=5.0, follow_redirects=True)
|
|
475
|
-
result["details"]["status_code"] = response.status_code
|
|
476
|
-
result["details"]["attempts"] = attempt + 1
|
|
477
|
-
result["details"]["body_preview"] = (
|
|
478
|
-
response.text[:4096] if response.text else ""
|
|
479
|
-
)
|
|
480
|
-
|
|
481
|
-
if _status_match(response.status_code, expected_status):
|
|
482
|
-
result["passed"] = True
|
|
483
|
-
result["message"] = f"HTTP {response.status_code} from {url}"
|
|
484
|
-
self.console.success(
|
|
485
|
-
f"HTTP test passed (direct port {port}, status: {response.status_code})"
|
|
486
|
-
)
|
|
487
|
-
return result
|
|
488
|
-
|
|
489
|
-
if response.status_code in {502, 503, 504}:
|
|
490
|
-
time.sleep(1)
|
|
491
|
-
continue
|
|
492
|
-
|
|
493
|
-
result["message"] = (
|
|
494
|
-
f"HTTP {response.status_code} (expected {_format_expected(expected_status)}) from {url}"
|
|
495
|
-
)
|
|
496
|
-
return result
|
|
497
|
-
|
|
498
|
-
except (httpx.HTTPError, httpx.ConnectError) as e:
|
|
499
|
-
result["details"]["last_error"] = str(e)
|
|
500
|
-
self.console.debug(f"Attempt {attempt + 1}/{max_retries}: {e}")
|
|
501
|
-
time.sleep(1)
|
|
502
|
-
|
|
503
|
-
result["message"] = f"HTTP test failed after {max_retries} attempts on {url}"
|
|
504
|
-
return result
|
|
505
|
-
|
|
506
466
|
def _test_http_via_ssh(
|
|
507
467
|
self,
|
|
508
468
|
port: int,
|