From c1b17398ecf53a6ad5a01f2034abe86e1a24b222 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Fri, 2 Aug 2024 16:46:39 -0400 Subject: [PATCH] WIP: feat: `tags` property on tests and subtests TODO: Worried about perf. from extra memory usage in tests. Conditional values defeat the purpose of tags, too. --- moz-webgpu-cts/src/main.rs | 2 + moz-webgpu-cts/src/wpt/metadata.rs | 170 +++++++++++++++++- moz-webgpu-cts/src/wpt/metadata/properties.rs | 6 + 3 files changed, 176 insertions(+), 2 deletions(-) diff --git a/moz-webgpu-cts/src/main.rs b/moz-webgpu-cts/src/main.rs index 1a69c7b..1b51f08 100644 --- a/moz-webgpu-cts/src/main.rs +++ b/moz-webgpu-cts/src/main.rs @@ -579,6 +579,7 @@ fn run(cli: Cli) -> ExitCode { is_disabled, expected, implementation_status: _, + tags: _, } = properties; let test_name = Arc::new(test_name); @@ -703,6 +704,7 @@ fn run(cli: Cli) -> ExitCode { is_disabled, expected, implementation_status: _, + tags: _, } = properties; if is_disabled { diff --git a/moz-webgpu-cts/src/wpt/metadata.rs b/moz-webgpu-cts/src/wpt/metadata.rs index 5696044..8480855 100644 --- a/moz-webgpu-cts/src/wpt/metadata.rs +++ b/moz-webgpu-cts/src/wpt/metadata.rs @@ -181,11 +181,34 @@ fn tags_parser<'a, T>( helper: &mut PropertiesParseHelper<'a>, conditional_term: impl Parser<'a, &'a str, T, ParseError<'a>>, ) -> impl Parser<'a, &'a str, PropertyValue>, ParseError<'a>> { + use crate::chumsky::{error::Error, util::MaybeRef}; + + let tag_ident = { + let underscore_or_hyphen = |c| matches!(c, '_' | '-'); + any::<'a, &'a str, ParseError<'a>>() + .try_map(move |c: char, span| { + if c.is_ascii_alphabetic() || underscore_or_hyphen(c) { + Ok(c) + } else { + Err(Error::<&'a str>::expected_found( + [], + Some(MaybeRef::Val(c)), + span, + )) + } + }) + .then( + any() + .filter(move |c: &char| c.is_ascii_alphanumeric() || underscore_or_hyphen(*c)) + .repeated(), + ) + .to_slice() + }; helper .parser( keyword("tags").to(()), conditional_term, - ascii::ident() + tag_ident .map(|i: &str| i.to_owned()) .separated_by(just(',').padded_by(inline_whitespace())) .collect() @@ -759,6 +782,7 @@ where is_disabled, expected, implementation_status, + tags, } = property; if *is_disabled { @@ -839,6 +863,25 @@ where Ok(()) } + if let Some(tags) = tags { + use std::borrow::Cow; + + #[derive(Clone, Debug, Default, Eq, PartialEq)] + struct TagsDisplay<'a>(Cow<'a, Vec>); + + impl Display for TagsDisplay<'_> { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let Self(tags) = self; + Display::fmt(&tags.iter().join_with(", "), f) + } + } + + let tags_ref = tags.as_ref(); + let tags_ref = tags_ref.map(Cow::Borrowed).map(TagsDisplay); + + write_normalized(f, &indent, TAGS_IDENT, tags_ref)?; + } + if let Some(implementation_status) = implementation_status { write_normalized( f, @@ -877,6 +920,7 @@ where pub is_disabled: bool, pub expected: Option>>, pub implementation_status: Option>, + pub tags: Option>>, } impl<'a, Out> TestProps @@ -888,6 +932,7 @@ where is_disabled, expected, implementation_status, + tags, } = self; let TestProp { kind, span } = prop; @@ -966,6 +1011,7 @@ where implementation_status, val, ), + TestPropKind::Tags(val) => conditional(emitter, span, TAGS_IDENT, tags, val), } } } @@ -993,6 +1039,7 @@ where Expected(PropertyValue>), Disabled, ImplementationStatus(PropertyValue), + Tags(PropertyValue>), } impl TestProp @@ -1170,18 +1217,23 @@ where helper .parser( ImplementationStatus::property_ident_parser(), - conditional_term, + conditional_term.clone(), ImplementationStatus::property_value_parser(), ) .map_with(|((), val), e| TestProp { span: e.span(), kind: TestPropKind::ImplementationStatus(val), }), + tags_parser(helper, conditional_term).map_with(|val, e| TestProp { + span: e.span(), + kind: TestPropKind::Tags(val), + }), )) } } pub(crate) const EXPECTED_IDENT: &str = "expected"; +pub(crate) const TAGS_IDENT: &str = "expected"; pub(crate) const PASS: &str = "PASS"; pub(crate) const FAIL: &str = "FAIL"; pub(crate) const NOTRUN: &str = "NOTRUN"; @@ -1345,6 +1397,7 @@ r#" is_disabled: false, expected: None, implementation_status: None, + tags: None, }, subtests: {}, }, @@ -1379,6 +1432,7 @@ r#" is_disabled: false, expected: None, implementation_status: None, + tags: None, }, subtests: { "blarg": Subtest { @@ -1386,6 +1440,7 @@ r#" is_disabled: false, expected: None, implementation_status: None, + tags: None, }, }, }, @@ -1422,6 +1477,7 @@ r#" is_disabled: false, expected: None, implementation_status: None, + tags: None, }, subtests: { "blarg": Subtest { @@ -1458,6 +1514,7 @@ r#" ), ), implementation_status: None, + tags: None, }, }, }, @@ -1490,6 +1547,7 @@ r#" is_disabled: false, expected: None, implementation_status: None, + tags: None, }, subtests: { "blarg": Subtest { @@ -1532,6 +1590,7 @@ r#" ), ), implementation_status: None, + tags: None, }, }, }, @@ -1591,6 +1650,7 @@ r#" ), ), implementation_status: None, + tags: None, }, subtests: { "blarg": Subtest { @@ -1627,6 +1687,7 @@ r#" ), ), implementation_status: None, + tags: None, }, }, }, @@ -1657,6 +1718,7 @@ r#" is_disabled: false, expected: None, implementation_status: None, + tags: None, }, subtests: { "blarg": Subtest { @@ -1693,6 +1755,7 @@ r#" ), ), implementation_status: None, + tags: None, }, }, }, @@ -1724,6 +1787,7 @@ r#" is_disabled: false, expected: None, implementation_status: None, + tags: None, }, subtests: { "blarg": Subtest { @@ -1760,6 +1824,7 @@ r#" ), ), implementation_status: None, + tags: None, }, }, }, @@ -1789,6 +1854,7 @@ r#" is_disabled: false, expected: None, implementation_status: None, + tags: None, }, subtests: { ":": Subtest { @@ -1825,6 +1891,7 @@ r#" ), ), implementation_status: None, + tags: None, }, }, }, @@ -1888,6 +1955,105 @@ r#" ), ), implementation_status: None, + tags: None, + }, + subtests: {}, + }, + ), + ), + errs: [], + } + "### + ); + assert_debug_snapshot!( + parser().parse( +r#" +[this_is_tagged.https.html] + tags: [webgpu, webgpu-long] + expected: [PASS, TIMEOUT] +"# + ), + @r###" + ParseResult { + output: Some( + ( + "this_is_tagged.https.html", + Test { + properties: TestProps { + is_disabled: false, + expected: Some( + ExpandedPropertyValue( + { + Windows: { + Debug: [ + Pass, + Timeout, + ], + Optimized: [ + Pass, + Timeout, + ], + }, + Linux: { + Debug: [ + Pass, + Timeout, + ], + Optimized: [ + Pass, + Timeout, + ], + }, + MacOs: { + Debug: [ + Pass, + Timeout, + ], + Optimized: [ + Pass, + Timeout, + ], + }, + }, + ), + ), + implementation_status: None, + tags: Some( + ExpandedPropertyValue( + { + Windows: { + Debug: [ + "webgpu", + "webgpu-long", + ], + Optimized: [ + "webgpu", + "webgpu-long", + ], + }, + Linux: { + Debug: [ + "webgpu", + "webgpu-long", + ], + Optimized: [ + "webgpu", + "webgpu-long", + ], + }, + MacOs: { + Debug: [ + "webgpu", + "webgpu-long", + ], + Optimized: [ + "webgpu", + "webgpu-long", + ], + }, + }, + ), + ), }, subtests: {}, }, diff --git a/moz-webgpu-cts/src/wpt/metadata/properties.rs b/moz-webgpu-cts/src/wpt/metadata/properties.rs index ee8bcb8..7cfd5a0 100644 --- a/moz-webgpu-cts/src/wpt/metadata/properties.rs +++ b/moz-webgpu-cts/src/wpt/metadata/properties.rs @@ -290,6 +290,12 @@ impl ExpandedPropertyValue { let Self(inner) = self; inner } + + pub(crate) fn as_ref(&self) -> ExpandedPropertyValue<&T> { + ExpandedPropertyValue::from_query(|platform, build_profile| { + &self[(platform, build_profile)] + }) + } } impl ExpandedPropertyValue {