Skip to content

Commit c680dd9

Browse files
committed
tests: add code for querying kernel state
The `lazy_static` crate is used to avoid querying the kernel more than once during any given test run.
1 parent cbd4ba8 commit c680dd9

File tree

5 files changed

+169
-0
lines changed

5 files changed

+169
-0
lines changed

Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ edition = "2018"
1313
[workspace]
1414
members = ["keyutils-raw"]
1515

16+
[dev-dependencies]
17+
lazy_static = "1"
18+
regex = "1"
19+
1620
[dependencies]
1721
bitflags = "1.0.4"
1822
errno = "0.2"

src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
3131
#![warn(missing_docs)]
3232

33+
#[cfg(test)]
34+
#[macro_use] extern crate lazy_static;
35+
3336
mod api;
3437
mod constants;
3538
mod keytype;
@@ -41,3 +44,6 @@ pub use self::constants::*;
4144
pub use self::keytype::*;
4245

4346
pub use keyutils_raw::{DefaultKeyring, KeyPermissions, KeyringSerial, TimeoutSeconds};
47+
48+
#[cfg(test)]
49+
mod tests;

src/tests/mod.rs

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) 2019, Ben Boeckel
2+
// All rights reserved.
3+
//
4+
// Redistribution and use in source and binary forms, with or without modification,
5+
// are permitted provided that the following conditions are met:
6+
//
7+
// * Redistributions of source code must retain the above copyright notice,
8+
// this list of conditions and the following disclaimer.
9+
// * Redistributions in binary form must reproduce the above copyright notice,
10+
// this list of conditions and the following disclaimer in the documentation
11+
// and/or other materials provided with the distribution.
12+
// * Neither the name of this project nor the names of its contributors
13+
// may be used to endorse or promote products derived from this software
14+
// without specific prior written permission.
15+
//
16+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20+
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23+
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
//! The test structure here comes from the structure in libkeyutils.
28+
29+
mod utils;

src/tests/utils/kernel.rs

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright (c) 2019, Ben Boeckel
2+
// All rights reserved.
3+
//
4+
// Redistribution and use in source and binary forms, with or without modification,
5+
// are permitted provided that the following conditions are met:
6+
//
7+
// * Redistributions of source code must retain the above copyright notice,
8+
// this list of conditions and the following disclaimer.
9+
// * Redistributions in binary form must reproduce the above copyright notice,
10+
// this list of conditions and the following disclaimer in the documentation
11+
// and/or other materials provided with the distribution.
12+
// * Neither the name of this project nor the names of its contributors
13+
// may be used to endorse or promote products derived from this software
14+
// without specific prior written permission.
15+
//
16+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20+
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23+
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
use std::collections::HashMap;
28+
use std::fs;
29+
use std::str::FromStr;
30+
31+
use regex::{Captures, Regex};
32+
33+
lazy_static! {
34+
pub static ref PAGE_SIZE: usize = page_size();
35+
pub static ref KEY_INFO: KeyQuota = key_user_info();
36+
}
37+
38+
fn page_size() -> usize {
39+
errno::set_errno(errno::Errno(0));
40+
let ret = unsafe { libc::sysconf(libc::_SC_PAGESIZE) };
41+
if ret < 0 {
42+
let err = errno::errno();
43+
if err.0 == 0 {
44+
panic!("page size is indeterminite?");
45+
} else {
46+
panic!("failed to query the page size: {}", errno::errno());
47+
}
48+
}
49+
ret as usize
50+
}
51+
52+
const KEY_USERS_FILE: &str = "/proc/key-users";
53+
54+
lazy_static! {
55+
static ref KEY_USERS: Regex =
56+
Regex::new(" *(?P<uid>\\d+): +\
57+
(?P<usage>\\d+) \
58+
(?P<nkeys>\\d+)/(?P<nikeys>\\d+) \
59+
(?P<qnkeys>\\d+)/(?P<maxkeys>\\d+) \
60+
(?P<qnbytes>\\d+)/(?P<maxbytes>\\d+)").unwrap();
61+
}
62+
63+
fn by_name<T: FromStr>(capture: &Captures, name: &str) -> T {
64+
let cap = capture.name(name).expect("name should be captured").as_str();
65+
match cap.parse() {
66+
Ok(v) => v,
67+
Err(_) => panic!("failed to parse {} as an integer", name),
68+
}
69+
}
70+
71+
#[derive(Debug, Clone, Copy)]
72+
pub struct KeyQuota {
73+
pub usage: usize,
74+
pub nkeys: usize,
75+
pub nikeys: usize,
76+
pub qnkeys: usize,
77+
pub maxkeys: usize,
78+
pub qnbytes: usize,
79+
pub maxbytes: usize,
80+
}
81+
82+
fn all_key_user_info() -> HashMap<libc::uid_t, KeyQuota> {
83+
let data = String::from_utf8(fs::read(KEY_USERS_FILE).unwrap()).unwrap();
84+
(*KEY_USERS).captures_iter(&data)
85+
.map(|capture| {
86+
let uid = by_name(&capture, "uid");
87+
let usage = by_name(&capture, "usage");
88+
let nkeys = by_name(&capture, "nkeys");
89+
let nikeys = by_name(&capture, "nikeys");
90+
let qnkeys = by_name(&capture, "qnkeys");
91+
let maxkeys = by_name(&capture, "maxkeys");
92+
let qnbytes = by_name(&capture, "qnbytes");
93+
let maxbytes = by_name(&capture, "maxbytes");
94+
95+
(uid, KeyQuota { usage, nkeys, nikeys, qnkeys, maxkeys, qnbytes, maxbytes })
96+
})
97+
.collect()
98+
}
99+
100+
fn key_user_info() -> KeyQuota {
101+
let uid = unsafe { libc::getuid() };
102+
*all_key_user_info().get(&uid).expect("the current user has no keys?")
103+
}

src/tests/utils/mod.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) 2019, Ben Boeckel
2+
// All rights reserved.
3+
//
4+
// Redistribution and use in source and binary forms, with or without modification,
5+
// are permitted provided that the following conditions are met:
6+
//
7+
// * Redistributions of source code must retain the above copyright notice,
8+
// this list of conditions and the following disclaimer.
9+
// * Redistributions in binary form must reproduce the above copyright notice,
10+
// this list of conditions and the following disclaimer in the documentation
11+
// and/or other materials provided with the distribution.
12+
// * Neither the name of this project nor the names of its contributors
13+
// may be used to endorse or promote products derived from this software
14+
// without specific prior written permission.
15+
//
16+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20+
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21+
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22+
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23+
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
pub mod kernel;

0 commit comments

Comments
 (0)