fix(work): import hashlib and wire heal subparser into main CLI
This commit is contained in:
@@ -31,6 +31,7 @@ def _load(name, relpath):
|
||||
|
||||
exec_constrained = _load("exec_constrained_approvals",
|
||||
"bin/exec-constrained.py")
|
||||
box_ctl = _load("box_ctl_approvalstest", "bin/box-ctl.py")
|
||||
|
||||
|
||||
def _box_ctl(*args):
|
||||
@@ -39,6 +40,34 @@ def _box_ctl(*args):
|
||||
capture_output=True, text=True, timeout=180)
|
||||
|
||||
|
||||
class _InProcResult:
|
||||
"""Minimal CompletedProcess stand-in (returncode/stdout only)."""
|
||||
|
||||
def __init__(self, returncode, stdout):
|
||||
self.returncode = returncode
|
||||
self.stdout = stdout
|
||||
|
||||
|
||||
def _box_ctl_inproc(*args):
|
||||
"""In-process _box_ctl (same proven pattern as test_box_loop_https).
|
||||
|
||||
Calls the real main(argv) -- identical argv parsing, dispatch, audit,
|
||||
and stdout JSON -- amortizing per-spawn interpreter cost over one
|
||||
import. Node order in fleet scans is nondeterministic either way
|
||||
(concurrent fan-out); per-node content is identical.
|
||||
"""
|
||||
import io
|
||||
from contextlib import redirect_stdout
|
||||
buf = io.StringIO()
|
||||
returncode = 0
|
||||
with redirect_stdout(buf):
|
||||
try:
|
||||
box_ctl.main(["box-ctl.py", *args])
|
||||
except SystemExit as e:
|
||||
returncode = e.code if isinstance(e.code, int) else 1
|
||||
return _InProcResult(returncode, buf.getvalue())
|
||||
|
||||
|
||||
class ExecApprovalOpsTests(unittest.TestCase):
|
||||
def test_ops_registered_and_side_effecting(self):
|
||||
spec = exec_constrained.OPS
|
||||
@@ -155,14 +184,14 @@ class BoxCtlApprovalTests(unittest.TestCase):
|
||||
["approval-allow", "badnode", "--message", "m"],
|
||||
["approval-deny", "badnode", "--message", "m"],
|
||||
["approval-auto", "badnode"]):
|
||||
r = _box_ctl(*args)
|
||||
r = _box_ctl_inproc(*args)
|
||||
self.assertNotEqual(r.returncode, 0, args)
|
||||
self.assertEqual(json.loads(r.stdout)["code"], "BAD_NODE",
|
||||
args)
|
||||
|
||||
def test_rejects_missing_node(self):
|
||||
for args in (["approval-allow"], ["approval-deny"]):
|
||||
r = _box_ctl(*args)
|
||||
r = _box_ctl_inproc(*args)
|
||||
self.assertNotEqual(r.returncode, 0, args)
|
||||
self.assertEqual(json.loads(r.stdout)["code"], "BAD_ARGS",
|
||||
args)
|
||||
@@ -194,7 +223,7 @@ class BoxCtlApprovalTests(unittest.TestCase):
|
||||
(["approval-auto", "a", "b"], False),
|
||||
]
|
||||
for args, valid in cases:
|
||||
r = _box_ctl("quality-validate", *args)
|
||||
r = _box_ctl_inproc("quality-validate", *args)
|
||||
self.assertEqual(json.loads(r.stdout)["valid"], valid, args)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user