func TestArchiver(t *testing.T) { src := new(test.Fetcher) blobHello := &test.Blob{Contents: "Hello"} blobWorld := &test.Blob{Contents: "World" + strings.Repeat("!", 1024)} golden := map[blob.Ref]string{ blobHello.BlobRef(): blobHello.Contents, blobWorld.BlobRef(): blobWorld.Contents, } a := &Archiver{ Source: src, DeleteSourceAfterStore: true, } src.AddBlob(blobHello) a.Store = func([]byte, []blob.SizedRef) error { return errors.New("Store shouldn't be called") } a.MinZipSize = 400 // empirically: the zip will be 416 bytes if err := a.RunOnce(); err != ErrSourceTooSmall { t.Fatalf("RunOnce with just Hello = %v; want ErrSourceTooSmall", err) } src.AddBlob(blobWorld) var zipData []byte var inZip []blob.SizedRef a.Store = func(zip []byte, brs []blob.SizedRef) error { zipData = zip inZip = brs return nil } if err := a.RunOnce(); err != nil { t.Fatalf("RunOnce with Hello and World = %v", err) } if zipData == nil { t.Error("no zip data stored") } if len(src.BlobrefStrings()) != 0 { t.Errorf("source still has blobs = %q; want none", src.BlobrefStrings) } if len(inZip) != 2 { t.Errorf("expected 2 blobs reported as in zip to Store; got %v", inZip) } got := map[blob.Ref]string{} if err := foreachZipEntry(zipData, func(br blob.Ref, all []byte) { got[br] = string(all) }); err != nil { t.Fatal(err) } if !reflect.DeepEqual(golden, got) { t.Errorf("zip contents didn't match. got: %v; want %v", got, golden) } }
func TestReceiveCorrupt(t *testing.T) { sto := new(test.Fetcher) data := []byte("some blob") br := blob.SHA1FromBytes(data) data[0] = 'X' // corrupt it _, err := blobserver.Receive(sto, br, bytes.NewReader(data)) if err != blobserver.ErrCorruptBlob { t.Errorf("Receive = %v; want ErrCorruptBlob", err) } if len(sto.BlobrefStrings()) > 0 { t.Errorf("nothing should be stored. Got %q", sto.BlobrefStrings()) } }
// Tests a bunch of rounds on a bunch of data. func TestArchiverStress(t *testing.T) { if testing.Short() { t.Skip("Skipping in short mode") } src := new(test.Fetcher) fileRef, err := schema.WriteFileFromReader(src, "random", io.LimitReader(randReader{}, 10<<20)) if err != nil { t.Fatal(err) } n0 := src.NumBlobs() t.Logf("Wrote %v in %d blobs", fileRef, n0) refs0 := src.BlobrefStrings() var zips [][]byte archived := map[blob.Ref]bool{} a := &Archiver{ Source: src, MinZipSize: 1 << 20, DeleteSourceAfterStore: true, Store: func(zipd []byte, brs []blob.SizedRef) error { zips = append(zips, zipd) for _, sbr := range brs { if archived[sbr.Ref] { t.Error("duplicate archive of %v", sbr.Ref) } archived[sbr.Ref] = true } return nil }, } for { err := a.RunOnce() if err == ErrSourceTooSmall { break } if err != nil { t.Fatal(err) } } if len(archived) == 0 { t.Errorf("unexpected small number of archived blobs = %d", len(archived)) } if len(zips) < 2 { t.Errorf("unexpected small number of zip files = %d", len(zips)) } if n1 := src.NumBlobs() + len(archived); n0 != n1 { t.Errorf("original %d blobs != %d after + %d archived (%d)", n0, src.NumBlobs(), len(archived), n1) } // And restore: for _, zipd := range zips { if err := foreachZipEntry(zipd, func(br blob.Ref, contents []byte) { tb := &test.Blob{Contents: string(contents)} if tb.BlobRef() != br { t.Fatal("corrupt zip callback") } src.AddBlob(tb) }); err != nil { t.Fatal(err) } } refs1 := src.BlobrefStrings() if !reflect.DeepEqual(refs0, refs1) { t.Error("Restore error.") } }