Skip to content

Commit c342593

Browse files
authored
Rollup merge of #112719 - djkoloski:fuchsia_test_runner_remove_fvdl, r=tmandry
Replace fvdl with ffx, allow test without install Along with replacing fvdl uses with the equivalent ffx commands, this also switches from using the install path for libstd-*.so and libtest-*.so to using the build directory (now passed on the command line). The user no longer needs to run x.py install before running tests now, and the correct libstd and libtest are detected on run instead of startup so the test runner can handle recompilations after starting the testing environment. r? ``@tmandry``
2 parents 63799ba + 12c6f1d commit c342593

File tree

2 files changed

+100
-156
lines changed

2 files changed

+100
-156
lines changed

src/ci/docker/scripts/fuchsia-test-runner.py

+92-145
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,9 @@
2525

2626
@dataclass
2727
class TestEnvironment:
28-
rust_dir: str
28+
rust_build_dir: str
2929
sdk_dir: str
3030
target: str
31-
package_server_pid: Optional[int] = None
32-
emu_addr: Optional[str] = None
33-
libstd_name: Optional[str] = None
34-
libtest_name: Optional[str] = None
3531
verbose: bool = False
3632

3733
@staticmethod
@@ -57,7 +53,7 @@ def env_file_path(cls):
5753
@classmethod
5854
def from_args(cls, args):
5955
return cls(
60-
os.path.abspath(args.rust),
56+
os.path.abspath(args.rust_build),
6157
os.path.abspath(args.sdk),
6258
args.target,
6359
verbose=args.verbose,
@@ -68,32 +64,16 @@ def read_from_file(cls):
6864
with open(cls.env_file_path(), encoding="utf-8") as f:
6965
test_env = json.loads(f.read())
7066
return cls(
71-
test_env["rust_dir"],
67+
test_env["rust_build_dir"],
7268
test_env["sdk_dir"],
7369
test_env["target"],
74-
libstd_name=test_env["libstd_name"],
75-
libtest_name=test_env["libtest_name"],
76-
emu_addr=test_env["emu_addr"],
77-
package_server_pid=test_env["package_server_pid"],
7870
verbose=test_env["verbose"],
7971
)
8072

8173
def write_to_file(self):
8274
with open(self.env_file_path(), "w", encoding="utf-8") as f:
8375
f.write(json.dumps(self.__dict__))
8476

85-
def ssh_dir(self):
86-
return os.path.join(self.tmp_dir(), "ssh")
87-
88-
def ssh_keyfile_path(self):
89-
return os.path.join(self.ssh_dir(), "fuchsia_ed25519")
90-
91-
def ssh_authfile_path(self):
92-
return os.path.join(self.ssh_dir(), "fuchsia_authorized_keys")
93-
94-
def vdl_output_path(self):
95-
return os.path.join(self.tmp_dir(), "vdl_output")
96-
9777
def package_server_log_path(self):
9878
return os.path.join(self.tmp_dir(), "package_server_log")
9979

@@ -113,7 +93,9 @@ def repo_dir(self):
11393

11494
def libs_dir(self):
11595
return os.path.join(
116-
self.rust_dir,
96+
self.rust_build_dir,
97+
"host",
98+
"stage2",
11799
"lib",
118100
)
119101

@@ -212,21 +194,19 @@ def start_ffx_isolation(self):
212194
# Set configs
213195
configs = {
214196
"log.enabled": "true",
215-
"ssh.pub": self.ssh_authfile_path(),
216-
"ssh.priv": self.ssh_keyfile_path(),
217197
"test.is_isolated": "true",
218198
"test.experimental_structured_output": "true",
219199
}
220200
for key, value in configs.items():
221201
subprocess.check_call(
222202
[
223-
self.tool_path("ffx"),
203+
ffx_path,
224204
"config",
225205
"set",
226206
key,
227207
value,
228208
],
229-
env=self.ffx_cmd_env(),
209+
env=ffx_env,
230210
stdout=self.subprocess_output(),
231211
stderr=self.subprocess_output(),
232212
)
@@ -248,6 +228,7 @@ def stop_ffx_isolation(self):
248228
self.tool_path("ffx"),
249229
"daemon",
250230
"stop",
231+
"-w",
251232
],
252233
env=self.ffx_cmd_env(),
253234
stdout=self.subprocess_output(),
@@ -275,87 +256,62 @@ def start(self):
275256
elif len(os.listdir(self.tmp_dir())) != 0:
276257
raise Exception(f"Temp directory is not clean (in {self.tmp_dir()})")
277258

278-
os.mkdir(self.ssh_dir())
279259
os.mkdir(self.output_dir())
280260

