arche / internal/syncpkg/syncpkg_test.go

commit 154431fd
  1package syncpkg_test
  2
  3import (
  4	"bytes"
  5	"crypto/sha256"
  6	"testing"
  7
  8	"arche/internal/syncpkg"
  9)
 10
 11func makeID(seed byte) [32]byte {
 12	var b [32]byte
 13	b[0] = seed
 14	return sha256.Sum256(b[:])
 15}
 16
 17func TestBloom_AddTest_HitAfterAdd(t *testing.T) {
 18	f := syncpkg.NewBloom(100)
 19	id := makeID(1)
 20	if f.Test(id) {
 21		t.Error("should not be present before Add")
 22	}
 23	f.Add(id)
 24	if !f.Test(id) {
 25		t.Error("should be present after Add")
 26	}
 27}
 28
 29func TestBloom_NoFalseNegatives(t *testing.T) {
 30	const n = 200
 31	f := syncpkg.NewBloom(n)
 32	ids := make([][32]byte, n)
 33	for i := range ids {
 34		ids[i] = makeID(byte(i))
 35		f.Add(ids[i])
 36	}
 37	for i, id := range ids {
 38		if !f.Test(id) {
 39			t.Errorf("false negative at index %d", i)
 40		}
 41	}
 42}
 43
 44func TestBloom_Serialize(t *testing.T) {
 45	f := syncpkg.NewBloom(50)
 46	for i := range 10 {
 47		f.Add(makeID(byte(i)))
 48	}
 49
 50	data := f.Bytes()
 51
 52	f2, err := syncpkg.BloomFilterFrom(data)
 53	if err != nil {
 54		t.Fatalf("BloomFilterFrom: %v", err)
 55	}
 56
 57	for i := range 10 {
 58		id := makeID(byte(i))
 59		if !f2.Test(id) {
 60			t.Errorf("id %d not found after deserialization", i)
 61		}
 62	}
 63}
 64
 65func TestBloom_EmptyBytes(t *testing.T) {
 66	_, err := syncpkg.BloomFilterFrom([]byte{})
 67	if err == nil {
 68		t.Error("expected error for empty data")
 69	}
 70}
 71
 72func TestPack_Empty(t *testing.T) {
 73	var buf bytes.Buffer
 74	if err := syncpkg.WritePack(&buf, nil); err != nil {
 75		t.Fatalf("WritePack (empty): %v", err)
 76	}
 77	entries, err := syncpkg.ReadPack(&buf)
 78	if err != nil {
 79		t.Fatalf("ReadPack (empty): %v", err)
 80	}
 81	if len(entries) != 0 {
 82		t.Errorf("expected 0 entries, got %d", len(entries))
 83	}
 84}
 85
 86func TestPack_SingleEntry(t *testing.T) {
 87	id := makeID(7)
 88	e := syncpkg.PackEntry{
 89		ID:   id,
 90		Kind: "blob",
 91		Data: []byte("hello pack"),
 92	}
 93
 94	var buf bytes.Buffer
 95	if err := syncpkg.WritePack(&buf, []syncpkg.PackEntry{e}); err != nil {
 96		t.Fatalf("WritePack: %v", err)
 97	}
 98
 99	entries, err := syncpkg.ReadPack(&buf)
100	if err != nil {
101		t.Fatalf("ReadPack: %v", err)
102	}
103	if len(entries) != 1 {
104		t.Fatalf("len: want 1, got %d", len(entries))
105	}
106	if entries[0].ID != id {
107		t.Errorf("ID mismatch")
108	}
109	if entries[0].Kind != "blob" {
110		t.Errorf("Kind: want blob, got %q", entries[0].Kind)
111	}
112	if !bytes.Equal(entries[0].Data, []byte("hello pack")) {
113		t.Errorf("Data mismatch")
114	}
115}
116
117func TestPack_MultipleEntries(t *testing.T) {
118	kinds := []string{"blob", "tree", "commit"}
119	in := make([]syncpkg.PackEntry, len(kinds))
120	for i, k := range kinds {
121		in[i] = syncpkg.PackEntry{
122			ID:   makeID(byte(i + 10)),
123			Kind: k,
124			Data: []byte("data-" + k),
125		}
126	}
127
128	var buf bytes.Buffer
129	if err := syncpkg.WritePack(&buf, in); err != nil {
130		t.Fatalf("WritePack: %v", err)
131	}
132	out, err := syncpkg.ReadPack(&buf)
133	if err != nil {
134		t.Fatalf("ReadPack: %v", err)
135	}
136	if len(out) != len(in) {
137		t.Fatalf("len: want %d, got %d", len(in), len(out))
138	}
139	for i := range in {
140		if out[i].ID != in[i].ID {
141			t.Errorf("[%d] ID mismatch", i)
142		}
143		if out[i].Kind != in[i].Kind {
144			t.Errorf("[%d] Kind: want %q got %q", i, in[i].Kind, out[i].Kind)
145		}
146		if !bytes.Equal(out[i].Data, in[i].Data) {
147			t.Errorf("[%d] Data mismatch", i)
148		}
149	}
150}
151
152func TestPack_LargeData(t *testing.T) {
153	large := make([]byte, 64*1024)
154	for i := range large {
155		large[i] = byte(i % 251)
156	}
157	e := syncpkg.PackEntry{ID: makeID(99), Kind: "blob", Data: large}
158
159	var buf bytes.Buffer
160	syncpkg.WritePack(&buf, []syncpkg.PackEntry{e}) //nolint:errcheck
161	out, err := syncpkg.ReadPack(&buf)
162	if err != nil {
163		t.Fatalf("ReadPack large: %v", err)
164	}
165	if !bytes.Equal(out[0].Data, large) {
166		t.Error("large data round-trip failed")
167	}
168}