Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 9cb78c6

Browse files
committedJan 20, 2023
add unit tests for FileHeader
Added tests that check: - if valid headers do indeed parse sucessfully, - if correct values are stored into the FileHeader struct, - if correct error is thrown when file ends unexprectedly, - that the header data is not completely incorrect.
1 parent b6a83c0 commit 9cb78c6

File tree

1 file changed

+237
-0
lines changed

1 file changed

+237
-0
lines changed
 

‎src/parser/header.rs

+237
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,240 @@ impl TryFrom<&[u8]> for FileHeader {
8787
Ok(file_header)
8888
}
8989
}
90+
91+
#[cfg(test)]
92+
mod tests {
93+
use super::*;
94+
95+
mod helpers {
96+
pub const VALID_HEADER: [u8; 32] = [
97+
0x52, 0x4D, 0x41, 0x4E, 0x02, 0x00, 0x00, 0x02, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00,
98+
0x00, 0x00, 0xD2, 0x17, 0xC3, 0xEF, 0xAB, 0x4A, 0x9C, 0x2B, 0x60, 0xA4, 0xD0, 0x01,
99+
0x00, 0x00, 0x00, 0x00,
100+
];
101+
102+
macro_rules! assert_error {
103+
($buf: ident, $error: ident) => {
104+
let Err(error) = crate::FileHeader::try_from(&$buf[..]) else {
105+
panic!("did not throw an error");
106+
};
107+
let crate::error::ManifestError::$error(..) = error else {
108+
panic!("some other error was thrown");
109+
};
110+
};
111+
}
112+
113+
pub(crate) use assert_error;
114+
}
115+
116+
#[test]
117+
fn should_parse_when_valid_header() {
118+
if let Err(error) = FileHeader::try_from(&helpers::VALID_HEADER[..]) {
119+
panic!(
120+
"there was an error when parsing header, header: {:?}",
121+
error
122+
);
123+
};
124+
}
125+
126+
#[test]
127+
fn should_have_correct_values_when_valid_header() {
128+
let header = FileHeader::try_from(&helpers::VALID_HEADER[..]).unwrap();
129+
130+
assert_eq!(header.magic, 0x4E414D52, "magic bytes did not match");
131+
assert_eq!(header.major, 2, "major version did not match");
132+
assert_eq!(header.minor, 0, "minor version did not match");
133+
assert_eq!(header.flags, 512, "flags did not match");
134+
assert_eq!(header.offset, 28, "offset did not match");
135+
assert_eq!(header.compressed_size, 0, "compressed size did not match");
136+
assert_eq!(
137+
header.manifest_id, 3142468742320166866,
138+
"manifest id did not match"
139+
);
140+
assert_eq!(
141+
header.uncompressed_size, 30450784,
142+
"unompressed size did not match"
143+
);
144+
}
145+
146+
#[test]
147+
fn should_throw_correct_errors_when_eof() {
148+
// EOF when reading magic bytes
149+
let error = FileHeader::try_from(&helpers::VALID_HEADER[..3])
150+
.err()
151+
.expect("did not throw an error on missing bytes");
152+
match error {
153+
crate::error::ManifestError::ReadBytesError(_) => (),
154+
_ => panic!("invalid ManifestError error when eof"),
155+
};
156+
157+
// EOF when reading major
158+
let error = FileHeader::try_from(&helpers::VALID_HEADER[..4])
159+
.err()
160+
.expect("did not throw an error on missing bytes");
161+
match error {
162+
crate::error::ManifestError::ReadBytesError(_) => (),
163+
_ => panic!("invalid ManifestError error when eof"),
164+
};
165+
166+
// EOF when reading minor
167+
let error = FileHeader::try_from(&helpers::VALID_HEADER[..5])
168+
.err()
169+
.expect("did not throw an error on missing bytes");
170+
match error {
171+
crate::error::ManifestError::ReadBytesError(_) => (),
172+
_ => panic!("invalid ManifestError error when eof"),
173+
};
174+
175+
// EOF when reading flags
176+
let error = FileHeader::try_from(&helpers::VALID_HEADER[..7])
177+
.err()
178+
.expect("did not throw an error on missing bytes");
179+
match error {
180+
crate::error::ManifestError::ReadBytesError(_) => (),
181+
_ => panic!("invalid ManifestError error when eof"),
182+
};
183+
184+
// EOF when reading offset
185+
let error = FileHeader::try_from(&helpers::VALID_HEADER[..11])
186+
.err()
187+
.expect("did not throw an error on missing bytes");
188+
match error {
189+
crate::error::ManifestError::ReadBytesError(_) => (),
190+
_ => panic!("invalid ManifestError error when eof"),
191+
};
192+
193+
// it should be impossible for reading to fail at this point, because
194+
// offset must be greater than 28 and and less then file size, which
195+
// in turn ensures that the file size is at least 28 bytes
196+
}
197+
198+
#[test]
199+
fn should_error_when_invalid_magic_bytes() {
200+
let buf = [&[0x53], &helpers::VALID_HEADER[1..]].concat();
201+
202+
helpers::assert_error!(buf, InvalidMagicBytes);
203+
}
204+
205+
#[test]
206+
fn should_error_when_invalid_major() {
207+
let buf = [
208+
&helpers::VALID_HEADER[..4],
209+
&[0x01],
210+
&helpers::VALID_HEADER[5..],
211+
]
212+
.concat();
213+
214+
#[cfg(not(feature = "version_error"))]
215+
if let Err(_) = FileHeader::try_from(&buf[..]) {
216+
panic!("error was thrown");
217+
}
218+
219+
#[cfg(feature = "version_error")]
220+
helpers::assert_error!(buf, InvalidMajor);
221+
}
222+
223+
#[test]
224+
fn should_error_when_invalid_minor() {
225+
let buf = [
226+
&helpers::VALID_HEADER[..5],
227+
&[0x01],
228+
&helpers::VALID_HEADER[6..],
229+
]
230+
.concat();
231+
232+
#[cfg(not(feature = "version_error"))]
233+
if let Err(_) = FileHeader::try_from(&buf[..]) {
234+
panic!("error was thrown")
235+
}
236+
237+
#[cfg(feature = "version_error")]
238+
helpers::assert_error!(buf, InvalidMinor);
239+
}
240+
241+
#[test]
242+
fn should_error_when_offset_too_small() {
243+
// too small
244+
let buf = [
245+
&helpers::VALID_HEADER[..8],
246+
&0u32.to_le_bytes(),
247+
&helpers::VALID_HEADER[12..],
248+
]
249+
.concat();
250+
251+
helpers::assert_error!(buf, InvalidOffset);
252+
253+
// slightly too small
254+
let buf = [
255+
&helpers::VALID_HEADER[..8],
256+
&27u32.to_le_bytes(),
257+
&helpers::VALID_HEADER[12..],
258+
]
259+
.concat();
260+
261+
helpers::assert_error!(buf, InvalidOffset);
262+
}
263+
264+
#[test]
265+
fn should_error_when_offset_too_large() {
266+
// slightly too large
267+
let size = u32::try_from(helpers::VALID_HEADER.len()).unwrap();
268+
let buf = [
269+
&helpers::VALID_HEADER[..8],
270+
&size.to_le_bytes(),
271+
&helpers::VALID_HEADER[12..],
272+
]
273+
.concat();
274+
275+
helpers::assert_error!(buf, InvalidOffset);
276+
277+
// too large
278+
let buf = [
279+
&helpers::VALID_HEADER[..8],
280+
&u32::MAX.to_le_bytes(),
281+
&helpers::VALID_HEADER[12..],
282+
]
283+
.concat();
284+
285+
helpers::assert_error!(buf, InvalidOffset);
286+
}
287+
288+
#[test]
289+
fn should_error_when_compressed_size_too_large() {
290+
// slightly too large
291+
let size = u32::try_from(helpers::VALID_HEADER.len()).unwrap();
292+
let buf = [
293+
&helpers::VALID_HEADER[..12],
294+
&(size - 27).to_le_bytes(),
295+
&helpers::VALID_HEADER[16..],
296+
]
297+
.concat();
298+
299+
helpers::assert_error!(buf, CompressedSizeTooLarge);
300+
301+
// too large
302+
let buf = [
303+
&helpers::VALID_HEADER[..12],
304+
&u32::MAX.to_le_bytes(),
305+
&helpers::VALID_HEADER[16..],
306+
]
307+
.concat();
308+
309+
helpers::assert_error!(buf, CompressedSizeTooLarge);
310+
}
311+
312+
#[test]
313+
fn should_error_when_compressed_size_and_offset_too_large() {
314+
let offset = 28u32;
315+
let size = u32::try_from(helpers::VALID_HEADER.len()).unwrap();
316+
let buf = [
317+
&helpers::VALID_HEADER[..8],
318+
&offset.to_le_bytes(),
319+
&(size - offset + 1).to_le_bytes(),
320+
&helpers::VALID_HEADER[16..],
321+
]
322+
.concat();
323+
324+
helpers::assert_error!(buf, CompressedSizeTooLarge);
325+
}
326+
}

0 commit comments

Comments
 (0)
Please sign in to comment.