diff testharness/tests/end2end.rs @ 104:a2676475e86b default tip

Create the very start of a test suite. - Creates a new testharness package - Sets up the outlines of a test suite that will execute there - A basic container where maybe those tests can execute
author Paul Fisher <paul@pfish.zone>
date Wed, 25 Jun 2025 16:56:56 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testharness/tests/end2end.rs	Wed Jun 25 16:56:56 2025 -0400
@@ -0,0 +1,51 @@
+use std::any::Any;
+use std::convert::Infallible;
+use std::error::Error;
+use std::io;
+use std::panic::UnwindSafe;
+use std::path::{Path, PathBuf};
+use std::{fs, panic};
+
+const PAM_CONFIG: &str = "\
+auth required pam_testharness.so
+account required pam_testharness.so
+password required pam_testharness.so
+session required pam_testharness.so
+";
+const PAM_CONFIG_PATH: &str = "/etc/pam.d/testharness";
+const PAM_MODULE_PATH: &str = "/lib/security/pam_testharness.so";
+
+#[derive(Debug, thiserror::Error)]
+enum TestError {
+    #[error("error in test harness: {0}")]
+    HarnessError(#[from] io::Error),
+    #[error("panic in test: {0:?}")]
+    Panic(Box<dyn Any + Send>),
+    #[error(transparent)]
+    TestError(anyhow::Error),
+}
+
+#[test]
+fn test_auth_only() -> Result<(), TestError> {
+    harness(|| Ok::<(), Infallible>(()))
+}
+
+fn harness<E: Error + Send + Sync + 'static>(
+    test: impl Fn() -> Result<(), E> + UnwindSafe,
+) -> Result<(), TestError> {
+    let dylib_path = test_cdylib::build_current_project();
+    let module_path = Path::new(PAM_MODULE_PATH);
+    let config_path = Path::new(PAM_CONFIG_PATH);
+    let parent = module_path.parent().unwrap();
+    fs::create_dir_all(parent)?;
+    fs::copy(dylib_path, module_path)?;
+    fs::write(config_path, PAM_CONFIG)?;
+    panic::catch_unwind(test)
+        .map_err(TestError::Panic)?
+        .map_err(|e| TestError::TestError(e.into()))?;
+    fs::remove_file(module_path)?;
+    fs::remove_file(config_path)?;
+    // If the /lib/security directory can't be removed, that's OK.
+    let _ = fs::remove_dir(parent);
+    Ok(())
+}