Index: go/src/infra/gae/libs/gae/upstream_errors_test.go |
diff --git a/go/src/infra/gae/libs/gae/upstream_errors_test.go b/go/src/infra/gae/libs/gae/upstream_errors_test.go |
index a5a2e8276454482ce4eabd22ab326b6ecfafb037..33012db25b73b88a1e6ad6b447fee3abd70f6227 100644 |
--- a/go/src/infra/gae/libs/gae/upstream_errors_test.go |
+++ b/go/src/infra/gae/libs/gae/upstream_errors_test.go |
@@ -6,6 +6,7 @@ package gae |
import ( |
"errors" |
+ "sync" |
"testing" |
. "github.com/smartystreets/goconvey/convey" |
@@ -58,3 +59,79 @@ func TestUpstreamErrors(t *testing.T) { |
So(SingleError(e), ShouldEqual, e) |
}) |
} |
+ |
+func TestLazyMultiError(t *testing.T) { |
+ t.Parallel() |
+ |
+ Convey("Test LazyMultiError", t, func() { |
+ lme := LazyMultiError{Size: 10} |
+ So(lme.Get(), ShouldEqual, nil) |
+ |
+ e := errors.New("sup") |
+ lme.Assign(6, e) |
+ So(lme.Get(), ShouldResemble, |
+ MultiError{nil, nil, nil, nil, nil, nil, e, nil, nil, nil}) |
+ |
+ lme.Assign(2, e) |
+ So(lme.Get(), ShouldResemble, |
+ MultiError{nil, nil, e, nil, nil, nil, e, nil, nil, nil}) |
+ |
+ So(func() { lme.Assign(20, e) }, ShouldPanic) |
+ |
+ Convey("Try to freak out the race detector", func() { |
+ lme := LazyMultiError{Size: 64} |
+ Convey("all nils", func() { |
+ wg := sync.WaitGroup{} |
+ for i := 0; i < 64; i++ { |
+ wg.Add(1) |
+ go func(i int) { |
+ lme.Assign(i, nil) |
+ wg.Done() |
+ }(i) |
+ } |
+ wg.Wait() |
+ So(lme.Get(), ShouldBeNil) |
+ }) |
+ Convey("every other", func() { |
+ wow := errors.New("wow") |
+ wg := sync.WaitGroup{} |
+ for i := 0; i < 64; i++ { |
+ wg.Add(1) |
+ go func(i int) { |
+ e := error(nil) |
+ if i&1 == 1 { |
+ e = wow |
+ } |
+ lme.Assign(i, e) |
+ wg.Done() |
+ }(i) |
+ } |
+ wg.Wait() |
+ me := make(MultiError, 64) |
+ for i := range me { |
+ if i&1 == 1 { |
+ me[i] = wow |
+ } |
+ } |
+ So(lme.Get(), ShouldResemble, me) |
+ }) |
+ Convey("all", func() { |
+ wow := errors.New("wow") |
+ wg := sync.WaitGroup{} |
+ for i := 0; i < 64; i++ { |
+ wg.Add(1) |
+ go func(i int) { |
+ lme.Assign(i, wow) |
+ wg.Done() |
+ }(i) |
+ } |
+ wg.Wait() |
+ me := make(MultiError, 64) |
+ for i := range me { |
+ me[i] = wow |
+ } |
+ So(lme.Get(), ShouldResemble, me) |
+ }) |
+ }) |
+ }) |
+} |