Skip to content

Commit

Permalink
[nextest-runner] initial support for recording runs
Browse files Browse the repository at this point in the history
Gated behind an environment variable.
  • Loading branch information
sunshowers committed Jan 29, 2024
1 parent 92522ce commit bce2805
Show file tree
Hide file tree
Showing 17 changed files with 1,719 additions and 45 deletions.
49 changes: 47 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 43 additions & 18 deletions cargo-nextest/src/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ use nextest_runner::{
platform::BuildPlatforms,
reporter::{structured, FinalStatusLevel, StatusLevel, TestOutputDisplay, TestReporterBuilder},
reuse_build::{archive_to_file, ArchiveReporter, MetadataOrPath, PathMapper, ReuseBuildInfo},
run_store::RunStore,
runner::{configure_handle_inheritance, RunStatsFailureKind, TestRunnerBuilder},
show_config::{ShowNextestVersion, ShowTestGroupSettings, ShowTestGroups, ShowTestGroupsMode},
signal::SignalHandlerKind,
target_runner::{PlatformRunner, TargetRunner},
test_filter::{RunIgnored, TestFilterBuilder},
test_output::CaptureStrategy,
};
use once_cell::sync::OnceCell;
use owo_colors::{OwoColorize, Stream, Style};
Expand Down Expand Up @@ -743,10 +745,7 @@ pub struct TestRunnerOpts {
}

