mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-10 22:13:27 +00:00
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.
This commit is contained in:
parent
6a94e87a54
commit
4c6fd7594d
@ -25,13 +25,9 @@ from typing import ClassVar, List, Optional
|
||||
|
||||
@dataclass
|
||||
class TestEnvironment:
|
||||
rust_dir: str
|
||||
rust_build_dir: str
|
||||
sdk_dir: str
|
||||
target: str
|
||||
package_server_pid: Optional[int] = None
|
||||
emu_addr: Optional[str] = None
|
||||
libstd_name: Optional[str] = None
|
||||
libtest_name: Optional[str] = None
|
||||
verbose: bool = False
|
||||
|
||||
@staticmethod
|
||||
@ -57,7 +53,7 @@ class TestEnvironment:
|
||||
@classmethod
|
||||
def from_args(cls, args):
|
||||
return cls(
|
||||
os.path.abspath(args.rust),
|
||||
os.path.abspath(args.rust_build),
|
||||
os.path.abspath(args.sdk),
|
||||
args.target,
|
||||
verbose=args.verbose,
|
||||
@ -68,13 +64,9 @@ class TestEnvironment:
|
||||
with open(cls.env_file_path(), encoding="utf-8") as f:
|
||||
test_env = json.loads(f.read())
|
||||
return cls(
|
||||
test_env["rust_dir"],
|
||||
test_env["rust_build_dir"],
|
||||
test_env["sdk_dir"],
|
||||
test_env["target"],
|
||||
libstd_name=test_env["libstd_name"],
|
||||
libtest_name=test_env["libtest_name"],
|
||||
emu_addr=test_env["emu_addr"],
|
||||
package_server_pid=test_env["package_server_pid"],
|
||||
verbose=test_env["verbose"],
|
||||
)
|
||||
|
||||
@ -82,18 +74,6 @@ class TestEnvironment:
|
||||
with open(self.env_file_path(), "w", encoding="utf-8") as f:
|
||||
f.write(json.dumps(self.__dict__))
|
||||
|
||||
def ssh_dir(self):
|
||||
return os.path.join(self.tmp_dir(), "ssh")
|
||||
|
||||
def ssh_keyfile_path(self):
|
||||
return os.path.join(self.ssh_dir(), "fuchsia_ed25519")
|
||||
|
||||
def ssh_authfile_path(self):
|
||||
return os.path.join(self.ssh_dir(), "fuchsia_authorized_keys")
|
||||
|
||||
def vdl_output_path(self):
|
||||
return os.path.join(self.tmp_dir(), "vdl_output")
|
||||
|
||||
def package_server_log_path(self):
|
||||
return os.path.join(self.tmp_dir(), "package_server_log")
|
||||
|
||||
@ -113,7 +93,9 @@ class TestEnvironment:
|
||||
|
||||
def libs_dir(self):
|
||||
return os.path.join(
|
||||
self.rust_dir,
|
||||
self.rust_build_dir,
|
||||
"host",
|
||||
"stage2",
|
||||
"lib",
|
||||
)
|
||||
|
||||
@ -212,21 +194,19 @@ class TestEnvironment:
|
||||
# Set configs
|
||||
configs = {
|
||||
"log.enabled": "true",
|
||||
"ssh.pub": self.ssh_authfile_path(),
|
||||
"ssh.priv": self.ssh_keyfile_path(),
|
||||
"test.is_isolated": "true",
|
||||
"test.experimental_structured_output": "true",
|
||||
}
|
||||
for key, value in configs.items():
|
||||
subprocess.check_call(
|
||||
[
|
||||
self.tool_path("ffx"),
|
||||
ffx_path,
|
||||
"config",
|
||||
"set",
|
||||
key,
|
||||
value,
|
||||
],
|
||||
env=self.ffx_cmd_env(),
|
||||
env=ffx_env,
|
||||
stdout=self.subprocess_output(),
|
||||
stderr=self.subprocess_output(),
|
||||
)
|
||||
@ -248,6 +228,7 @@ class TestEnvironment:
|
||||
self.tool_path("ffx"),
|
||||
"daemon",
|
||||
"stop",
|
||||
"-w",
|
||||
],
|
||||
env=self.ffx_cmd_env(),
|
||||
stdout=self.subprocess_output(),
|
||||
@ -275,86 +256,61 @@ class TestEnvironment:
|
||||
elif len(os.listdir(self.tmp_dir())) != 0:
|
||||
raise Exception(f"Temp directory is not clean (in {self.tmp_dir()})")
|
||||
|
||||
os.mkdir(self.ssh_dir())
|
||||
os.mkdir(self.output_dir())
|
||||
|
||||
# Find libstd and libtest
|
||||
libstd_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libstd-*.so"))
|
||||
libtest_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libtest-*.so"))
|
||||
|
||||
if not libstd_paths:
|
||||
raise Exception(f"Failed to locate libstd (in {self.rustlibs_dir()})")
|
||||
|
||||
if not libtest_paths:
|
||||
raise Exception(f"Failed to locate libtest (in {self.rustlibs_dir()})")
|
||||
|
||||
self.libstd_name = os.path.basename(libstd_paths[0])
|
||||
self.libtest_name = os.path.basename(libtest_paths[0])
|
||||
|
||||
# Generate SSH keys for the emulator to use
|
||||
self.log_info("Generating SSH keys...")
|
||||
subprocess.check_call(
|
||||
[
|
||||
"ssh-keygen",
|
||||
"-N",
|
||||
"",
|
||||
"-t",
|
||||
"ed25519",
|
||||
"-f",
|
||||
self.ssh_keyfile_path(),
|
||||
"-C",
|
||||
"Generated by fuchsia-test-runner.py",
|
||||
],
|
||||
stdout=self.subprocess_output(),
|
||||
stderr=self.subprocess_output(),
|
||||
)
|
||||
authfile_contents = subprocess.check_output(
|
||||
[
|
||||
"ssh-keygen",
|
||||
"-y",
|
||||
"-f",
|
||||
self.ssh_keyfile_path(),
|
||||
],
|
||||
stderr=self.subprocess_output(),
|
||||
)
|
||||
with open(self.ssh_authfile_path(), "wb") as authfile:
|
||||
authfile.write(authfile_contents)
|
||||
ffx_path = self.tool_path("ffx")
|
||||
ffx_env = self.ffx_cmd_env()
|
||||
|
||||
# Start ffx isolation
|
||||
self.log_info("Starting ffx isolation...")
|
||||
self.start_ffx_isolation()
|
||||
|
||||
# Start emulator (this will generate the vdl output)
|
||||
self.log_info("Starting emulator...")
|
||||
# Stop any running emulators (there shouldn't be any)
|
||||
subprocess.check_call(
|
||||
[
|
||||
self.tool_path("fvdl"),
|
||||
"--sdk",
|
||||
"start",
|
||||
"--tuntap",
|
||||
"--headless",
|
||||
"--nointeractive",
|
||||
"--ssh",
|
||||
self.ssh_dir(),
|
||||
"--vdl-output",
|
||||
self.vdl_output_path(),
|
||||
"--emulator-log",
|
||||
self.emulator_log_path(),
|
||||
"--image-name",
|
||||
"qemu-" + self.triple_to_arch(self.target),
|
||||
ffx_path,
|
||||
"emu",
|
||||
"stop",
|
||||
"--all",
|
||||
],
|
||||
env=ffx_env,
|
||||
stdout=self.subprocess_output(),
|
||||
stderr=self.subprocess_output(),
|
||||
)
|
||||
|
||||
# Parse vdl output for relevant information
|
||||
with open(self.vdl_output_path(), encoding="utf-8") as f:
|
||||
vdl_content = f.read()
|
||||
matches = re.search(
|
||||
r'network_address:\s+"\[([0-9a-f]{1,4}:(:[0-9a-f]{1,4}){4}%qemu)\]"',
|
||||
vdl_content,
|
||||
)
|
||||
self.emu_addr = matches.group(1)
|
||||
# Start emulator
|
||||
self.log_info("Starting emulator...")
|
||||
product_bundle = "terminal.qemu-" + self.triple_to_arch(self.target)
|
||||
subprocess.check_call(
|
||||
[
|
||||
ffx_path,
|
||||
"product-bundle",
|
||||
"get",
|
||||
product_bundle,
|
||||
],
|
||||
env=ffx_env,
|
||||
stdout=self.subprocess_output(),
|
||||
stderr=self.subprocess_output(),
|
||||
)
|
||||
# FIXME: condition --accel hyper on target arch matching host arch
|
||||
subprocess.check_call(
|
||||
[
|
||||
ffx_path,
|
||||
"emu",
|
||||
"start",
|
||||
product_bundle,
|
||||
"--headless",
|
||||
"--log",
|
||||
self.emulator_log_path(),
|
||||
"--net",
|
||||
"tap",
|
||||
"--accel",
|
||||
"hyper",
|
||||
],
|
||||
env=ffx_env,
|
||||
stdout=self.subprocess_output(),
|
||||
stderr=self.subprocess_output(),
|
||||
)
|
||||
|
||||
# Create new package repo
|
||||
self.log_info("Creating package repo...")
|
||||
@ -369,55 +325,40 @@ class TestEnvironment:
|
||||
stderr=self.subprocess_output(),
|
||||
)
|
||||
|
||||
# Start package server
|
||||
self.log_info("Starting package server...")
|
||||
with open(
|
||||
self.package_server_log_path(), "w", encoding="utf-8"
|
||||
) as package_server_log:
|
||||
# We want this to be a long-running process that persists after the script finishes
|
||||
# pylint: disable=consider-using-with
|
||||
self.package_server_pid = subprocess.Popen(
|
||||
[
|
||||
self.tool_path("pm"),
|
||||
"serve",
|
||||
"-vt",
|
||||
"-repo",
|
||||
self.repo_dir(),
|
||||
"-l",
|
||||
":8084",
|
||||
],
|
||||
stdout=package_server_log,
|
||||
stderr=package_server_log,
|
||||
).pid
|
||||
|
||||
# Register package server with emulator
|
||||
self.log_info("Registering package server...")
|
||||
ssh_client = subprocess.check_output(
|
||||
[
|
||||
"ssh",
|
||||
"-i",
|
||||
self.ssh_keyfile_path(),
|
||||
"-o",
|
||||
"StrictHostKeyChecking=accept-new",
|
||||
self.emu_addr,
|
||||
"-f",
|
||||
"echo $SSH_CLIENT",
|
||||
],
|
||||
text=True,
|
||||
)
|
||||
repo_addr = ssh_client.split()[0].replace("%", "%25")
|
||||
repo_url = f"http://[{repo_addr}]:8084/config.json"
|
||||
# Add repo
|
||||
subprocess.check_call(
|
||||
[
|
||||
"ssh",
|
||||
"-i",
|
||||
self.ssh_keyfile_path(),
|
||||
"-o",
|
||||
"StrictHostKeyChecking=accept-new",
|
||||
self.emu_addr,
|
||||
"-f",
|
||||
f"pkgctl repo add url -f 1 -n {self.TEST_REPO_NAME} {repo_url}",
|
||||
ffx_path,
|
||||
"repository",
|
||||
"add-from-pm",
|
||||
self.repo_dir(),
|
||||
"--repository",
|
||||
self.TEST_REPO_NAME,
|
||||
],
|
||||
env=ffx_env,
|
||||
stdout=self.subprocess_output(),
|
||||
stderr=self.subprocess_output(),
|
||||
)
|
||||
|
||||
# Start repository server
|
||||
subprocess.check_call(
|
||||
[ffx_path, "repository", "server", "start", "--address", "[::]:0"],
|
||||
env=ffx_env,
|
||||
stdout=self.subprocess_output(),
|
||||
stderr=self.subprocess_output(),
|
||||
)
|
||||
|
||||
# Register with newly-started emulator
|
||||
subprocess.check_call(
|
||||
[
|
||||
ffx_path,
|
||||
"target",
|
||||
"repository",
|
||||
"register",
|
||||
"--repository",
|
||||
self.TEST_REPO_NAME,
|
||||
],
|
||||
env=ffx_env,
|
||||
stdout=self.subprocess_output(),
|
||||
stderr=self.subprocess_output(),
|
||||
)
|
||||
@ -471,8 +412,8 @@ class TestEnvironment:
|
||||
meta/package={package_dir}/meta/package
|
||||
meta/{package_name}.cm={package_dir}/meta/{package_name}.cm
|
||||
bin/{exe_name}={bin_path}
|
||||
lib/{libstd_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libstd_name}
|
||||
lib/{libtest_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libtest_name}
|
||||
lib/{libstd_name}={libstd_path}
|
||||
lib/{libtest_name}={libtest_path}
|
||||
lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/dist/lib/ld.so.1
|
||||
lib/libfdio.so={sdk_dir}/arch/{target_arch}/dist/libfdio.so
|
||||
"""
|
||||
@ -502,6 +443,16 @@ class TestEnvironment:
|
||||
|
||||
bin_path = os.path.abspath(args.bin_path)
|
||||
|
||||
# Find libstd and libtest
|
||||
libstd_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libstd-*.so"))
|
||||
libtest_paths = glob.glob(os.path.join(self.rustlibs_dir(), "libtest-*.so"))
|
||||
|
||||
if not libstd_paths:
|
||||
raise Exception(f"Failed to locate libstd (in {self.rustlibs_dir()})")
|
||||
|
||||
if not libtest_paths:
|
||||
raise Exception(f"Failed to locate libtest (in {self.rustlibs_dir()})")
|
||||
|
||||
# Build a unique, deterministic name for the test using the name of the
|
||||
# binary and the last 6 hex digits of the hash of the full path
|
||||
def path_checksum(path):
|
||||
@ -604,11 +555,12 @@ class TestEnvironment:
|
||||
exe_name=exe_name,
|
||||
package_dir=package_dir,
|
||||
package_name=package_name,
|
||||
rust_dir=self.rust_dir,
|
||||
rustlib_dir=self.target,
|
||||
target=self.target,
|
||||
sdk_dir=self.sdk_dir,
|
||||
libstd_name=self.libstd_name,
|
||||
libtest_name=self.libtest_name,
|
||||
libstd_name=os.path.basename(libstd_paths[0]),
|
||||
libtest_name=os.path.basename(libtest_paths[0]),
|
||||
libstd_path=libstd_paths[0],
|
||||
libtest_path=libtest_paths[0],
|
||||
target_arch=self.triple_to_arch(self.target),
|
||||
)
|
||||
)
|
||||
@ -779,20 +731,15 @@ class TestEnvironment:
|
||||
else:
|
||||
self.log_debug("No ffx daemon log found")
|
||||
|
||||
# Stop package server
|
||||
self.log_info("Stopping package server...")
|
||||
os.kill(self.package_server_pid, signal.SIGTERM)
|
||||
|
||||
# Shut down the emulator
|
||||
self.log_info("Stopping emulator...")
|
||||
subprocess.check_call(
|
||||
[
|
||||
self.tool_path("fvdl"),
|
||||
"--sdk",
|
||||
"kill",
|
||||
"--launched-proto",
|
||||
self.vdl_output_path(),
|
||||
self.tool_path("ffx"),
|
||||
"emu",
|
||||
"stop",
|
||||
],
|
||||
env=self.ffx_cmd_env(),
|
||||
stdout=self.subprocess_output(),
|
||||
stderr=self.subprocess_output(),
|
||||
)
|
||||
@ -969,8 +916,8 @@ def main():
|
||||
"start", help="initializes the testing environment"
|
||||
)
|
||||
start_parser.add_argument(
|
||||
"--rust",
|
||||
help="the directory of the installed Rust compiler for Fuchsia",
|
||||
"--rust-build",
|
||||
help="the current compiler build directory (`$RUST_SRC/build` by default)",
|
||||
required=True,
|
||||
)
|
||||
start_parser.add_argument(
|
||||
|
@ -681,12 +681,9 @@ local Rust source checkout:
|
||||
cd ${RUST_SRC_PATH}
|
||||
```
|
||||
|
||||
To run the Rust test suite on an emulated Fuchsia device, you must install the
|
||||
Rust compiler locally. See "[Targeting Fuchsia with a compiler built from source](#targeting-fuchsia-with-a-compiler-built-from-source)"
|
||||
for the steps to build locally.
|
||||
|
||||
You'll also need to download a copy of the Fuchsia SDK. The current minimum
|
||||
supported SDK version is [10.20221207.2.89][minimum_supported_sdk_version].
|
||||
To run the Rust test suite on an emulated Fuchsia device, you'll also need to
|
||||
download a copy of the Fuchsia SDK. The current minimum supported SDK version is
|
||||
[10.20221207.2.89][minimum_supported_sdk_version].
|
||||
|
||||
[minimum_supported_sdk_version]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:10.20221207.2.89
|
||||
|
||||
@ -695,13 +692,13 @@ Fuchsia's test runner interacts with the Fuchsia emulator and is located at
|
||||
test environment with:
|
||||
|
||||
```sh
|
||||
src/ci/docker/scripts/fuchsia-test-runner.py start
|
||||
--rust ${RUST_SRC_PATH}/install
|
||||
--sdk ${SDK_PATH}
|
||||
--target {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia}
|
||||
src/ci/docker/scripts/fuchsia-test-runner.py start \
|
||||
--rust ${RUST_SRC_PATH}/build \
|
||||
--sdk ${SDK_PATH} \
|
||||
--target {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia} \
|
||||
```
|
||||
|
||||
Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and
|
||||
Where `${RUST_SRC_PATH}/build` is the `build-dir` set in `config.toml` and
|
||||
`${SDK_PATH}` is the path to the downloaded and unzipped SDK.
|
||||
|
||||
Once our environment is started, we can run our tests using `x.py` as usual. The
|
||||
|
Loading…
Reference in New Issue
Block a user