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(-)
@@ -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"]
@@ -178,3 +178,79 @@ enum TreeItem {
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);
});
}
}
@@ -319,7 +319,6 @@ impl PackFileEntry {
}
}
#[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() {
@@ -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",
},
),
]
@@ -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