mirror of
				https://github.com/restic/restic.git
				synced 2025-11-04 07:11:01 +00:00 
			
		
		
		
	- changed variable names, especially changed DataFile into PackFile - changed in some comments - always use "pack file" in docu
		
			
				
	
	
		
			159 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package backend_test
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"context"
 | 
						|
	"io"
 | 
						|
	"math/rand"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/restic/restic/internal/backend"
 | 
						|
	"github.com/restic/restic/internal/backend/mem"
 | 
						|
	"github.com/restic/restic/internal/errors"
 | 
						|
	"github.com/restic/restic/internal/restic"
 | 
						|
	rtest "github.com/restic/restic/internal/test"
 | 
						|
)
 | 
						|
 | 
						|
const KiB = 1 << 10
 | 
						|
const MiB = 1 << 20
 | 
						|
 | 
						|
func TestLoadAll(t *testing.T) {
 | 
						|
	b := mem.New()
 | 
						|
	var buf []byte
 | 
						|
 | 
						|
	for i := 0; i < 20; i++ {
 | 
						|
		data := rtest.Random(23+i, rand.Intn(MiB)+500*KiB)
 | 
						|
 | 
						|
		id := restic.Hash(data)
 | 
						|
		h := restic.Handle{Name: id.String(), Type: restic.PackFile}
 | 
						|
		err := b.Save(context.TODO(), h, restic.NewByteReader(data))
 | 
						|
		rtest.OK(t, err)
 | 
						|
 | 
						|
		buf, err := backend.LoadAll(context.TODO(), buf, b, restic.Handle{Type: restic.PackFile, Name: id.String()})
 | 
						|
		rtest.OK(t, err)
 | 
						|
 | 
						|
		if len(buf) != len(data) {
 | 
						|
			t.Errorf("length of returned buffer does not match, want %d, got %d", len(data), len(buf))
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		if !bytes.Equal(buf, data) {
 | 
						|
			t.Errorf("wrong data returned")
 | 
						|
			continue
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func save(t testing.TB, be restic.Backend, buf []byte) restic.Handle {
 | 
						|
	id := restic.Hash(buf)
 | 
						|
	h := restic.Handle{Name: id.String(), Type: restic.PackFile}
 | 
						|
	err := be.Save(context.TODO(), h, restic.NewByteReader(buf))
 | 
						|
	if err != nil {
 | 
						|
		t.Fatal(err)
 | 
						|
	}
 | 
						|
	return h
 | 
						|
}
 | 
						|
 | 
						|
func TestLoadAllAppend(t *testing.T) {
 | 
						|
	b := mem.New()
 | 
						|
 | 
						|
	h1 := save(t, b, []byte("foobar test string"))
 | 
						|
	randomData := rtest.Random(23, rand.Intn(MiB)+500*KiB)
 | 
						|
	h2 := save(t, b, randomData)
 | 
						|
 | 
						|
	var tests = []struct {
 | 
						|
		handle restic.Handle
 | 
						|
		buf    []byte
 | 
						|
		want   []byte
 | 
						|
	}{
 | 
						|
		{
 | 
						|
			handle: h1,
 | 
						|
			buf:    nil,
 | 
						|
			want:   []byte("foobar test string"),
 | 
						|
		},
 | 
						|
		{
 | 
						|
			handle: h1,
 | 
						|
			buf:    []byte("xxx"),
 | 
						|
			want:   []byte("foobar test string"),
 | 
						|
		},
 | 
						|
		{
 | 
						|
			handle: h2,
 | 
						|
			buf:    nil,
 | 
						|
			want:   randomData,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			handle: h2,
 | 
						|
			buf:    make([]byte, 0, 200),
 | 
						|
			want:   randomData,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			handle: h2,
 | 
						|
			buf:    []byte("foobarbaz"),
 | 
						|
			want:   randomData,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for _, test := range tests {
 | 
						|
		t.Run("", func(t *testing.T) {
 | 
						|
			buf, err := backend.LoadAll(context.TODO(), test.buf, b, test.handle)
 | 
						|
			if err != nil {
 | 
						|
				t.Fatal(err)
 | 
						|
			}
 | 
						|
 | 
						|
			if !bytes.Equal(buf, test.want) {
 | 
						|
				t.Errorf("wrong data returned, want %q, got %q", test.want, buf)
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type mockReader struct {
 | 
						|
	closed bool
 | 
						|
}
 | 
						|
 | 
						|
func (rd *mockReader) Read(p []byte) (n int, err error) {
 | 
						|
	return 0, nil
 | 
						|
}
 | 
						|
func (rd *mockReader) Close() error {
 | 
						|
	rd.closed = true
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
func TestDefaultLoad(t *testing.T) {
 | 
						|
 | 
						|
	h := restic.Handle{Name: "id", Type: restic.PackFile}
 | 
						|
	rd := &mockReader{}
 | 
						|
 | 
						|
	// happy case, assert correct parameters are passed around and content stream is closed
 | 
						|
	err := backend.DefaultLoad(context.TODO(), h, 10, 11, func(ctx context.Context, ih restic.Handle, length int, offset int64) (io.ReadCloser, error) {
 | 
						|
		rtest.Equals(t, h, ih)
 | 
						|
		rtest.Equals(t, int(10), length)
 | 
						|
		rtest.Equals(t, int64(11), offset)
 | 
						|
 | 
						|
		return rd, nil
 | 
						|
	}, func(ird io.Reader) error {
 | 
						|
		rtest.Equals(t, rd, ird)
 | 
						|
		return nil
 | 
						|
	})
 | 
						|
	rtest.OK(t, err)
 | 
						|
	rtest.Equals(t, true, rd.closed)
 | 
						|
 | 
						|
	// unhappy case, assert producer errors are handled correctly
 | 
						|
	err = backend.DefaultLoad(context.TODO(), h, 10, 11, func(ctx context.Context, ih restic.Handle, length int, offset int64) (io.ReadCloser, error) {
 | 
						|
		return nil, errors.Errorf("producer error")
 | 
						|
	}, func(ird io.Reader) error {
 | 
						|
		t.Fatalf("unexpected consumer invocation")
 | 
						|
		return nil
 | 
						|
	})
 | 
						|
	rtest.Equals(t, "producer error", err.Error())
 | 
						|
 | 
						|
	// unhappy case, assert consumer errors are handled correctly
 | 
						|
	rd = &mockReader{}
 | 
						|
	err = backend.DefaultLoad(context.TODO(), h, 10, 11, func(ctx context.Context, ih restic.Handle, length int, offset int64) (io.ReadCloser, error) {
 | 
						|
		return rd, nil
 | 
						|
	}, func(ird io.Reader) error {
 | 
						|
		return errors.Errorf("consumer error")
 | 
						|
	})
 | 
						|
	rtest.Equals(t, true, rd.closed)
 | 
						|
	rtest.Equals(t, "consumer error", err.Error())
 | 
						|
}
 |