Skip to content

Commit c6bf4e2

Browse files
committed
test(mount): add integration tests for mount namespace refactoring
Functional tests covering greenboot's own API with mock temp dirs: - ensure_mount_namespace succeeds under test-remount feature - is_boot_writable_at detects writable, read-only, and missing paths - remount_boot_rw succeeds under test-remount feature - Public API surface compile-time validation All sensitive paths mocked — no real /boot or mount operations. Ref: fedora-iot#120 Made-with: Cursor
1 parent b719e21 commit c6bf4e2

1 file changed

Lines changed: 79 additions & 0 deletions

File tree

tests/mount_namespace.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
//
3+
// Integration tests for mount namespace refactoring (issue #120).
4+
// All sensitive system paths are mocked using tempdir — no real /boot,
5+
// /proc, mount, or unshare operations are performed.
6+
7+
use std::fs;
8+
use std::os::unix::fs::PermissionsExt;
9+
use std::path::Path;
10+
11+
// ---------------------------------------------------------------------------
12+
// Mount namespace setup
13+
// ---------------------------------------------------------------------------
14+
15+
#[test]
16+
fn ensure_mount_namespace_succeeds() {
17+
let result = greenboot::ensure_mount_namespace();
18+
assert!(result.is_ok(), "ensure_mount_namespace should succeed");
19+
}
20+
21+
// ---------------------------------------------------------------------------
22+
// Boot writable check
23+
// ---------------------------------------------------------------------------
24+
25+
#[test]
26+
fn is_boot_writable_at_detects_writable_path() {
27+
let mock_boot = tempfile::tempdir().unwrap();
28+
let result = greenboot::is_boot_writable_at(mock_boot.path());
29+
assert!(result.is_ok());
30+
assert!(result.unwrap(), "Writable mock /boot should return true");
31+
}
32+
33+
#[test]
34+
fn is_boot_writable_at_detects_readonly_path() {
35+
let mock_boot = tempfile::tempdir().unwrap();
36+
let mut perms = fs::metadata(mock_boot.path()).unwrap().permissions();
37+
perms.set_mode(0o555);
38+
fs::set_permissions(mock_boot.path(), perms).unwrap();
39+
40+
let result = greenboot::is_boot_writable_at(mock_boot.path());
41+
assert!(result.is_ok());
42+
assert!(!result.unwrap(), "Read-only mock /boot should return false");
43+
44+
let mut perms = fs::metadata(mock_boot.path()).unwrap().permissions();
45+
perms.set_mode(0o755);
46+
fs::set_permissions(mock_boot.path(), perms).unwrap();
47+
}
48+
49+
#[test]
50+
fn is_boot_writable_at_errors_on_missing_path() {
51+
let result = greenboot::is_boot_writable_at(Path::new("/nonexistent/mock/boot"));
52+
assert!(result.is_err(), "Missing path should return error");
53+
}
54+
55+
// ---------------------------------------------------------------------------
56+
// Boot remount in namespace
57+
// ---------------------------------------------------------------------------
58+
59+
#[test]
60+
fn remount_boot_rw_succeeds() {
61+
let result = greenboot::remount_boot_rw();
62+
assert!(result.is_ok(), "remount_boot_rw should succeed");
63+
}
64+
65+
// ---------------------------------------------------------------------------
66+
// Public API surface — compile-time + runtime validation
67+
// ---------------------------------------------------------------------------
68+
69+
#[test]
70+
fn public_api_surface() {
71+
let _: Result<(), greenboot::MountError> = greenboot::ensure_mount_namespace();
72+
let _: Result<(), greenboot::MountError> = greenboot::remount_boot_rw();
73+
74+
let _fn_ref: fn() -> Result<bool, greenboot::MountError> = greenboot::is_boot_writable;
75+
76+
let _: greenboot::MountError = greenboot::MountError::RemountFailed("test".to_string());
77+
let _: greenboot::MountError = greenboot::MountError::NamespaceError("test".to_string());
78+
let _: greenboot::MountError = greenboot::MountError::BootCheckError("test".to_string());
79+
}

0 commit comments

Comments
 (0)