Initial Commit
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env python3
|
||||
"""The agent and its supervisor must mean the same thing by "here".
|
||||
|
||||
python3 tests/test_vm_working_directory.py
|
||||
|
||||
WHY
|
||||
|
||||
A Windows session was asked to write a PowerShell script, test it, and
|
||||
keep it. It did all three, perfectly, and the session was reported as a
|
||||
failure.
|
||||
|
||||
The agent's `run` inherited whatever directory the guest agent happened to
|
||||
start in - on Windows, `C:\\Windows\\system32`. So `Set-Content
|
||||
Get-SystemInfo.ps1`, `Get-Content .\\Get-SystemInfo.ps1` and
|
||||
`powershell .\\Get-SystemInfo.ps1` all agreed with each other and all
|
||||
passed. The supervisor then re-ran the verification from the PROJECT
|
||||
folder, because that is the only place work survives, and found nothing
|
||||
there. The model read the failure, worked out what had happened, and spent
|
||||
a second whole session redoing it - roughly four minutes of machine time
|
||||
to move a file.
|
||||
|
||||
Two rules come out of that, and this file holds both:
|
||||
|
||||
1. There is ONE definition of where a command runs, and both sides call
|
||||
it. Two copies of this logic is exactly how they came to disagree.
|
||||
2. It is the project folder, because that is the only thing that
|
||||
outlives the machine. A file written anywhere else is deleted with
|
||||
the disk.
|
||||
"""
|
||||
|
||||
import ast
|
||||
import os
|
||||
import sys
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
VMD = os.path.join(HERE, "..", "vm", "vmd")
|
||||
sys.path.insert(0, VMD)
|
||||
|
||||
FAILS: list[str] = []
|
||||
|
||||
|
||||
def check(label: str, condition: bool, detail: str = "") -> None:
|
||||
if condition:
|
||||
print(f"ok {label}")
|
||||
else:
|
||||
FAILS.append(label)
|
||||
print(f"FAIL {label}\n {detail}")
|
||||
|
||||
|
||||
import verify # noqa: E402
|
||||
|
||||
|
||||
class FakeSession:
|
||||
def __init__(self, os_name, share):
|
||||
self.os_name = os_name
|
||||
self.share = share
|
||||
|
||||
|
||||
# --- the prelude itself --------------------------------------------------
|
||||
linux = verify.working_directory_prelude(FakeSession("ubuntu", "/Pool/vmprojects/x"))
|
||||
windows = verify.working_directory_prelude(FakeSession("windows", "/Pool/vmprojects/x"))
|
||||
|
||||
check("a Linux command starts in the project folder", "/mnt/project" in linux, linux)
|
||||
check("a Windows command starts in the project folder", "Z:\\" in windows, windows)
|
||||
check("the Windows prelude is PowerShell, not shell",
|
||||
"Set-Location" in windows and "||" not in windows,
|
||||
"PowerShell has no ||; this exact mistake reported correct work as a claim")
|
||||
check("the Linux prelude is shell", "cd " in linux)
|
||||
check("neither prelude can fail the command it prefixes",
|
||||
"SilentlyContinue" in windows and "2>/dev/null" in linux,
|
||||
"a missing share must not turn every command into an error")
|
||||
|
||||
# With no project folder there is nowhere to keep anything, but a command
|
||||
# still has to run somewhere predictable.
|
||||
check("a session with no project folder still lands somewhere definite",
|
||||
"C:\\" in verify.working_directory_prelude(FakeSession("windows", None))
|
||||
and "/root" in verify.working_directory_prelude(FakeSession("ubuntu", None)))
|
||||
|
||||
# --- and both sides use it -----------------------------------------------
|
||||
vmd_src = open(os.path.join(VMD, "vmd.py"), encoding="utf-8").read()
|
||||
verify_src = open(os.path.join(VMD, "verify.py"), encoding="utf-8").read()
|
||||
|
||||
tree = ast.parse(vmd_src)
|
||||
run_verb = next(n for n in ast.walk(tree)
|
||||
if isinstance(n, ast.FunctionDef) and n.name == "v_run")
|
||||
run_src = ast.get_source_segment(vmd_src, run_verb) or ""
|
||||
check("the agent's own run is given the prelude",
|
||||
"working_directory_prelude" in run_src,
|
||||
"this is the half that was missing, and it cost a whole extra session")
|
||||
check("the supervisor's re-run is given the same prelude",
|
||||
"working_directory_prelude" in verify_src)
|
||||
|
||||
# One definition, not two. The duplicate is how they drifted apart.
|
||||
check("the directory is decided in exactly one place",
|
||||
verify_src.count('Set-Location -LiteralPath') == 1
|
||||
and vmd_src.count("Set-Location") == 0,
|
||||
"a second copy is how the agent and the supervisor came to disagree")
|
||||
|
||||
print()
|
||||
if FAILS:
|
||||
print(f"FAILED {len(FAILS)}")
|
||||
raise SystemExit(1)
|
||||
print("the agent and its supervisor start in the same place, and it is the one that survives")
|
||||
Reference in New Issue
Block a user