]> git.proxmox.com Git - pxar.git/blob - tests/simple/main.rs
676322d5480c2f81edc3e32a2bacc64c0d341b73
[pxar.git] / tests / simple / main.rs
1 use std::io::Read;
2 use std::path::Path;
3
4 use pxar::accessor::sync as accessor;
5 use pxar::decoder::sync as decoder;
6 use pxar::encoder::sync as encoder;
7 use pxar::encoder::SeqWrite;
8 use pxar::EntryKind as PxarEntryKind;
9
10 macro_rules! format_err {
11 ($($msg:tt)+) => {
12 std::io::Error::new(std::io::ErrorKind::Other, format!($($msg)+))
13 };
14 }
15
16 macro_rules! bail {
17 ($($msg:tt)+) => {{
18 return Err(format_err!($($msg)+).into());
19 }};
20 }
21
22 pub type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
23
24 mod fs;
25
26 fn encode_directory<T: SeqWrite>(
27 encoder: &mut encoder::Encoder<T>,
28 entry: &fs::Entry,
29 ) -> Result<(), Error> {
30 let mut hardlinks = fs::HardlinkList::new();
31
32 match &entry.entry {
33 fs::EntryKind::Directory(entries) => {
34 for entry in entries {
35 entry.encode_into(encoder, &mut hardlinks, Path::new("/"))?;
36 }
37 Ok(())
38 }
39 _ => bail!("encode_directory on a non-directory"),
40 }
41 }
42
43 #[test]
44 fn test1() {
45 let mut file = Vec::<u8>::new();
46
47 let test_fs = fs::test_fs();
48 let mut encoder =
49 encoder::Encoder::from_std(&mut file, &test_fs.metadata).expect("failed to create encoder");
50 encode_directory(&mut encoder, &test_fs).expect("failed to encode test file system");
51 encoder
52 .finish()
53 .expect("failed to finish encoding the pxar archive");
54
55 assert!(!file.is_empty(), "encoder did not write any data");
56
57 // may be useful for testing...
58 // std::fs::write("myarchive.pxar", &file).expect("failed to write out test archive");
59
60 let mut input = &file[..];
61 let mut decoder = decoder::Decoder::from_std(&mut input).expect("failed to create decoder");
62 let decoded_fs =
63 fs::Entry::decode_from(&mut decoder).expect("failed to decode previously encoded archive");
64
65 assert_eq!(test_fs, decoded_fs);
66
67 let accessor = accessor::Accessor::new(&file[..], file.len() as u64)
68 .expect("failed to create random access reader for encoded archive");
69
70 check_bunzip2(&accessor);
71 check_run_special_files(&accessor);
72 }
73
74 fn check_bunzip2(accessor: &accessor::Accessor<&[u8]>) {
75 let root = accessor
76 .open_root()
77 .expect("failed to open root of encoded archive");
78
79 let bunzip2 = root
80 .lookup("usr/bin/bunzip2")
81 .expect("failed to lookup usr/bin/bunzip2 in test data")
82 .expect("missing usr/bin/bunzip2 in test data");
83 match bunzip2.kind() {
84 PxarEntryKind::Hardlink(link) => assert_eq!(link.as_os_str(), "/usr/bin/bzip2"),
85 _ => panic!("expected usr/bin/bunzip2 in test data to be a hardlink"),
86 }
87 let bzip2 = accessor
88 .follow_hardlink(&bunzip2)
89 .expect("failed to follow usr/bin/bunzip2 hardlink in test data");
90 assert!(bzip2.is_regular_file());
91 let mut content = String::new();
92 let len = bzip2
93 .contents()
94 .expect("failed to get contents of bzip2 file")
95 .read_to_string(&mut content)
96 .expect("failed to read bzip2 file into a string");
97 match bzip2.kind() {
98 PxarEntryKind::File { size, .. } => assert_eq!(len as u64, *size),
99 _ => panic!("expected usr/bin/bzip2 in test data to be a regular file"),
100 }
101
102 assert_eq!(content, "This is the bzip2 executable");
103 }
104
105 fn check_run_special_files(accessor: &accessor::Accessor<&[u8]>) {
106 let rundir = accessor
107 .open_root()
108 .expect("failed to open root of encoded archive")
109 .lookup("run")
110 .expect("failed to open /run in encoded archive")
111 .expect("missing /run in encoded archive")
112 .enter_directory()
113 .expect("expected /run to be a directory in the test archive");
114
115 assert_eq!(rundir.entry_count(), 2, "expected 2 entries in /run");
116
117 let mut rd = rundir.read_dir();
118 let fifo0 = rd
119 .next()
120 .expect("expected 'fifo0' entry in rundir")
121 .expect("failed to get first (fifo0) entry in test archive /run directory");
122 assert_eq!(
123 fifo0.file_name(),
124 Path::new("fifo0"),
125 "expected first file in /run to be fifo0"
126 );
127
128 let _entry = fifo0
129 .decode_entry()
130 .expect("failed to decode entry for fifo0");
131
132 let sock0 = rd
133 .next()
134 .expect("expected 'sock0' entry in rundir")
135 .expect("failed to get second (sock0) entry in test archive /run directory");
136 assert_eq!(
137 sock0.file_name(),
138 Path::new("sock0"),
139 "expected second file in /run to be sock0"
140 );
141
142 let _entry = sock0
143 .decode_entry()
144 .expect("failed to decode entry for sock0");
145 }