Skip to content

Commit 5595873

Browse files
authored
fix!: Remove unstable features from libtest (#95)
This originally started as a direct replacement for libtest and was aiming for 1:1 feature parity, even for unstable features. As we've instead shifted to trying to define a minimal API for test runners to call into and for a lot of these responsibilities to be in test runners, a lot of this does not make sense to include.
2 parents 8bd08ea + ad28f8a commit 5595873

14 files changed

Lines changed: 15 additions & 646 deletions

File tree

crates/libtest-json/event.schema.json

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,6 @@
4444
"elapsed_s": {
4545
"$ref": "#/$defs/Elapsed"
4646
},
47-
"seed": {
48-
"type": [
49-
"integer",
50-
"null"
51-
],
52-
"format": "uint64",
53-
"minimum": 0
54-
},
5547
"event": {
5648
"type": "string",
5749
"const": "discover-complete"

crates/libtest-json/src/event.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ pub enum Event {
1313
DiscoverComplete {
1414
#[allow(dead_code)]
1515
elapsed_s: Elapsed,
16-
seed: Option<u64>,
1716
},
1817
SuiteStart,
1918
CaseStart {

crates/libtest-lexarg/src/lib.rs

Lines changed: 2 additions & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,14 @@ pub struct TestOpts {
2424
pub list: bool,
2525
pub filters: Vec<String>,
2626
pub filter_exact: bool,
27-
pub force_run_in_process: bool,
28-
pub exclude_should_panic: bool,
2927
pub run_ignored: RunIgnored,
3028
pub run_tests: bool,
3129
pub bench_benchmarks: bool,
3230
pub nocapture: bool,
3331
pub color: ColorConfig,
3432
pub format: OutputFormat,
35-
pub shuffle: bool,
36-
pub shuffle_seed: Option<u64>,
3733
pub test_threads: Option<std::num::NonZeroUsize>,
3834
pub skip: Vec<String>,
39-
pub time_options: Option<TestTimeOptions>,
4035
/// Stop at first failing test.
4136
/// May run a few more tests due to threading, but will
4237
/// abort as soon as possible.
@@ -83,8 +78,6 @@ pub enum OutputFormat {
8378
Terse,
8479
/// JSON output
8580
Json,
86-
/// JUnit output
87-
Junit,
8881
}
8982

9083
impl Default for OutputFormat {
@@ -93,90 +86,6 @@ impl Default for OutputFormat {
9386
}
9487
}
9588

96-
/// Structure with parameters for calculating test execution time (see [`TestOpts::time_options`])
97-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
98-
pub struct TestTimeOptions {
99-
/// Denotes if the test critical execution time limit excess should be considered
100-
/// a test failure.
101-
pub error_on_excess: bool,
102-
pub unit_threshold: TimeThreshold,
103-
pub integration_threshold: TimeThreshold,
104-
pub doctest_threshold: TimeThreshold,
105-
}
106-
107-
impl Default for TestTimeOptions {
108-
fn default() -> Self {
109-
Self {
110-
error_on_excess: false,
111-
unit_threshold: TimeThreshold {
112-
warn: std::time::Duration::from_millis(50),
113-
critical: std::time::Duration::from_millis(100),
114-
},
115-
integration_threshold: TimeThreshold {
116-
warn: std::time::Duration::from_millis(50),
117-
critical: std::time::Duration::from_millis(100),
118-
},
119-
doctest_threshold: TimeThreshold {
120-
warn: std::time::Duration::from_millis(50),
121-
critical: std::time::Duration::from_millis(100),
122-
},
123-
}
124-
}
125-
}
126-
127-
/// Structure denoting time limits for test execution (see [`TestTimeOptions`])
128-
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
129-
pub struct TimeThreshold {
130-
pub warn: std::time::Duration,
131-
pub critical: std::time::Duration,
132-
}
133-
134-
impl TimeThreshold {
135-
/// Attempts to create a `TimeThreshold` instance with values obtained
136-
/// from the environment variable, and returns `None` if the variable
137-
/// is not set.
138-
/// Environment variable format is expected to match `\d+,\d+`.
139-
///
140-
/// # Panics
141-
///
142-
/// Panics if variable with provided name is set but contains inappropriate
143-
/// value.
144-
fn from_env_var(env_var_name: &str) -> Result<Option<Self>, ErrorContext<'static>> {
145-
use std::str::FromStr;
146-
147-
let durations_str = match std::env::var(env_var_name) {
148-
Ok(value) => value,
149-
Err(_) => {
150-
return Ok(None);
151-
}
152-
};
153-
let (warn_str, critical_str) = durations_str.split_once(',').ok_or_else(|| {
154-
ErrorContext::msg(format_args!(
155-
"Duration variable {env_var_name} expected to have 2 numbers separated by comma, but got {durations_str}"
156-
))
157-
})?;
158-
159-
let parse_u64 = |v| {
160-
u64::from_str(v).map_err(|_err| {
161-
ErrorContext::msg(format_args!(
162-
"Duration value in variable {env_var_name} is expected to be a number, but got {v}"
163-
))
164-
})
165-
};
166-
167-
let warn = parse_u64(warn_str)?;
168-
let critical = parse_u64(critical_str)?;
169-
if warn > critical {
170-
panic!("Test execution warn time should be less or equal to the critical time");
171-
}
172-
173-
Ok(Some(Self {
174-
warn: std::time::Duration::from_millis(warn),
175-
critical: std::time::Duration::from_millis(critical),
176-
}))
177-
}
178-
}
179-
18089
/// Options for the test run defined by the caller (instead of CLI arguments) (see
18190
/// [`TestOpts::options`])
18291
///
@@ -194,10 +103,6 @@ Options:
194103
--include-ignored
195104
Run ignored and not ignored tests
196105
--ignored Run only ignored tests
197-
--force-run-in-process
198-
Forces tests to run in-process when panic=abort
199-
--exclude-should-panic
200-
Excludes tests marked as should_panic
201106
--test Run tests and not benchmarks
202107
--bench Run benchmarks instead of tests
203108
--list List all tests and benchmarks
@@ -216,12 +121,11 @@ Options:
216121
on serially (default);
217122
always = always colorize output;
218123
never = never colorize output;
219-
--format pretty|terse|json|junit
124+
--format pretty|terse|json
220125
Configure formatting of output:
221126
pretty = Print verbose output;
222127
terse = Display one character per test;
223128
json = Output a json document;
224-
junit = Output a JUnit document
225129
--show-output Show captured stdout of successful tests
226130
-Z unstable-options Enable nightly-only flags:
227131
unstable-options = Allow use of experimental features
@@ -247,10 +151,6 @@ Options:
247151
`VARIABLE=WARN_TIME,CRITICAL_TIME`.
248152
`CRITICAL_TIME` here means the limit that should not
249153
be exceeded by test.
250-
--shuffle Run tests in random order
251-
--shuffle-seed SEED
252-
Run tests in random order; seed the random number
253-
generator with SEED
254154
"#;
255155

256156
pub const AFTER_HELP: &str = r#"
@@ -262,12 +162,6 @@ By default, all tests are run in parallel. This can be altered with the
262162
--test-threads flag or the RUST_TEST_THREADS environment variable when running
263163
tests (set it to 1).
264164
265-
By default, the tests are run in alphabetical order. Use --shuffle or set
266-
RUST_TEST_SHUFFLE to run the tests in random order. Pass the generated
267-
"shuffle seed" to --shuffle-seed (or set RUST_TEST_SHUFFLE_SEED) to run the
268-
tests in the same order again. Note that --shuffle and --shuffle-seed do not
269-
affect whether the tests are run in parallel.
270-
271165
All tests have their standard output and standard error captured by default.
272166
This can be overridden with the --nocapture flag or setting RUST_TEST_NOCAPTURE
273167
environment variable to a value other than "0". Logging is not captured by default.
@@ -318,12 +212,6 @@ impl TestOptsBuilder {
318212
self.include_ignored = true;
319213
}
320214
Long("ignored") => self.ignored = true,
321-
Long("force-run-in-process") => {
322-
self.opts.force_run_in_process = true;
323-
}
324-
Long("exclude-should-panic") => {
325-
self.opts.exclude_should_panic = true;
326-
}
327215
Long("test") => {
328216
self.opts.run_tests = true;
329217
}
@@ -377,13 +265,12 @@ impl TestOptsBuilder {
377265
let format = parser
378266
.next_flag_value()
379267
.ok_or_missing(Value(std::ffi::OsStr::new("FORMAT")))
380-
.one_of(&["pretty", "terse", "json", "junit"])
268+
.one_of(&["pretty", "terse", "json"])
381269
.within(arg)?;
382270
self.format = Some(match format {
383271
"pretty" => OutputFormat::Pretty,
384272
"terse" => OutputFormat::Terse,
385273
"json" => OutputFormat::Json,
386-
"junit" => OutputFormat::Junit,
387274
_ => unreachable!("`one_of` should prevent this"),
388275
});
389276
}
@@ -402,34 +289,6 @@ impl TestOptsBuilder {
402289
// Don't validate `feature` as other parsers might provide values
403290
self.opts.allowed_unstable.push(feature.to_owned());
404291
}
405-
Long("report-time") => {
406-
self.opts.time_options.get_or_insert_with(Default::default);
407-
}
408-
Long("ensure-time") => {
409-
let time = self.opts.time_options.get_or_insert_with(Default::default);
410-
time.error_on_excess = true;
411-
if let Some(threshold) = TimeThreshold::from_env_var("RUST_TEST_TIME_UNIT")? {
412-
time.unit_threshold = threshold;
413-
}
414-
if let Some(threshold) = TimeThreshold::from_env_var("RUST_TEST_TIME_INTEGRATION")?
415-
{
416-
time.integration_threshold = threshold;
417-
}
418-
if let Some(threshold) = TimeThreshold::from_env_var("RUST_TEST_TIME_DOCTEST")? {
419-
time.doctest_threshold = threshold;
420-
}
421-
}
422-
Long("shuffle") => {
423-
self.opts.shuffle = true;
424-
}
425-
Long("shuffle-seed") => {
426-
let seed = parser
427-
.next_flag_value()
428-
.ok_or_missing(Value(std::ffi::OsStr::new("SEED")))
429-
.parse()
430-
.within(arg)?;
431-
self.opts.shuffle_seed = Some(seed);
432-
}
433292
Value(filter) => {
434293
let filter = filter.string("FILTER")?;
435294
self.opts.filters.push(filter.to_owned());
@@ -449,49 +308,6 @@ impl TestOptsBuilder {
449308
.iter()
450309
.any(|f| f == UNSTABLE_OPTIONS);
451310

452-
if self.opts.force_run_in_process && !allow_unstable_options {
453-
return Err(ErrorContext::msg(
454-
"`--force-run-in-process` requires `-Zunstable-options`",
455-
));
456-
}
457-
458-
if self.opts.exclude_should_panic && !allow_unstable_options {
459-
return Err(ErrorContext::msg(
460-
"`--exclude-should-panic` requires `-Zunstable-options`",
461-
));
462-
}
463-
464-
if self.opts.shuffle && !allow_unstable_options {
465-
return Err(ErrorContext::msg(
466-
"`--shuffle` requires `-Zunstable-options`",
467-
));
468-
}
469-
if !self.opts.shuffle && allow_unstable_options {
470-
self.opts.shuffle = match std::env::var("RUST_TEST_SHUFFLE") {
471-
Ok(val) => &val != "0",
472-
Err(_) => false,
473-
};
474-
}
475-
476-
if self.opts.shuffle_seed.is_some() && !allow_unstable_options {
477-
return Err(ErrorContext::msg(
478-
"`--shuffle-seed` requires `-Zunstable-options`",
479-
));
480-
}
481-
if self.opts.shuffle_seed.is_none() && allow_unstable_options {
482-
self.opts.shuffle_seed = match std::env::var("RUST_TEST_SHUFFLE_SEED") {
483-
Ok(val) => match val.parse::<u64>() {
484-
Ok(n) => Some(n),
485-
Err(_) => {
486-
return Err(ErrorContext::msg(
487-
"RUST_TEST_SHUFFLE_SEED is `{val}`, should be a number.",
488-
));
489-
}
490-
},
491-
Err(_) => None,
492-
};
493-
}
494-
495311
if !self.opts.nocapture {
496312
self.opts.nocapture = match std::env::var("RUST_TEST_NOCAPTURE") {
497313
Ok(val) => &val != "0",

crates/libtest2-harness/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ pre-release-replacements = [
2727
default = []
2828
color = ["dep:anstream", "dep:anstyle"]
2929
json = ["libtest-json/serde", "dep:serde", "dep:serde_json"]
30-
junit = []
3130
threads = []
3231

3332
[dependencies]

crates/libtest2-harness/src/harness.rs

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use libtest_lexarg::OutputFormat;
22

3-
use crate::{cli, notify, shuffle, Case, RunError, RunMode, State};
3+
use crate::{cli, notify, Case, RunError, RunMode, State};
44

55
pub struct Harness {
66
raw: Vec<std::ffi::OsString>,
@@ -149,15 +149,6 @@ fn notifier(opts: &libtest_lexarg::TestOpts) -> std::io::Result<Box<dyn notify::
149149
_ if opts.list => Box::new(notify::TerseListNotifier::new(stdout)),
150150
OutputFormat::Pretty => Box::new(notify::PrettyRunNotifier::new(stdout)),
151151
OutputFormat::Terse => Box::new(notify::TerseRunNotifier::new(stdout)),
152-
#[cfg(feature = "junit")]
153-
OutputFormat::Junit => Box::new(notify::JunitRunNotifier::new(stdout)),
154-
#[cfg(not(feature = "junit"))]
155-
OutputFormat::Junit => {
156-
return Err(std::io::Error::new(
157-
std::io::ErrorKind::Other,
158-
"`--format=junit` is not supported",
159-
));
160-
}
161152
};
162153
Ok(notifier)
163154
}
@@ -172,10 +163,6 @@ fn discover(
172163

173164
// Do this first so it applies to both discover and running
174165
cases.sort_unstable_by_key(|case| case.name().to_owned());
175-
let seed = shuffle::get_shuffle_seed(opts);
176-
if let Some(seed) = seed {
177-
shuffle::shuffle_tests(seed, cases);
178-
}
179166

180167
let matches_filter = |case: &dyn Case, filter: &str| {
181168
let test_name = case.name();
@@ -207,7 +194,6 @@ fn discover(
207194

208195
notifier.notify(notify::Event::DiscoverComplete {
209196
elapsed_s: notify::Elapsed(timer.elapsed()),
210-
seed,
211197
})?;
212198

213199
Ok(())
@@ -221,18 +207,9 @@ fn run(
221207
notifier.notify(notify::Event::SuiteStart)?;
222208
let timer = std::time::Instant::now();
223209

224-
if opts.force_run_in_process {
225-
todo!("`--force-run-in-process` is not yet supported");
226-
}
227-
if opts.exclude_should_panic {
228-
todo!("`--exclude-should-panic` is not yet supported");
229-
}
230210
if opts.nocapture {
231211
todo!("`--nocapture` is not yet supported");
232212
}
233-
if opts.time_options.is_some() {
234-
todo!("`--report-time` / `--ensure-time` are not yet supported");
235-
}
236213
if opts.options.display_output {
237214
todo!("`--show-output` is not yet supported");
238215
}

crates/libtest2-harness/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
mod case;
2929
mod harness;
3030
mod notify;
31-
mod shuffle;
3231
mod state;
3332

3433
pub mod cli;

0 commit comments

Comments
 (0)