Mercurial > crates > nonstick
diff testharness/src/bin/testharness.rs @ 163:a75a66cb4181
Add end-to-end tests; fix issues found by tests.
- Create tests and installer/remover shell script
- Fix Pointer/pointee problems
- Add Debug formatting
- Misc cleanup
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Mon, 14 Jul 2025 17:40:11 -0400 |
parents | a2676475e86b |
children | 2f5913131295 |
line wrap: on
line diff
--- a/testharness/src/bin/testharness.rs Mon Jul 14 15:07:16 2025 -0400 +++ b/testharness/src/bin/testharness.rs Mon Jul 14 17:40:11 2025 -0400 @@ -1,3 +1,121 @@ //! The actual program which runs the tests. -fn main() {} +use nonstick::conv::Exchange; +use nonstick::items::Items; +use nonstick::libpam::TransactionBuilder; +use nonstick::{Conversation, ErrorCode, Flags, LibPamTransaction, PamShared, Transaction}; +use std::cell::Cell; +use std::ffi::OsString; +use std::os::unix::ffi::OsStrExt; + +fn main() { + test_wrong_user(); + test_wrong_password(); + test_correct(); +} + +#[derive(Debug, Default)] +struct TestHarness { + username_requested: Cell<bool>, + wrong_username: bool, + wrong_password: bool, + changing_password: Cell<bool>, + change_prompt_count: Cell<u8>, +} + +impl Conversation for &TestHarness { + fn communicate(&self, messages: &[Exchange]) { + if let [only_msg] = messages { + match only_msg { + Exchange::Prompt(p) => { + if self.username_requested.get() { + panic!("username already requested!") + } + if self.wrong_username { + p.set_answer(Ok(OsString::from("not-right"))) + } else { + p.set_answer(Ok(OsString::from("initial"))) + } + self.username_requested.set(true) + } + Exchange::MaskedPrompt(p) => { + let answer = if self.changing_password.get() { + let prompts = self.change_prompt_count.get(); + self.change_prompt_count.set(prompts + 1); + match prompts { + 0 => "mistake", + 1 => "mismatch", + 2 => "acceptable", + 3 => "acceptable", + _ => panic!("unexpected number of prompts!"), + } + } else if self.wrong_password { + "bogus" + } else { + "valid" + }; + p.set_answer(Ok(OsString::from(answer))); + } + Exchange::Error(e) if self.changing_password.get() => e.set_answer(Ok(())), + other => panic!("Unknown message {other:?}!"), + } + } else { + for msg in messages { + match msg { + Exchange::Info(i) => i.set_answer(Ok(())), + Exchange::Error(e) => e.set_answer(Ok(())), + Exchange::Prompt(p) => match p.question().as_bytes() { + b"How many?" => p.set_answer(Ok(OsString::from("123"))), + _ => p.set_answer(Err(ErrorCode::ConversationError)), + }, + Exchange::MaskedPrompt(p) => match p.question().as_bytes() { + b"Where?" => p.set_answer(Ok(OsString::from("abc"))), + _ => p.set_answer(Err(ErrorCode::ConversationError)), + }, + other => other.set_error(ErrorCode::Abort), + } + } + } + } +} + +impl TestHarness { + fn start(&self) -> LibPamTransaction<&Self> { + TransactionBuilder::new_with_service("nonstick-testharness") + .build(self) + .expect("expected build success") + } +} + +fn test_wrong_user() { + let harness = TestHarness { + wrong_username: true, + ..Default::default() + }; + let mut tx = harness.start(); + let auth = tx.authenticate(Flags::empty()); + assert_eq!(auth, Err(ErrorCode::UserUnknown)); +} + +fn test_wrong_password() { + let harness = TestHarness { + wrong_password: true, + ..Default::default() + }; + let mut tx = harness.start(); + let auth = tx.authenticate(Flags::empty()); + assert_eq!(auth, Err(ErrorCode::AuthenticationError)); +} + +fn test_correct() { + let harness = TestHarness::default(); + let mut tx = harness.start(); + tx.authenticate(Flags::empty()).unwrap(); + assert_eq!(tx.items().user().unwrap().unwrap(), "updated-in-process"); + let result = tx.account_management(Flags::empty()); + assert_eq!(result, Err(ErrorCode::NewAuthTokRequired)); + harness.changing_password.set(true); + let change = tx.change_authtok(Flags::CHANGE_EXPIRED_AUTHTOK); + assert_eq!(change, Err(ErrorCode::TryAgain)); + tx.change_authtok(Flags::CHANGE_EXPIRED_AUTHTOK).unwrap(); +}