summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Martin <evan.martin@gmail.com>2024-01-08 13:24:14 -0800
committerEvan Martin <evan.martin@gmail.com>2024-01-08 13:26:15 -0800
commit43cfa7fa15b6b5c24cdad9908b04800020fd8c83 (patch)
treeeef0ef49045ffe10b3b30d72692080270e06c42f
parent438506aa01ce44d608db7a19ec08512ecd5c42eb (diff)
downloadn2-43cfa7fa15b6b5c24cdad9908b04800020fd8c83.tar.gz
improve test for validation execution order
The test wanted to verify that in a file containing build foo: ... |@ bar it's possible for foo to finish before bar does. This changes to the test to make the bar step wait (at runtime) for the foo step to finish, enforcing that that ordering is possible. Fixes #102.
-rw-r--r--tests/e2e/mod.rs4
-rw-r--r--tests/e2e/validations.rs37
2 files changed, 12 insertions, 29 deletions
diff --git a/tests/e2e/mod.rs b/tests/e2e/mod.rs
index 93f26ff..a1e7e7f 100644
--- a/tests/e2e/mod.rs
+++ b/tests/e2e/mod.rs
@@ -84,10 +84,6 @@ impl TestSpace {
Ok(())
}
- pub fn path(&self) -> &std::path::Path {
- self.dir.path()
- }
-
/// Invoke n2, returning process output.
pub fn run(&self, cmd: &mut std::process::Command) -> std::io::Result<std::process::Output> {
cmd.current_dir(self.dir.path()).output()
diff --git a/tests/e2e/validations.rs b/tests/e2e/validations.rs
index 1b1eb98..46c48ae 100644
--- a/tests/e2e/validations.rs
+++ b/tests/e2e/validations.rs
@@ -1,3 +1,5 @@
+//! Tests for the 'validations' feature, which are build edges marked with |@.
+
use crate::e2e::*;
#[test]
@@ -22,44 +24,29 @@ fn basic_validation() -> anyhow::Result<()> {
#[cfg(unix)]
#[test]
fn build_starts_before_validation_finishes() -> anyhow::Result<()> {
+ // When a given target has a validation, that validation is part of the
+ // overall build. But despite there being a build edge, the target shouldn't
+ // wait for the validation.
+ // To verify this, we make the validation command internally wait for the
+ // target, effectively reversing the dependency order at runtime.
let space = TestSpace::new()?;
space.write(
"build.ninja",
"
+# Waits for the file $wait_for to exist, then touches $out.
rule build_slow
- command = sleep 0.3 && touch $out
+ command = until [ -f $wait_for ]; do sleep 0.1; done; touch $out
rule build_fast
- command = sleep 0.1 && touch $out
+ command = touch $out
build out: build_fast regular_input |@ validation_input
build regular_input: build_fast
build validation_input: build_slow
+ wait_for = regular_input
",
)?;
- let command = n2_command(vec!["out"])
- .current_dir(space.path())
- .stdout(std::process::Stdio::null())
- .stderr(std::process::Stdio::null())
- .stdin(std::process::Stdio::null())
- .spawn()?;
- std::thread::sleep(std::time::Duration::from_millis(50));
- assert!(space.read("out").is_err());
- assert!(space.read("regular_input").is_err());
- assert!(space.read("validation_input").is_err());
- std::thread::sleep(std::time::Duration::from_millis(100));
- assert!(space.read("out").is_err());
- assert!(space.read("regular_input").is_ok());
- assert!(space.read("validation_input").is_err());
- std::thread::sleep(std::time::Duration::from_millis(100));
- assert!(space.read("out").is_ok());
- assert!(space.read("regular_input").is_ok());
- assert!(space.read("validation_input").is_err());
- std::thread::sleep(std::time::Duration::from_millis(100));
- assert!(space.read("out").is_ok());
- assert!(space.read("regular_input").is_ok());
- assert!(space.read("validation_input").is_ok());
- assert!(command.wait_with_output()?.status.success());
+ space.run_expect(&mut n2_command(vec!["out"]))?;
Ok(())
}