281-
# Find libstd and libtest
282-
libstd_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libstd-*.so"))
283-
libtest_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libtest-*.so"))
284-
285-
if not libstd_paths:
286-
raise Exception(f"Failed to locate libstd (in {self.rustlibs_dir()})")
287-
288-
if not libtest_paths:
289-
raise Exception(f"Failed to locate libtest (in {self.rustlibs_dir()})")
261+
ffx_path = self.tool_path("ffx")
262+
ffx_env = self.ffx_cmd_env()
290263

291-
self.libstd_name = os.path.basename(libstd_paths[0])
292-
self.libtest_name = os.path.basename(libtest_paths[0])
264+
# Start ffx isolation
265+
self.log_info("Starting ffx isolation...")
266+
self.start_ffx_isolation()
293267

294-
# Generate SSH keys for the emulator to use
295-
self.log_info("Generating SSH keys...")
268+
# Stop any running emulators (there shouldn't be any)
296269
subprocess.check_call(
297270
[
298-
"ssh-keygen",
299-
"-N",
300-
"",
301-
"-t",
302-
"ed25519",
303-
"-f",
304-
self.ssh_keyfile_path(),
305-
"-C",
306-
"Generated by fuchsia-test-runner.py",
271+
ffx_path,
272+
"emu",
273+
"stop",
274+
"--all",
307275
],
276+
env=ffx_env,
308277
stdout=self.subprocess_output(),
309278
stderr=self.subprocess_output(),
310279
)
311-
authfile_contents = subprocess.check_output(
280+
281+
# Start emulator
282+
self.log_info("Starting emulator...")
283+
product_bundle = "terminal.qemu-" + self.triple_to_arch(self.target)
284+
subprocess.check_call(
312285
[
313-
"ssh-keygen",
314-
"-y",
315-
"-f",
316-
self.ssh_keyfile_path(),
286+
ffx_path,
287+
"product-bundle",
288+
"get",
289+
product_bundle,
317290
],
291+
env=ffx_env,
292+
stdout=self.subprocess_output(),
318293
stderr=self.subprocess_output(),
319294
)
320-
with open(self.ssh_authfile_path(), "wb") as authfile:
321-
authfile.write(authfile_contents)
322-
323-
# Start ffx isolation
324-
self.log_info("Starting ffx isolation...")
325-
self.start_ffx_isolation()
326-
327-
# Start emulator (this will generate the vdl output)
328-
self.log_info("Starting emulator...")
295+
# FIXME: condition --accel hyper on target arch matching host arch
329296
subprocess.check_call(
330297
[
331-
self.tool_path("fvdl"),
332-
"--sdk",
298+
ffx_path,
299+
"emu",
333300
"start",
334-
"--tuntap",
301+
product_bundle,
335302
"--headless",
336-
"--nointeractive",
337-
"--ssh",
338-
self.ssh_dir(),
339-
"--vdl-output",
340-
self.vdl_output_path(),
341-
"--emulator-log",
303+
"--log",
342304
self.emulator_log_path(),
343-
"--image-name",
344-
"qemu-" + self.triple_to_arch(self.target),
305+
"--net",
306+
"tap",
307+
"--accel",
308+
"hyper",
345309
],
310+
env=ffx_env,
346311
stdout=self.subprocess_output(),
347312
stderr=self.subprocess_output(),
348313
)
349314

350-
# Parse vdl output for relevant information
351-
with open(self.vdl_output_path(), encoding="utf-8") as f:
352-
vdl_content = f.read()
353-
matches = re.search(
354-
r'network_address:\s+"\[([0-9a-f]{1,4}:(:[0-9a-f]{1,4}){4}%qemu)\]"',
355-
vdl_content,
356-
)
357-
self.emu_addr = matches.group(1)
358-
359315
# Create new package repo
360316
self.log_info("Creating package repo...")
361317
subprocess.check_call(
@@ -369,55 +325,40 @@ def start(self):
369325
stderr=self.subprocess_output(),
370326
)
371327

372-
# Start package server
373-
self.log_info("Starting package server...")
374-
with open(
375-
self.package_server_log_path(), "w", encoding="utf-8"
376-
) as package_server_log:
377-
# We want this to be a long-running process that persists after the script finishes
378-
# pylint: disable=consider-using-with
379-
self.package_server_pid = subprocess.Popen(
380-
[
381-
self.tool_path("pm"),
382-
"serve",
383-
"-vt",
384-
"-repo",
385-
self.repo_dir(),
386-
"-l",
387-
":8084",
388-
],
389-
stdout=package_server_log,
390-
stderr=package_server_log,
391-
).pid
392-
393-
# Register package server with emulator
394-
self.log_info("Registering package server...")
395-
ssh_client = subprocess.check_output(
328+
# Add repo
329+
subprocess.check_call(
396330
[
397-
"ssh",
398-
"-i",
399-
self.ssh_keyfile_path(),
400-
"-o",
401-
"StrictHostKeyChecking=accept-new",
402-
self.emu_addr,
403-
"-f",
404-
"echo $SSH_CLIENT",
331+
ffx_path,
332+
"repository",
333+
"add-from-pm",
334+
self.repo_dir(),
335+
"--repository",
336+
self.TEST_REPO_NAME,
405337
],
406-
text=True,
338+
env=ffx_env,
339+
stdout=self.subprocess_output(),
340+
stderr=self.subprocess_output(),
407341
)
408-
repo_addr = ssh_client.split()[0].replace("%", "%25")
409-
repo_url = f"http://[{repo_addr}]:8084/config.json"
342+
343+
# Start repository server
344+
subprocess.check_call(
345+
[ffx_path, "repository", "server", "start", "--address", "[::]:0"],
346+
env=ffx_env,
347+
stdout=self.subprocess_output(),
348+
stderr=self.subprocess_output(),
349+
)
350+
351+
# Register with newly-started emulator
410352
subprocess.check_call(
411353
[
412-
"ssh",
413-
"-i",
414-
self.ssh_keyfile_path(),
415-
"-o",
416-
"StrictHostKeyChecking=accept-new",
417-
self.emu_addr,
418-
"-f",
419-
f"pkgctl repo add url -f 1 -n {self.TEST_REPO_NAME} {repo_url}",
354+
ffx_path,
355+
"target",
356+
"repository",
357+
"register",
358+
"--repository",
359+
self.TEST_REPO_NAME,
420360
],
361+
env=ffx_env,
421362
stdout=self.subprocess_output(),
422363
stderr=self.subprocess_output(),
423364
)
@@ -471,8 +412,8 @@ def start(self):
471412
meta/package={package_dir}/meta/package
472413
meta/{package_name}.cm={package_dir}/meta/{package_name}.cm
473414
bin/{exe_name}={bin_path}
474-
lib/{libstd_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libstd_name}
475-
lib/{libtest_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libtest_name}
415+
lib/{libstd_name}={libstd_path}
416+
lib/{libtest_name}={libtest_path}
476417
lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/dist/lib/ld.so.1
477418
lib/libfdio.so={sdk_dir}/arch/{target_arch}/dist/libfdio.so
478419
"""
@@ -502,6 +443,16 @@ def run(self, args):
502443

503444
bin_path = os.path.abspath(args.bin_path)
504445

446+
# Find libstd and libtest
447+
libstd_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libstd-*.so"))
448+
libtest_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libtest-*.so"))
449+
450+
if not libstd_paths:
451+
raise Exception(f"Failed to locate libstd (in {self.rustlibs_dir()})")
452+
453+
if not libtest_paths:
454+
raise Exception(f"Failed to locate libtest (in {self.rustlibs_dir()})")
455+
505456
# Build a unique, deterministic name for the test using the name of the
506457
# binary and the last 6 hex digits of the hash of the full path
507458
def path_checksum(path):
@@ -604,11 +555,12 @@ def log(msg):
604555
exe_name=exe_name,
605556
package_dir=package_dir,
606557
package_name=package_name,
607-
rust_dir=self.rust_dir,
608-
rustlib_dir=self.target,
558+
target=self.target,
609559
sdk_dir=self.sdk_dir,
610-
libstd_name=self.libstd_name,
611-
libtest_name=self.libtest_name,
560+
libstd_name=os.path.basename(libstd_paths[0]),
561+
libtest_name=os.path.basename(libtest_paths[0]),
562+
libstd_path=libstd_paths[0],
563+
libtest_path=libtest_paths[0],
612564
target_arch=self.triple_to_arch(self.target),
613565
)
614566
)
@@ -779,20 +731,15 @@ def stop(self):
779731
else:
780732
self.log_debug("No ffx daemon log found")
781733

782-
# Stop package server
783-
self.log_info("Stopping package server...")
784-
os.kill(self.package_server_pid, signal.SIGTERM)
785-
786734
# Shut down the emulator
787735
self.log_info("Stopping emulator...")
788736
subprocess.check_call(
789737
[
790-
self.tool_path("fvdl"),
791-
"--sdk",
792-
"kill",
793-
"--launched-proto",
794-
self.vdl_output_path(),
738+
self.tool_path("ffx"),
739+
"emu",
740+
"stop",
795741
],
742+
env=self.ffx_cmd_env(),
796743
stdout=self.subprocess_output(),
797744
stderr=self.subprocess_output(),
798745
)
@@ -969,8 +916,8 @@ def print_help(args):
969916
"start", help="initializes the testing environment"
970917
)
971918
start_parser.add_argument(
972-
"--rust",
973-
help="the directory of the installed Rust compiler for Fuchsia",
919+
"--rust-build",
920+
help="the current compiler build directory (`$RUST_SRC/build` by default)",
974921
required=True,
975922
)
976923
start_parser.add_argument(

0 commit comments

Comments
 (0)