Skip to content

Commit 074e823

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

File tree

2 files changed

+74
-19
lines changed

2 files changed

+74
-19
lines changed

nextest-metadata/src/test_list.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,9 @@ 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+
pub kind: RustTestKind,
742+
740743
/// Returns true if this test is marked ignored.
741744
///
742745
/// Ignored tests, if run, are executed with the `--ignored` argument.
@@ -748,6 +751,38 @@ pub struct RustTestCaseSummary {
748751
pub filter_match: FilterMatch,
749752
}
750753

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

nextest-runner/src/list/test_list.rs

Lines changed: 39 additions & 19 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,
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,
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,31 @@ 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(
680-
binary_id.clone(),
681-
format!(
682-
"line '{line}' did not end with the string ': test' or ': benchmark'"
683-
),
684-
list_output,
685-
)
686-
})
687-
})
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 => {
685+
return Err(CreateTestListError::parse_line(
686+
binary_id.clone(),
687+
format!(
688+
"line '{line}' did not end with the string \
689+
': test' or ': benchmark'"
690+
),
691+
list_output,
692+
));
693+
}
694+
},
695+
})
688696
}
689697

690698
/// Writes this test list out in a human-friendly format.
@@ -1384,26 +1392,32 @@ mod tests {
13841392
status: RustTestSuiteStatus::Listed {
13851393
test_cases: btreemap! {
13861394
"tests::foo::test_bar".to_owned() => RustTestCaseSummary {
1395+
kind: RustTestKind::TEST,
13871396
ignored: false,
13881397
filter_match: FilterMatch::Matches,
13891398
},
13901399
"tests::baz::test_quux".to_owned() => RustTestCaseSummary {
1400+
kind: RustTestKind::TEST,
13911401
ignored: false,
13921402
filter_match: FilterMatch::Matches,
13931403
},
13941404
"benches::bench_foo".to_owned() => RustTestCaseSummary {
1405+
kind: RustTestKind::BENCH,
13951406
ignored: false,
13961407
filter_match: FilterMatch::Matches,
13971408
},
13981409
"tests::ignored::test_bar".to_owned() => RustTestCaseSummary {
1410+
kind: RustTestKind::TEST,
13991411
ignored: true,
14001412
filter_match: FilterMatch::Mismatch { reason: MismatchReason::Ignored },
14011413
},
14021414
"tests::baz::test_ignored".to_owned() => RustTestCaseSummary {
1415+
kind: RustTestKind::TEST,
14031416
ignored: true,
14041417
filter_match: FilterMatch::Mismatch { reason: MismatchReason::Ignored },
14051418
},
14061419
"benches::ignored_bench_foo".to_owned() => RustTestCaseSummary {
1420+
kind: RustTestKind::BENCH,
14071421
ignored: true,
14081422
filter_match: FilterMatch::Mismatch { reason: MismatchReason::Ignored },
14091423
},
@@ -1512,38 +1526,44 @@ mod tests {
15121526
"status": "listed",
15131527
"testcases": {
15141528
"benches::bench_foo": {
1529+
"kind": "bench",
15151530
"ignored": false,
15161531
"filter-match": {
15171532
"status": "matches"
15181533
}
15191534
},
15201535
"benches::ignored_bench_foo": {
1536+
"kind": "bench",
15211537
"ignored": true,
15221538
"filter-match": {
15231539
"status": "mismatch",
15241540
"reason": "ignored"
15251541
}
15261542
},
15271543
"tests::baz::test_ignored": {
1544+
"kind": "test",
15281545
"ignored": true,
15291546
"filter-match": {
15301547
"status": "mismatch",
15311548
"reason": "ignored"
15321549
}
15331550
},
15341551
"tests::baz::test_quux": {
1552+
"kind": "test",
15351553
"ignored": false,
15361554
"filter-match": {
15371555
"status": "matches"
15381556
}
15391557
},
15401558
"tests::foo::test_bar": {
1559+
"kind": "test",
15411560
"ignored": false,
15421561
"filter-match": {
15431562
"status": "matches"
15441563
}
15451564
},
15461565
"tests::ignored::test_bar": {
1566+
"kind": "test",
15471567
"ignored": true,
15481568
"filter-match": {
15491569
"status": "mismatch",

0 commit comments

Comments
 (0)