in GaiaXStretch/scripts/gentest/src/main.rs [14:151]
fn main() {
env_logger::init();
// this requires being run by cargo, which is iffy
let root_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").unwrap());
let repo_root = root_dir.parent().and_then(Path::parent).unwrap();
let fixtures_root = repo_root.join("test_fixtures");
let fixtures = fs::read_dir(fixtures_root).unwrap();
info!("reading test fixtures from disk");
let mut fixtures: Vec<_> = fixtures
.into_iter()
.filter_map(|a| a.ok())
.filter(|f| f.path().is_file() && f.path().extension().map(|p| p == "html").unwrap_or(false))
.map(|f| {
let fixture_path = f.path().to_path_buf();
let name = fixture_path.file_stem().unwrap().to_str().unwrap().to_string();
(name, fixture_path)
})
.collect();
fixtures.sort_unstable_by_key(|f| f.0.clone());
info!("starting webdriver instance");
let webdriver_url = "http://localhost:4444";
let mut webdriver_handle = Command::new("chromedriver").arg("--port=4444").spawn().unwrap();
// this is silly, but it works
std::thread::sleep(std::time::Duration::from_secs(1));
let mut caps = serde_json::map::Map::new();
let chrome_opts = serde_json::json!({ "args": ["--headless", "--disable-gpu"] });
caps.insert("goog:chromeOptions".to_string(), chrome_opts.clone());
use indicatif::ProgressBar;
let pb = ProgressBar::new(fixtures.len() as u64);
let (test_descs_sink, mut test_descs) = channel();
info!("spawning webdriver client and collecting test descriptions");
tokio::run(
Client::with_capabilities(webdriver_url, caps.clone())
.map_err(|e| Error::from(e))
.and_then(move |client| {
futures::stream::iter_ok(pb.wrap_iter(fixtures.into_iter()))
.and_then(move |(name, fixture_path)| {
pb.set_message(&name);
test_root_element(client.clone(), name, fixture_path)
})
.collect()
.map(move |descs| {
info!("finished collecting descriptions, sending them back to main");
let _ = test_descs_sink.send(descs);
})
})
.map_err(|e| {
error!("top-level error encountered: {:?}", e);
}),
);
info!("killing webdriver instance...");
webdriver_handle.kill().unwrap();
info!("collecting test descriptions from async runtime...");
let test_descs = loop {
if let Ok(Some(descs)) = test_descs.try_recv() {
break descs;
}
};
info!("generating test sources and concatenating...");
let bench_descs: Vec<_> = test_descs
.iter()
.map(|(name, description)| {
debug!("generating bench contents for {}", &name);
(name.clone(), generate_bench(description))
})
.collect();
let test_descs: Vec<_> = test_descs
.iter()
.map(|(name, description)| {
debug!("generating test contents for {}", &name);
(name.clone(), generate_test(name, description))
})
.collect();
let benchmarks: Vec<_> = test_descs
.iter()
.map(|(name, _)| {
let bench_mod = Ident::new(name, Span::call_site());
quote!(#bench_mod::compute())
})
.collect();
let test_mods = test_descs
.iter()
.map(|(name, _)| {
let name = Ident::new(name, Span::call_site());
quote!(mod #name;)
})
.fold(quote!(), |a, b| quote!(#a #b));
for (name, bench_body) in bench_descs {
let mut bench_filename = repo_root.join("benches").join("generated").join(&name);
bench_filename.set_extension("rs");
debug!("writing {} to disk...", &name);
fs::write(bench_filename, bench_body.to_string()).unwrap();
}
for (name, test_body) in test_descs {
let mut test_filename = repo_root.join("tests").join("generated").join(&name);
test_filename.set_extension("rs");
debug!("writing {} to disk...", &name);
fs::write(test_filename, test_body.to_string()).unwrap();
}
let bench_mods = quote!(
use criterion::{criterion_group, criterion_main, Criterion};
#test_mods
fn benchmark(c: &mut Criterion) {
c.bench_function("generated benchmarks", |b| {
b.iter(|| { #(#benchmarks;)* })
});
}
criterion_group!(benches, benchmark);
criterion_main!(benches);
);
info!("writing generated test file to disk...");
fs::write(repo_root.join("benches").join("generated").join("mod.rs"), bench_mods.to_string()).unwrap();
fs::write(repo_root.join("tests").join("generated").join("mod.rs"), test_mods.to_string()).unwrap();
info!("formatting the source directory");
Command::new("cargo").arg("fmt").current_dir(repo_root).status().unwrap();
}