]> git.lizzy.rs Git - rust.git/blob - library/test/src/tests.rs
Rollup merge of #95342 - jyn514:ignore-revs, r=Mark-Simulacrum
[rust.git] / library / test / src / tests.rs
1 use super::*;
2
3 use crate::{
4     bench::Bencher,
5     console::OutputLocation,
6     formatters::PrettyFormatter,
7     options::OutputFormat,
8     test::{
9         filter_tests,
10         parse_opts,
11         run_test,
12         DynTestFn,
13         DynTestName,
14         MetricMap,
15         RunIgnored,
16         RunStrategy,
17         ShouldPanic,
18         StaticTestName,
19         TestDesc,
20         TestDescAndFn,
21         TestOpts,
22         TrIgnored,
23         TrOk,
24         // FIXME (introduced by #65251)
25         // ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TestTimeOptions,
26         // TestType, TrFailedMsg, TrIgnored, TrOk,
27     },
28     time::{TestTimeOptions, TimeThreshold},
29 };
30 use std::sync::mpsc::channel;
31 use std::time::Duration;
32
33 impl TestOpts {
34     fn new() -> TestOpts {
35         TestOpts {
36             list: false,
37             filters: vec![],
38             filter_exact: false,
39             force_run_in_process: false,
40             exclude_should_panic: false,
41             run_ignored: RunIgnored::No,
42             run_tests: false,
43             bench_benchmarks: false,
44             logfile: None,
45             nocapture: false,
46             color: AutoColor,
47             format: OutputFormat::Pretty,
48             shuffle: false,
49             shuffle_seed: None,
50             test_threads: None,
51             skip: vec![],
52             time_options: None,
53             options: Options::new(),
54         }
55     }
56 }
57
58 fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
59     vec![
60         TestDescAndFn {
61             desc: TestDesc {
62                 name: StaticTestName("1"),
63                 ignore: true,
64                 #[cfg(not(bootstrap))]
65                 ignore_message: None,
66                 should_panic: ShouldPanic::No,
67                 compile_fail: false,
68                 no_run: false,
69                 test_type: TestType::Unknown,
70             },
71             testfn: DynTestFn(Box::new(move || {})),
72         },
73         TestDescAndFn {
74             desc: TestDesc {
75                 name: StaticTestName("2"),
76                 ignore: false,
77                 #[cfg(not(bootstrap))]
78                 ignore_message: None,
79                 should_panic: ShouldPanic::No,
80                 compile_fail: false,
81                 no_run: false,
82                 test_type: TestType::Unknown,
83             },
84             testfn: DynTestFn(Box::new(move || {})),
85         },
86     ]
87 }
88
89 #[test]
90 pub fn do_not_run_ignored_tests() {
91     fn f() {
92         panic!();
93     }
94     let desc = TestDescAndFn {
95         desc: TestDesc {
96             name: StaticTestName("whatever"),
97             ignore: true,
98             #[cfg(not(bootstrap))]
99             ignore_message: None,
100             should_panic: ShouldPanic::No,
101             compile_fail: false,
102             no_run: false,
103             test_type: TestType::Unknown,
104         },
105         testfn: DynTestFn(Box::new(f)),
106     };
107     let (tx, rx) = channel();
108     run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
109     let result = rx.recv().unwrap().result;
110     assert_ne!(result, TrOk);
111 }
112
113 #[test]
114 pub fn ignored_tests_result_in_ignored() {
115     fn f() {}
116     let desc = TestDescAndFn {
117         desc: TestDesc {
118             name: StaticTestName("whatever"),
119             ignore: true,
120             #[cfg(not(bootstrap))]
121             ignore_message: None,
122             should_panic: ShouldPanic::No,
123             compile_fail: false,
124             no_run: false,
125             test_type: TestType::Unknown,
126         },
127         testfn: DynTestFn(Box::new(f)),
128     };
129     let (tx, rx) = channel();
130     run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
131     let result = rx.recv().unwrap().result;
132     assert_eq!(result, TrIgnored);
133 }
134
135 // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
136 #[test]
137 #[cfg(not(target_os = "emscripten"))]
138 fn test_should_panic() {
139     fn f() {
140         panic!();
141     }
142     let desc = TestDescAndFn {
143         desc: TestDesc {
144             name: StaticTestName("whatever"),
145             ignore: false,
146             #[cfg(not(bootstrap))]
147             ignore_message: None,
148             should_panic: ShouldPanic::Yes,
149             compile_fail: false,
150             no_run: false,
151             test_type: TestType::Unknown,
152         },
153         testfn: DynTestFn(Box::new(f)),
154     };
155     let (tx, rx) = channel();
156     run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
157     let result = rx.recv().unwrap().result;
158     assert_eq!(result, TrOk);
159 }
160
161 // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
162 #[test]
163 #[cfg(not(target_os = "emscripten"))]
164 fn test_should_panic_good_message() {
165     fn f() {
166         panic!("an error message");
167     }
168     let desc = TestDescAndFn {
169         desc: TestDesc {
170             name: StaticTestName("whatever"),
171             ignore: false,
172             #[cfg(not(bootstrap))]
173             ignore_message: None,
174             should_panic: ShouldPanic::YesWithMessage("error message"),
175             compile_fail: false,
176             no_run: false,
177             test_type: TestType::Unknown,
178         },
179         testfn: DynTestFn(Box::new(f)),
180     };
181     let (tx, rx) = channel();
182     run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
183     let result = rx.recv().unwrap().result;
184     assert_eq!(result, TrOk);
185 }
186
187 // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
188 #[test]
189 #[cfg(not(target_os = "emscripten"))]
190 fn test_should_panic_bad_message() {
191     use crate::tests::TrFailedMsg;
192     fn f() {
193         panic!("an error message");
194     }
195     let expected = "foobar";
196     let failed_msg = r#"panic did not contain expected string
197       panic message: `"an error message"`,
198  expected substring: `"foobar"`"#;
199     let desc = TestDescAndFn {
200         desc: TestDesc {
201             name: StaticTestName("whatever"),
202             ignore: false,
203             #[cfg(not(bootstrap))]
204             ignore_message: None,
205             should_panic: ShouldPanic::YesWithMessage(expected),
206             compile_fail: false,
207             no_run: false,
208             test_type: TestType::Unknown,
209         },
210         testfn: DynTestFn(Box::new(f)),
211     };
212     let (tx, rx) = channel();
213     run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
214     let result = rx.recv().unwrap().result;
215     assert_eq!(result, TrFailedMsg(failed_msg.to_string()));
216 }
217
218 // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
219 #[test]
220 #[cfg(not(target_os = "emscripten"))]
221 fn test_should_panic_non_string_message_type() {
222     use crate::tests::TrFailedMsg;
223     use std::any::TypeId;
224     fn f() {
225         std::panic::panic_any(1i32);
226     }
227     let expected = "foobar";
228     let failed_msg = format!(
229         r#"expected panic with string value,
230  found non-string value: `{:?}`
231      expected substring: `"foobar"`"#,
232         TypeId::of::<i32>()
233     );
234     let desc = TestDescAndFn {
235         desc: TestDesc {
236             name: StaticTestName("whatever"),
237             ignore: false,
238             #[cfg(not(bootstrap))]
239             ignore_message: None,
240             should_panic: ShouldPanic::YesWithMessage(expected),
241             compile_fail: false,
242             no_run: false,
243             test_type: TestType::Unknown,
244         },
245         testfn: DynTestFn(Box::new(f)),
246     };
247     let (tx, rx) = channel();
248     run_test(&TestOpts::new(), false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
249     let result = rx.recv().unwrap().result;
250     assert_eq!(result, TrFailedMsg(failed_msg));
251 }
252
253 // FIXME: Re-enable emscripten once it can catch panics again (introduced by #65251)
254 #[test]
255 #[cfg(not(target_os = "emscripten"))]
256 fn test_should_panic_but_succeeds() {
257     let should_panic_variants = [ShouldPanic::Yes, ShouldPanic::YesWithMessage("error message")];
258
259     for &should_panic in should_panic_variants.iter() {
260         fn f() {}
261         let desc = TestDescAndFn {
262             desc: TestDesc {
263                 name: StaticTestName("whatever"),
264                 ignore: false,
265                 #[cfg(not(bootstrap))]
266                 ignore_message: None,
267                 should_panic,
268                 compile_fail: false,
269                 no_run: false,
270                 test_type: TestType::Unknown,
271             },
272             testfn: DynTestFn(Box::new(f)),
273         };
274         let (tx, rx) = channel();
275         run_test(
276             &TestOpts::new(),
277             false,
278             TestId(0),
279             desc,
280             RunStrategy::InProcess,
281             tx,
282             Concurrent::No,
283         );
284         let result = rx.recv().unwrap().result;
285         assert_eq!(
286             result,
287             TrFailedMsg("test did not panic as expected".to_string()),
288             "should_panic == {:?}",
289             should_panic
290         );
291     }
292 }
293
294 fn report_time_test_template(report_time: bool) -> Option<TestExecTime> {
295     fn f() {}
296     let desc = TestDescAndFn {
297         desc: TestDesc {
298             name: StaticTestName("whatever"),
299             ignore: false,
300             #[cfg(not(bootstrap))]
301             ignore_message: None,
302             should_panic: ShouldPanic::No,
303             compile_fail: false,
304             no_run: false,
305             test_type: TestType::Unknown,
306         },
307         testfn: DynTestFn(Box::new(f)),
308     };
309     let time_options = if report_time { Some(TestTimeOptions::default()) } else { None };
310
311     let test_opts = TestOpts { time_options, ..TestOpts::new() };
312     let (tx, rx) = channel();
313     run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
314     let exec_time = rx.recv().unwrap().exec_time;
315     exec_time
316 }
317
318 #[test]
319 fn test_should_not_report_time() {
320     let exec_time = report_time_test_template(false);
321     assert!(exec_time.is_none());
322 }
323
324 #[test]
325 fn test_should_report_time() {
326     let exec_time = report_time_test_template(true);
327     assert!(exec_time.is_some());
328 }
329
330 fn time_test_failure_template(test_type: TestType) -> TestResult {
331     fn f() {}
332     let desc = TestDescAndFn {
333         desc: TestDesc {
334             name: StaticTestName("whatever"),
335             ignore: false,
336             #[cfg(not(bootstrap))]
337             ignore_message: None,
338             should_panic: ShouldPanic::No,
339             compile_fail: false,
340             no_run: false,
341             test_type,
342         },
343         testfn: DynTestFn(Box::new(f)),
344     };
345     // `Default` will initialize all the thresholds to 0 milliseconds.
346     let mut time_options = TestTimeOptions::default();
347     time_options.error_on_excess = true;
348
349     let test_opts = TestOpts { time_options: Some(time_options), ..TestOpts::new() };
350     let (tx, rx) = channel();
351     run_test(&test_opts, false, TestId(0), desc, RunStrategy::InProcess, tx, Concurrent::No);
352     let result = rx.recv().unwrap().result;
353
354     result
355 }
356
357 #[test]
358 fn test_error_on_exceed() {
359     let types = [TestType::UnitTest, TestType::IntegrationTest, TestType::DocTest];
360
361     for test_type in types.iter() {
362         let result = time_test_failure_template(*test_type);
363
364         assert_eq!(result, TestResult::TrTimedFail);
365     }
366
367     // Check that for unknown tests thresholds aren't applied.
368     let result = time_test_failure_template(TestType::Unknown);
369     assert_eq!(result, TestResult::TrOk);
370 }
371
372 fn typed_test_desc(test_type: TestType) -> TestDesc {
373     TestDesc {
374         name: StaticTestName("whatever"),
375         ignore: false,
376         #[cfg(not(bootstrap))]
377         ignore_message: None,
378         should_panic: ShouldPanic::No,
379         compile_fail: false,
380         no_run: false,
381         test_type,
382     }
383 }
384
385 fn test_exec_time(millis: u64) -> TestExecTime {
386     TestExecTime(Duration::from_millis(millis))
387 }
388
389 #[test]
390 fn test_time_options_threshold() {
391     let unit = TimeThreshold::new(Duration::from_millis(50), Duration::from_millis(100));
392     let integration = TimeThreshold::new(Duration::from_millis(500), Duration::from_millis(1000));
393     let doc = TimeThreshold::new(Duration::from_millis(5000), Duration::from_millis(10000));
394
395     let options = TestTimeOptions {
396         error_on_excess: false,
397         unit_threshold: unit.clone(),
398         integration_threshold: integration.clone(),
399         doctest_threshold: doc.clone(),
400     };
401
402     let test_vector = [
403         (TestType::UnitTest, unit.warn.as_millis() - 1, false, false),
404         (TestType::UnitTest, unit.warn.as_millis(), true, false),
405         (TestType::UnitTest, unit.critical.as_millis(), true, true),
406         (TestType::IntegrationTest, integration.warn.as_millis() - 1, false, false),
407         (TestType::IntegrationTest, integration.warn.as_millis(), true, false),
408         (TestType::IntegrationTest, integration.critical.as_millis(), true, true),
409         (TestType::DocTest, doc.warn.as_millis() - 1, false, false),
410         (TestType::DocTest, doc.warn.as_millis(), true, false),
411         (TestType::DocTest, doc.critical.as_millis(), true, true),
412     ];
413
414     for (test_type, time, expected_warn, expected_critical) in test_vector.iter() {
415         let test_desc = typed_test_desc(*test_type);
416         let exec_time = test_exec_time(*time as u64);
417
418         assert_eq!(options.is_warn(&test_desc, &exec_time), *expected_warn);
419         assert_eq!(options.is_critical(&test_desc, &exec_time), *expected_critical);
420     }
421 }
422
423 #[test]
424 fn parse_ignored_flag() {
425     let args = vec!["progname".to_string(), "filter".to_string(), "--ignored".to_string()];
426     let opts = parse_opts(&args).unwrap().unwrap();
427     assert_eq!(opts.run_ignored, RunIgnored::Only);
428 }
429
430 #[test]
431 fn parse_show_output_flag() {
432     let args = vec!["progname".to_string(), "filter".to_string(), "--show-output".to_string()];
433     let opts = parse_opts(&args).unwrap().unwrap();
434     assert!(opts.options.display_output);
435 }
436
437 #[test]
438 fn parse_include_ignored_flag() {
439     let args = vec!["progname".to_string(), "filter".to_string(), "--include-ignored".to_string()];
440     let opts = parse_opts(&args).unwrap().unwrap();
441     assert_eq!(opts.run_ignored, RunIgnored::Yes);
442 }
443
444 #[test]
445 pub fn filter_for_ignored_option() {
446     // When we run ignored tests the test filter should filter out all the
447     // unignored tests and flip the ignore flag on the rest to false
448
449     let mut opts = TestOpts::new();
450     opts.run_tests = true;
451     opts.run_ignored = RunIgnored::Only;
452
453     let tests = one_ignored_one_unignored_test();
454     let filtered = filter_tests(&opts, tests);
455
456     assert_eq!(filtered.len(), 1);
457     assert_eq!(filtered[0].desc.name.to_string(), "1");
458     assert!(!filtered[0].desc.ignore);
459 }
460
461 #[test]
462 pub fn run_include_ignored_option() {
463     // When we "--include-ignored" tests, the ignore flag should be set to false on
464     // all tests and no test filtered out
465
466     let mut opts = TestOpts::new();
467     opts.run_tests = true;
468     opts.run_ignored = RunIgnored::Yes;
469
470     let tests = one_ignored_one_unignored_test();
471     let filtered = filter_tests(&opts, tests);
472
473     assert_eq!(filtered.len(), 2);
474     assert!(!filtered[0].desc.ignore);
475     assert!(!filtered[1].desc.ignore);
476 }
477
478 #[test]
479 pub fn exclude_should_panic_option() {
480     let mut opts = TestOpts::new();
481     opts.run_tests = true;
482     opts.exclude_should_panic = true;
483
484     let mut tests = one_ignored_one_unignored_test();
485     tests.push(TestDescAndFn {
486         desc: TestDesc {
487             name: StaticTestName("3"),
488             ignore: false,
489             #[cfg(not(bootstrap))]
490             ignore_message: None,
491             should_panic: ShouldPanic::Yes,
492             compile_fail: false,
493             no_run: false,
494             test_type: TestType::Unknown,
495         },
496         testfn: DynTestFn(Box::new(move || {})),
497     });
498
499     let filtered = filter_tests(&opts, tests);
500
501     assert_eq!(filtered.len(), 2);
502     assert!(filtered.iter().all(|test| test.desc.should_panic == ShouldPanic::No));
503 }
504
505 #[test]
506 pub fn exact_filter_match() {
507     fn tests() -> Vec<TestDescAndFn> {
508         ["base", "base::test", "base::test1", "base::test2"]
509             .into_iter()
510             .map(|name| TestDescAndFn {
511                 desc: TestDesc {
512                     name: StaticTestName(name),
513                     ignore: false,
514                     #[cfg(not(bootstrap))]
515                     ignore_message: None,
516                     should_panic: ShouldPanic::No,
517                     compile_fail: false,
518                     no_run: false,
519                     test_type: TestType::Unknown,
520                 },
521                 testfn: DynTestFn(Box::new(move || {})),
522             })
523             .collect()
524     }
525
526     let substr =
527         filter_tests(&TestOpts { filters: vec!["base".into()], ..TestOpts::new() }, tests());
528     assert_eq!(substr.len(), 4);
529
530     let substr =
531         filter_tests(&TestOpts { filters: vec!["bas".into()], ..TestOpts::new() }, tests());
532     assert_eq!(substr.len(), 4);
533
534     let substr =
535         filter_tests(&TestOpts { filters: vec!["::test".into()], ..TestOpts::new() }, tests());
536     assert_eq!(substr.len(), 3);
537
538     let substr =
539         filter_tests(&TestOpts { filters: vec!["base::test".into()], ..TestOpts::new() }, tests());
540     assert_eq!(substr.len(), 3);
541
542     let substr = filter_tests(
543         &TestOpts { filters: vec!["test1".into(), "test2".into()], ..TestOpts::new() },
544         tests(),
545     );
546     assert_eq!(substr.len(), 2);
547
548     let exact = filter_tests(
549         &TestOpts { filters: vec!["base".into()], filter_exact: true, ..TestOpts::new() },
550         tests(),
551     );
552     assert_eq!(exact.len(), 1);
553
554     let exact = filter_tests(
555         &TestOpts { filters: vec!["bas".into()], filter_exact: true, ..TestOpts::new() },
556         tests(),
557     );
558     assert_eq!(exact.len(), 0);
559
560     let exact = filter_tests(
561         &TestOpts { filters: vec!["::test".into()], filter_exact: true, ..TestOpts::new() },
562         tests(),
563     );
564     assert_eq!(exact.len(), 0);
565
566     let exact = filter_tests(
567         &TestOpts { filters: vec!["base::test".into()], filter_exact: true, ..TestOpts::new() },
568         tests(),
569     );
570     assert_eq!(exact.len(), 1);
571
572     let exact = filter_tests(
573         &TestOpts {
574             filters: vec!["base".into(), "base::test".into()],
575             filter_exact: true,
576             ..TestOpts::new()
577         },
578         tests(),
579     );
580     assert_eq!(exact.len(), 2);
581 }
582
583 fn sample_tests() -> Vec<TestDescAndFn> {
584     let names = vec![
585         "sha1::test".to_string(),
586         "isize::test_to_str".to_string(),
587         "isize::test_pow".to_string(),
588         "test::do_not_run_ignored_tests".to_string(),
589         "test::ignored_tests_result_in_ignored".to_string(),
590         "test::first_free_arg_should_be_a_filter".to_string(),
591         "test::parse_ignored_flag".to_string(),
592         "test::parse_include_ignored_flag".to_string(),
593         "test::filter_for_ignored_option".to_string(),
594         "test::run_include_ignored_option".to_string(),
595         "test::sort_tests".to_string(),
596     ];
597     fn testfn() {}
598     let mut tests = Vec::new();
599     for name in &names {
600         let test = TestDescAndFn {
601             desc: TestDesc {
602                 name: DynTestName((*name).clone()),
603                 ignore: false,
604                 #[cfg(not(bootstrap))]
605                 ignore_message: None,
606                 should_panic: ShouldPanic::No,
607                 compile_fail: false,
608                 no_run: false,
609                 test_type: TestType::Unknown,
610             },
611             testfn: DynTestFn(Box::new(testfn)),
612         };
613         tests.push(test);
614     }
615     tests
616 }
617
618 #[test]
619 pub fn sort_tests() {
620     let mut opts = TestOpts::new();
621     opts.run_tests = true;
622
623     let tests = sample_tests();
624     let filtered = filter_tests(&opts, tests);
625
626     let expected = vec![
627         "isize::test_pow".to_string(),
628         "isize::test_to_str".to_string(),
629         "sha1::test".to_string(),
630         "test::do_not_run_ignored_tests".to_string(),
631         "test::filter_for_ignored_option".to_string(),
632         "test::first_free_arg_should_be_a_filter".to_string(),
633         "test::ignored_tests_result_in_ignored".to_string(),
634         "test::parse_ignored_flag".to_string(),
635         "test::parse_include_ignored_flag".to_string(),
636         "test::run_include_ignored_option".to_string(),
637         "test::sort_tests".to_string(),
638     ];
639
640     for (a, b) in expected.iter().zip(filtered) {
641         assert_eq!(*a, b.desc.name.to_string());
642     }
643 }
644
645 #[test]
646 pub fn shuffle_tests() {
647     let mut opts = TestOpts::new();
648     opts.shuffle = true;
649
650     let shuffle_seed = get_shuffle_seed(&opts).unwrap();
651
652     let left =
653         sample_tests().into_iter().enumerate().map(|(i, e)| (TestId(i), e)).collect::<Vec<_>>();
654     let mut right =
655         sample_tests().into_iter().enumerate().map(|(i, e)| (TestId(i), e)).collect::<Vec<_>>();
656
657     assert!(left.iter().zip(&right).all(|(a, b)| a.1.desc.name == b.1.desc.name));
658
659     helpers::shuffle::shuffle_tests(shuffle_seed, right.as_mut_slice());
660
661     assert!(left.iter().zip(right).any(|(a, b)| a.1.desc.name != b.1.desc.name));
662 }
663
664 #[test]
665 pub fn shuffle_tests_with_seed() {
666     let mut opts = TestOpts::new();
667     opts.shuffle = true;
668
669     let shuffle_seed = get_shuffle_seed(&opts).unwrap();
670
671     let mut left =
672         sample_tests().into_iter().enumerate().map(|(i, e)| (TestId(i), e)).collect::<Vec<_>>();
673     let mut right =
674         sample_tests().into_iter().enumerate().map(|(i, e)| (TestId(i), e)).collect::<Vec<_>>();
675
676     helpers::shuffle::shuffle_tests(shuffle_seed, left.as_mut_slice());
677     helpers::shuffle::shuffle_tests(shuffle_seed, right.as_mut_slice());
678
679     assert!(left.iter().zip(right).all(|(a, b)| a.1.desc.name == b.1.desc.name));
680 }
681
682 #[test]
683 pub fn order_depends_on_more_than_seed() {
684     let mut opts = TestOpts::new();
685     opts.shuffle = true;
686
687     let shuffle_seed = get_shuffle_seed(&opts).unwrap();
688
689     let mut left_tests = sample_tests();
690     let mut right_tests = sample_tests();
691
692     left_tests.pop();
693     right_tests.remove(0);
694
695     let mut left =
696         left_tests.into_iter().enumerate().map(|(i, e)| (TestId(i), e)).collect::<Vec<_>>();
697     let mut right =
698         right_tests.into_iter().enumerate().map(|(i, e)| (TestId(i), e)).collect::<Vec<_>>();
699
700     assert_eq!(left.len(), right.len());
701
702     assert!(left.iter().zip(&right).all(|(a, b)| a.0 == b.0));
703
704     helpers::shuffle::shuffle_tests(shuffle_seed, left.as_mut_slice());
705     helpers::shuffle::shuffle_tests(shuffle_seed, right.as_mut_slice());
706
707     assert!(left.iter().zip(right).any(|(a, b)| a.0 != b.0));
708 }
709
710 #[test]
711 pub fn test_metricmap_compare() {
712     let mut m1 = MetricMap::new();
713     let mut m2 = MetricMap::new();
714     m1.insert_metric("in-both-noise", 1000.0, 200.0);
715     m2.insert_metric("in-both-noise", 1100.0, 200.0);
716
717     m1.insert_metric("in-first-noise", 1000.0, 2.0);
718     m2.insert_metric("in-second-noise", 1000.0, 2.0);
719
720     m1.insert_metric("in-both-want-downwards-but-regressed", 1000.0, 10.0);
721     m2.insert_metric("in-both-want-downwards-but-regressed", 2000.0, 10.0);
722
723     m1.insert_metric("in-both-want-downwards-and-improved", 2000.0, 10.0);
724     m2.insert_metric("in-both-want-downwards-and-improved", 1000.0, 10.0);
725
726     m1.insert_metric("in-both-want-upwards-but-regressed", 2000.0, -10.0);
727     m2.insert_metric("in-both-want-upwards-but-regressed", 1000.0, -10.0);
728
729     m1.insert_metric("in-both-want-upwards-and-improved", 1000.0, -10.0);
730     m2.insert_metric("in-both-want-upwards-and-improved", 2000.0, -10.0);
731 }
732
733 #[test]
734 pub fn test_bench_once_no_iter() {
735     fn f(_: &mut Bencher) {}
736     bench::run_once(f);
737 }
738
739 #[test]
740 pub fn test_bench_once_iter() {
741     fn f(b: &mut Bencher) {
742         b.iter(|| {})
743     }
744     bench::run_once(f);
745 }
746
747 #[test]
748 pub fn test_bench_no_iter() {
749     fn f(_: &mut Bencher) {}
750
751     let (tx, rx) = channel();
752
753     let desc = TestDesc {
754         name: StaticTestName("f"),
755         ignore: false,
756         #[cfg(not(bootstrap))]
757         ignore_message: None,
758         should_panic: ShouldPanic::No,
759         compile_fail: false,
760         no_run: false,
761         test_type: TestType::Unknown,
762     };
763
764     crate::bench::benchmark(TestId(0), desc, tx, true, f);
765     rx.recv().unwrap();
766 }
767
768 #[test]
769 pub fn test_bench_iter() {
770     fn f(b: &mut Bencher) {
771         b.iter(|| {})
772     }
773
774     let (tx, rx) = channel();
775
776     let desc = TestDesc {
777         name: StaticTestName("f"),
778         ignore: false,
779         #[cfg(not(bootstrap))]
780         ignore_message: None,
781         should_panic: ShouldPanic::No,
782         compile_fail: false,
783         no_run: false,
784         test_type: TestType::Unknown,
785     };
786
787     crate::bench::benchmark(TestId(0), desc, tx, true, f);
788     rx.recv().unwrap();
789 }
790
791 #[test]
792 fn should_sort_failures_before_printing_them() {
793     let test_a = TestDesc {
794         name: StaticTestName("a"),
795         ignore: false,
796         #[cfg(not(bootstrap))]
797         ignore_message: None,
798         should_panic: ShouldPanic::No,
799         compile_fail: false,
800         no_run: false,
801         test_type: TestType::Unknown,
802     };
803
804     let test_b = TestDesc {
805         name: StaticTestName("b"),
806         ignore: false,
807         #[cfg(not(bootstrap))]
808         ignore_message: None,
809         should_panic: ShouldPanic::No,
810         compile_fail: false,
811         no_run: false,
812         test_type: TestType::Unknown,
813     };
814
815     let mut out = PrettyFormatter::new(OutputLocation::Raw(Vec::new()), false, 10, false, None);
816
817     let st = console::ConsoleTestState {
818         log_out: None,
819         total: 0,
820         passed: 0,
821         failed: 0,
822         ignored: 0,
823         filtered_out: 0,
824         measured: 0,
825         exec_time: None,
826         metrics: MetricMap::new(),
827         failures: vec![(test_b, Vec::new()), (test_a, Vec::new())],
828         options: Options::new(),
829         not_failures: Vec::new(),
830         time_failures: Vec::new(),
831     };
832
833     out.write_failures(&st).unwrap();
834     let s = match out.output_location() {
835         &OutputLocation::Raw(ref m) => String::from_utf8_lossy(&m[..]),
836         &OutputLocation::Pretty(_) => unreachable!(),
837     };
838
839     let apos = s.find("a").unwrap();
840     let bpos = s.find("b").unwrap();
841     assert!(apos < bpos);
842 }