diff --git a/.github/workflows/extended.yml b/.github/workflows/extended.yml index cdddc3c9a4c4b..8d3b13c5b8370 100644 --- a/.github/workflows/extended.yml +++ b/.github/workflows/extended.yml @@ -15,6 +15,14 @@ # specific language governing permissions and limitations # under the License. +# Each test command below is implemented with `cargo xtask` so developers can +# run the same suite locally. Append `--explain` to print the underlying +# `cargo test` invocation without running it. Job setup, the clean working tree +# check, and `cargo clean` remain in this workflow. +# +# See `xtask/README.md` for details about DataFusion's `xtask` tooling. +# Track progress at https://github.com/apache/datafusion/issues/24487. + name: Datafusion extended tests concurrency: @@ -75,22 +83,7 @@ jobs: run: | df -h - name: Run tests (excluding doctests) - env: - RUST_BACKTRACE: 1 - # Run more random scenarios of the spill pool fuzzer than the - # default suite does (about a minute). - DATAFUSION_SPILL_POOL_FUZZ_ITERATIONS: 1000 - run: | - cargo test \ - --profile ci \ - --exclude datafusion-examples \ - --exclude datafusion-benchmarks \ - --exclude datafusion-cli \ - --workspace \ - --lib \ - --tests \ - --bins \ - --features avro,json,backtrace,extended_tests,recursive_protection,parquet_encryption + run: cargo xtask ci step test extended - parallel: - name: Verify Working Directory Clean run: git diff --exit-code @@ -118,8 +111,8 @@ jobs: rust-version: stable - name: Run tests run: | + cargo xtask ci step test hash-collisions cd datafusion - cargo test --profile ci --exclude datafusion-examples --exclude datafusion-benchmarks --exclude datafusion-sqllogictest --exclude datafusion-cli --workspace --lib --tests --features=force_hash_collisions,avro cargo clean sqllogictest-sqlite: @@ -142,5 +135,4 @@ jobs: run: | apt-get update && apt-get install -y protobuf-compiler - name: Run sqllogictest - run: | - cargo test --features backtrace,parquet_encryption --profile ci-optimized --test sqllogictests -- --include-sqlite + run: cargo xtask ci step test sqlite diff --git a/xtask/src/ci_steps.rs b/xtask/src/ci_steps.rs index e409d141649d2..521d527ab8a97 100644 --- a/xtask/src/ci_steps.rs +++ b/xtask/src/ci_steps.rs @@ -55,7 +55,7 @@ static CI_STEPS: &[StepInfo] = &[ }, StepInfo { command: "test", - help_usage: "test [--explain]", + help_usage: "test [--explain]", help_examples: &["test cli", "test workspace"], help_description: "Run a CI test suite", error_message: "Cargo test step failed", @@ -358,6 +358,70 @@ impl StepContext { "limit.slt", ]); } + "extended" => { + command + .args([ + "test", + "--profile", + "ci", + "--exclude", + "datafusion-examples", + "--exclude", + "datafusion-benchmarks", + "--exclude", + "datafusion-cli", + "--workspace", + "--lib", + "--tests", + "--bins", + "--features", + "avro,json,backtrace,extended_tests,recursive_protection,parquet_encryption", + ]) + .env("RUST_BACKTRACE", "1") + // Run more random scenarios of the spill pool fuzzer than the + // default suite does (about a minute). + .env("DATAFUSION_SPILL_POOL_FUZZ_ITERATIONS", "1000"); + } + "hash-collisions" => { + // Check answers are correct when hash values collide. The CI job + // runs from the `datafusion` directory with the builder setup, + // which sets `RUST_BACKTRACE=1`. + command + .args([ + "test", + "--profile", + "ci", + "--exclude", + "datafusion-examples", + "--exclude", + "datafusion-benchmarks", + "--exclude", + "datafusion-sqllogictest", + "--exclude", + "datafusion-cli", + "--workspace", + "--lib", + "--tests", + "--features=force_hash_collisions,avro", + ]) + .current_dir(self.root.join("datafusion")) + .env("RUST_BACKTRACE", "1"); + } + "sqlite" => { + // The CI job skips the builder setup because backtraces make this + // suite expensive, so `RUST_BACKTRACE` is deliberately not set. + command.args([ + "test", + "--features", + "backtrace,parquet_encryption", + "--profile", + "ci-optimized", + "--test", + "sqllogictests", + "--", + "--include-sqlite", + ]); + } _ => return Err(StepError::Usage), } @@ -546,6 +610,8 @@ fn required_env(name: &str) -> Result { mod tests { use super::*; + const TEST_USAGE: &str = "usage: cargo xtask ci step test [--explain]"; + fn args(args: &[&str]) -> Vec { args.iter().map(|arg| (*arg).to_string()).collect() } @@ -590,10 +656,17 @@ mod tests { .err() .unwrap(); - assert_eq!( - error, - "usage: cargo xtask ci step test [--explain]" - ); + assert_eq!(error, TEST_USAGE); + } + + #[test] + fn unknown_test_variant_is_rejected() { + let error = context() + .ci_step(&args(&["test", "extended_tests", "--explain"])) + .err() + .unwrap(); + + assert_eq!(error, TEST_USAGE); } // Test all available commands, ensure their executed command is expected @@ -775,6 +848,58 @@ cargo test \ --test sqllogictests \ --features substrait \ -- --substrait-round-trip limit.slt +") + }, + }, + Cmd { + command: &["test", "extended"], + expected: |actual| { + insta::assert_snapshot!(actual, @r" +cd /workspace && \ +DATAFUSION_SPILL_POOL_FUZZ_ITERATIONS=1000 \ +RUST_BACKTRACE=1 \ +cargo test \ +--profile ci \ +--exclude datafusion-examples \ +--exclude datafusion-benchmarks \ +--exclude datafusion-cli \ +--workspace \ +--lib \ +--tests \ +--bins \ +--features avro,json,backtrace,extended_tests,recursive_protection,parquet_encryption +") + }, + }, + Cmd { + command: &["test", "hash-collisions"], + expected: |actual| { + insta::assert_snapshot!(actual, @r" +cd /workspace/datafusion && \ +RUST_BACKTRACE=1 \ +cargo test \ +--profile ci \ +--exclude datafusion-examples \ +--exclude datafusion-benchmarks \ +--exclude datafusion-sqllogictest \ +--exclude datafusion-cli \ +--workspace \ +--lib \ +--tests \ +--features=force_hash_collisions,avro +") + }, + }, + Cmd { + command: &["test", "sqlite"], + expected: |actual| { + insta::assert_snapshot!(actual, @r" +cd /workspace && \ +cargo test \ +--features backtrace,parquet_encryption \ +--profile ci-optimized \ +--test sqllogictests \ +-- --include-sqlite ") }, },