public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH pxar 5/6] add entry v1 compatiblity test
Date: Tue, 28 Jul 2020 12:33:20 +0200	[thread overview]
Message-ID: <20200728103321.16843-7-w.bumiller@proxmox.com> (raw)
In-Reply-To: <20200728103321.16843-1-w.bumiller@proxmox.com>

Signed-off-by: Wolfgang Bumiller <w.bumiller@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





  parent reply	other threads:[~2020-07-28 10:33 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-28 10:33 [pbs-devel] [PATCH pxar/backup 0/6] bump timestamps to 96 bit Wolfgang Bumiller
2020-07-28 10:33 ` [pbs-devel] [PATCH pxar 1/6] add format description to format module Wolfgang Bumiller
2020-07-28 10:33 ` [pbs-devel] [PATCH backup] update to pxar 0.3 to support negative timestamps Wolfgang Bumiller
2020-07-29  6:32   ` [pbs-devel] applied: " Dietmar Maurer
2020-07-28 10:33 ` [pbs-devel] [PATCH pxar 2/6] introduce StatxTimestamp helper type Wolfgang Bumiller
2020-07-28 14:05   ` [pbs-devel] [PATCH pxar v2 " Wolfgang Bumiller
2020-07-28 10:33 ` [pbs-devel] [PATCH pxar 3/6] update mk-format-hashes for a new ENTRY Wolfgang Bumiller
2020-07-28 10:33 ` [pbs-devel] [PATCH pxar 4/6] implement Entry v2 Wolfgang Bumiller
2020-07-28 10:33 ` Wolfgang Bumiller [this message]
2020-07-28 10:33 ` [pbs-devel] [PATCH pxar 6/6] bump version to 0.3.0-1 Wolfgang Bumiller
2020-07-29  6:14 ` [pbs-devel] applied: [PATCH pxar/backup 0/6] bump timestamps to 96 bit Dietmar Maurer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200728103321.16843-7-w.bumiller@proxmox.com \
    --to=w.bumiller@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal