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 } |