@@ -65,6 +65,25 @@ pub fn run_cts(
6565 let llvm_cov = args. contains ( "--llvm-cov" ) ;
6666 let release = args. contains ( "--release" ) ;
6767 let running_on_backend = args. opt_value_from_str :: < _ , String > ( "--backend" ) ?;
68+ let mut filter_pattern = args. opt_value_from_str :: < _ , String > ( "--filter" ) ?;
69+ let mut filter_invert = false ;
70+
71+ if let Some ( filter) = filter_pattern. as_deref ( ) {
72+ if let Some ( filter) = filter. strip_prefix ( '!' ) {
73+ filter_pattern = Some ( filter. to_owned ( ) ) ;
74+ filter_invert = true ;
75+ }
76+ }
77+
78+ // Compile filter regex early to fail fast on invalid patterns
79+ let filter = if let Some ( pattern) = filter_pattern {
80+ Some (
81+ Regex :: new ( & pattern)
82+ . context ( format ! ( "Invalid regex pattern '{pattern}' for --filter" ) ) ?,
83+ )
84+ } else {
85+ None
86+ } ;
6887
6988 if running_on_backend. is_none ( ) {
7089 log:: warn!(
@@ -125,6 +144,33 @@ pub fn run_cts(
125144 } ) )
126145 }
127146
147+ // Apply filter if specified
148+ if let Some ( ref filter) = filter {
149+ let original_count = tests. len ( ) ;
150+ tests. retain ( |test| {
151+ let selector_str = test. selector . to_string_lossy ( ) ;
152+ let matched = filter. is_match ( & selector_str) ;
153+ if filter_invert {
154+ !matched
155+ } else {
156+ matched
157+ }
158+ } ) ;
159+ let filtered_count = tests. len ( ) ;
160+ if filtered_count == original_count {
161+ log:: warn!( "Filter did not exclude any tests" ) ;
162+ } else if filtered_count != 0 {
163+ log:: info!(
164+ "Filter selected {filtered_count} of {original_count} test{}" ,
165+ if original_count == 1 { "" } else { "s" } ,
166+ ) ;
167+ } else if filtered_count == 0 {
168+ bail ! ( "Filter did not select any tests" ) ;
169+ } else {
170+ bail ! ( "Filtering introduced additional tests??" ) ;
171+ }
172+ }
173+
128174 let wgpu_cargo_toml = std:: path:: absolute ( shell. current_dir ( ) . join ( "Cargo.toml" ) )
129175 . context ( "Failed to get path to Cargo.toml" ) ?;
130176
0 commit comments