Skip to content

Commit 20c1b2d

Browse files
committed
[nextest-runner] track test kind in RustTestCaseSummary
We're going to use this to run benchmarks in the future.
1 parent 720c124 commit 20c1b2d

File tree

2 files changed

+70
-15
lines changed

2 files changed

+70
-15
lines changed

nextest-metadata/src/test_list.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,12 @@ impl RustTestSuiteStatusSummary {
737737
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
738738
#[serde(rename_all = "kebab-case")]
739739
pub struct RustTestCaseSummary {
740+
/// The kind of Rust test this is.
741+
///
742+
/// This field is present since cargo-nextest 0.9.100. In earlier versions
743+
/// it is set to null.
744+
pub kind: Option<RustTestKind>,
745+
740746
/// Returns true if this test is marked ignored.
741747
///
742748
/// Ignored tests, if run, are executed with the `--ignored` argument.
@@ -748,6 +754,38 @@ pub struct RustTestCaseSummary {
748754
pub filter_match: FilterMatch,
749755
}
750756

757+
/// The kind of Rust test something is.
758+
///
759+
/// Part of a [`RustTestCaseSummary`].
760+
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Deserialize, Serialize)]
761+
#[serde(transparent)]
762+
pub struct RustTestKind(pub Cow<'static, str>);
763+
764+
impl RustTestKind {
765+
/// Creates a new `RustTestKind` from a string.
766+
#[inline]
767+
pub fn new(kind: impl Into<Cow<'static, str>>) -> Self {
768+
Self(kind.into())
769+
}
770+
771+
/// Creates a new `RustTestKind` from a static string.
772+
#[inline]
773+
pub const fn new_const(kind: &'static str) -> Self {
774+
Self(Cow::Borrowed(kind))
775+
}
776+
777+
/// Returns the kind as a string.
778+
pub fn as_str(&self) -> &str {
779+
&self.0
780+
}
781+
782+
/// The "test" kind, used for functions annotated with `#[test]`.
783+
pub const TEST: Self = Self::new_const("test");
784+
785+
/// The "bench" kind, used for functions annotated with `#[bench]`.
786+
pub const BENCH: Self = Self::new_const("bench");
787+
}
788+
751789
/// An enum describing whether a test matches a filter.
752790
#[derive(Copy, Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
753791
#[serde(rename_all = "kebab-case", tag = "status")]

nextest-runner/src/list/test_list.rs

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ use guppy::{
2929
use nextest_filtering::{BinaryQuery, EvalContext, TestQuery};
3030
use nextest_metadata::{
3131
BuildPlatform, FilterMatch, MismatchReason, RustBinaryId, RustNonTestBinaryKind,
32-
RustTestBinaryKind, RustTestBinarySummary, RustTestCaseSummary, RustTestSuiteStatusSummary,
33-
RustTestSuiteSummary, TestListSummary,
32+
RustTestBinaryKind, RustTestBinarySummary, RustTestCaseSummary, RustTestKind,
33+
RustTestSuiteStatusSummary, RustTestSuiteSummary, TestListSummary,
3434
};
3535
use owo_colors::OwoColorize;
3636
use std::{
@@ -604,10 +604,11 @@ impl<'g> TestList<'g> {
604604
// Treat ignored and non-ignored as separate sets of single filters, so that partitioning
605605
// based on one doesn't affect the other.
606606
let mut non_ignored_filter = filter.build();
607-
for test_name in Self::parse(&test_binary.binary_id, non_ignored.as_ref())? {
607+
for (test_name, kind) in Self::parse(&test_binary.binary_id, non_ignored.as_ref())? {
608608
test_cases.insert(
609609
test_name.into(),
610610
RustTestCaseSummary {
611+
kind: Some(kind),
611612
ignored: false,
612613
filter_match: non_ignored_filter.filter_match(
613614
&test_binary,
@@ -621,14 +622,15 @@ impl<'g> TestList<'g> {
621622
}
622623

623624
let mut ignored_filter = filter.build();
624-
for test_name in Self::parse(&test_binary.binary_id, ignored.as_ref())? {
625+
for (test_name, kind) in Self::parse(&test_binary.binary_id, ignored.as_ref())? {
625626
// Note that libtest prints out:
626627
// * just ignored tests if --ignored is passed in
627628
// * all tests, both ignored and non-ignored, if --ignored is not passed in
628629
// Adding ignored tests after non-ignored ones makes everything resolve correctly.
629630
test_cases.insert(
630631
test_name.into(),
631632
RustTestCaseSummary {
633+
kind: Some(kind),
632634
ignored: true,
633635
filter_match: ignored_filter.filter_match(
634636
&test_binary,
@@ -657,7 +659,7 @@ impl<'g> TestList<'g> {
657659
fn parse<'a>(
658660
binary_id: &'a RustBinaryId,
659661
list_output: &'a str,
660-
) -> Result<Vec<&'a str>, CreateTestListError> {
662+
) -> Result<Vec<(&'a str, RustTestKind)>, CreateTestListError> {
661663
let mut list = Self::parse_impl(binary_id, list_output).collect::<Result<Vec<_>, _>>()?;
662664
list.sort_unstable();
663665
Ok(list)
@@ -666,25 +668,29 @@ impl<'g> TestList<'g> {
666668
fn parse_impl<'a>(
667669
binary_id: &'a RustBinaryId,
668670
list_output: &'a str,
669-
) -> impl Iterator<Item = Result<&'a str, CreateTestListError>> + 'a + use<'a> {
671+
) -> impl Iterator<Item = Result<(&'a str, RustTestKind), CreateTestListError>> + 'a + use<'a>
672+
{
670673
// The output is in the form:
671674
// <test name>: test
672675
// <test name>: test
673676
// ...
674677

675-
list_output.lines().map(move |line| {
676-
line.strip_suffix(": test")
677-
.or_else(|| line.strip_suffix(": benchmark"))
678-
.ok_or_else(|| {
679-
CreateTestListError::parse_line(
678+
list_output
679+
.lines()
680+
.map(move |line| match line.strip_suffix(": test") {
681+
Some(test_name) => Ok((test_name, RustTestKind::TEST)),
682+
None => match line.strip_suffix(": benchmark") {
683+
Some(test_name) => Ok((test_name, RustTestKind::BENCH)),
684+
None => Err(CreateTestListError::parse_line(
680685
binary_id.clone(),
681686
format!(
682-
"line '{line}' did not end with the string ': test' or ': benchmark'"
687+
"line '{line}' did not end with the string \
688+
': test' or ': benchmark'"
683689
),
684690
list_output,
685-
)
686-
})
687-
})
691+
)),
692+
},
693+
})
688694
}
689695

690696
/// Writes this test list out in a human-friendly format.
@@ -1384,26 +1390,32 @@ mod tests {
13841390
status: RustTestSuiteStatus::Listed {
13851391
test_cases: btreemap! {
13861392
"tests::foo::test_bar".to_owned() => RustTestCaseSummary {
1393+
kind: Some(RustTestKind::TEST),
13871394
ignored: false,
13881395
filter_match: FilterMatch::Matches,
13891396
},
13901397
"tests::baz::test_quux".to_owned() => RustTestCaseSummary {
1398+
kind: Some(RustTestKind::TEST),
13911399
ignored: false,
13921400
filter_match: FilterMatch::Matches,
13931401
},
13941402
"benches::bench_foo".to_owned() => RustTestCaseSummary {
1403+
kind: Some(RustTestKind::BENCH),
13951404
ignored: false,
13961405
filter_match: FilterMatch::Matches,
13971406
},
13981407
"tests::ignored::test_bar".to_owned() => RustTestCaseSummary {
1408+
kind: Some(RustTestKind::TEST),
13991409
ignored: true,
14001410
filter_match: FilterMatch::Mismatch { reason: MismatchReason::Ignored },
14011411
},
14021412
"tests::baz::test_ignored".to_owned() => RustTestCaseSummary {
1413+
kind: None,
14031414
ignored: true,
14041415
filter_match: FilterMatch::Mismatch { reason: MismatchReason::Ignored },
14051416
},
14061417
"benches::ignored_bench_foo".to_owned() => RustTestCaseSummary {
1418+
kind: Some(RustTestKind::BENCH),
14071419
ignored: true,
14081420
filter_match: FilterMatch::Mismatch { reason: MismatchReason::Ignored },
14091421
},
@@ -1512,12 +1524,14 @@ mod tests {
15121524
"status": "listed",
15131525
"testcases": {
15141526
"benches::bench_foo": {
1527+
"kind": "bench",
15151528
"ignored": false,
15161529
"filter-match": {
15171530
"status": "matches"
15181531
}
15191532
},
15201533
"benches::ignored_bench_foo": {
1534+
"kind": "bench",
15211535
"ignored": true,
15221536
"filter-match": {
15231537
"status": "mismatch",
@@ -1532,18 +1546,21 @@ mod tests {
15321546
}
15331547
},
15341548
"tests::baz::test_quux": {
1549+
"kind": "test",
15351550
"ignored": false,
15361551
"filter-match": {
15371552
"status": "matches"
15381553
}
15391554
},
15401555
"tests::foo::test_bar": {
1556+
"kind": "test",
15411557
"ignored": false,
15421558
"filter-match": {
15431559
"status": "matches"
15441560
}
15451561
},
15461562
"tests::ignored::test_bar": {
1563+
"kind": "test",
15471564
"ignored": true,
15481565
"filter-match": {
15491566
"status": "mismatch",

0 commit comments

Comments
 (0)