Skip to content

Commit 6c3a874

Browse files
committed
Add unit tests
Signed-off-by: Malhar Vora <mlvora.2010@gmail.com>
1 parent 4a6eeba commit 6c3a874

2 files changed

Lines changed: 149 additions & 0 deletions

File tree

tests/by-util/test_lsns.rs

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// This file is part of the uutils util-linux package.
2+
//
3+
// For the full copyright and license information, please view the LICENSE
4+
// file that was distributed with this source code.
5+
6+
use uutests::new_ucmd;
7+
8+
#[test]
9+
fn test_invalid_arg() {
10+
new_ucmd!().arg("--definitely-invalid").fails().code_is(1);
11+
}
12+
13+
#[test]
14+
#[cfg(target_os = "linux")]
15+
fn test_basic_output() {
16+
let res = new_ucmd!().succeeds();
17+
let stdout = res.no_stderr().stdout_str();
18+
19+
// Check for header columns
20+
assert!(stdout.contains("NS"));
21+
assert!(stdout.contains("TYPE"));
22+
assert!(stdout.contains("NPROCS"));
23+
assert!(stdout.contains("PID"));
24+
assert!(stdout.contains("USER"));
25+
assert!(stdout.contains("COMMAND"));
26+
}
27+
28+
#[test]
29+
#[cfg(target_os = "linux")]
30+
fn test_namespace_types() {
31+
let res = new_ucmd!().succeeds();
32+
let stdout = res.no_stderr().stdout_str();
33+
34+
// We should see at least some common namespace types
35+
// Note: Not all may be present on all systems, so we check for at least one
36+
let has_namespace = stdout.contains("mnt")
37+
|| stdout.contains("net")
38+
|| stdout.contains("pid")
39+
|| stdout.contains("uts")
40+
|| stdout.contains("ipc")
41+
|| stdout.contains("user")
42+
|| stdout.contains("cgroup");
43+
44+
assert!(
45+
has_namespace,
46+
"Expected to see at least one namespace type in output"
47+
);
48+
}
49+
50+
#[test]
51+
#[cfg(target_os = "linux")]
52+
fn test_output_has_processes() {
53+
let res = new_ucmd!().succeeds();
54+
let stdout = res.no_stderr().stdout_str();
55+
56+
// The output should have at least one process (the test process itself)
57+
// Count lines (excluding header)
58+
let lines: Vec<&str> = stdout.lines().collect();
59+
assert!(
60+
lines.len() >= 2,
61+
"Expected at least header line and one namespace entry"
62+
);
63+
}
64+
65+
#[test]
66+
#[cfg(not(target_os = "linux"))]
67+
fn test_unsupported_platform() {
68+
// On non-Linux platforms, lsns should fail with an appropriate error
69+
new_ucmd!().fails();
70+
}
71+
72+
#[test]
73+
#[cfg(target_os = "linux")]
74+
fn test_output_format() {
75+
let res = new_ucmd!().succeeds();
76+
let stdout = res.no_stderr().stdout_str();
77+
78+
// Verify the output has proper table format
79+
/*
80+
Each line should have multiple columns separated by whitespace.We check
81+
for at least 4 columns as the minimum (NS, TYPE, NPROCS, PID). These
82+
fields are always present. For mnt namespaces the PID and COMMAND column
83+
will be empty.
84+
*/
85+
for line in stdout.lines().skip(1) {
86+
// Skip header
87+
if !line.is_empty() {
88+
let columns: Vec<&str> = line.split_whitespace().collect();
89+
assert!(
90+
columns.len() >= 4,
91+
"Each namespace entry should have at least 4 columns"
92+
);
93+
}
94+
}
95+
}
96+
97+
#[test]
98+
#[cfg(target_os = "linux")]
99+
fn test_namespace_ids_are_numeric() {
100+
let res = new_ucmd!().succeeds();
101+
let stdout = res.no_stderr().stdout_str();
102+
103+
/*
104+
The first column of each line should be the namespace ID which is an inod number
105+
and it should be numeric.
106+
*/
107+
108+
// Skip the header line and check that namespace IDs are numeric
109+
for line in stdout.lines().skip(1) {
110+
if !line.is_empty() {
111+
let columns: Vec<&str> = line.split_whitespace().collect();
112+
if !columns.is_empty() {
113+
let ns_id = columns[0];
114+
assert!(
115+
ns_id.chars().all(|c| c.is_ascii_digit()),
116+
"Namespace ID should be numeric: {}",
117+
ns_id
118+
);
119+
}
120+
}
121+
}
122+
}
123+
124+
#[test]
125+
#[cfg(target_os = "linux")]
126+
fn test_user_column_not_empty() {
127+
let res = new_ucmd!().succeeds();
128+
let stdout = res.no_stderr().stdout_str();
129+
130+
// Check that USER column (5th column) is not empty for entries with processes
131+
for line in stdout.lines().skip(1) {
132+
if !line.is_empty() {
133+
let columns: Vec<&str> = line.split_whitespace().collect();
134+
if columns.len() >= 5 {
135+
// If there's a PID (4th column is not empty), there should be a user
136+
if !columns[3].is_empty() && columns[3] != "0" {
137+
assert!(
138+
!columns[4].is_empty(),
139+
"User column should not be empty when PID is present"
140+
);
141+
}
142+
}
143+
}
144+
}
145+
}

tests/tests.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ mod test_lsmem;
2727
#[path = "by-util/test_lslocks.rs"]
2828
mod test_lslocks;
2929

30+
#[cfg(feature = "lsns")]
31+
#[path = "by-util/test_lsns.rs"]
32+
mod test_lsns;
33+
3034
#[cfg(feature = "mesg")]
3135
#[path = "by-util/test_mesg.rs"]
3236
mod test_mesg;

0 commit comments

Comments
 (0)