Skip to content

Commit 20d5146

Browse files
committed
tests: Split up tmt tests into separate plans
Because tmt right now doesn't support isolation automatically, and many of the tests we'll want to write mutate the system, we'll need to copy-paste the base plan. This changes the `make test-tmt` to have its own little tmt wrapper that dynamically scans the plans/ and sorts them by a priority, then runs them one by one currently. Closes: #735 Signed-off-by: Colin Walters <[email protected]>
1 parent 48b4029 commit 20d5146

File tree

7 files changed

+59
-7
lines changed

7 files changed

+59
-7
lines changed

plans/integration-run.fmf renamed to plans/test-01-readonly.fmf

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ provision:
55
# Generated by make test-tmt
66
image: file://./target/testvm/disk.qcow2
77
disk: 20
8-
summary: Execute booted tests
8+
summary: Execute booted readonly/nondestructive tests
99
execute:
1010
how: tmt
1111
# There's currently two dynamic test frameworks; python and nushell.
1212
# python is well known and understood. nushell is less well known, but
1313
# is quite nice for running subprocesses and the like while making
1414
# it easy to parse JSON etc.
15+
# All of these tests should generally be read-only - avoid any kind
16+
# of persistent changes.
17+
# If you need to do that, unfortunately right now that needs to be
18+
# a separate plan.
1519
script: |
1620
set -xeu
17-
pytest tests/booted/*.py
18-
ls tests/booted/*-test-*.nu |sort -n | while read t; do nu $t; done
21+
pytest tests/booted/readonly/*.py
22+
ls tests/booted/readonly/*-test-*.nu |sort -n | while read t; do nu $t; done

plans/test-20-local-upgrade.fmf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#
2+
provision:
3+
how: virtual
4+
# Generated by make test-tmt
5+
image: file://./target/testvm/disk.qcow2
6+
disk: 20
7+
summary: Execute local upgrade tests
8+
execute:
9+
how: tmt
10+
# We avoid writing nontrivial shell script as a general rule,
11+
# so this is written in nu.
12+
script: exec nu tests/booted/test-image-pushpull-upgrade.nu
File renamed without changes.

tests/booted/readonly/tap.nu

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../tap.nu

xtask/src/xtask.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,48 @@ fn update_generated(sh: &Shell) -> Result<()> {
148148

149149
#[context("test-integration")]
150150
fn test_tmt(sh: &Shell) -> Result<()> {
151+
// We need to split most of our tests into separate plans because tmt doesn't
152+
// support automatic isolation. (xref)
153+
let mut all_plan_files =
154+
sh.read_dir("plans")?
155+
.into_iter()
156+
.try_fold(Vec::new(), |mut acc, ent| -> Result<_> {
157+
let path = Utf8PathBuf::try_from(ent)?;
158+
let Some(ext) = path.extension() else {
159+
return Ok(acc);
160+
};
161+
if ext != "fmf" {
162+
return Ok(acc);
163+
}
164+
let stem = path.file_stem().expect("file stem");
165+
let Some((prefix, suffix)) = stem.split_once('-') else {
166+
return Ok(acc);
167+
};
168+
if prefix != "test" {
169+
return Ok(acc);
170+
}
171+
let Some((priority, _)) = suffix.split_once('-') else {
172+
anyhow::bail!("Invalid test {path}");
173+
};
174+
let priority: u32 = priority
175+
.parse()
176+
.with_context(|| format!("Parsing {path}"))?;
177+
acc.push((priority, stem.to_string()));
178+
Ok(acc)
179+
})?;
180+
all_plan_files.sort_by_key(|v| v.0);
181+
println!("Discovered plans: {all_plan_files:?}");
182+
151183
cmd!(sh, "cargo run -p tests-integration run-vm prepare-tmt").run()?;
152184
// cc https://pagure.io/testcloud/pull-request/174
153185
cmd!(sh, "rm -vf /var/tmp/tmt/testcloud/images/disk.qcow2").run()?;
154-
if let Err(e) = cmd!(sh, "tmt run plans -n integration-run").run() {
155-
// tmt annoyingly does not output errors by default
156-
let _ = cmd!(sh, "tmt run -l report -vvv").run();
157-
return Err(e.into());
186+
187+
for (_prio, name) in all_plan_files {
188+
if let Err(e) = cmd!(sh, "tmt run plans -n {name}").run() {
189+
// tmt annoyingly does not output errors by default
190+
let _ = cmd!(sh, "tmt run -l report -vvv").run();
191+
return Err(e.into());
192+
}
158193
}
159194
Ok(())
160195
}

0 commit comments

Comments
 (0)