diff options
Diffstat (limited to 'src/tests/run.rs')
-rw-r--r-- | src/tests/run.rs | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/tests/run.rs b/src/tests/run.rs index 33191d3..e4bbb28 100644 --- a/src/tests/run.rs +++ b/src/tests/run.rs @@ -5,8 +5,12 @@ use std::collections; use std::convert; +use std::convert::TryFrom as _; use std::convert::TryInto as _; +use std::fs; +use std::io::Write; use std::ops; +use std::os::unix::fs::OpenOptionsExt; use std::path; use super::*; @@ -277,3 +281,114 @@ fn connect_usb_path_model_wrong_serial(_model: nitrokey::Model) -> anyhow::Resul } Ok(()) } + +#[test] +fn extension() -> anyhow::Result<()> { + let ext_dir = tempfile::tempdir()?; + { + let mut ext = fs::OpenOptions::new() + .create(true) + .mode(0o755) + .write(true) + .open(ext_dir.path().join("nitrocli-ext"))?; + + ext.write_all( + br#"#!/usr/bin/env python +print("success") +"#, + )?; + } + + let path = ext_dir.path().as_os_str().to_os_string(); + let out = Nitrocli::new().path(path).handle(&["ext"])?; + assert_eq!(out, "success\n"); + Ok(()) +} + +#[test] +fn extension_failure() -> anyhow::Result<()> { + let ext_dir = tempfile::tempdir()?; + { + let mut ext = fs::OpenOptions::new() + .create(true) + .mode(0o755) + .write(true) + .open(ext_dir.path().join("nitrocli-ext"))?; + + ext.write_all( + br#"#!/usr/bin/env python +import sys +sys.exit(42); +"#, + )?; + } + + let path = ext_dir.path().as_os_str().to_os_string(); + let mut ncli = Nitrocli::new().path(path); + + let err = ncli.handle(&["ext"]).unwrap_err(); + // The extension is responsible for printing any error messages. + // Nitrocli is expected not to mess with them, including adding + // additional information. + if let Some(crate::DirectExitError(rc)) = err.downcast_ref::<crate::DirectExitError>() { + assert_eq!(*rc, 42) + } else { + panic!("encountered unexpected error: {:#}", err) + } + + let (rc, out, err) = ncli.run(&["ext"]); + assert_eq!(rc, 42); + assert_eq!(out, b""); + assert_eq!(err, b""); + Ok(()) +} + +#[test_device] +fn extension_arguments(model: nitrokey::Model) -> anyhow::Result<()> { + fn test<F>(model: nitrokey::Model, what: &str, args: &[&str], check: F) -> anyhow::Result<()> + where + F: FnOnce(&str) -> bool, + { + let ext_dir = tempfile::tempdir()?; + { + let mut ext = fs::OpenOptions::new() + .create(true) + .mode(0o755) + .write(true) + .open(ext_dir.path().join("nitrocli-ext"))?; + + ext.write_all(include_bytes!("extension_var_test.py"))?; + } + + let mut args = args.to_vec(); + args.append(&mut vec!["ext", what]); + + let path = ext_dir.path().as_os_str().to_os_string(); + let out = Nitrocli::new().model(model).path(path).handle(&args)?; + + assert!(check(&out), out); + Ok(()) + } + + test(model, "binary", &[], |out| { + path::Path::new(out) + .file_stem() + .unwrap() + .to_str() + .unwrap() + .trim() + .contains("nitrocli") + })?; + test(model, "model", &[], |out| { + out == args::DeviceModel::try_from(model).unwrap().to_string() + "\n" + })?; + test(model, "no-cache", &[], |out| out == "true\n")?; + test(model, "serial-numbers", &[], |out| out == "\n")?; + test(model, "verbosity", &[], |out| out == "0\n")?; + test(model, "verbosity", &["-v"], |out| out == "1\n")?; + test(model, "verbosity", &["-v", "--verbose"], |out| out == "2\n")?; + + // NITROCLI_USB_PATH should not be set, so the program errors out. + let _ = test(model, "usb-path", &[], |out| out == "\n").unwrap_err(); + Ok(()) +} |