Skip to content

Commit 4aa4472

Browse files
sunshowersbors-libra
authored andcommitted
[x] integrate nextest, a new test runner
See diem#7994 for the details.
1 parent 7b1cc87 commit 4aa4472

File tree

9 files changed

+292
-15
lines changed

9 files changed

+292
-15
lines changed

.cargo/config

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ xfix = "run --package x --bin x -- fix"
77
xtest = "run --package x --bin x -- test"
88
xlint = "run --package x --bin x -- lint"
99
xbuild = "run --package x --bin x -- build"
10+
nextest = "run --package x --bin x -- nextest"

Cargo.lock

+69-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

devtools/x-core/src/lib.rs

+17
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,23 @@ impl XCoreContext {
9696
Ok(self.package_graph_plus()?.head())
9797
}
9898

99+
/// For a given list of workspace packages, returns a tuple of (known, unknown) packages.
100+
///
101+
/// Initializes the package graph if it isn't already done so, and returns an error if the
102+
pub fn partition_workspace_names<'a, B>(
103+
&self,
104+
names: impl IntoIterator<Item = &'a str>,
105+
) -> Result<(B, B)>
106+
where
107+
B: Default + Extend<&'a str>,
108+
{
109+
let workspace = self.package_graph()?.workspace();
110+
let (known, unknown) = names
111+
.into_iter()
112+
.partition(|name| workspace.contains_name(name));
113+
Ok((known, unknown))
114+
}
115+
99116
/// Returns information about the subsets for this workspace.
100117
pub fn subsets(&self) -> Result<&WorkspaceSubsets> {
101118
Ok(self.package_graph_plus()?.suffix())

devtools/x/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ license = "Apache-2.0"
99

1010
[dependencies]
1111
camino = "1.0.3"
12+
cargo_metadata = "0.13.1"
1213
determinator = "0.4.0"
1314
serde = { version = "1.0.124", features = ["derive"] }
1415
serde_json = "1.0.64"
@@ -25,6 +26,7 @@ chrono = "0.4.19"
2526
globset = "0.4.6"
2627
regex = "1.4.3"
2728
rayon = "1.5.0"
29+
testrunner = { git = "https://github.com/diem/diem-devtools", branch = "main" }
2830
indexmap = "1.6.2"
2931
x-core = { path = "../x-core" }
3032
x-lint = { path = "../x-lint" }

devtools/x/src/build.rs

-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ use structopt::StructOpt;
1313
pub struct Args {
1414
#[structopt(flatten)]
1515
package_args: SelectedPackageArgs,
16-
#[structopt(long, number_of_values = 1)]
17-
/// Package to exclude (see `cargo help pkgid`)
18-
exclude: Vec<String>,
1916
#[structopt(flatten)]
2017
build_args: BuildArgs,
2118
#[structopt(long, parse(from_os_str))]

devtools/x/src/cargo.rs

+32-7
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ use crate::{
77
utils::{apply_sccache_if_possible, project_root},
88
Result,
99
};
10-
use anyhow::anyhow;
10+
use anyhow::{anyhow, Context};
11+
use cargo_metadata::Message;
1112
use indexmap::map::IndexMap;
1213
use log::{info, warn};
1314
use std::{
1415
env,
1516
ffi::{OsStr, OsString},
17+
io::Cursor,
1618
path::Path,
1719
process::{Command, Output, Stdio},
1820
time::Instant,
@@ -207,12 +209,10 @@ impl Cargo {
207209
}
208210

209211
/// Runs this command, capturing the standard output into a `Vec<u8>`.
210-
/// No logging/timing will be displayed as the result of this call from x.
211-
#[allow(dead_code)]
212+
/// Standard error is forwarded.
212213
pub fn run_with_output(&mut self) -> Result<Vec<u8>> {
213214
self.inner.stderr(Stdio::inherit());
214-
// Since system out hijacked don't log for this command
215-
self.do_run(false).map(|o| o.stdout)
215+
self.do_run(true).map(|o| o.stdout)
216216
}
217217

218218
/// Internal run command, where the magic happens.
@@ -332,14 +332,39 @@ impl<'a> CargoCommand<'a> {
332332
return Ok(());
333333
}
334334

335+
let mut cargo = self.prepare_cargo(packages);
336+
cargo.run()
337+
}
338+
339+
/// Runs this command on the selected packages, returning the standard output as a bytestring.
340+
pub fn run_capture_messages(
341+
&self,
342+
packages: &SelectedPackages<'_>,
343+
) -> Result<impl Iterator<Item = Result<Message>>> {
344+
// Early return if we have no packages to run.
345+
let output = if !packages.should_invoke() {
346+
info!("no packages to {}: exiting early", self.as_str());
347+
vec![]
348+
} else {
349+
let mut cargo = self.prepare_cargo(packages);
350+
cargo.args(&["--message-format", "json"]);
351+
cargo.run_with_output()?
352+
};
353+
354+
Ok(Message::parse_stream(Cursor::new(output))
355+
.map(|message| message.context("error while parsing message from Cargo")))
356+
}
357+
358+
fn prepare_cargo(&self, packages: &SelectedPackages<'_>) -> Cargo {
335359
let mut cargo = Cargo::new(self.cargo_config(), self.as_str(), true);
336360
cargo
337361
.current_dir(project_root())
338362
.args(self.direct_args())
339363
.packages(packages)
340364
.pass_through(self.pass_through_args())
341-
.envs(self.get_extra_env().to_owned())
342-
.run()
365+
.envs(self.get_extra_env().to_owned());
366+
367+
cargo
343368
}
344369

345370
pub fn as_str(&self) -> &'static str {

devtools/x/src/cargo/selected_package.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use crate::{changed_since::changed_since_impl, context::XContext, Result};
55
use anyhow::anyhow;
66
use guppy::graph::DependencyDirection;
7+
use log::warn;
78
use std::collections::BTreeSet;
89
use structopt::StructOpt;
910
use x_core::WorkspaceStatus;
@@ -17,6 +18,9 @@ pub struct SelectedPackageArgs {
1718
#[structopt(long, short, number_of_values = 1)]
1819
/// Run on the specified members (package subsets)
1920
pub(crate) members: Vec<String>,
21+
#[structopt(long, number_of_values = 1)]
22+
/// Exclude packages
23+
pub(crate) exclude: Vec<String>,
2024
#[structopt(long, short)]
2125
/// Run on packages changed since the merge base of this commit
2226
changed_since: Option<String>,
@@ -70,7 +74,26 @@ impl SelectedPackageArgs {
7074
);
7175
}
7276

73-
Ok(SelectedPackages::new(includes))
77+
let mut ret = SelectedPackages::new(includes);
78+
79+
if !self.exclude.is_empty() {
80+
let workspace = xctx.core().package_graph()?.workspace();
81+
// Check that all the excluded package names are valid.
82+
let (known, unknown): (Vec<_>, Vec<_>) = xctx
83+
.core()
84+
.partition_workspace_names(self.exclude.iter().map(|package| package.as_str()))?;
85+
if !unknown.is_empty() {
86+
warn!(
87+
"excluded package(s) `{}` not found in workspace `{}`",
88+
unknown.join(", "),
89+
workspace.root()
90+
)
91+
}
92+
93+
ret.add_excludes(known);
94+
}
95+
96+
Ok(ret)
7497
}
7598
}
7699

devtools/x/src/main.rs

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ mod generate_summaries;
2424
mod generate_workspace_hack;
2525
mod installer;
2626
mod lint;
27+
mod nextest;
2728
mod playground;
2829
mod test;
2930
mod tools;
@@ -68,6 +69,9 @@ enum Command {
6869
#[structopt(name = "test")]
6970
/// Run tests
7071
Test(test::Args),
72+
#[structopt(name = "nextest")]
73+
/// Run tests with new test runner
74+
Nextest(nextest::Args),
7175
#[structopt(name = "tools")]
7276
/// Run tests
7377
Tools(tools::Args),
@@ -115,6 +119,7 @@ fn main() -> Result<()> {
115119
match args.cmd {
116120
Command::Tools(args) => tools::run(args, xctx),
117121
Command::Test(args) => test::run(args, xctx),
122+
Command::Nextest(args) => nextest::run(args, xctx),
118123
Command::Build(args) => build::run(args, xctx),
119124
Command::ChangedSince(args) => changed_since::run(args, xctx),
120125
Command::Check(args) => check::run(args, xctx),

0 commit comments

Comments
 (0)