| 
									
										
										
										
											2016-01-23 23:41:55 +01:00
										 |  |  | package backend_test | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2017-06-03 17:39:57 +02:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2018-01-16 23:59:16 -05:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2016-01-23 23:41:55 +01:00
										 |  |  | 	"math/rand" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-23 14:21:03 +02:00
										 |  |  | 	"github.com/restic/restic/internal/backend" | 
					
						
							|  |  |  | 	"github.com/restic/restic/internal/backend/mem" | 
					
						
							| 
									
										
										
										
											2018-01-16 23:59:16 -05:00
										 |  |  | 	"github.com/restic/restic/internal/errors" | 
					
						
							| 
									
										
										
										
											2017-07-24 17:42:25 +02:00
										 |  |  | 	"github.com/restic/restic/internal/restic" | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 	rtest "github.com/restic/restic/internal/test" | 
					
						
							| 
									
										
										
										
											2016-01-23 23:41:55 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const KiB = 1 << 10 | 
					
						
							|  |  |  | const MiB = 1 << 20 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func TestLoadAll(t *testing.T) { | 
					
						
							|  |  |  | 	b := mem.New() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < 20; i++ { | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 		data := rtest.Random(23+i, rand.Intn(MiB)+500*KiB) | 
					
						
							| 
									
										
										
										
											2016-01-23 23:41:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 22:51:35 +02:00
										 |  |  | 		id := restic.Hash(data) | 
					
						
							| 
									
										
										
										
											2017-06-03 17:39:57 +02:00
										 |  |  | 		err := b.Save(context.TODO(), restic.Handle{Name: id.String(), Type: restic.DataFile}, bytes.NewReader(data)) | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 		rtest.OK(t, err) | 
					
						
							| 
									
										
										
										
											2016-01-23 23:41:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-03 17:39:57 +02:00
										 |  |  | 		buf, err := backend.LoadAll(context.TODO(), b, restic.Handle{Type: restic.DataFile, Name: id.String()}) | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 		rtest.OK(t, err) | 
					
						
							| 
									
										
										
										
											2016-01-23 23:41:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		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 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-02-07 23:48:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | func TestLoadSmallBuffer(t *testing.T) { | 
					
						
							|  |  |  | 	b := mem.New() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < 20; i++ { | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 		data := rtest.Random(23+i, rand.Intn(MiB)+500*KiB) | 
					
						
							| 
									
										
										
										
											2016-02-07 23:48:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 22:51:35 +02:00
										 |  |  | 		id := restic.Hash(data) | 
					
						
							| 
									
										
										
										
											2017-06-03 17:39:57 +02:00
										 |  |  | 		err := b.Save(context.TODO(), restic.Handle{Name: id.String(), Type: restic.DataFile}, bytes.NewReader(data)) | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 		rtest.OK(t, err) | 
					
						
							| 
									
										
										
										
											2016-02-07 23:48:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-03 17:39:57 +02:00
										 |  |  | 		buf, err := backend.LoadAll(context.TODO(), b, restic.Handle{Type: restic.DataFile, Name: id.String()}) | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 		rtest.OK(t, err) | 
					
						
							| 
									
										
										
										
											2016-02-07 23:48:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		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 TestLoadLargeBuffer(t *testing.T) { | 
					
						
							|  |  |  | 	b := mem.New() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := 0; i < 20; i++ { | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 		data := rtest.Random(23+i, rand.Intn(MiB)+500*KiB) | 
					
						
							| 
									
										
										
										
											2016-02-07 23:48:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-31 22:51:35 +02:00
										 |  |  | 		id := restic.Hash(data) | 
					
						
							| 
									
										
										
										
											2017-06-03 17:39:57 +02:00
										 |  |  | 		err := b.Save(context.TODO(), restic.Handle{Name: id.String(), Type: restic.DataFile}, bytes.NewReader(data)) | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 		rtest.OK(t, err) | 
					
						
							| 
									
										
										
										
											2016-02-07 23:48:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-03 17:39:57 +02:00
										 |  |  | 		buf, err := backend.LoadAll(context.TODO(), b, restic.Handle{Type: restic.DataFile, Name: id.String()}) | 
					
						
							| 
									
										
										
										
											2017-10-02 15:06:39 +02:00
										 |  |  | 		rtest.OK(t, err) | 
					
						
							| 
									
										
										
										
											2016-02-07 23:48:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		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 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-01-16 23:59:16 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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.DataFile} | 
					
						
							|  |  |  | 	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()) | 
					
						
							|  |  |  | } |