Repository navigation
feat(runner): add the test runner, plans and tmachine Session API, and run a plan on CI - #4773
matthewgrossman wants to merge 7 commits into
Conversation
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
🌿 Preview your docs: https://nvidia-preview-pr-4773.docs.buildwithfern.com/openshell |
e06a0eb to
a23e140
Compare
be4af48 to
63f4141
Compare
63f4141 to
df44e02
Compare
df44e02 to
4d19336
Compare
4d19336 to
6c9a275
Compare
6c9a275 to
1da9c3b
Compare
1da9c3b to
4781a50
Compare
| let specs: Vec<_> = testkit_spec::scan(&source) | ||
| .map_err(|error| anyhow::anyhow!("{}: {error}", file.display()))? | ||
| .into_iter() | ||
| .filter(|spec| !spec.ignored) |
There was a problem hiding this comment.
The source catalog does not account for conditional attributes, so a healthy lane can fail JUnit verification. For example:
/// Disabled on every target.
#[cfg(any())]
#[testkit::test]
async fn disabled(cx: &mut Context) -> testkit::Result { /* ... */ }I reproduced the catalog including disabled and result verification reporting it missing, although Cargo correctly excludes it. Platform-specific #[cfg(...)] tests have the same problem, and #[cfg_attr(..., ignore)] is not recognized by the literal #[ignore] check either.
Could we resolve these attributes for the guest build, or explicitly reject unsupported conditional declarations with a clear error, rather than adding them to the expected test set? Reproduced on 1da9c3b832bdae01be7f4022bd9e030a84b2dbe4; the relevant catalog and parser behavior remains present at 4781a500c1f8e4064c1c64e8b37c963fa4a46902.
There was a problem hiding this comment.
Thanks, good catch. Rather than evaluate cfg for the guest target, testkit-spec now refuses it: a #[cfg] or #[cfg_attr] on a #[testkit::test] function, or a file-level #![cfg] in a file that has tests, is an error from both the macro and the catalog scan, so the catalog and the build can't disagree. A test that only applies to some environments belongs in a features or drivers suite, and #[ignore = "<issue>"] remains the way to skip one everywhere. Tests are in testkit-spec (rejects_conditional_tests, scan_rejects_conditional_files_with_tests), and tests/testkit/README.md documents the rule. Fixed in 1b80fad.
8e7e5d4 to
2b879b0
Compare
c4f944f to
be103d6
Compare
Add a library API that boots an environment, runs commands in it with timeouts, copies files in and out, collects diagnostics and tears it down, so a caller can drive a machine without writing an Ansible playbook per suite. SSH and exec timeouts and QEMU cleanup on SIGTERM keep a hung guest or a cancelled CI job from leaving QEMU running. Add the `openshell-test-runner` flake package, which runs tests/runner with the toolchains and VM tools it needs. The Session API and test-runner package are adapted from #4629. Co-authored-by: Evan Lezar <elezar@nvidia.com> Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
…like the root `cargo --locked` only checks a lockfile against its own manifest. A workspace outside the root that builds root crates through path dependencies, such as the testkit suites building `openshell-sdk`, has its own Cargo.lock, so the two lockfiles can resolve a shared crate to different versions without any check failing. That is how aws-lc-sys 0.46 was picked up in #4629, which does not link against the AWS-LC that Nix provides. check_cargo_lockfile_alignment.py fails when an aligned workspace locks a registry crate that the root lockfile also contains at a version the root lockfile does not have. With --fix it re-locks the workspace starting from the root lockfile. tests/testkit is the first aligned workspace. The script and its tests come from #4629 (a37ebe9). Co-authored-by: Evan Lezar <elezar@nvidia.com> Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
Add the `sandbox` crate to the conformance workspace with one testkit test that creates a sandbox, runs `echo` in it with exec, deletes it and checks it is gone. It is deliberately small: it exists so the runner can run a real test in a tmachine environment on CI before the existing suites move to testkit. The workspace's other crate, the CLI conformance suite, keeps running as it does today. The conformance workspace joins the lockfile alignment check, so its lockfile is realigned with the root lockfile. The test is adapted from the `sandbox-lifecycle` suite in #4629. Co-authored-by: Evan Lezar <elezar@nvidia.com> Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
`openshell-test-runner` builds a family's packages (a workspace under
tests/suites/) on the host as a nextest archive for the guest's musl target,
boots one tmachine environment by name with the named installer through the
Session API, runs nextest in it and brings back the JUnit report and log. No
per-suite Ansible playbook is involved:
nix run .#openshell-test-runner -- --environment ubuntu-docker-rootful \
--installer deb --family conformance --package sandbox
The runner points the tests at the system under test with environment
variables: OPENSHELL_GATEWAY (the gateway the installer registered, `--gateway`,
default `openshell`) and OPENSHELL_BIN (the installed CLI). It waits for the
gateway with `testkit-ready` before the tests start. Nextest runs with
`--test-threads 1` and a slow-timeout that terminates a hung test.
A run passes if nextest succeeds and its JUnit report shows at least one test
and no failures. `--filter` narrows the tests with a nextest filterset, and
`--keep` leaves the VM up for debugging. Results from an earlier run are
removed first, and the guest's diagnostics are collected after a failure.
Which tests run in which environments is left to the caller for now; there are
no plans, environment registry or per-test requirements, and a broken test is
`#[ignore]`d.
Most of this comes from #4629, adapted to testkit finding the gateway the way the
CLI does instead of reading a target file.
Co-authored-by: Evan Lezar <elezar@nvidia.com>
Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
Run fmt, clippy and nextest for tests/tmachine and tests/runner, and fmt and clippy for the new `sandbox` suite crate, wherever tests/testkit already runs them: the mise tasks and Branch Checks. The suite's tests need a gateway, so they run through `mise run e2e:testkit` against a local Docker gateway and, on CI, through the test runner rather than the unit-test job. The lockfile task and the Cargo lockfiles job also run the alignment check, and its own tests run with `mise run test`. Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
…workflow Add a reusable workflow with an explicit matrix: each row names a tmachine environment and installer, a family and package, and the runner label. Each row runs `nix run .#openshell-test-runner` once. The jobs use the same integration inputs as the existing tmachine lanes, cache the tmachine disks keyed on the Ansible tree, upload the JUnit report and logs whether or not the run passes, and an aggregator job reports the overall result. The only row runs the conformance sandbox suite on amd64 Ubuntu with rootful Docker and the Debian package, which CI can provision today. Branch E2E calls the workflow when the test:e2e label is set. The job is not in the Core E2E result's needs yet, so it starts out advisory. The existing conformance, feature and driver lanes are unchanged. Modeled on the E2E Suites workflow in #4629. Co-authored-by: Evan Lezar <elezar@nvidia.com> Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
Describe how the runner runs a family in a tmachine environment, locally and on CI, in TESTING.md, add a README for the sandbox suite, point the testkit README at the runner, and add rows for tests/suites, tests/tmachine and tests/runner to the project-structure tables in AGENTS.md and CONTRIBUTING.md. Signed-off-by: Matthew Grossman <mgrossman@nvidia.com>
be103d6 to
f244394
Compare
|
Label |
Summary
This PR makes it possible to run a testkit test on top of tmachine. A small runner builds a test family's tests for the guest, boots one tmachine environment with OpenShell installed, runs the tests inside it, and checks the JUnit results. On CI, an advisory lane runs one smoke test on Ubuntu with rootful Docker.
nix run .#openshell-test-runner -- \ --environment ubuntu-docker-rootful --installer deb \ --family conformance --package sandboxMost of the runner and the tmachine
SessionAPI come from @elezar's draft #4629.Stack
SessionAPI, a runner for one family in one tmachine environment, a smoke suite, and an advisory CI lane with an explicit matrix.featuresanddriverssuites move to testkit.Deferred from this PR
testkit-spec. They are kept on a branch at be103d6 (the previous head of this PR) and come back after features. Until then, CI lists what runs where as an explicit matrix ine2e-suites.yml.e2e-suiteslane is advisory and not part of the Core E2E result.Dropped from #4629, not planned:
requires, capabilities and waivers. A test that fails in an environment fails the lane.#[ignore = "<issue link>"]takes a broken test out everywhere.OPENSHELL_GATEWAYandOPENSHELL_BIN.Out of scope for the whole stack: version compatibility guarantees between the conformance suite and gateways, and running tests from other repositories.
Related Issue
Part of #3954
Changes
SessionAPI; SSH, scp, and exec timeouts;down()never panics; QEMU is cleaned up on SIGTERM; the SSH port isTMACHINE_SSH_PORT. Anopenshell-test-runnerflake package. Environment setup is unchanged.tests/runner(openshell-test-runner): picks the tmachine environment and installer by name, builds the family's packages (a workspace undertests/suites/) as a nextest archive for the guest's musl target, waits for the gateway withtestkit-ready, runs nextest in the guest, and writesjunit.xml,nextest.logand, after a failure, the guest's diagnostics to--results. A run passes if nextest succeeds and its report shows at least one test and no failures.--filternarrows with a nextest filterset, and--keepkeeps the VM for debugging.tests/suites/conformance/sandbox: the smoke suite (create a sandbox, exececho, delete it).mise run e2e:testkitruns it against a local Docker gateway..github/workflows/e2e-suites.yml(reusable), with an explicitincludematrix of one row, and ane2e-suitesjob in Branch E2E (labeltest:e2e). JUnit and logs are uploaded ase2e-results-<family>-<package>-<environment>-<installer>. It is not part of the Core E2E result yet.TESTING.md,AGENTS.md,CONTRIBUTING.mdand the testkit and suite READMEs describe the runner.Testing
clippy -D warningsfor testkit, the runner, tmachine and the conformance suite; the runner (10), tmachine (8) and testkit unit tests; the lockfile alignment check and its tests; the SPDX header check. Every commit builds with--locked.nix run .#openshell-test-runner -- --helpbuilds and runs.Checklist