[pbs-devel] [PATCH pxar 5/6] add entry v1 compatiblity test
Wolfgang Bumiller
w.bumiller at proxmox.com
Tue Jul 28 12:33:20 CEST 2020
Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
---
tests/compat.rs | 136 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 136 insertions(+)
create mode 100644 tests/compat.rs
diff --git a/tests/compat.rs b/tests/compat.rs
new file mode 100644
index 0000000..53e2d09
--- /dev/null
+++ b/tests/compat.rs
@@ -0,0 +1,136 @@
+//! Test for old timestamp format compatibility.
+
+use std::io::{self, Read};
+
+use endian_trait::Endian;
+
+use pxar::{decoder, format, EntryKind};
+
+fn write_raw_struct<T: Endian, W: io::Write + ?Sized>(output: &mut W, data: T) -> io::Result<()> {
+ let data = data.to_le();
+ output.write_all(unsafe {
+ std::slice::from_raw_parts(&data as *const T as *const u8, std::mem::size_of::<T>())
+ })
+}
+
+fn write_data<W>(output: &mut W, htype: u64, data: &[u8]) -> io::Result<()>
+where
+ W: io::Write + ?Sized,
+{
+ let header = format::Header::with_content_size(htype, data.len() as u64);
+ header.check_header_size()?;
+ write_raw_struct(output, header)?;
+ output.write_all(data)
+}
+
+fn write_entry<T, W>(output: &mut W, htype: u64, data: T) -> io::Result<()>
+where
+ T: Endian,
+ W: io::Write + ?Sized,
+{
+ let data = data.to_le();
+ let data = unsafe {
+ std::slice::from_raw_parts(&data as *const T as *const u8, std::mem::size_of::<T>())
+ };
+ write_data(output, htype, data)
+}
+
+const MAY_1_2015_1530: u64 = 1430487000u64;
+
+const FILE_NAME: &str = "file.txt";
+const FILE_NAME_BYTES: &[u8] = b"file.txt\0";
+const FILE_CONTENT: &[u8] = b"This is a small text file.\n";
+const ROOT_STAT: format::Entry_V1 = format::Entry_V1 {
+ mode: format::mode::IFDIR | 0o755,
+ flags: 0,
+ uid: 1000,
+ gid: 1000,
+ mtime: MAY_1_2015_1530 * 1_000_000_000u64,
+};
+const FILE_STAT: format::Entry_V1 = format::Entry_V1 {
+ mode: format::mode::IFREG | 0o644,
+ flags: 0,
+ uid: 1000,
+ gid: 1000,
+ mtime: MAY_1_2015_1530 * 1_000_000_000u64,
+};
+
+fn create_archive() -> io::Result<Vec<u8>> {
+ let mut out = Vec::new();
+
+ write_entry(&mut out, format::PXAR_ENTRY_V1, ROOT_STAT.clone())?;
+
+ let file_offset = out.len();
+ write_data(&mut out, format::PXAR_FILENAME, FILE_NAME_BYTES)?;
+ write_entry(&mut out, format::PXAR_ENTRY_V1, FILE_STAT.clone())?;
+ write_data(&mut out, format::PXAR_PAYLOAD, FILE_CONTENT)?;
+
+ let mut gbt = Vec::new();
+ write_raw_struct(
+ &mut gbt,
+ format::GoodbyeItem::new(
+ FILE_NAME.as_bytes(),
+ file_offset as u64,
+ FILE_CONTENT.len() as u64,
+ ),
+ )?;
+
+ let gbt_size = gbt.len();
+ write_raw_struct(
+ &mut gbt,
+ format::GoodbyeItem {
+ hash: format::PXAR_GOODBYE_TAIL_MARKER,
+ offset: out.len() as u64,
+ size: gbt_size as u64,
+ },
+ )?;
+
+ write_data(&mut out, format::PXAR_GOODBYE, &{ gbt })?;
+
+ Ok(out)
+}
+
+#[test]
+fn test_archive() {
+ let archive = create_archive().expect("failed to create test archive");
+ let mut input = &archive[..];
+ let mut decoder = decoder::Decoder::from_std(&mut input).expect("failed to create decoder");
+
+ let item = decoder
+ .next()
+ .expect("missing root directory in test archive")
+ .expect("failed to extract root directory from test archive");
+ match item.kind() {
+ EntryKind::Directory => (),
+ other => panic!("unexpected root entry in archive: {:?}", other),
+ }
+ assert_eq!(item.file_name(), "");
+ assert_eq!(item.metadata().stat, ROOT_STAT.into());
+ assert_eq!(
+ item.metadata().stat.mtime,
+ format::StatxTimestamp {
+ secs: MAY_1_2015_1530 as i64,
+ nanos: 0,
+ },
+ );
+
+ let item = decoder
+ .next()
+ .expect("missing file entry in test archive")
+ .expect("failed to extract file entry from test archive");
+ match item.kind() {
+ EntryKind::File { size, .. } => assert_eq!(*size, FILE_CONTENT.len() as u64),
+ other => panic!("unexpected file entry in archive: {:?}", other),
+ }
+ assert_eq!(item.file_name(), FILE_NAME);
+ assert_eq!(item.metadata().stat, FILE_STAT.into());
+ let mut content = Vec::new();
+ decoder
+ .contents()
+ .expect("failed to get contents for file entry")
+ .read_to_end(&mut content)
+ .expect("failed to read test file contents");
+ assert_eq!(&content[..], FILE_CONTENT);
+
+ assert!(decoder.next().is_none(), "expected end of test archive");
+}
--
2.20.1
More information about the pbs-devel
mailing list