Mercurial > crates > nonstick
comparison libpam-sys/libpam-sys-test/build.rs @ 110:2346fd501b7a
Add tests for constants and do other macro niceties.
- Adds tests for all the constants. Pretty sweet.
- Moves documentation for cfg-pam-impl macro to `libpam-sys`.
- Renames `Illumos` to `Sun`.
- other stuff
| author | Paul Fisher <paul@pfish.zone> |
|---|---|
| date | Sun, 29 Jun 2025 02:15:46 -0400 |
| parents | |
| children | 04105e9a7de8 |
comparison
equal
deleted
inserted
replaced
| 109:bb465393621f | 110:2346fd501b7a |
|---|---|
| 1 use bindgen::MacroTypeVariation; | |
| 2 use libpam_sys_impls::cfg_pam_impl; | |
| 3 use quote::ToTokens; | |
| 4 use std::path::PathBuf; | |
| 5 use std::{env, fs}; | |
| 6 use syn::{Item, ItemConst}; | |
| 7 | |
| 8 fn main() { | |
| 9 generate_const_test(); | |
| 10 } | |
| 11 | |
| 12 #[cfg_pam_impl("LinuxPam")] | |
| 13 fn test_config() -> TestConfig { | |
| 14 TestConfig { | |
| 15 headers: vec![ | |
| 16 "security/_pam_types.h".into(), | |
| 17 "security/pam_appl.h".into(), | |
| 18 "security/pam_ext.h".into(), | |
| 19 "security/pam_modules.h".into(), | |
| 20 ], | |
| 21 ignore_consts: vec!["__LINUX_PAM__".into(), "__LINUX_PAM_MINOR__".into()], | |
| 22 } | |
| 23 } | |
| 24 | |
| 25 #[cfg_pam_impl("OpenPam")] | |
| 26 fn test_config() -> TestConfig { | |
| 27 TestConfig { | |
| 28 headers: vec![ | |
| 29 "security/pam_types.h", | |
| 30 "security/openpam.h", | |
| 31 "security/pam_appl.h", | |
| 32 "security/pam_constants.h", | |
| 33 ], | |
| 34 ignore_consts: vec![], | |
| 35 } | |
| 36 } | |
| 37 | |
| 38 #[cfg_pam_impl(not(any("LinuxPam", "OpenPam")))] | |
| 39 fn test_config() -> TestConfig { | |
| 40 panic!("This PAM implementation is not yet tested.") | |
| 41 } | |
| 42 | |
| 43 fn generate_const_test() { | |
| 44 let config = test_config(); | |
| 45 let builder = bindgen::Builder::default() | |
| 46 .header_contents("_.h", &config.header_contents()) | |
| 47 .merge_extern_blocks(true) | |
| 48 .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) | |
| 49 .blocklist_type(".*") | |
| 50 .blocklist_function(".*") | |
| 51 .allowlist_var(".*") | |
| 52 .default_macro_constant_type(MacroTypeVariation::Unsigned); | |
| 53 | |
| 54 let generated = builder.generate().unwrap().to_string(); | |
| 55 let file = syn::parse_file(&generated).unwrap(); | |
| 56 let mut tests = vec![]; | |
| 57 tests.push("{".into()); | |
| 58 tests.extend( | |
| 59 file.items | |
| 60 .iter() | |
| 61 .filter_map(|item| { | |
| 62 if let Item::Const(item) = item { | |
| 63 Some(item) | |
| 64 } else { | |
| 65 None | |
| 66 } | |
| 67 }) | |
| 68 .filter(|item| config.should_check_const(item)) | |
| 69 .map(|item| { | |
| 70 let tokens = item.expr.to_token_stream(); | |
| 71 format!( | |
| 72 "assert_eq!({tokens}, libpam_sys::{name});", | |
| 73 name = item.ident | |
| 74 ) | |
| 75 }), | |
| 76 ); | |
| 77 tests.push("}".into()); | |
| 78 fs::write( | |
| 79 PathBuf::from(env::var("OUT_DIR").unwrap()).join("constant_test.rs"), | |
| 80 tests.join("\n"), | |
| 81 ) | |
| 82 .unwrap(); | |
| 83 } | |
| 84 | |
| 85 struct TestConfig { | |
| 86 headers: Vec<String>, | |
| 87 ignore_consts: Vec<String>, | |
| 88 } | |
| 89 | |
| 90 impl TestConfig { | |
| 91 fn header_contents(&self) -> String { | |
| 92 let vec: Vec<_> = self | |
| 93 .headers | |
| 94 .iter() | |
| 95 .map(|h| format!("#include <{h}>\n")) | |
| 96 .collect(); | |
| 97 vec.join("") | |
| 98 } | |
| 99 | |
| 100 fn should_check_const(&self, item: &ItemConst) -> bool { | |
| 101 !self.ignore_consts.contains(&item.ident.to_string()) | |
| 102 } | |
| 103 } |
