1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
use log::{debug, error, info};
use obnam_benchmark::junk::junk;
use obnam_benchmark::result::Result;
use obnam_benchmark::specification::Specification;
use obnam_benchmark::suite::Suite;
use std::fs::File;
use std::path::PathBuf;
use std::process::exit;
use structopt::StructOpt;
fn main() {
pretty_env_logger::init_custom_env("OBNAM_BENCHMARK_LOG");
info!("obnam-benchmark starts");
if let Err(err) = real_main() {
eprintln!("ERROR: {}", err);
error!("{}", err);
exit(1);
}
info!("obnam-benchmark ends successfully");
}
fn real_main() -> anyhow::Result<()> {
debug!("parsing command line");
let opt = Opt::from_args();
debug!("parsed: {:#?}", opt);
match opt.cmd {
Command::GenerateJunk(x) => x.run()?,
Command::Run(x) => x.run()?,
Command::Spec(x) => x.run()?,
}
Ok(())
}
#[derive(Debug, StructOpt)]
struct Opt {
#[structopt(subcommand)]
cmd: Command,
}
#[derive(Debug, StructOpt)]
enum Command {
/// Run benchmarks
Run(Run),
/// Dump the specification as JSON
Spec(Spec),
/// Generate some junk data in a file.
GenerateJunk(GenerateJunk),
}
#[derive(Debug, StructOpt)]
struct Run {
/// Name of the specification file
#[structopt(parse(from_os_str))]
spec: PathBuf,
/// Name of file where the results will be written.
#[structopt(long, parse(from_os_str))]
output: PathBuf,
}
impl Run {
fn run(&self) -> anyhow::Result<()> {
info!("running benchmarks from {}", self.spec.display());
let spec = Specification::from_file(&self.spec)?;
let mut suite = Suite::new()?;
let mut result = Result::default();
for step in spec.steps().iter() {
result.push(suite.execute(step)?);
}
debug!("writing results to {}", self.output.display());
let output = File::create(&self.output)?;
serde_json::to_writer_pretty(&output, &result)?;
Ok(())
}
}
#[derive(Debug, StructOpt)]
struct Spec {
/// Name of the specification file
#[structopt(parse(from_os_str))]
spec: PathBuf,
/// Name of JSON file to write
#[structopt(long, parse(from_os_str))]
output: PathBuf,
}
impl Spec {
fn run(&self) -> anyhow::Result<()> {
info!("dumping specification file as JSON");
debug!("reading specification from {}", self.spec.display());
let input = File::open(&self.spec)?;
let spec: Specification = serde_yaml::from_reader(&input)?;
debug!("writing specification as JSON to {}", self.output.display());
let output = File::create(&self.output)?;
serde_json::to_writer(&output, &spec)?;
Ok(())
}
}
#[derive(Debug, StructOpt)]
struct GenerateJunk {
/// Number of bytes of junk to create
#[structopt()]
bytes: u64,
/// Name of the output file
#[structopt(parse(from_os_str))]
filename: PathBuf,
}
impl GenerateJunk {
fn run(&self) -> anyhow::Result<()> {
info!(
"generating {} bytes of junk into {}",
self.bytes,
self.filename.display()
);
let mut output = File::create(&self.filename)?;
junk(&mut output, self.bytes)?;
Ok(())
}
}
|