Skip to content
This repository has been archived by the owner on Jun 20, 2022. It is now read-only.

Commit

Permalink
Add tests for cli (#50)
Browse files Browse the repository at this point in the history
* Adding tests for cli

Setup cli testing via integration test

Add all executables in target/debug to kcov

Ignore more test binaries

Adding tests

Attempt to run cli tests via kcov

Use single thread for kcov tests

Make sure kcov only runs in linux build containers

Fix cfg

Fix cfg

Attempt to fix kcov cli tests

Fix kcov paths

Use macro in tests

Another attempt to collect coverage

Use xenial

* Enable branch builds

* Add some tests

* Add tests

* Add test

* Reproduction tests
  • Loading branch information
mbrobbel authored Apr 15, 2019
1 parent d5b11b4 commit 49acc6e
Show file tree
Hide file tree
Showing 11 changed files with 808 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/target
target
**/*.rs.bk
*.repro
9 changes: 2 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ rust:
# allow_failures:
# - rust: nightly

branches:
only:
- master

cache:
directories:
- $HOME/.cargo
Expand Down Expand Up @@ -53,6 +49,7 @@ addons:
env:
global:
- DQCSIM_HOME=$HOME/.dqcsim
- PATH=$PATH:$HOME/kcov/bin/

install:
# pip3 install --upgrade pip setuptools
Expand All @@ -64,7 +61,6 @@ install:
(
[ "$TRAVIS_OS_NAME" = "linux" ] &&
[ "$TRAVIS_RUST_VERSION" = "stable" ] &&
export PATH=$PATH:$HOME/kcov/bin/ &&
( kcov --version ||
(
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
Expand All @@ -87,8 +83,7 @@ script:
after_success: |
[ "$TRAVIS_OS_NAME" = "linux" ] &&
[ "$TRAVIS_RUST_VERSION" = "stable" ] &&
export PATH=$PATH:$HOME/kcov/bin/ &&
for file in target/debug/{dqcsim,simulation,plugin,enum,quantum}*; do [ -x "${file}" ] || continue; mkdir -p "target/cov/$(basename $file)"; kcov --exclude-pattern=/.cargo,/usr/lib,/cpp/test_,/cpp/build/,/dqcsim/tests/ --exclude-region='#[cfg(test)]:#[cfg(testkcovstopmarker)]' --verify "target/cov/$(basename $file)" "$file"; done &&
for file in target/debug/*; do [ -x "${file}" ] || continue; mkdir -p "target/cov/$(basename $file)"; kcov --exclude-pattern=/.cargo,/usr/lib,/cpp/test_,/cpp/build/,/dqcsim/tests/,/dqcsim-cli/tests,/enum-variants/tests --exclude-region='#[cfg(test)]:#[cfg(testkcovstopmarker)]' --verify "target/cov/$(basename $file)" "$file"; done &&
for file in `find dqcsim-api/cpp/build/test_* -executable -and -type f`; do [ -x "${file}" ] || continue; mkdir -p "target/cov/$(basename $file)"; kcov --exclude-pattern=/.cargo,/usr/lib,/cpp/test_,/cpp/build/,/dqcsim/tests/ --exclude-region='#[cfg(test)]:#[cfg(testkcovstopmarker)]' --verify "target/cov/$(basename $file)" "$file"; done &&
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/target/debug &&
cd dqcsim-api/py &&
Expand Down
155 changes: 155 additions & 0 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions dqcsim-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,13 @@ structopt = "0.2"
failure = "0.1"
ansi_term = "0.11"
clap = "~2.33.0"

[dev-dependencies]
assert_cmd = "0.11"
predicates = "1.0"
escargot = "0.5.0"
lazy_static = "1.3.0"
rand = "0.6"

[features]
kcov = []
13 changes: 13 additions & 0 deletions dqcsim-cli/Makefile.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,16 @@
dependencies = ["release"]
command = "make"
args = ["install"]

[tasks.build_examples]
command = "cargo"
args = ["build", "--examples"]

[tasks.kcov-test]
env = { "RUSTFLAGS" = "-C link-dead-code" }
run_task = "test_kcov"

[tasks.test_kcov]
command = "cargo"
dependencies = ["build_examples", "build"]
args = ["test", "--features", "kcov", "--", "--test-threads", "1"]
3 changes: 2 additions & 1 deletion dqcsim-cli/examples/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ fn main() -> Result<(), Error> {
Ok(())
});

definition.run = Box::new(|_state, _| {
definition.run = Box::new(|state, _| {
info!("running run callback!");
state.send(ArbData::default()).expect("send failed");
Ok(ArbData::default())
});

Expand Down
29 changes: 21 additions & 8 deletions dqcsim-cli/src/arg_parse/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,14 +230,6 @@ pub struct CommandLineConfiguration {
}

impl CommandLineConfiguration {
/// Produces a DQCsim configuration from `std::env::args()`.
///
/// This is just a shorthand for `parse_from(std::env::args())`, refer
/// to its docs for more info.
pub fn parse() -> Result<CommandLineConfiguration, Error> {
CommandLineConfiguration::parse_from(std::env::args())
}

/// Produces a DQCsim configuration from the specified command line
/// argument iterable.
///
Expand Down Expand Up @@ -450,3 +442,24 @@ fn format_error_ctxt<T>(ctxt: &str, e: impl Into<Error>) -> Result<T, Error> {
)))
.into())
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn debug() {
let c = CommandLineConfiguration {
host_calls: vec![],
host_stdout: true,
dqcsim: SimulatorConfiguration::default().with_seed("test"),
reproduction_file: None,
};

assert_eq!(format!("{:?}", c), "CommandLineConfiguration { host_calls: [], host_stdout: true, dqcsim: SimulatorConfiguration { seed: Seed { value: 14402189752926126668 }, stderr_level: Info, tee_files: [], log_callback: None, dqcsim_level: Trace, plugins: [], reproduction_path_style: Some(Keep) }, reproduction_file: None }");
}

#[test]
fn help() {}

}
121 changes: 121 additions & 0 deletions dqcsim-cli/src/arg_parse/plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,124 @@ impl PluginDefinition {
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use dqcsim::{
common::types::PluginType, host::configuration::PluginProcessNonfunctionalConfiguration,
};

#[test]
fn non_func_opt() {
let pnfo = PluginNonfunctionalOpts::default();
assert_eq!(
pnfo,
PluginNonfunctionalOpts {
verbosity: None,
tee_files: vec![],
stdout_mode: None,
stderr_mode: None,
accept_timeout: None,
shutdown_timeout: None,
},
);
}

#[test]
fn non_func_opt_debug() {
let pnfo = PluginNonfunctionalOpts::default();
assert_eq!(
format!("{:?}", pnfo),
"PluginNonfunctionalOpts { verbosity: None, tee_files: [], stdout_mode: None, stderr_mode: None, accept_timeout: None, shutdown_timeout: None }",
);
}

#[test]
fn into_process_conf() {
let p = PluginNonfunctionalOpts::default();
let c: PluginProcessNonfunctionalConfiguration = p.into_config(LoglevelFilter::Debug);
assert_eq!(
c,
PluginProcessNonfunctionalConfiguration {
verbosity: LoglevelFilter::Debug,
tee_files: vec![],
stdout_mode: StreamCaptureMode::Capture(Loglevel::Info),
stderr_mode: StreamCaptureMode::Capture(Loglevel::Info),
accept_timeout: Timeout::from_seconds(5),
shutdown_timeout: Timeout::from_seconds(5),
}
);

let p = PluginNonfunctionalOpts {
verbosity: Some(LoglevelFilter::Fatal),
tee_files: vec![TeeFileConfiguration::new(
LoglevelFilter::Error,
"/dev/null",
)],
stdout_mode: Some(StreamCaptureMode::Null),
stderr_mode: Some(StreamCaptureMode::Pass),
accept_timeout: Some(Timeout::Infinite),
shutdown_timeout: Some(Timeout::from_seconds(1)),
};
let c: PluginProcessNonfunctionalConfiguration = p.into_config(LoglevelFilter::Debug);
assert_eq!(
c,
PluginProcessNonfunctionalConfiguration {
verbosity: LoglevelFilter::Fatal,
tee_files: vec![TeeFileConfiguration::new(
LoglevelFilter::Error,
"/dev/null",
)],
stdout_mode: StreamCaptureMode::Null,
stderr_mode: StreamCaptureMode::Pass,
accept_timeout: Timeout::Infinite,
shutdown_timeout: Timeout::from_seconds(1),
}
);
}

#[test]
fn into_def_conf() {
let p = PluginDefinition {
name: "name".to_string(),
specification: PluginProcessSpecification::from_sugar(
"/bin/echo",
PluginType::Operator,
)
.unwrap(),
functional: PluginProcessFunctionalConfiguration::default(),
nonfunctional: PluginNonfunctionalOpts::default(),
};
let c: PluginProcessConfiguration = p.into_config(LoglevelFilter::Trace);
assert_eq!(
c,
PluginProcessConfiguration {
name: "name".to_string(),
specification: PluginProcessSpecification::from_sugar(
"/bin/echo",
PluginType::Operator
)
.unwrap(),
functional: PluginProcessFunctionalConfiguration::default(),
nonfunctional: PluginProcessNonfunctionalConfiguration::default(),
}
);
}

#[test]
fn debug() {
let p = PluginDefinition {
name: "name".to_string(),
specification: PluginProcessSpecification::from_sugar(
"/bin/echo",
PluginType::Operator,
)
.unwrap(),
functional: PluginProcessFunctionalConfiguration::default(),
nonfunctional: PluginNonfunctionalOpts::default(),
};
assert_eq!(format!("{:?}", p), "PluginDefinition { name: \"name\", specification: PluginProcessSpecification { executable: \"/bin/echo\", script: None, typ: Operator }, functional: PluginProcessFunctionalConfiguration { init: [], env: [], work: \".\" }, nonfunctional: PluginNonfunctionalOpts { verbosity: None, tee_files: [], stdout_mode: None, stderr_mode: None, accept_timeout: None, shutdown_timeout: None } }");
}

}
11 changes: 8 additions & 3 deletions dqcsim-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use dqcsim::{
host::{accelerator::Accelerator, reproduction::HostCall, simulator::Simulator},
info, note,
};
use std::ffi::OsString;

use failure::Error;

Expand Down Expand Up @@ -58,8 +59,12 @@ fn run(
Ok(())
}

fn internal_main() -> Result<(), Error> {
let mut cfg = CommandLineConfiguration::parse().or_else(|e| {
fn internal_main<I, T>(args: I) -> Result<(), Error>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let mut cfg = CommandLineConfiguration::parse_from(args).or_else(|e| {
println!("{}", e);
Err(e)
})?;
Expand Down Expand Up @@ -87,7 +92,7 @@ fn internal_main() -> Result<(), Error> {
}

fn main() {
let result = internal_main();
let result = internal_main(std::env::args());
std::process::exit(match result {
Ok(_) => 0,
Err(_) => 1,
Expand Down
Loading

0 comments on commit 49acc6e

Please sign in to comment.