8 "github.com/git-lfs/git-lfs/errors"
10 "github.com/stretchr/testify/assert"
17 func TestIndexEntrySearch(t *testing.T) {
18 e, err := idx.Entry([]byte{
19 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
20 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
23 assert.NoError(t, err)
24 assert.EqualValues(t, 6, e.PackOffset)
27 func TestIndexEntrySearchClampLeft(t *testing.T) {
28 e, err := idx.Entry([]byte{
29 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
30 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
33 assert.NoError(t, err)
34 assert.EqualValues(t, 0, e.PackOffset)
37 func TestIndexEntrySearchClampRight(t *testing.T) {
38 e, err := idx.Entry([]byte{
39 0xff, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
40 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
43 assert.NoError(t, err)
44 assert.EqualValues(t, 0x4ff, e.PackOffset)
47 func TestIndexSearchOutOfBounds(t *testing.T) {
48 e, err := idx.Entry([]byte{
49 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
50 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
53 assert.True(t, IsNotFound(err), "expected err to be 'not found'")
57 func TestIndexEntryNotFound(t *testing.T) {
58 e, err := idx.Entry([]byte{
59 0x1, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6,
60 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6,
63 assert.True(t, IsNotFound(err), "expected err to be 'not found'")
67 func TestIndexCount(t *testing.T) {
68 fanout := make([]uint32, 256)
69 for i := 0; i < len(fanout); i++ {
73 idx := &Index{fanout: fanout}
75 assert.EqualValues(t, 255, idx.Count())
78 func TestIndexIsNotFound(t *testing.T) {
79 assert.True(t, IsNotFound(errNotFound),
80 "expected 'errNotFound' to satisfy 'IsNotFound()'")
83 func TestIndexIsNotFoundForOtherErrors(t *testing.T) {
84 assert.False(t, IsNotFound(errors.New("git/odb/pack: misc")),
85 "expected 'err' not to satisfy 'IsNotFound()'")
88 // init generates some fixture data and then constructs an *Index instance using
91 // eps is the number of SHA1 names generated under each 0x<t> slot.
95 0xff, 0x74, 0x4f, 0x63, // Index file v2+ magic header
96 0x00, 0x00, 0x00, 0x02, // 4-byte version indicator
99 // Create a fanout table using uint32s (later marshalled using
100 // binary.BigEndian).
102 // Since we have an even distribution of SHA1s in the generated index,
103 // each entry will increase by the number of entries per slot (see: eps
105 fanout := make([]uint32, indexFanoutEntries)
106 for i := 0; i < len(fanout); i++ {
107 // Begin the index at (i+1), since the fanout table mandates
108 // objects less than the value at index "i".
109 fanout[i] = uint32((i + 1) * eps)
112 offs := make([]uint32, 0, 256*eps)
113 crcs := make([]uint32, 0, 256*eps)
115 names := make([][]byte, 0, 256*eps)
116 for i := 0; i < 256; i++ {
117 // For each name, generate a unique SHA using the prefix "i",
118 // and then suffix "j".
120 // In other words, when i=1, we will generate:
121 // []byte{0x1 0x0 0x0 0x0 ...}
122 // []byte{0x1 0x1 0x1 0x1 ...}
123 // []byte{0x1 0x2 0x2 0x2 ...}
126 for j := 0; j < eps; j++ {
130 for r := 1; r < len(sha); r++ {
134 cpy := make([]byte, len(sha))
137 names = append(names, cpy)
138 offs = append(offs, uint32((i*eps)+j))
139 crcs = append(crcs, 0)
143 // Create a buffer to hold the index contents:
144 buf := bytes.NewBuffer(hdr)
146 // Write each value in the fanout table using a 32bit network byte-order
148 for _, f := range fanout {
149 binary.Write(buf, binary.BigEndian, f)
151 // Write each SHA1 name to the table next.
152 for _, name := range names {
155 // Then write each of the CRC values in network byte-order as a 32bit
157 for _, crc := range crcs {
158 binary.Write(buf, binary.BigEndian, crc)
160 // Do the same with the offsets.
161 for _, off := range offs {
162 binary.Write(buf, binary.BigEndian, off)
167 // version is unimportant here, use V2 since it's more common in
171 // *bytes.Buffer does not implement io.ReaderAt, but
172 // *bytes.Reader does.
174 // Call (*bytes.Buffer).Bytes() to get the data, and then
175 // construct a new *bytes.Reader with it to implement
177 r: bytes.NewReader(buf.Bytes()),