impl TestRunnerOpts {
fn to_builder(
&self,
cap_strat: nextest_runner::test_output::CaptureStrategy,
) -> Option<TestRunnerBuilder> {
fn to_builder(&self, cap_strat: CaptureStrategy) -> Option<TestRunnerBuilder> {
if self.no_run {
return None;
}
Expand Down Expand Up @@ -1557,7 +1556,6 @@ impl App {
structured_reporter.set_libtest(libtest);
}
};
use nextest_runner::test_output::CaptureStrategy;

let cap_strat = if no_capture {
CaptureStrategy::None
Expand All @@ -1584,19 +1582,6 @@ impl App {
let output = output_writer.reporter_output();
let profile = profile.apply_build_platforms(&build_platforms);

let mut reporter = reporter_opts
.to_builder(no_capture)
.set_verbose(self.base.output.verbose)
.build(&test_list, &profile, output, structured_reporter);
if self
.base
.output
.color
.should_colorize(supports_color::Stream::Stderr)
{
reporter.colorize();
}

let handler = SignalHandlerKind::Standard;
let runner_builder = match runner_opts.to_builder(cap_strat) {
Some(runner_builder) => runner_builder,
Expand All @@ -1615,11 +1600,51 @@ impl App {
target_runner.clone(),
)?;

// Start recording runs if the environment variable is set.
{
const EXPERIMENTAL_ENV: &str = "NEXTEST_EXPERIMENTAL_RECORD_RUNS";
if std::env::var(EXPERIMENTAL_ENV).as_deref() == Ok("1") {
// For the record reporter, use the global store dir to share runs across profiles.
let store = RunStore::new(profile.global_store_dir())
.map_err(|err| ExpectedError::RunRecordError { err })?;
let locked_store = store
.lock_exclusive()
.map_err(|err| ExpectedError::RunRecordError { err })?;
let recorder = locked_store
.create_run_recorder(
runner.run_id(),
self.base.current_version.clone(),
runner.started_at().fixed_offset(),
)
.map_err(|err| ExpectedError::RunRecordError { err })?;

Check warning on line 1619 in cargo-nextest/src/dispatch.rs

View check run for this annotation

Codecov / codecov/patch

cargo-nextest/src/dispatch.rs#L1608-L1619

Added lines #L1608 - L1619 were not covered by tests

let record = structured::RecordReporter::new(recorder);
structured_reporter.set_record(record);

Check warning on line 1622 in cargo-nextest/src/dispatch.rs

View check run for this annotation

Codecov / codecov/patch

cargo-nextest/src/dispatch.rs#L1621-L1622

Added lines #L1621 - L1622 were not covered by tests
}
}

let mut reporter = reporter_opts
.to_builder(no_capture)
.set_verbose(self.base.output.verbose)
.build(&test_list, &profile, output, structured_reporter);
if self
.base
.output
.color
.should_colorize(supports_color::Stream::Stderr)
{
reporter.colorize();

Check warning on line 1636 in cargo-nextest/src/dispatch.rs

View check run for this annotation

Codecov / codecov/patch

cargo-nextest/src/dispatch.rs#L1635-L1636

Added lines #L1635 - L1636 were not covered by tests
}

configure_handle_inheritance(no_capture)?;
reporter.report_meta(&self.base.cargo_metadata_json, &test_list);

let run_stats = runner.try_execute(|event| {
// Write and flush the event.
reporter.report_event(event)
})?;
reporter.finish()?;

self.base
.check_version_config_final(version_only_config.nextest_version())?;
if !run_stats.is_success() {
Expand Down
10 changes: 10 additions & 0 deletions cargo-nextest/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,11 @@ pub enum ExpectedError {
#[from]
err: FromMessagesError,
},
#[error("error recording test run")]
RunRecordError {
#[source]
err: RunStoreError,
},
#[error("create test list error")]
CreateTestListError {
#[source]
Expand Down Expand Up @@ -386,6 +391,7 @@ impl ExpectedError {
| Self::TestFilterBuilderError { .. }
| Self::UnknownHostPlatform { .. }
| Self::ArgumentFileReadError { .. }
| Self::RunRecordError { .. }
| Self::UnknownArchiveFormat { .. }
| Self::ArchiveExtractError { .. }
| Self::RustBuildMetaParseError { .. }
Expand Down Expand Up @@ -700,6 +706,10 @@ impl ExpectedError {
log::error!("failed to parse messages generated by Cargo");
Some(err as &dyn Error)
}
Self::RunRecordError { err } => {
log::error!("error recording run");
Some(err as &dyn Error)

Check warning on line 711 in cargo-nextest/src/errors.rs

View check run for this annotation

Codecov / codecov/patch

cargo-nextest/src/errors.rs#L709-L711

Added lines #L709 - L711 were not covered by tests
}
Self::CreateTestListError { err } => {
log::error!("creating test list failed");
Some(err as &dyn Error)
Expand Down
1 change: 1 addition & 0 deletions nextest-metadata/src/test_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ impl TestListSummary {
rust_suites: BTreeMap::new(),
}
}

/// Parse JSON output from `cargo nextest list --message-format json`.
pub fn parse_json(json: impl AsRef<str>) -> Result<Self, serde_json::Error> {
serde_json::from_str(json.as_ref())
Expand Down
6 changes: 4 additions & 2 deletions nextest-runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ config = { version = "0.13.4", default-features = false, features = [
] }
cargo_metadata = "0.18.1"
cfg-if = "1.0.0"
chrono = "0.4.33"
chrono = { version = "0.4.33", features = ["serde"] }
debug-ignore = "1.0.5"
display-error-chain = "0.2.0"
either = "1.9.0"
futures = "0.3.30"
fs4 = "0.7.0"
guppy = "0.17.4"
# Used to find the cargo root directory, which is needed in case the user has
# added a config.toml there
Expand Down Expand Up @@ -77,6 +78,7 @@ tokio = { version = "1.35.1", features = [
toml = "0.8.8"
toml_edit = { version = "0.21.0", features = ["serde"] }
xxhash-rust = { version = "0.8.8", features = ["xxh64"] }
zip = { version = "0.6.6", default-features = false, features = ["zstd"] }
zstd = { version = "0.13.0", features = ["zstdmt"] }

###
Expand All @@ -93,7 +95,7 @@ self_update = { version = "0.39.0", optional = true, default-features = false, f
nextest-filtering = { version = "0.7.1", path = "../nextest-filtering" }
nextest-metadata = { version = "0.10.0", path = "../nextest-metadata" }
quick-junit = { version = "0.3.5", path = "../quick-junit" }
uuid = { version = "1.7.0", features = ["v4"] }
uuid = { version = "1.7.0", features = ["v4", "serde"] }
console-subscriber = { version = "0.2.0", optional = true }
unicode-ident = "1.0.12"
unicode-normalization = "0.1.22"
Expand Down
Loading

0 comments on commit bce2805

Please sign in to comment.