From a305af544db154ade691457f7d275558909c6916 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Thu, 1 Dec 2022 14:41:20 +0100 Subject: [PATCH] setup extra test run for selective `gitoxide`-enabled tests Using a rust config flag we are able to selective run only those tests that have been cleared to run with `gitoxide`, as part of a separate test run. That way we will keep testing all `git2` related code as before but step by step enable more tests to work correctly with `gitoxide`. For now it's only planned to run git-related tests, but it's possible to one-day run the entire test suite if oen were to be willing to pay the cost. CI is configured to run separate tests for `gitoxide` as well. --- .github/workflows/main.yml | 2 ++ crates/cargo-test-macro/src/lib.rs | 34 +++++++++++++++++++++++++++- crates/cargo-test-support/src/git.rs | 23 +++++++++++++++++++ tests/testsuite/registry.rs | 4 +++- 4 files changed, 61 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cd08bebddd53..c375b7081eac 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -80,6 +80,8 @@ jobs: # Deny warnings on CI to avoid warnings getting into the codebase. - run: cargo test --features 'deny-warnings' + - name: gitoxide tests (git-related and enabled tests only) + run: RUSTFLAGS='--cfg test_gitoxide' cargo test git # The testsuite generates a huge amount of data, and fetch-smoke-test was # running out of disk space. - name: Clear test output diff --git a/crates/cargo-test-macro/src/lib.rs b/crates/cargo-test-macro/src/lib.rs index 40661ca5119e..e484151eba2b 100644 --- a/crates/cargo-test-macro/src/lib.rs +++ b/crates/cargo-test-macro/src/lib.rs @@ -32,6 +32,8 @@ pub fn cargo_test(attr: TokenStream, item: TokenStream) -> TokenStream { }; } let is_not_nightly = !version().1; + #[cfg(test_gitoxide)] + let mut enable_gitoxide_test = false; for rule in split_rules(attr) { match rule.as_str() { "build_std_real" => { @@ -59,6 +61,12 @@ pub fn cargo_test(attr: TokenStream, item: TokenStream) -> TokenStream { requires_reason = true; set_ignore!(is_not_nightly, "requires nightly"); } + "gitoxide" => { + #[cfg(test_gitoxide)] + { + enable_gitoxide_test = true; + } + } s if s.starts_with("requires_") => { let command = &s[9..]; set_ignore!(!has_command(command), "{command} not installed"); @@ -81,6 +89,13 @@ pub fn cargo_test(attr: TokenStream, item: TokenStream) -> TokenStream { such as #[cargo_test(nightly, reason = \"needs -Z unstable-thing\")]" ); } + #[cfg(test_gitoxide)] + if !enable_gitoxide_test { + ignore = true; + implicit_reasons.push( + "not yet enabled for using 'gitoxide' and tested in the standard test run".to_string(), + ) + } // Construct the appropriate attributes. let span = Span::call_site(); @@ -114,7 +129,8 @@ pub fn cargo_test(attr: TokenStream, item: TokenStream) -> TokenStream { } // Find where the function body starts, and add the boilerplate at the start. - for token in item { + let mut item = item.into_iter(); + while let Some(token) = item.next() { let group = match token { TokenTree::Group(g) => { if g.delimiter() == Delimiter::Brace { @@ -124,6 +140,22 @@ pub fn cargo_test(attr: TokenStream, item: TokenStream) -> TokenStream { continue; } } + // Remove duplicate ignore statements to avoid errors - ours take precedence. + // Only needed for handling `gitoxide` tests. + #[cfg(test_gitoxide)] + TokenTree::Punct(p) if p.as_char() == '#' && ignore => { + let next = item.next().expect("group"); + let TokenTree::Group(g) = next else { + ret.extend([TokenTree::Punct(p), next]); + continue + }; + if g.delimiter() == Delimiter::Bracket && g.to_string().contains("ignore") { + continue; + } + + ret.extend([TokenTree::Punct(p), TokenTree::Group(g)]); + continue; + } other => { ret.extend(Some(other)); continue; diff --git a/crates/cargo-test-support/src/git.rs b/crates/cargo-test-support/src/git.rs index 18c4646b37d2..7783aa944ff3 100644 --- a/crates/cargo-test-support/src/git.rs +++ b/crates/cargo-test-support/src/git.rs @@ -247,3 +247,26 @@ pub fn tag(repo: &git2::Repository, name: &str) { false )); } + +/// A utility trait to make enabling `gitoxide` related features easier in select tests. +/// +/// Generally this will only affect arguments to `Execs` if we are in a special test run +/// marked with `RUSTFLAGS=--cfg test_gitoxide`. +pub trait Gitoxide { + fn maybe_fetch_with_gitoxide(&mut self) -> &mut Self; +} + +impl Gitoxide for crate::Execs { + /// Fetch both the crates-index as well as git dependencies with `gitoxide`. + fn maybe_fetch_with_gitoxide(&mut self) -> &mut Self { + #[cfg(test_gitoxide)] + enable_feature(self, "fetch"); + self + } +} + +#[cfg(test_gitoxide)] +fn enable_feature(exec: &mut crate::Execs, name: &str) { + exec.masquerade_as_nightly_cargo(&["gitoxide"]) + .arg(format!("-Zgitoxide={}", name)); +} diff --git a/tests/testsuite/registry.rs b/tests/testsuite/registry.rs index 6932f1a8d824..8aad97ce48ae 100644 --- a/tests/testsuite/registry.rs +++ b/tests/testsuite/registry.rs @@ -2,6 +2,7 @@ use cargo::core::SourceId; use cargo_test_support::cargo_process; +use cargo_test_support::git::Gitoxide; use cargo_test_support::paths::{self, CargoPathExt}; use cargo_test_support::registry::{ self, registry_path, Dependency, Package, RegistryBuilder, TestRegistry, @@ -1422,7 +1423,7 @@ fn fetch_downloads_http() { fetch_downloads(cargo_http); } -#[cargo_test] +#[cargo_test(gitoxide)] fn fetch_downloads_git() { fetch_downloads(cargo_stable); } @@ -1447,6 +1448,7 @@ fn fetch_downloads(cargo: fn(&Project, &str) -> Execs) { Package::new("a", "0.1.0").publish(); cargo(&p, "fetch") + .maybe_fetch_with_gitoxide() .with_stderr( "\ [UPDATING] `[..]` index