Skip to content

Commit 3d946ea

Browse files
Merge pull request #103 from ErichDonGubler/align-test-scope
Rework `TestScope` model to meet Servo's needs
2 parents 98e2ff9 + a5fc188 commit 3d946ea

1 file changed

Lines changed: 123 additions & 84 deletions

File tree

moz-webgpu-cts/src/shared.rs

Lines changed: 123 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -435,12 +435,12 @@ pub(crate) struct TestPath<'a> {
435435
pub variant: Option<Cow<'a, str>>,
436436
}
437437

438-
const SCOPE_DIR_FX_PRIVATE_STR: &str = "testing/web-platform/mozilla";
439-
const SCOPE_DIR_FX_PRIVATE_COMPONENTS: &[&str] = &["testing", "web-platform", "mozilla"];
440-
const SCOPE_DIR_FX_PUBLIC_STR: &str = "testing/web-platform";
441-
const SCOPE_DIR_FX_PUBLIC_COMPONENTS: &[&str] = &["testing", "web-platform"];
442-
const SCOPE_DIR_SERVO_PUBLIC_STR: &str = "tests/wpt/webgpu";
443-
const SCOPE_DIR_SERVO_PUBLIC_COMPONENTS: &[&str] = &["tests", "wpt", "webgpu"];
438+
const SCOPE_DIR_FX_MOZILLA_STR: &str = "testing/web-platform/mozilla";
439+
const SCOPE_DIR_FX_MOZILLA_COMPONENTS: &[&str] = &["testing", "web-platform", "mozilla"];
440+
const SCOPE_DIR_FX_UPSTREAM_STR: &str = "testing/web-platform";
441+
const SCOPE_DIR_FX_UPSTREAM_COMPONENTS: &[&str] = &["testing", "web-platform"];
442+
const SCOPE_DIR_SERVO_WEBGPU_STR: &str = "tests/wpt/webgpu";
443+
const SCOPE_DIR_SERVO_WEBGPU_COMPONENTS: &[&str] = &["tests", "wpt", "webgpu"];
444444

