🏡 index : ~doyle/packfile.git

author Jordan Doyle <jordan@doyle.la> 2023-07-04 19:36:55.0 +00:00:00
committer Jordan Doyle <jordan@doyle.la> 2023-07-04 19:36:55.0 +00:00:00
commit
5143b6fc59a18c5d0ceec31dd8a531c1e0ac9885 [patch]
tree
50b6f50e750779f34b87ddb0fa36ecc4a619df00
parent
22bfb75cd9c1f0466bef234a2650652f7754dad2
download
5143b6fc59a18c5d0ceec31dd8a531c1e0ac9885.tar.gz

Add packfile unit tests against reference git binary



Diff

 Cargo.toml                                                     |   4 +-
 src/high_level.rs                                              |  76 +++-
 src/low_level.rs                                               |   3 +-
 src/snapshots/packfile__high_level__test__deterministic.snap   | 243 ++++++++++-
 src/snapshots/packfile__high_level__test__git_verify_pack.snap |  16 +-
 5 files changed, 340 insertions(+), 2 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 7cf6a2b..5e7824f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,5 +24,9 @@ time = "0.3.15"
tokio-util = { version = "0.7", features = ["codec"], optional = true }
tracing = "0.1"

[dev-dependencies]
insta = { version = "1.29", features = ["filters"] }
tempfile = "3.5"

[features]
default = ["tokio-util"]
diff --git a/src/high_level.rs b/src/high_level.rs
index 08a4bd7..9e3035c 100644
--- a/src/high_level.rs
+++ b/src/high_level.rs
@@ -178,3 +178,79 @@ enum TreeItem {
    /// Refers to a nested directory
    Tree(Tree),
}

#[cfg(test)]
mod test {
    use crate::{high_level::GitRepository, low_level::PackFile};
    use bytes::{Bytes, BytesMut};
    use std::process::{Command, Stdio};
    use tempfile::TempDir;

    #[test]
    fn deterministic() {
        let mut repo = GitRepository::default();
        repo.insert(&["a", "b"], "c.txt", Bytes::from("hello world!"))
            .unwrap();
        repo.insert(&["c", "d"], "c.txt", Bytes::from("test"))
            .unwrap();
        let (hash, packfile) = repo
            .commit("me", "me@example.com", "initial commit")
            .unwrap();

        assert_eq!(
            hex::encode(&hash),
            "6ba08bda5731edfb2a0a00e602d1dd4bbd9d341c"
        );
        insta::assert_debug_snapshot!(packfile);
    }

