Skip to content

Commit 463b4d0

Browse files
authored
feat: add unit tests for cpio and compression modules (#2)
1 parent bd70f4d commit 463b4d0

File tree

2 files changed

+175
-0
lines changed

2 files changed

+175
-0
lines changed

src/initramfs/compress.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,86 @@ pub fn compress_archive(data: &[u8], output_path: &Path, compression: Compressio
7878

7979
Ok(output_size)
8080
}
81+
82+
#[cfg(test)]
83+
mod tests {
84+
use super::*;
85+
use std::fs;
86+
use std::io::Read;
87+
use tempfile::TempDir;
88+
89+
#[test]
90+
fn test_compression_from_str() {
91+
assert_eq!("gzip".parse::<Compression>().unwrap(), Compression::Gzip);
92+
assert_eq!("gz".parse::<Compression>().unwrap(), Compression::Gzip);
93+
assert_eq!("zstd".parse::<Compression>().unwrap(), Compression::Zstd);
94+
assert_eq!("zst".parse::<Compression>().unwrap(), Compression::Zstd);
95+
assert_eq!("none".parse::<Compression>().unwrap(), Compression::None);
96+
assert_eq!("raw".parse::<Compression>().unwrap(), Compression::None);
97+
assert!("invalid".parse::<Compression>().is_err());
98+
}
99+
100+
#[test]
101+
fn test_compression_display() {
102+
assert_eq!(format!("{}", Compression::Gzip), "gzip");
103+
assert_eq!(format!("{}", Compression::Zstd), "zstd");
104+
assert_eq!(format!("{}", Compression::None), "none");
105+
}
106+
107+
#[test]
108+
fn test_compression_default() {
109+
assert_eq!(Compression::default(), Compression::Gzip);
110+
}
111+
112+
#[test]
113+
fn test_gzip_compression() {
114+
let temp_dir = TempDir::new().unwrap();
115+
let output_path = temp_dir.path().join("test.gz");
116+
// Use repetitive data that compresses well
117+
let data: Vec<u8> = b"hello world ".repeat(100).to_vec();
118+
119+
let size = compress_archive(&data, &output_path, Compression::Gzip).unwrap();
120+
121+
assert!(output_path.exists());
122+
assert!(size > 0);
123+
124+
// Verify it's valid gzip and decompresses correctly
125+
let file = File::open(&output_path).unwrap();
126+
let mut decoder = flate2::read::GzDecoder::new(file);
127+
let mut decompressed = Vec::new();
128+
decoder.read_to_end(&mut decompressed).unwrap();
129+
assert_eq!(decompressed, data);
130+
}
131+
132+
#[test]
133+
fn test_zstd_compression() {
134+
let temp_dir = TempDir::new().unwrap();
135+
let output_path = temp_dir.path().join("test.zst");
136+
let data = b"hello world hello world hello world";
137+
138+
let size = compress_archive(data, &output_path, Compression::Zstd).unwrap();
139+
140+
assert!(output_path.exists());
141+
assert!(
142+
size < data.len() as u64,
143+
"Compressed size should be smaller"
144+
);
145+
146+
// Verify it's valid zstd
147+
let compressed = fs::read(&output_path).unwrap();
148+
let decompressed = zstd::decode_all(&compressed[..]).unwrap();
149+
assert_eq!(decompressed, data);
150+
}
151+
152+
#[test]
153+
fn test_no_compression() {
154+
let temp_dir = TempDir::new().unwrap();
155+
let output_path = temp_dir.path().join("test.cpio");
156+
let data = b"hello world";
157+
158+
let size = compress_archive(data, &output_path, Compression::None).unwrap();
159+
160+
assert_eq!(size, data.len() as u64);
161+
assert_eq!(fs::read(&output_path).unwrap(), data);
162+
}
163+
}

src/initramfs/cpio.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,95 @@ impl Default for CpioArchive {
188188
Self::new()
189189
}
190190
}
191+
192+
#[cfg(test)]
193+
mod tests {
194+
use super::*;
195+
use std::fs;
196+
use tempfile::TempDir;
197+
198+
#[test]
199+
fn test_empty_archive() {
200+
let archive = CpioArchive::new();
201+
assert!(archive.is_empty());
202+
assert_eq!(archive.len(), 0);
203+
}
204+
205+
#[test]
206+
fn test_archive_from_directory() {
207+
let temp_dir = TempDir::new().unwrap();
208+
let file_path = temp_dir.path().join("test.txt");
209+
fs::write(&file_path, b"hello world").unwrap();
210+
211+
let archive = CpioArchive::from_directory(temp_dir.path()).unwrap();
212+
assert_eq!(archive.len(), 1);
213+
}
214+
215+
#[test]
216+
fn test_cpio_header_magic() {
217+
let temp_dir = TempDir::new().unwrap();
218+
let file_path = temp_dir.path().join("test.txt");
219+
fs::write(&file_path, b"test").unwrap();
220+
221+
let archive = CpioArchive::from_directory(temp_dir.path()).unwrap();
222+
let mut output = Vec::new();
223+
archive.write_to(&mut output).unwrap();
224+
225+
let header = String::from_utf8_lossy(&output[..6]);
226+
assert_eq!(header, "070701", "CPIO header should start with newc magic");
227+
}
228+
229+
#[test]
230+
fn test_cpio_trailer() {
231+
let archive = CpioArchive::new();
232+
let mut output = Vec::new();
233+
archive.write_to(&mut output).unwrap();
234+
235+
let output_str = String::from_utf8_lossy(&output);
236+
assert!(
237+
output_str.contains("TRAILER!!!"),
238+
"Archive should end with TRAILER!!!"
239+
);
240+
}
241+
242+
#[test]
243+
fn test_multiple_files() {
244+
let temp_dir = TempDir::new().unwrap();
245+
fs::write(temp_dir.path().join("a.txt"), b"aaa").unwrap();
246+
fs::write(temp_dir.path().join("b.txt"), b"bbb").unwrap();
247+
fs::create_dir(temp_dir.path().join("subdir")).unwrap();
248+
fs::write(temp_dir.path().join("subdir/c.txt"), b"ccc").unwrap();
249+
250+
let archive = CpioArchive::from_directory(temp_dir.path()).unwrap();
251+
assert_eq!(archive.len(), 4); // 3 files + 1 directory
252+
}
253+
254+
#[test]
255+
fn test_symlink_handling() {
256+
let temp_dir = TempDir::new().unwrap();
257+
let target = temp_dir.path().join("target.txt");
258+
let link = temp_dir.path().join("link.txt");
259+
fs::write(&target, b"target content").unwrap();
260+
261+
#[cfg(unix)]
262+
std::os::unix::fs::symlink(&target, &link).unwrap();
263+
264+
let archive = CpioArchive::from_directory(temp_dir.path()).unwrap();
265+
266+
#[cfg(unix)]
267+
assert_eq!(archive.len(), 2);
268+
}
269+
270+
#[test]
271+
fn test_output_alignment() {
272+
let temp_dir = TempDir::new().unwrap();
273+
fs::write(temp_dir.path().join("odd.txt"), b"123").unwrap(); // 3 bytes, needs padding
274+
275+
let archive = CpioArchive::from_directory(temp_dir.path()).unwrap();
276+
let mut output = Vec::new();
277+
archive.write_to(&mut output).unwrap();
278+
279+
// Output should be 4-byte aligned
280+
assert_eq!(output.len() % 4, 0, "CPIO output should be 4-byte aligned");
281+
}
282+
}

0 commit comments

Comments
 (0)