-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathtest_build_validation.py
More file actions
115 lines (101 loc) · 3.84 KB
/
test_build_validation.py
File metadata and controls
115 lines (101 loc) · 3.84 KB
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import pytest
import platform
from pathlib import Path
from guppylang import guppy
from guppylang.std.quantum import discard, qubit
from selene_sim.build import build
from selene_sim import Quest
@pytest.mark.xfail(
platform.system() == "Windows",
reason=(
"As Lief doesn't support COFF formats yet, we can't "
"detect undefined symbols in Windows lib files, and "
"thus can't run a strict build on Windows."
),
)
@pytest.mark.parametrize(
"build_config",
[
{"name": "default", "kwargs": {}},
{"name": "llvm_ir", "kwargs": {"build_method": "via-llvm-ir"}},
{"name": "llvm_bc", "kwargs": {"build_method": "via-llvm-bitcode"}},
],
)
def test_strict_builds_guppy(build_config):
"""
Selene sim builds are multi-step processes that
are described by a build graph, with artifacts
as nodes and build steps as edges.
Artifacts have 'kinds' that allow an incoming
artifact (e.g. passed to `selene_sim.build`)
to be matched against in order to establish the
build sequence.
Examples:
- An .ll file that is expected to depend on
specific function signatures.
- A .o file that depends on undefined functions
that we expect to be defined after linking.
By default, we only run artifact kind matching
on the user input - this is because checking can
be intensive (e.g. invoking system utilities to
identify undefined functions in an object file, or
parsing an LLVM file).
If we pass `strict=True` to `build`, then outputs of
steps are also checked against their expected kind.
Here we do that test to ensure that standard builds
and all of their intermediate artifacts conform to
expectations - and, importantly, to ensure that the
checks are working as intended.
"""
@guppy
def main() -> None:
q0 = qubit()
discard(q0)
runner = build(main.compile(), strict=True, **build_config["kwargs"])
got = list(runner.run(Quest(), n_qubits=1))
assert len(got) == 0
# now try mutating intermediates to other types and see how they fair
# when strict mode is on.
for artifact in runner.artifacts.iterdir():
match artifact.suffix:
case ".o":
# read as bytes and build from that
contents = artifact.read_bytes()
build(contents, strict=True)
case ".ll":
# read as string and build from that
contents = artifact.read_text()
build(contents, strict=True)
case ".bc":
# read as bytes and build from that
contents = artifact.read_bytes()
build(contents, strict=True)
@pytest.mark.xfail(
platform.system() == "Windows",
reason=(
"As Lief doesn't support COFF formats yet, we can't "
"detect undefined symbols in Windows lib files, and "
"thus can't run a strict build on Windows."
),
)
def test_strict_builds_qir():
qir_file = Path(__file__).parent / "resources/qir/adaptive_cond_loop.ll"
runner = build(qir_file, strict=True)
got = list(runner.run(Quest(), n_qubits=6))
assert len(got) == 2
# now try mutating intermediates to other types and see how they fair
# when strict mode is on.
for artifact in runner.artifacts.iterdir():
match artifact.suffix:
case ".o":
# read as bytes and build from that
contents = artifact.read_bytes()
build(contents, strict=True)
case ".ll":
# read as string and build from that
contents = artifact.read_text()
build(contents, strict=True)
case ".bc":
# read as bytes and build from that
contents = artifact.read_bytes()
build(contents, strict=True)