From e29c43bfde39c2e5d4a73bbc940d4812854205f4 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sat, 18 Jan 2014 22:53:03 -0800 Subject: [PATCH] replica: test minWritesForSuccess Change-Id: I5c845e99b1c440c35bfb7a5a7865176fd72ae031 --- pkg/blobserver/replica/replica_test.go | 42 ++++++++++++++++++++++---- pkg/test/fetcher.go | 6 ++++ pkg/test/loader.go | 3 ++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/pkg/blobserver/replica/replica_test.go b/pkg/blobserver/replica/replica_test.go index 71d7afcba..1e5db3e95 100644 --- a/pkg/blobserver/replica/replica_test.go +++ b/pkg/blobserver/replica/replica_test.go @@ -19,6 +19,7 @@ package replica import ( "testing" + "camlistore.org/pkg/blob" "camlistore.org/pkg/blobserver" "camlistore.org/pkg/jsonconfig" "camlistore.org/pkg/test" @@ -33,13 +34,9 @@ func newReplica(t *testing.T, config jsonconfig.Obj) *replicaStorage { return sto.(*replicaStorage) } -func TestReceive(t *testing.T) { - sto := newReplica(t, map[string]interface{}{ - "backends": []interface{}{"/good-1/", "/good-2/"}, - }) - tb := &test.Blob{Contents: "stuff"} +func mustReceive(t *testing.T, dst blobserver.Storage, tb *test.Blob) blob.SizedRef { tbRef := tb.BlobRef() - sb, err := blobserver.Receive(sto, tbRef, tb.Reader()) + sb, err := blobserver.Receive(dst, tbRef, tb.Reader()) if err != nil { t.Fatalf("Receive: %v", err) } @@ -49,6 +46,16 @@ func TestReceive(t *testing.T) { if sb.Ref != tbRef { t.Fatal("wrong blob received") } + return sb +} + +func TestReceiveGood(t *testing.T) { + sto := newReplica(t, map[string]interface{}{ + "backends": []interface{}{"/good-1/", "/good-2/"}, + }) + tb := &test.Blob{Contents: "stuff"} + sb := mustReceive(t, sto, tb) + if len(sto.replicas) != 2 { t.Fatalf("replicas = %d; want 2", len(sto.replicas)) } @@ -61,3 +68,26 @@ func TestReceive(t *testing.T) { } } } + +func TestReceiveOneGoodOneFail(t *testing.T) { + sto := newReplica(t, map[string]interface{}{ + "backends": []interface{}{"/good-1/", "/fail-1/"}, + "minWritesForSuccess": float64(1), + }) + tb := &test.Blob{Contents: "stuff"} + sb := mustReceive(t, sto, tb) + + if len(sto.replicas) != 2 { + t.Fatalf("replicas = %d; want 2", len(sto.replicas)) + } + for i, rep := range sto.replicas { + got, err := blobserver.StatBlob(rep, sb.Ref) + pfx := sto.replicaPrefixes[i] + if (i == 0) != (err == nil) { + t.Errorf("For replica %s, unexpected error: %v", pfx, err) + } + if err == nil && got != sb { + t.Errorf("Replica %s got %+v; want %+v", sto.replicaPrefixes[i], got, sb) + } + } +} diff --git a/pkg/test/fetcher.go b/pkg/test/fetcher.go index e43833b0d..213582fc4 100644 --- a/pkg/test/fetcher.go +++ b/pkg/test/fetcher.go @@ -39,6 +39,9 @@ type Fetcher struct { m map[string]*Blob // keyed by blobref string sorted []string // blobrefs sorted + // ReceiveErr optionally returns the error to return on receive. + ReceiveErr error + // FetchErr, if non-nil, specifies the error to return on the next fetch call. // If it returns nil, fetches proceed as normal. FetchErr func() error @@ -117,6 +120,9 @@ func (tf *Fetcher) ReceiveBlob(br blob.Ref, source io.Reader) (blob.SizedRef, er // it's worth the cost. return sb, fmt.Errorf("Hash mismatch receiving blob %s", br) } + if err := tf.ReceiveErr; err != nil { + return sb, err + } b := &Blob{Contents: string(all)} tf.AddBlob(b) return blob.SizedRef{br, int64(len(all))}, nil diff --git a/pkg/test/loader.go b/pkg/test/loader.go index e6a1c6fda..5001f5d61 100644 --- a/pkg/test/loader.go +++ b/pkg/test/loader.go @@ -58,5 +58,8 @@ func (ld *Loader) GetStorage(prefix string) (blobserver.Storage, error) { if strings.HasPrefix(prefix, "/good") { return &Fetcher{}, nil } + if strings.HasPrefix(prefix, "/fail") { + return &Fetcher{ReceiveErr: errors.New("test.Loader intentional failure for /fail storage handler")}, nil + } panic("test.Loader.GetStorage: unrecognized prefix type") }