Skip to content

Commit

Permalink
Introduce builder infrastructure for assembling Nitrocli instance
Browse files Browse the repository at this point in the history
In the future we would like to provide more ways for tests to create a
Nitrocli instance. In order to prevent explosion of with_XXX methods for
each possible combination of arguments, this change introduces a Builder
struct that can be used to create such an instance in an idiomatic way.
  • Loading branch information
d-e-s-o committed Aug 25, 2020
1 parent 147d016 commit b114125
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 40 deletions.
14 changes: 11 additions & 3 deletions src/tests/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,22 @@ $"#,
)
.unwrap();

let out = Nitrocli::with_model(model).handle(&["config", "get"])?;
let out = Nitrocli::make()
.model(model)
.build()
.handle(&["config", "get"])?;

assert!(re.is_match(&out), out);
Ok(())
}

#[test_device]
fn set_wrong_usage(model: nitrokey::Model) {
let res = Nitrocli::with_model(model).handle(&["config", "set", "--numlock", "2", "-N"]);
let res =
Nitrocli::make()
.model(model)
.build()
.handle(&["config", "set", "--numlock", "2", "-N"]);
let err = res.unwrap_str_err();
assert!(
err.contains("The argument '--numlock <numlock>' cannot be used with '--no-numlock'"),
Expand All @@ -65,7 +73,7 @@ fn set_wrong_usage(model: nitrokey::Model) {

#[test_device]
fn set_get(model: nitrokey::Model) -> crate::Result<()> {
let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let _ = ncli.handle(&["config", "set", "-s", "1", "-c", "0", "-N"])?;

let re = regex::Regex::new(
Expand Down
10 changes: 7 additions & 3 deletions src/tests/encrypted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ $"#,
regex::Regex::new(&re).unwrap()
}

let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let out = ncli.handle(&["status"])?;
assert!(make_re(None).is_match(&out), out);

Expand All @@ -61,7 +61,11 @@ $"#,

#[test_device(pro)]
fn encrypted_open_on_pro(model: nitrokey::Model) {
let res = Nitrocli::with_model(model).handle(&["encrypted", "open"]);
let res = Nitrocli::make()
.model(model)
.build()
.handle(&["encrypted", "open"]);

assert_eq!(
res.unwrap_str_err(),
"This command is only available on the Nitrokey Storage",
Expand All @@ -70,7 +74,7 @@ fn encrypted_open_on_pro(model: nitrokey::Model) {

#[test_device(storage)]
fn encrypted_open_close(model: nitrokey::Model) -> crate::Result<()> {
let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let out = ncli.handle(&["encrypted", "open"])?;
assert!(out.is_empty());

Expand Down
2 changes: 1 addition & 1 deletion src/tests/hidden.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use super::*;

#[test_device(storage)]
fn hidden_create_open_close(model: nitrokey::Model) -> crate::Result<()> {
let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).password("1234567").build();
let out = ncli.handle(&["hidden", "create", "0", "50", "100"])?;
assert!(out.is_empty());

Expand Down
2 changes: 1 addition & 1 deletion src/tests/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn connected(model: nitrokey::Model) -> crate::Result<()> {
)
.unwrap();

let out = Nitrocli::with_model(model).handle(&["list"])?;
let out = Nitrocli::make().model(model).build().handle(&["list"])?;
assert!(re.is_match(&out), out);
Ok(())
}
4 changes: 2 additions & 2 deletions src/tests/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ use super::*;
#[test_device(pro)]
fn lock_pro(model: nitrokey::Model) -> crate::Result<()> {
// We can't really test much more here than just success of the command.
let out = Nitrocli::with_model(model).handle(&["lock"])?;
let out = Nitrocli::make().model(model).build().handle(&["lock"])?;
assert!(out.is_empty());

Ok(())
}

#[test_device(storage)]
fn lock_storage(model: nitrokey::Model) -> crate::Result<()> {
let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let _ = ncli.handle(&["encrypted", "open"])?;

let out = ncli.handle(&["lock"])?;
Expand Down
38 changes: 26 additions & 12 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,30 @@ where
}
}

struct Builder(Nitrocli);

impl Builder {
/// Set the model to use.
fn model(mut self, model: nitrokey::Model) -> Self {
self.0.model = Some(model);
self
}

/// Set the password to use for certain operations.
fn password<P>(mut self, password: P) -> Self
where
P: Into<ffi::OsString>,
{
self.0.password = Some(password.into());
self
}

/// Build the final `Nitrocli` object.
fn build(self) -> Nitrocli {
self.0
}
}

struct Nitrocli {
model: Option<nitrokey::Model>,
admin_pin: Option<ffi::OsString>,
Expand All @@ -105,18 +129,8 @@ impl Nitrocli {
}
}

pub fn with_model<M>(model: M) -> Self
where
M: Into<nitrokey::Model>,
{
Self {
model: Some(model.into()),
admin_pin: Some(nitrokey::DEFAULT_ADMIN_PIN.into()),
user_pin: Some(nitrokey::DEFAULT_USER_PIN.into()),
new_admin_pin: None,
new_user_pin: None,
password: Some("1234567".into()),
}
pub fn make() -> Builder {
Builder(Self::new())
}

pub fn admin_pin(&mut self, pin: impl Into<ffi::OsString>) {
Expand Down
20 changes: 13 additions & 7 deletions src/tests/otp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ use crate::args;

#[test_device]
fn set_invalid_slot_raw(model: nitrokey::Model) {
let (rc, out, err) = Nitrocli::with_model(model).run(&["otp", "set", "100", "name", "1234"]);
let (rc, out, err) = Nitrocli::make()
.model(model)
.build()
.run(&["otp", "set", "100", "name", "1234"]);

assert_ne!(rc, 0);
assert_eq!(out, b"");
Expand All @@ -32,7 +35,10 @@ fn set_invalid_slot_raw(model: nitrokey::Model) {

#[test_device]
fn set_invalid_slot(model: nitrokey::Model) {
let res = Nitrocli::with_model(model).handle(&["otp", "set", "100", "name", "1234"]);
let res = Nitrocli::make()
.model(model)
.build()
.handle(&["otp", "set", "100", "name", "1234"]);

assert_eq!(
res.unwrap_lib_err(),
Expand All @@ -51,7 +57,7 @@ fn status(model: nitrokey::Model) -> crate::Result<()> {
)
.unwrap();

let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
// Make sure that we have at least something to display by ensuring
// that there is one slot programmed.
let _ = ncli.handle(&["otp", "set", "0", "the-name", "123456"])?;
Expand All @@ -69,7 +75,7 @@ fn set_get_hotp(model: nitrokey::Model) -> crate::Result<()> {
const OTP1: &str = concat!(755224, "\n");
const OTP2: &str = concat!(287082, "\n");

let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let _ = ncli.handle(&[
"otp", "set", "-a", "hotp", "-f", "ascii", "1", "name", &SECRET,
])?;
Expand All @@ -90,7 +96,7 @@ fn set_get_totp(model: nitrokey::Model) -> crate::Result<()> {
const TIME: &str = stringify!(1111111111);
const OTP: &str = concat!(14050471, "\n");

let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let _ = ncli.handle(&["otp", "set", "-d", "8", "-f", "ascii", "2", "name", &SECRET])?;

let out = ncli.handle(&["otp", "get", "-t", TIME, "2"])?;
Expand All @@ -106,15 +112,15 @@ fn set_totp_uneven_chars(model: nitrokey::Model) -> crate::Result<()> {
];

for (format, secret) in &secrets {
let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let _ = ncli.handle(&["otp", "set", "-f", format.as_ref(), "3", "foobar", &secret])?;
}
Ok(())
}

#[test_device]
fn clear(model: nitrokey::Model) -> crate::Result<()> {
let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let _ = ncli.handle(&["otp", "set", "3", "hotp-test", "abcdef"])?;
let _ = ncli.handle(&["otp", "clear", "3"])?;
let res = ncli.handle(&["otp", "get", "3"]);
Expand Down
7 changes: 5 additions & 2 deletions src/tests/pin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ fn unblock(model: nitrokey::Model) -> crate::Result<()> {
assert!(device.get_user_retry_count()? < 3);
}

let _ = Nitrocli::with_model(model).handle(&["pin", "unblock"])?;
let _ = Nitrocli::make()
.model(model)
.build()
.handle(&["pin", "unblock"])?;

{
let mut manager = nitrokey::force_take()?;
Expand All @@ -47,7 +50,7 @@ fn unblock(model: nitrokey::Model) -> crate::Result<()> {

#[test_device]
fn set_user(model: nitrokey::Model) -> crate::Result<()> {
let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
// Set a new user PIN.
ncli.new_user_pin("new-pin");
let out = ncli.handle(&["pin", "set", "user"])?;
Expand Down
13 changes: 8 additions & 5 deletions src/tests/pws.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ use super::*;

#[test_device]
fn set_invalid_slot(model: nitrokey::Model) {
let res = Nitrocli::with_model(model).handle(&["pws", "set", "100", "name", "login", "1234"]);
let res = Nitrocli::make()
.model(model)
.build()
.handle(&["pws", "set", "100", "name", "login", "1234"]);

assert_eq!(
res.unwrap_lib_err(),
Expand All @@ -40,7 +43,7 @@ fn status(model: nitrokey::Model) -> crate::Result<()> {
)
.unwrap();

let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
// Make sure that we have at least something to display by ensuring
// that there are there is one slot programmed.
let _ = ncli.handle(&["pws", "set", "0", "the-name", "the-login", "123456"])?;
Expand All @@ -56,7 +59,7 @@ fn set_get(model: nitrokey::Model) -> crate::Result<()> {
const LOGIN: &str = "d-e-s-o";
const PASSWORD: &str = "my-secret-password";

let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let _ = ncli.handle(&["pws", "set", "1", &NAME, &LOGIN, &PASSWORD])?;

let out = ncli.handle(&["pws", "get", "1", "--quiet", "--name"])?;
Expand Down Expand Up @@ -88,7 +91,7 @@ fn set_reset_get(model: nitrokey::Model) -> crate::Result<()> {
const LOGIN: &str = "a\\user";
const PASSWORD: &str = "!@&-)*(&+%^@";

let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let _ = ncli.handle(&["pws", "set", "2", &NAME, &LOGIN, &PASSWORD])?;

let out = ncli.handle(&["reset"])?;
Expand All @@ -107,7 +110,7 @@ fn set_reset_get(model: nitrokey::Model) -> crate::Result<()> {

#[test_device]
fn clear(model: nitrokey::Model) -> crate::Result<()> {
let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let _ = ncli.handle(&["pws", "set", "10", "clear-test", "some-login", "abcdef"])?;
let _ = ncli.handle(&["pws", "clear", "10"])?;
let res = ncli.handle(&["pws", "get", "10"]);
Expand Down
2 changes: 1 addition & 1 deletion src/tests/reset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use super::*;
#[test_device]
fn reset(model: nitrokey::Model) -> crate::Result<()> {
let new_admin_pin = "87654321";
let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();

// Change the admin PIN.
ncli.new_admin_pin(new_admin_pin);
Expand Down
4 changes: 2 additions & 2 deletions src/tests/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ $"#,
)
.unwrap();

let out = Nitrocli::with_model(model).handle(&["status"])?;
let out = Nitrocli::make().model(model).build().handle(&["status"])?;
assert!(re.is_match(&out), out);
Ok(())
}
Expand All @@ -75,7 +75,7 @@ $"#,
)
.unwrap();

let out = Nitrocli::with_model(model).handle(&["status"])?;
let out = Nitrocli::make().model(model).build().handle(&["status"])?;
assert!(re.is_match(&out), out);
Ok(())
}
2 changes: 1 addition & 1 deletion src/tests/unencrypted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use super::*;

#[test_device(storage)]
fn unencrypted_set_read_write(model: nitrokey::Model) -> crate::Result<()> {
let mut ncli = Nitrocli::with_model(model);
let mut ncli = Nitrocli::make().model(model).build();
let out = ncli.handle(&["unencrypted", "set", "read-write"])?;
assert!(out.is_empty());

Expand Down

0 comments on commit b114125

Please sign in to comment.