1const USAGE: &str = "Usage: puke [--max-machines=<#>] [--reorder] [--fail-io] [module file.pk]
2
3Falls back to repl if no module is provided.
4
5Options:
6 --max-machines=<#> Maximum concurrency bound [default: number of cores * 1.2].
7 --scramble Scramble in-flight messages and scheduling orders.
8 --fail-io=<#> Causes random IO failures on 1 out of every N IO operations.
9 --fuzz=<corpus path> Feeds the provided module fuzzed inputs derived from the provided corpus directory.
10";
11
12#[derive(Debug, Clone)]
14pub struct Args {
15 pub max_machines: usize,
16 pub scramble: bool,
17 pub fail_io: Option<usize>,
18 pub fuzz: Option<String>,
19 pub module: Option<String>,
20}
21
22impl Default for Args {
23 fn default() -> Args {
24 Args {
25 max_machines: ((num_cpus::get_physical() as f64) * 1.2) as usize,
26 scramble: false,
27 fail_io: None,
28 fuzz: None,
29 module: None,
30 }
31 }
32}
33
34fn parse<'a, I, T>(mut iter: I) -> T
35where
36 I: Iterator<Item = &'a str>,
37 T: std::str::FromStr,
38 <T as std::str::FromStr>::Err: std::fmt::Debug,
39{
40 iter.next().expect(USAGE).parse().expect(USAGE)
41}
42
43impl Args {
44 pub fn parse() -> Args {
45 let mut args = Args::default();
46 for raw_arg in std::env::args().skip(1) {
47 let mut splits = raw_arg[2..].split('=');
48 match splits.next().unwrap() {
49 "max-machines" => args.max_machines = parse(&mut splits),
50 "scramble" => args.scramble = true,
51 "fail-io" => args.fail_io = Some(parse(&mut splits)),
52 "fuzz" => args.fuzz = Some(parse(&mut splits)),
53 other => panic!("unknown option: {}, {}", other, USAGE),
54 }
55 }
56 args
57 }
58}