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
116
117
118
119
120
121
122
|
#!/usr/bin/env python3
"""
Build arti and rpc client library, and run RPC integration tests.
ENVIRONMENT VARIABLES:
- CARGO: the cargo binary to use. Defaults to "cargo".
- PYTHON3: path to a python binary to use. Defaults to `sys.executable`
- ARTI_RPC_TEST_DIR: A location in which to store arti's state and config.
Defaults to ".arti_rpc_test" at the top level of this git repo.
ARGUMENTS:
- `--arti-dir=DIR`: Override ARTI_RPC_TEST_DIR.
"""
from __future__ import annotations
import argparse
import os
import sys
import subprocess
def parent(path: str, n: int = 1):
"""
Return the parent of (the parent of (... the directory of path)).
The number of "parent of"s is controlled by "n"
"""
for _ in range(n):
path = os.path.split(path)[0]
return path
def cargo_build(packages: list[str], extra_flags: list[str] = []):
"""
Use cargo to build all of the rust packages in `packages`,
passing `extra_flags` on the command line.
"""
args = [
CARGO,
"build",
"--profile",
CARGO_PROFILE,
]
for p in packages:
args.extend(["-p", p])
args.extend(extra_flags)
outcome = subprocess.run(args, cwd=TOPLEVEL)
outcome.check_returncode()
######
# Parse the command line.
parser = argparse.ArgumentParser(
prog="run", description="Invoke Arti RPC integration tests"
)
parser.add_argument("--arti-dir", help="Location for Arti proxy storage and config")
parser.add_argument("remainder", nargs="*", help="Passed directly to arti_rpc_tests")
args = parser.parse_args()
######
# Set up locations and paths from the environment.
CARGO_PROFILE = "quicktest"
TOPLEVEL = os.path.abspath(parent(os.path.dirname(__file__), n=3))
CARGO = os.environ.get("CARGO", "cargo")
PYTHON3 = os.environ.get("PYTHON3", sys.executable)
lib_extension = {"win32": "dll", "darwin": "dylib"}.get(sys.platform, "so")
ARTI = os.path.join(TOPLEVEL, "target", CARGO_PROFILE, "arti")
LIBRPC = os.path.join(
TOPLEVEL, "target", CARGO_PROFILE, "libarti_rpc_client_core." + lib_extension
)
PYRPC = os.path.join(TOPLEVEL, "python", "arti_rpc", "src")
PYRPC_TESTS = os.path.join(TOPLEVEL, "python", "arti_rpc_tests", "src")
if args.arti_dir is not None:
ARTI_RPC_TEST_DIR = args.arti_dir
else:
ARTI_RPC_TEST_DIR = os.environ.get(
"ARTI_RPC_TEST_DIR", os.path.join(TOPLEVEL, ".arti_rpc_test")
)
os.makedirs(ARTI_RPC_TEST_DIR, mode=0o700, exist_ok=True)
#####
# Build Arti, and make sure it is there.
cargo_build(["arti", "arti-rpc-client-core"], ["--all-features"])
if not os.path.exists(ARTI):
print("whoops no arti at", ARTI)
sys.exit(1)
if not os.path.exists(ARTI):
print("whoops no librpc at", LIBRPC)
sys.exit(1)
#####
# Set up the environment expected by `arti_rpc_tests`.
os.environ["ARTI"] = ARTI
os.environ["LIBARTI_RPC_CLIENT_CORE"] = LIBRPC
os.environ["ARTI_RPC_TEST_DIR"] = ARTI_RPC_TEST_DIR
# Note that we're prepending these locations to PYTHONPATH.
# We want to use these versions, not ones that might happen to be installed.
pathelts = [PYRPC, PYRPC_TESTS]
try:
pathelts.append(os.environ["PYTHONPATH"])
except KeyError:
pass
os.environ["PYTHONPATH"] = os.pathsep.join(pathelts)
# Run `arti_rpc_tests` and wait for it to finish.
outcome = subprocess.run([PYTHON3, "-m", "arti_rpc_tests"] + args.remainder)
# Give an error if it failed.
outcome.check_returncode()
|