445445
impl<'a> TestPath<'a> {
446446
pub fn from_execution_report(
@@ -449,23 +449,9 @@ impl<'a> TestPath<'a> {
449449
) -> Result<Self, ExecutionReportPathError<'a>> {
450450
let err = || ExecutionReportPathError { test_url_path };
451451

452-
let try_strip_with = |prefix, visibility| {
453-
test_url_path
454-
.strip_prefix(prefix)
455-
.map(|stripped| (visibility, stripped))
456-
};
457-
let vis_and_path = match browser {
458-
Browser::Firefox => try_strip_with("/_mozilla/", TestVisibility::Private),
459-
Browser::Servo => try_strip_with("/_webgpu/", TestVisibility::Public),
460-
}
461-
.or_else(|| try_strip_with("/", TestVisibility::Public));
462-
let Some((visibility, path)) = vis_and_path else {
463-
return Err(err());
464-
};
465-
let scope = TestScope {
466-
browser,
467-
visibility,
468-
};
452+
let (scope, path) = browser
453+
.strip_scope_url_prefix(test_url_path)
454+
.ok_or_else(err)?;
469455

470456
if path.contains('\\') {
471457
return Err(err());
@@ -510,21 +496,9 @@ impl<'a> TestPath<'a> {
510496
.ok_or(err())?,
511497
);
512498

513-
let (private_path, public_path) = match browser {
514-
Browser::Firefox => (SCOPE_DIR_FX_PRIVATE_STR, SCOPE_DIR_FX_PUBLIC_STR),
515-
Browser::Servo => (SCOPE_DIR_FX_PRIVATE_STR, SCOPE_DIR_SERVO_PUBLIC_STR),
516-
};
517-
let (visibility, path) = if let Ok(path) = rel_meta_file_path.strip_prefix(private_path) {
518-
(TestVisibility::Private, path)
519-
} else if let Ok(path) = rel_meta_file_path.strip_prefix(public_path) {
520-
(TestVisibility::Public, path)
521-
} else {
522-
return Err(err());
523-
};
524-
let scope = TestScope {
525-
browser,
526-
visibility,
527-
};
499+
let (scope, path) = browser
500+
.strip_scope_metadata_parent_path(rel_meta_file_path)
501+
.map_err(|_e| err())?;
528502

529503
let Ok(path) = path.strip_prefix("meta/") else {
530504
return Err(err());
@@ -538,7 +512,7 @@ impl<'a> TestPath<'a> {
538512

539513
Ok(Self {
540514
scope,
541-
path: Utf8Path::new(path).into(),
515+
path: path.into(),
542516
variant: variant.map(Into::into),
543517
})
544518
}
@@ -591,17 +565,12 @@ impl<'a> TestPath<'a> {
591565
scope,
592566
} = self;
593567
lazy_format!(move |f| {
594-
let TestScope {
595-
browser,
596-
visibility,
597-
} = scope;
598-
let scope_prefix = match (browser, visibility) {
599-
(Browser::Firefox, TestVisibility::Public) => "",
600-
(Browser::Firefox, TestVisibility::Private) => "_mozilla/",
601-
(Browser::Servo, TestVisibility::Public) => "_webgpu/",
602-
(Browser::Servo, TestVisibility::Private) => todo!(),
603-
};
604-
write!(f, "{scope_prefix}{}", path.components().join_with('/'))?;
568+
write!(
569+
f,
570+
"{}{}",
571+
scope.url_prefix(),
572+
path.components().join_with('/')
573+
)?;
605574
if let Some(variant) = variant.as_ref() {
606575
write!(f, "{}", variant)?;
607576
}
@@ -616,24 +585,16 @@ impl<'a> TestPath<'a> {
616585
scope,
617586
} = self;
618587

619-
let TestScope {
620-
browser,
621-
visibility,
622-
} = scope;
623-
let scope_dir = match (browser, visibility) {
624-
(Browser::Firefox, TestVisibility::Public) => SCOPE_DIR_FX_PUBLIC_COMPONENTS,
625-
(Browser::Firefox, TestVisibility::Private) => SCOPE_DIR_FX_PRIVATE_COMPONENTS,
626-
(Browser::Servo, TestVisibility::Public) => SCOPE_DIR_SERVO_PUBLIC_COMPONENTS,
627-
(Browser::Servo, TestVisibility::Private) => todo!(),
628-
}
629-
.iter()
630-
.chain(&["meta"])
631-
.join_with(std::path::MAIN_SEPARATOR);
588+
let scope_dir = scope
589+
.metadata_parent_path_components()
590+
.chain(["meta"].iter().cloned())
591+
.join_with(std::path::MAIN_SEPARATOR);
632592

633593
lazy_format!(move |f| { write!(f, "{scope_dir}{}{path}.ini", std::path::MAIN_SEPARATOR) })
634594
}
635595
}
636596

597+
/// An error encountered during [`TestPath::from_execution_report`].
637598
#[derive(Debug)]
638599
pub struct ExecutionReportPathError<'a> {
639600
test_url_path: &'a str,
@@ -653,6 +614,7 @@ impl Display for ExecutionReportPathError<'_> {
653614
}
654615
}
655616

617+
/// An error encountered during [`TestPath::from_metadata_test`].
656618
#[derive(Debug)]
657619
pub struct MetadataTestPathError<'a> {
658620
rel_meta_file_path: &'a Path,
@@ -673,28 +635,114 @@ impl Display for MetadataTestPathError<'_> {
673635
}
674636
}
675637

638+
/// A browser supported by [super::main], used for [`TestPath`]s.
676639
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, ValueEnum)]
677640
pub(crate) enum Browser {
678641
Firefox,
679642
Servo,
680643
}
681644

