From 75375be7ac6b4d2ac8a92bc1bbebc3e6da7fbadd Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 18 Nov 2024 09:42:01 +0100 Subject: [PATCH] Rust: add optional dependencies to ql tests Also accept `options.yml` and `options.yaml` files as well for test options, to get YAML syntax highlighting. In a follow up PR we might make the extension mandatory. --- rust/extractor/src/config.rs | 9 ++++++++- rust/extractor/src/qltest.rs | 11 +++++++++-- .../qltest/dependencies/functions.expected | 1 + .../qltest/dependencies/functions.ql | 5 +++++ .../qltest/dependencies/options.yml | 4 ++++ .../qltest/dependencies/test.rs | 7 +++++++ rust/ql/integration-tests/qltest/test.py | 19 +++++++++++++------ 7 files changed, 47 insertions(+), 9 deletions(-) create mode 100644 rust/ql/integration-tests/qltest/dependencies/functions.expected create mode 100644 rust/ql/integration-tests/qltest/dependencies/functions.ql create mode 100644 rust/ql/integration-tests/qltest/dependencies/options.yml create mode 100644 rust/ql/integration-tests/qltest/dependencies/test.rs diff --git a/rust/extractor/src/config.rs b/rust/extractor/src/config.rs index f477663f6070..8520df189304 100644 --- a/rust/extractor/src/config.rs +++ b/rust/extractor/src/config.rs @@ -43,6 +43,7 @@ pub struct Config { pub inputs: Vec, pub qltest: bool, pub qltest_cargo_check: bool, + pub qltest_dependencies: Vec, } impl Config { @@ -61,7 +62,13 @@ impl Config { .ancestors() // only travel up while we're within the test pack .take_while_inclusive(|p| !p.join("qlpack.yml").exists()) - .map(|p| p.join("options")) + .flat_map(|p| { + [ + p.join("options"), + p.join("options.yml"), + p.join("options.yaml"), + ] + }) .filter(|p| p.exists()) .collect_vec(); option_files.reverse(); diff --git a/rust/extractor/src/qltest.rs b/rust/extractor/src/qltest.rs index 169e2c433c71..f047271140a2 100644 --- a/rust/extractor/src/qltest.rs +++ b/rust/extractor/src/qltest.rs @@ -21,7 +21,7 @@ fn dump_lib() -> anyhow::Result<()> { fs::write("lib.rs", lib).context("writing lib.rs") } -fn dump_cargo_manifest() -> anyhow::Result<()> { +fn dump_cargo_manifest(dependencies: &[String]) -> anyhow::Result<()> { let mut manifest = String::from( r#"[workspace] [package] @@ -40,6 +40,13 @@ path = "main.rs" "#, ); } + if !dependencies.is_empty() { + manifest.push_str("[dependencies]\n"); + for dep in dependencies { + manifest.push_str(dep); + manifest.push('\n'); + } + } fs::write("Cargo.toml", manifest).context("writing Cargo.toml") } @@ -54,7 +61,7 @@ fn set_sources(config: &mut Config) -> anyhow::Result<()> { pub(crate) fn prepare(config: &mut Config) -> anyhow::Result<()> { dump_lib()?; set_sources(config)?; - dump_cargo_manifest()?; + dump_cargo_manifest(&config.qltest_dependencies)?; if config.qltest_cargo_check { let status = Command::new("cargo") .env("RUSTFLAGS", "-Awarnings") diff --git a/rust/ql/integration-tests/qltest/dependencies/functions.expected b/rust/ql/integration-tests/qltest/dependencies/functions.expected new file mode 100644 index 000000000000..c062595f9237 --- /dev/null +++ b/rust/ql/integration-tests/qltest/dependencies/functions.expected @@ -0,0 +1 @@ +| test.rs:4:1:7:1 | foo | diff --git a/rust/ql/integration-tests/qltest/dependencies/functions.ql b/rust/ql/integration-tests/qltest/dependencies/functions.ql new file mode 100644 index 000000000000..8d9a3213dad7 --- /dev/null +++ b/rust/ql/integration-tests/qltest/dependencies/functions.ql @@ -0,0 +1,5 @@ +import rust + +from Function f +where exists(f.getLocation().getFile().getRelativePath()) +select f diff --git a/rust/ql/integration-tests/qltest/dependencies/options.yml b/rust/ql/integration-tests/qltest/dependencies/options.yml new file mode 100644 index 000000000000..a628d3ca8b1b --- /dev/null +++ b/rust/ql/integration-tests/qltest/dependencies/options.yml @@ -0,0 +1,4 @@ +qltest_cargo_check: true +qltest_dependencies: + - anyhow = "1.0.86" + - log = "0.4.22" diff --git a/rust/ql/integration-tests/qltest/dependencies/test.rs b/rust/ql/integration-tests/qltest/dependencies/test.rs new file mode 100644 index 000000000000..3b591ff9f651 --- /dev/null +++ b/rust/ql/integration-tests/qltest/dependencies/test.rs @@ -0,0 +1,7 @@ +use anyhow; +use log::info; + +fn foo() -> anyhow::Result<()> { + info!("logging works"); + Ok(()) +} diff --git a/rust/ql/integration-tests/qltest/test.py b/rust/ql/integration-tests/qltest/test.py index 87d9a09cef4c..e488dee25717 100644 --- a/rust/ql/integration-tests/qltest/test.py +++ b/rust/ql/integration-tests/qltest/test.py @@ -1,17 +1,24 @@ import runs_on +import pytest + # these tests are meant to exercise QL test running on multiple platforms # therefore they don't rely on integration test built-in QL test running # (which skips `qltest.{sh,cmd}`) -def test_lib(codeql, rust, cwd): - codeql.test.run("lib", threads=1) +@pytest.fixture(autouse=True) +def default_options(codeql): + codeql.flags.update( + threads = 1, + show_extractor_output = True, + check_databases = False, + ) -def test_main(codeql, rust): - codeql.test.run("main", threads=1) +@pytest.mark.parametrize("dir", ["lib", "main", "dependencies"]) +def test(codeql, rust, dir): + codeql.test.run(dir) def test_failing_cargo_check(codeql, rust): - out = codeql.test.run("failing_cargo_check", threads=1, show_extractor_output=True, - _assert_failure=True, _capture="stderr") + out = codeql.test.run("failing_cargo_check", _assert_failure=True, _capture="stderr") # TODO: QL test output redirection is currently broken on windows, leaving it up for follow-up work if not runs_on.windows: assert "requested cargo check failed" in out