aboutsummaryrefslogtreecommitdiff
path: root/src/tests/run.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/run.rs')
-rw-r--r--src/tests/run.rs115
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(())
+}