682-
#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
683-
pub(crate) enum TestVisibility {
645+
impl Browser {
646+
/// NOTE: Keep this implementation in sync with [`TestScope::url_prefix`].
647+
pub(crate) fn strip_scope_url_prefix<'a>(
648+
&self,
649+
url_path: &'a str,
650+
) -> Option<(TestScope, &'a str)> {
651+
let strip_prefix = |prefix, scope| {
652+
url_path
653+
.strip_prefix(prefix)
654+
.map(|stripped| (scope, stripped))
655+
};
656+
match self {
657+
Browser::Firefox => strip_prefix("/_mozilla/", FirefoxTestScope::Mozilla.into())
658+
.or_else(|| strip_prefix("/", FirefoxTestScope::Upstream.into())),
659+
Browser::Servo => strip_prefix("/_webgpu/", ServoTestScope::WebGpu.into()),
660+
}
661+
}
662+
663+
/// NOTE: Keep this implementation in sync with [`TestScope::metadata_parent_path_components`].
664+
pub(crate) fn strip_scope_metadata_parent_path<'a>(
665+
&self,
666+
path: &'a Utf8Path,
667+
) -> Result<(TestScope, &'a Utf8Path), std::path::StripPrefixError> {
668+
let strip_prefix =
669+
|prefix, scope| path.strip_prefix(prefix).map(|stripped| (scope, stripped));
670+
match self {
671+
Browser::Firefox => {
672+
strip_prefix(SCOPE_DIR_FX_MOZILLA_STR, FirefoxTestScope::Mozilla.into()).or_else(
673+
|_| strip_prefix(SCOPE_DIR_FX_UPSTREAM_STR, FirefoxTestScope::Upstream.into()),
674+
)
675+
}
676+
Browser::Servo => {
677+
strip_prefix(SCOPE_DIR_SERVO_WEBGPU_STR, ServoTestScope::WebGpu.into())
678+
}
679+
}
680+
}
681+
}
682+
683+
/// Symbolically represents a file root from which tests and metadata are based. Scopes are based
684+
/// on a specific [`Browser`].
685+
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
686+
pub(crate) enum TestScope {
687+
Firefox(FirefoxTestScope),
688+
Servo(ServoTestScope),
689+
}
690+
691+
impl TestScope {
692+
/// NOTE: Keep this implementation in sync with [`Browser::strip_scope_url_prefix`].
693+
fn url_prefix(&self) -> &str {
694+
match self {
695+
TestScope::Firefox(scope) => match scope {
696+
FirefoxTestScope::Upstream => "",
697+
FirefoxTestScope::Mozilla => "_mozilla/",
698+
},
699+
TestScope::Servo(ServoTestScope::WebGpu) => "_webgpu/",
700+
}
701+
}
702+
703+
/// NOTE: Keep this implementation in sync with [`Browser::strip_scope_metadata_parent_path`].
704+
fn metadata_parent_path_components(&self) -> impl Iterator<Item = &str> + Clone {
705+
match self {
706+
TestScope::Firefox(scope) => match scope {
707+
FirefoxTestScope::Upstream => SCOPE_DIR_FX_UPSTREAM_COMPONENTS,
708+
FirefoxTestScope::Mozilla => SCOPE_DIR_FX_MOZILLA_COMPONENTS,
709+
},
710+
TestScope::Servo(ServoTestScope::WebGpu) => SCOPE_DIR_SERVO_WEBGPU_COMPONENTS,
711+
}
712+
.iter()
713+
.cloned()
714+
}
715+
}
716+
717+
/// Subset of [`TestScope`] for [`Browser::Firefox`].
718+
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
719+
pub(crate) enum FirefoxTestScope {
684720
/// A public test available at some point in the history of [WPT upstream]. Note that while
685721
/// a test may be public, metadata associated with it is in a private location.
686722
///
687723
/// [WPT upstream]: https://github.com/web-platform-tests/wpt
688-
Public,
689-
/// A private test specific to browser.
690-
Private,
724+
Upstream,
725+
/// A private test specific to Firefox.
726+
Mozilla,
727+
}
728+
729+
impl From<FirefoxTestScope> for TestScope {
730+
fn from(value: FirefoxTestScope) -> Self {
731+
Self::Firefox(value)
732+
}
691733
}
692734

693-
/// Symbolically represents a file root from which tests and metadata are based.
735+
/// Subset of [`TestScope`] for [`Browser::Servo`].
694736
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
695-
pub(crate) struct TestScope {
696-
browser: Browser,
697-
visibility: TestVisibility,
737+
pub(crate) enum ServoTestScope {
738+
/// A WebGPU CTS test vendored into Servo's source tree.
739+
WebGpu,
740+
}
741+
742+
impl From<ServoTestScope> for TestScope {
743+
fn from(value: ServoTestScope) -> Self {
744+
Self::Servo(value)
745+
}
698746
}
699747

700748
#[test]
@@ -707,10 +755,7 @@ fn parse_test_path() {
707755
)
708756
.unwrap(),
709757
TestPath {
710-
scope: TestScope {
711-
browser: Browser::Firefox,
712-
visibility: TestVisibility::Private
713-
},
758+
scope: FirefoxTestScope::Mozilla.into(),
714759
path: Utf8Path::new("blarg/cts.https.html").into(),
715760
variant: Some("?stuff=things".into()),
716761
}
@@ -724,10 +769,7 @@ fn parse_test_path() {
724769
)
725770
.unwrap(),
726771
TestPath {
727-
scope: TestScope {
728-
browser: Browser::Firefox,
729-
visibility: TestVisibility::Public
730-
},
772+
scope: FirefoxTestScope::Upstream.into(),
731773
path: Utf8Path::new("stuff/things/cts.https.html").into(),
732774
variant: None,
733775
}
@@ -741,10 +783,7 @@ fn parse_test_path() {
741783
)
742784
.unwrap(),
743785
TestPath {
744-
scope: TestScope {
745-
browser: Browser::Servo,
746-
visibility: TestVisibility::Public
747-
},
786+
scope: ServoTestScope::WebGpu.into(),
748787
path: Utf8Path::new("webgpu/cts.https.html").into(),
749788
variant: Some("?stuff=things".into()),
750789
}

0 commit comments

Comments
 (0)