    #[test]
    fn git_verify_pack() {
        let mut repo = GitRepository::default();
        repo.insert(&[], "c.txt", Bytes::from(vec![0; 256]))
            .unwrap();
        repo.insert(&["e", "f"], "c.txt", Bytes::from("hiya"))
            .unwrap();
        repo.insert(&["c", "d"], "c.txt", Bytes::from("hello world!"))
            .unwrap();
        let (_hash, packfile) = repo
            .commit("me", "me@example.com", "initial commit")
            .unwrap();

        let scratch_dir = TempDir::new().unwrap();
        let packfile_path = scratch_dir.path().join("example.pack");

        let mut output = BytesMut::new();
        PackFile::new(&packfile).encode_to(&mut output).unwrap();

        std::fs::write(&packfile_path, &output).unwrap();

        let res = Command::new("git")
            .arg("index-pack")
            .arg(&packfile_path)
            .stdout(Stdio::piped())
            .spawn()
            .unwrap()
            .wait()
            .unwrap();
        assert!(res.success());

        let command = Command::new("git")
            .arg("verify-pack")
            .arg("-v")
            .stdout(Stdio::piped())
            .arg(&packfile_path)
            .spawn()
            .unwrap();

        let out = command.wait_with_output().unwrap();
        assert!(out.status.success(), "git exited non-0");

        let stdout = String::from_utf8_lossy(&out.stdout);
        insta::with_settings!({filters => vec![
            (r#"/(.*)/example.pack"#, "/path/to/example.pack")
        ]}, {
            insta::assert_snapshot!(stdout);
        });
    }
}
diff --git a/src/low_level.rs b/src/low_level.rs
index cdfe3d5..4d51d6c 100644
--- a/src/low_level.rs
+++ b/src/low_level.rs
@@ -319,7 +319,6 @@ impl PackFileEntry {
        }
    }

    // wen const generics for RustCrypto? :-(
    #[instrument(skip(self), err)]
    pub fn hash(&self) -> Result<HashOutput, Error> {
        let size = self.uncompressed_size();
@@ -357,8 +356,8 @@ impl PackFileEntry {
#[cfg(test)]
mod test {
    mod packfile_entry {
        use bytes::{Bytes, BytesMut};
        use crate::low_level::PackFileEntry;
        use bytes::{Bytes, BytesMut};

        #[test]
        fn header_size_bytes_large() {
diff --git a/src/snapshots/packfile__high_level__test__deterministic.snap b/src/snapshots/packfile__high_level__test__deterministic.snap
new file mode 100644
index 0000000..048d4c5
--- /dev/null
+++ b/src/snapshots/packfile__high_level__test__deterministic.snap
@@ -0,0 +1,243 @@
---
source: src/high_level.rs
expression: packfile
---
[
    Blob(
        b"hello world!",
    ),
    Blob(
        b"test",
    ),
    Tree(
        [
            TreeItem {
                kind: File,
                name: Cow(
                    "c.txt",
                ),
                hash: [
                    188,
                    119,
                    116,
                    167,
                    177,
                    141,
                    235,
                    29,
                    123,
                    208,
                    33,
                    45,
                    52,
                    36,
                    106,
                    155,
                    18,
                    96,
                    174,
                    23,
                ],
                sort_name: "c.txt",
            },
        ],
    ),
    Tree(
        [
            TreeItem {
                kind: Directory,
                name: Cow(
                    "b",
                ),
                hash: [
                    65,
                    198,
                    120,
                    31,
                    37,
                    221,
                    177,
                    61,
                    142,
                    242,
                    236,
                    254,
                    191,
                    80,
                    202,
                    186,
                    44,
                    71,
                    71,
                    234,
                ],
                sort_name: "b/",
            },
        ],
    ),
    Tree(
        [
            TreeItem {
                kind: File,
                name: Cow(
                    "c.txt",
                ),
                hash: [
                    48,
                    215,
                    77,
                    37,
                    132,
                    66,
                    199,
                    198,
                    85,
                    18,
                    234,
                    250,
                    180,
                    116,
                    86,
                    141,
                    215,
                    6,
                    196,
                    48,
                ],
                sort_name: "c.txt",
            },
        ],
    ),
    Tree(
        [
            TreeItem {
                kind: Directory,
                name: Cow(
                    "d",
                ),
                hash: [
                    72,
                    157,
                    22,
                    218,
                    2,
                    209,
                    127,
                    99,
                    17,
                    32,
                    172,
                    39,
                    148,
                    57,
                    221,
                    204,
                    132,
                    195,
                    168,
                    129,
                ],
                sort_name: "d/",
            },
        ],
    ),
    Tree(
        [
            TreeItem {
                kind: Directory,
                name: Cow(
                    "a",
                ),
                hash: [
                    159,
                    188,
                    55,
                    140,
                    131,
                    37,
                    51,
                    16,
                    124,
                    161,
                    77,
                    229,
                    135,
                    77,
                    235,
                    251,
                    219,
                    170,
                    205,
                    168,
                ],
                sort_name: "a/",
            },
            TreeItem {
                kind: Directory,
                name: Cow(
                    "c",
                ),
                hash: [
                    40,
                    81,
                    135,
                    177,
                    189,
                    171,
                    157,
                    76,
                    228,
                    114,
                    5,
                    171,
                    120,
                    67,
                    95,
                    184,
                    109,
                    93,
                    6,
                    109,
                ],
                sort_name: "c/",
            },
        ],
    ),
    Commit(
        Commit {
            tree: [
                116,
                147,
                237,
                243,
                146,
                103,
                126,
                119,
                24,
                44,
                0,
                155,
                212,
                236,
                177,
                214,
                30,
                171,
                22,
                210,
            ],
            author: CommitUserInfo {
                name: "me",
                email: "me@example.com",
                time: 1970-01-01 0:00:00.0 +00:00:00,
            },
            committer: CommitUserInfo {
                name: "me",
                email: "me@example.com",
                time: 1970-01-01 0:00:00.0 +00:00:00,
            },
            message: "initial commit",
        },
    ),
]
diff --git a/src/snapshots/packfile__high_level__test__git_verify_pack.snap b/src/snapshots/packfile__high_level__test__git_verify_pack.snap
new file mode 100644
index 0000000..1b64d26
--- /dev/null
+++ b/src/snapshots/packfile__high_level__test__git_verify_pack.snap
@@ -0,0 +1,16 @@
---
source: src/high_level.rs
expression: stdout
---
65f57c2ee985713476ac0b6e3483e6fe472e2176 blob   256 23 12
556fdb625a861caa62cdb0ed1679b03605d4844e blob   4 14 35
bc7774a7b18deb1d7bd0212d34246a9b1260ae17 blob   12 22 49
6123a501156670e9ad772926ffde2d282782f60d tree   33 46 71
b3d17d9cf721128fe605a8895ab375c17517896f tree   28 37 117
41c6781f25ddb13d8ef2ecfebf50caba2c4747ea tree   33 46 154
2c5a03f4e06322f845afffee2515c213df662f3d tree   28 37 200
7c3b586d518694f71878ff437f1a271dad248f76 tree   89 102 237
79d1ae79ac5da77976b123c848d31f15f564fe66 commit 134 107 339
non delta: 9 objects
/path/to/example.pack: ok