restic/internal/repository/pack/pack_test.go

147 lines
3.5 KiB
Go
Raw Normal View History

2015-04-26 13:36:49 +00:00
package pack_test
import (
"bytes"
2017-06-04 09:16:55 +00:00
"context"
2015-04-26 13:36:49 +00:00
"crypto/rand"
"crypto/sha256"
"encoding/json"
"io"
"testing"
"github.com/restic/restic/internal/backend"
2017-07-23 12:21:03 +00:00
"github.com/restic/restic/internal/backend/mem"
"github.com/restic/restic/internal/crypto"
2024-05-24 21:09:58 +00:00
"github.com/restic/restic/internal/repository/pack"
2017-07-24 15:42:25 +00:00
"github.com/restic/restic/internal/restic"
2017-10-02 13:06:39 +00:00
rtest "github.com/restic/restic/internal/test"
2015-04-26 13:36:49 +00:00
)
2016-08-07 14:24:02 +00:00
var testLens = []int{23, 31650, 25860, 10928, 13769, 19862, 5211, 127, 13690, 30231}
2015-04-26 13:36:49 +00:00
type Buf struct {
data []byte
2016-08-31 21:07:50 +00:00
id restic.ID
}
2015-04-26 13:36:49 +00:00
2016-08-07 14:24:02 +00:00
func newPack(t testing.TB, k *crypto.Key, lengths []int) ([]Buf, []byte, uint) {
2015-04-26 13:36:49 +00:00
bufs := []Buf{}
for _, l := range lengths {
b := make([]byte, l)
_, err := io.ReadFull(rand.Reader, b)
2017-10-02 13:06:39 +00:00
rtest.OK(t, err)
2015-04-26 13:36:49 +00:00
h := sha256.Sum256(b)
bufs = append(bufs, Buf{data: b, id: h})
2015-04-26 13:36:49 +00:00
}
// pack blobs
2020-07-22 21:53:55 +00:00
var buf bytes.Buffer
p := pack.NewPacker(k, &buf)
2015-04-26 13:36:49 +00:00
for _, b := range bufs {
2022-02-13 16:24:09 +00:00
_, err := p.Add(restic.TreeBlob, b.id, b.data, 2*len(b.data))
2021-01-30 18:35:46 +00:00
rtest.OK(t, err)
2015-04-26 13:36:49 +00:00
}
err := p.Finalize()
2017-10-02 13:06:39 +00:00
rtest.OK(t, err)
2015-04-26 13:36:49 +00:00
2020-07-22 21:53:55 +00:00
return bufs, buf.Bytes(), p.Size()
}
2016-08-25 19:51:07 +00:00
func verifyBlobs(t testing.TB, bufs []Buf, k *crypto.Key, rd io.ReaderAt, packSize uint) {
2015-04-26 13:36:49 +00:00
written := 0
2016-08-07 14:24:02 +00:00
for _, buf := range bufs {
written += len(buf.data)
2015-04-26 13:36:49 +00:00
}
// read and parse it again
2020-11-16 03:03:45 +00:00
entries, hdrSize, err := pack.List(k, rd, int64(packSize))
2017-10-02 13:06:39 +00:00
rtest.OK(t, err)
rtest.Equals(t, len(entries), len(bufs))
2022-03-28 20:12:16 +00:00
// check the head size calculation for consistency
headerSize := pack.CalculateHeaderSize(entries)
written += headerSize
// check length
rtest.Equals(t, uint(written), packSize)
2020-11-16 03:03:45 +00:00
rtest.Equals(t, headerSize, int(hdrSize))
2015-04-26 13:36:49 +00:00
2016-08-07 12:50:24 +00:00
var buf []byte
2015-04-26 13:36:49 +00:00
for i, b := range bufs {
2016-08-25 19:08:16 +00:00
e := entries[i]
2017-10-02 13:06:39 +00:00
rtest.Equals(t, b.id, e.ID)
2015-04-26 13:36:49 +00:00
2016-08-07 12:50:24 +00:00
if len(buf) < int(e.Length) {
buf = make([]byte, int(e.Length))
}
buf = buf[:int(e.Length)]
2016-08-25 19:51:07 +00:00
n, err := rd.ReadAt(buf, int64(e.Offset))
2017-10-02 13:06:39 +00:00
rtest.OK(t, err)
2016-08-07 12:50:24 +00:00
buf = buf[:n]
2015-04-26 13:36:49 +00:00
2017-10-02 13:06:39 +00:00
rtest.Assert(t, bytes.Equal(b.data, buf),
2015-04-26 13:36:49 +00:00
"data for blob %v doesn't match", i)
}
}
func TestCreatePack(t *testing.T) {
// create random keys
k := crypto.NewRandomKey()
2016-08-07 14:24:02 +00:00
bufs, packData, packSize := newPack(t, k, testLens)
2017-10-02 13:06:39 +00:00
rtest.Equals(t, uint(len(packData)), packSize)
2016-08-25 19:51:07 +00:00
verifyBlobs(t, bufs, k, bytes.NewReader(packData), packSize)
}
2015-10-25 17:21:48 +00:00
var blobTypeJSON = []struct {
2016-08-31 21:07:50 +00:00
t restic.BlobType
2015-04-26 13:36:49 +00:00
res string
}{
2016-08-31 21:07:50 +00:00
{restic.DataBlob, `"data"`},
{restic.TreeBlob, `"tree"`},
2015-04-26 13:36:49 +00:00
}
func TestBlobTypeJSON(t *testing.T) {
2015-10-25 17:21:48 +00:00
for _, test := range blobTypeJSON {
2015-04-26 13:36:49 +00:00
// test serialize
buf, err := json.Marshal(test.t)
2017-10-02 13:06:39 +00:00
rtest.OK(t, err)
rtest.Equals(t, test.res, string(buf))
2015-04-26 13:36:49 +00:00
// test unserialize
2016-08-31 21:07:50 +00:00
var v restic.BlobType
2015-04-26 13:36:49 +00:00
err = json.Unmarshal([]byte(test.res), &v)
2017-10-02 13:06:39 +00:00
rtest.OK(t, err)
rtest.Equals(t, test.t, v)
2015-04-26 13:36:49 +00:00
}
}
func TestUnpackReadSeeker(t *testing.T) {
// create random keys
k := crypto.NewRandomKey()
2016-08-07 14:24:02 +00:00
bufs, packData, packSize := newPack(t, k, testLens)
b := mem.New()
2016-08-31 21:07:50 +00:00
id := restic.Hash(packData)
2016-08-07 14:24:02 +00:00
handle := backend.Handle{Type: backend.PackFile, Name: id.String()}
rtest.OK(t, b.Save(context.TODO(), handle, backend.NewByteReader(packData, b.Hasher())))
verifyBlobs(t, bufs, k, backend.ReaderAt(context.TODO(), b, handle), packSize)
2016-08-07 14:24:02 +00:00
}
func TestShortPack(t *testing.T) {
k := crypto.NewRandomKey()
bufs, packData, packSize := newPack(t, k, []int{23})
b := mem.New()
2016-08-31 21:07:50 +00:00
id := restic.Hash(packData)
handle := backend.Handle{Type: backend.PackFile, Name: id.String()}
rtest.OK(t, b.Save(context.TODO(), handle, backend.NewByteReader(packData, b.Hasher())))
verifyBlobs(t, bufs, k, backend.ReaderAt(context.TODO(), b, handle), packSize)
}