mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
Second, deeper pass over tools/gateway/hermes_cli plus first pass over the trees wave 1 missed (acp, acp_adapter, skills, computer_use, docker, dashboard, conformance, monitoring, secret_sources, hermes_state, providers). Same rubric as wave 1 (AGENTS.md test policy); security, alternation/caching invariants, issue-number regressions, and E2E kept. Real test-quality fixes found and rooted out along the way: - tests/tools/test_command_guards.py made real auxiliary-LLM HTTPS calls (DEFAULT_CONFIG smart-approval leaked in) — pinned approval mode=manual via autouse fixture: 17.4s → 0.4s. - test_model_switch_custom_providers.py / test_user_providers_model_switch.py silently probed live provider catalogs (~2s/test) — stubbed cached_provider_model_ids/provider_model_ids/fetch_api_models. - test_telegram_noise_filter.py: 15-platform copy-paste matrix over shared gateway.run logic → 3 representative platforms (55s → 3.9s). - test_gateway_shutdown.py: stop()'s 5s interrupt-deadline loop spun on MagicMock agents — interrupt.side_effect now clears _running_agents (22s → 1.0s). - test_gateway_inactivity_timeout.py poll-harness timings shrunk 3-5x (24s → 1.1s); test_mcp_stability.py backoff/SIGTERM-grace sleeps patched (15.4s → 2.5s); test_async_delegation.py negative-drain wait 5s → 0.5s. - test_telegram_init_deadline.py: loop-block margin restored to 1.0s with rationale comment — the watchdog-dump assertion needs the loop blocked well past deadline+grace under parallel load (flaked once in the 40-worker verification run at a 0.2s margin). Verification: full hermetic suite via scripts/run_tests.sh — 2,438 files, 21,718 tests passed, 0 failed, 293.9s wall. Suite totals vs original baseline: 46,820 → 19,757 test functions (−57.8%), wall 583.5s → 293.9s (−50%), subprocess CPU 13,564s → 11,623s.
150 lines
4.5 KiB
Python
150 lines
4.5 KiB
Python
"""Tests for optional-skills/web-development/cloudflare-temporary-deploy/scripts/parse_deploy_output.py"""
|
|
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
|
|
SCRIPTS_DIR = (
|
|
Path(__file__).resolve().parents[2]
|
|
/ "optional-skills"
|
|
/ "web-development"
|
|
/ "cloudflare-temporary-deploy"
|
|
/ "scripts"
|
|
)
|
|
sys.path.insert(0, str(SCRIPTS_DIR))
|
|
|
|
import parse_deploy_output as pdo
|
|
|
|
|
|
CREATED = """\
|
|
Continuing means you accept Cloudflare's Terms of Service and Privacy Policy.
|
|
|
|
Temporary account ready:
|
|
Account: swift-otter (created)
|
|
Claim within: 60 minutes
|
|
Claim URL: https://dash.cloudflare.com/claim-preview?claimToken=TOKEN_AAA
|
|
|
|
Uploaded my-worker
|
|
Deployed my-worker triggers
|
|
https://my-worker.swift-otter.workers.dev
|
|
"""
|
|
|
|
REUSED = """\
|
|
Temporary account ready:
|
|
Account: swift-otter (reused)
|
|
Claim within: 17 minutes
|
|
Claim URL: https://dash.cloudflare.com/claim-preview?claimToken=TOKEN_BBB
|
|
Deployed my-worker triggers
|
|
https://my-worker.swift-otter.workers.dev
|
|
"""
|
|
|
|
NOT_LOGGED_IN = """\
|
|
✘ [ERROR] You are not logged in.
|
|
|
|
To continue without logging in, rerun this command with `--temporary`.
|
|
"""
|
|
|
|
AUTH_PRESENT_ERROR = """\
|
|
✘ [ERROR] The --temporary flag cannot be used while Wrangler is authenticated.
|
|
Run `wrangler logout` first, or remove CLOUDFLARE_API_TOKEN.
|
|
"""
|
|
|
|
|
|
class TestParseCreated:
|
|
def test_live_url(self):
|
|
assert pdo.parse(CREATED)["live_url"] == "https://my-worker.swift-otter.workers.dev"
|
|
|
|
def test_claim_url(self):
|
|
assert (
|
|
pdo.parse(CREATED)["claim_url"]
|
|
== "https://dash.cloudflare.com/claim-preview?claimToken=TOKEN_AAA"
|
|
)
|
|
|
|
def test_account_and_state(self):
|
|
r = pdo.parse(CREATED)
|
|
assert r["account"] == "swift-otter"
|
|
assert r["account_state"] == "created"
|
|
|
|
def test_expiry_and_deployed(self):
|
|
r = pdo.parse(CREATED)
|
|
assert r["expires_minutes"] == 60
|
|
assert r["deployed"] is True
|
|
|
|
|
|
class TestParseReused:
|
|
def test_state_is_reused(self):
|
|
assert pdo.parse(REUSED)["account_state"] == "reused"
|
|
|
|
|
|
|
|
|
|
class TestNoDeploy:
|
|
def test_not_logged_in_has_no_urls(self):
|
|
r = pdo.parse(NOT_LOGGED_IN)
|
|
assert r["live_url"] is None
|
|
assert r["claim_url"] is None
|
|
assert r["account"] is None
|
|
assert r["deployed"] is False
|
|
|
|
def test_auth_present_error_has_no_urls(self):
|
|
r = pdo.parse(AUTH_PRESENT_ERROR)
|
|
assert r["live_url"] is None
|
|
assert r["claim_url"] is None
|
|
assert r["deployed"] is False
|
|
|
|
|
|
class TestRealWorldOutput:
|
|
"""Regression: real wrangler output uses tab-indent + multi-word account names."""
|
|
|
|
REAL = (
|
|
"⛅️ wrangler 4.103.0\n"
|
|
"Continuing means you accept Cloudflare's Terms of Service and Privacy Policy.\n"
|
|
"Solving proof-of-work challenge…\n"
|
|
"Temporary account ready:\n"
|
|
"\tAccount: Serene Temple (created)\n"
|
|
"\tClaim within: 60 minutes\n"
|
|
"\tClaim URL: https://dash.cloudflare.com/claim-preview?claimToken=fxLzyAD-vlTzMQmClpg\n"
|
|
"Total Upload: 0.19 KiB / gzip: 0.16 KiB\n"
|
|
"Uploaded hermes-temp-hello (0.74 sec)\n"
|
|
"Deployed hermes-temp-hello triggers (0.42 sec)\n"
|
|
" https://hermes-temp-hello.serene-temple.workers.dev\n"
|
|
)
|
|
|
|
def test_multiword_account_name(self):
|
|
r = pdo.parse(self.REAL)
|
|
assert r["account"] == "Serene Temple"
|
|
assert r["account_state"] == "created"
|
|
|
|
def test_all_fields_from_real_output(self):
|
|
r = pdo.parse(self.REAL)
|
|
assert r["live_url"] == "https://hermes-temp-hello.serene-temple.workers.dev"
|
|
assert r["claim_url"].endswith("claimToken=fxLzyAD-vlTzMQmClpg")
|
|
assert r["expires_minutes"] == 60
|
|
assert r["deployed"] is True
|
|
|
|
|
|
class TestUrlHygiene:
|
|
def test_trailing_punctuation_stripped(self):
|
|
text = "Deployed\n see https://w.acct.workers.dev. for details"
|
|
assert pdo.parse(text)["live_url"] == "https://w.acct.workers.dev"
|
|
|
|
|
|
|
|
class TestCli:
|
|
def test_selftest_exits_zero(self):
|
|
assert pdo.main(["--selftest"]) == 0
|
|
|
|
def test_main_prints_json_and_exit_zero_on_live(self, capsys):
|
|
with mock.patch.object(sys.stdin, "read", return_value=CREATED):
|
|
rc = pdo.main([])
|
|
out = json.loads(capsys.readouterr().out)
|
|
assert rc == 0
|
|
assert out["live_url"] == "https://my-worker.swift-otter.workers.dev"
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(pytest.main([__file__, "-q"]))
|