~james/scope

ref: cb7f12d3e8eeba75b4f02821fbb85d2741a69beb scope/test/cli.py -rw-r--r-- 3.7 KiB
cb7f12d3 — james ci(build): check ocaml versions and xen guest validation 13 days ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import json
from pathlib import Path
import subprocess
import sys
import tempfile


executable = str(Path(sys.argv[1]).resolve())
checks = 0


def run(*args, status=0, structured=True):
    global checks
    command = [executable, *map(str, args)]
    if structured:
        command.append("--json")
    result = subprocess.run(command, capture_output=True, text=True, timeout=10)
    assert result.returncode == status, (command, result.returncode, result.stdout, result.stderr)
    checks += 1
    if structured:
        value = json.loads(result.stdout if result.stdout else result.stderr)
        assert value["schema"] == "scope.report.v1"
        return value
    return result.stdout


with tempfile.TemporaryDirectory(prefix="scope") as directory:
    root = Path(directory)
    run("demo", root)
    before, after = root / "before", root / "after"
    assert run("info", before)["pages"] == 5
    result = run("walk", before, "0x400abc")
    assert result["result"]["mapping"]["physical"] == "0x0000000000009abc"
    result = run("explain", before, "0x400000", "--access", "write", "--privilege", "supervisor", status=1)
    assert result["result"]["fault"]["level"] == 2
    assert result["result"]["fault"]["error_code"] == 3
    assert len(run("aliases", before, status=1)["aliases"]) == 1
    assert run("aliases", after)["aliases"] == []
    assert len(run("diff", before, after, status=1)["changes"]) == 2
    assert run("diff", before, before)["changes"] == []
    assert len(run("mappings", before, "--start", "0x800000")["regions"]) == 1
    assert run("walk", before, "0x800000000000", status=1)["result"]["fault"]["vector"] == 13
    overridden = run("walk", before, "0x400000", "--root", "0x6000", status=2)
    assert overridden["complete"] is False
    assert overridden["context"]["registers"]["cr3"] == "0x0000000000001000"
    assert overridden["context"]["root"] == "0x0000000000006000"
    run("explain", before, "0x400000", status=64)
    run("walk", before, "0x400000", "--include-ad", status=64)
    run("walk", before, "0x400000", "--root", "0x1000", "--root", "0x2000", status=64)
    run("mappings", before, "--max-entries", "1", status=2)
    run("capture", "0", root / "capture", "--vcpu", "0", "--phys-bits", "48", "--nx", "on", "--gb-pages", "on", status=2)
    run("walk", before, "-1", status=64)
    run("unknown", status=64)
    run("watch", "7", root / "history", "--interval", "nan", status=64)
    run("watch", "7", root / "history", "--retain", "0", status=64)
    run("walk", before, "0x400000", "--count", "2", status=64)
    run("info", root / "missing", status=2)
    text = run("explain", before, "0x400000", "--access", "write", "--privilege", "supervisor", status=1, structured=False)
    assert "level=2" in text and "error=0x3" in text
    damaged = root / "damaged"
    damaged.write_bytes(before.read_bytes()[:-1])
    run("info", damaged, status=2)
    transcript = root / "transcript"
    transcript.write_text("context 0x80010001 0x0 0x1000 0x20 0xd00 0x2 0x0 48 1 1\nmissing 0x1000 permission denied\n")
    run("import", transcript, root / "partial", "--source", 'quote" and newline\n', status=2)
    assert run("walk", root / "partial", "0x0", status=2)["result"]["reason"] == "permission denied"
    partial = run("diff", before, root / "partial", status=2)
    assert all(change["kinds"] == ["incomplete"] for change in partial["changes"])
    page = (0x83).to_bytes(8, "little") + bytes(4088)
    transcript.write_text("context 0x80010001 0x0 0x1000 0x20 0xd00 0x2 0x0 48 1 1\npage 0x1000 " + page.hex() + "\n")
    run("import", transcript, root / "invalid")
    assert run("mappings", root / "invalid", status=1)["regions"][0]["state"]["status"] == "invalid"
    assert run("aliases", root / "invalid", status=1)["aliases"] == []

print(f"{checks} cli checks passed")