summaryrefslogtreecommitdiff
path: root/src/mongo/gotools/vendor/src/gopkg.in/tomb.v2/tomb_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/gotools/vendor/src/gopkg.in/tomb.v2/tomb_test.go')
-rw-r--r--src/mongo/gotools/vendor/src/gopkg.in/tomb.v2/tomb_test.go183
1 files changed, 183 insertions, 0 deletions
diff --git a/src/mongo/gotools/vendor/src/gopkg.in/tomb.v2/tomb_test.go b/src/mongo/gotools/vendor/src/gopkg.in/tomb.v2/tomb_test.go
new file mode 100644
index 00000000000..a1064dffe65
--- /dev/null
+++ b/src/mongo/gotools/vendor/src/gopkg.in/tomb.v2/tomb_test.go
@@ -0,0 +1,183 @@
+package tomb_test
+
+import (
+ "errors"
+ "gopkg.in/tomb.v2"
+ "reflect"
+ "testing"
+)
+
+func nothing() error { return nil }
+
+func TestNewTomb(t *testing.T) {
+ tb := &tomb.Tomb{}
+ checkState(t, tb, false, false, tomb.ErrStillAlive)
+}
+
+func TestGo(t *testing.T) {
+ tb := &tomb.Tomb{}
+ alive := make(chan bool)
+ tb.Go(func() error {
+ alive <- true
+ tb.Go(func() error {
+ alive <- true
+ <-tb.Dying()
+ return nil
+ })
+ <-tb.Dying()
+ return nil
+ })
+ <-alive
+ <-alive
+ checkState(t, tb, false, false, tomb.ErrStillAlive)
+ tb.Kill(nil)
+ tb.Wait()
+ checkState(t, tb, true, true, nil)
+}
+
+func TestGoErr(t *testing.T) {
+ first := errors.New("first error")
+ second := errors.New("first error")
+ tb := &tomb.Tomb{}
+ alive := make(chan bool)
+ tb.Go(func() error {
+ alive <- true
+ tb.Go(func() error {
+ alive <- true
+ return first
+ })
+ <-tb.Dying()
+ return second
+ })
+ <-alive
+ <-alive
+ tb.Wait()
+ checkState(t, tb, true, true, first)
+}
+
+func TestGoPanic(t *testing.T) {
+ // ErrDying being used properly, after a clean death.
+ tb := &tomb.Tomb{}
+ tb.Go(nothing)
+ tb.Wait()
+ defer func() {
+ err := recover()
+ if err != "tomb.Go called after all goroutines terminated" {
+ t.Fatalf("Wrong panic on post-death tomb.Go call: %v", err)
+ }
+ checkState(t, tb, true, true, nil)
+ }()
+ tb.Go(nothing)
+}
+
+func TestKill(t *testing.T) {
+ // a nil reason flags the goroutine as dying
+ tb := &tomb.Tomb{}
+ tb.Kill(nil)
+ checkState(t, tb, true, false, nil)
+
+ // a non-nil reason now will override Kill
+ err := errors.New("some error")
+ tb.Kill(err)
+ checkState(t, tb, true, false, err)
+
+ // another non-nil reason won't replace the first one
+ tb.Kill(errors.New("ignore me"))
+ checkState(t, tb, true, false, err)
+
+ tb.Go(nothing)
+ tb.Wait()
+ checkState(t, tb, true, true, err)
+}
+
+func TestKillf(t *testing.T) {
+ tb := &tomb.Tomb{}
+
+ err := tb.Killf("BO%s", "OM")
+ if s := err.Error(); s != "BOOM" {
+ t.Fatalf(`Killf("BO%s", "OM"): want "BOOM", got %q`, s)
+ }
+ checkState(t, tb, true, false, err)
+
+ // another non-nil reason won't replace the first one
+ tb.Killf("ignore me")
+ checkState(t, tb, true, false, err)
+
+ tb.Go(nothing)
+ tb.Wait()
+ checkState(t, tb, true, true, err)
+}
+
+func TestErrDying(t *testing.T) {
+ // ErrDying being used properly, after a clean death.
+ tb := &tomb.Tomb{}
+ tb.Kill(nil)
+ tb.Kill(tomb.ErrDying)
+ checkState(t, tb, true, false, nil)
+
+ // ErrDying being used properly, after an errorful death.
+ err := errors.New("some error")
+ tb.Kill(err)
+ tb.Kill(tomb.ErrDying)
+ checkState(t, tb, true, false, err)
+
+ // ErrDying being used badly, with an alive tomb.
+ tb = &tomb.Tomb{}
+ defer func() {
+ err := recover()
+ if err != "tomb: Kill with ErrDying while still alive" {
+ t.Fatalf("Wrong panic on Kill(ErrDying): %v", err)
+ }
+ checkState(t, tb, false, false, tomb.ErrStillAlive)
+ }()
+ tb.Kill(tomb.ErrDying)
+}
+
+func TestKillErrStillAlivePanic(t *testing.T) {
+ tb := &tomb.Tomb{}
+ defer func() {
+ err := recover()
+ if err != "tomb: Kill with ErrStillAlive" {
+ t.Fatalf("Wrong panic on Kill(ErrStillAlive): %v", err)
+ }
+ checkState(t, tb, false, false, tomb.ErrStillAlive)
+ }()
+ tb.Kill(tomb.ErrStillAlive)
+}
+
+func checkState(t *testing.T, tb *tomb.Tomb, wantDying, wantDead bool, wantErr error) {
+ select {
+ case <-tb.Dying():
+ if !wantDying {
+ t.Error("<-Dying: should block")
+ }
+ default:
+ if wantDying {
+ t.Error("<-Dying: should not block")
+ }
+ }
+ seemsDead := false
+ select {
+ case <-tb.Dead():
+ if !wantDead {
+ t.Error("<-Dead: should block")
+ }
+ seemsDead = true
+ default:
+ if wantDead {
+ t.Error("<-Dead: should not block")
+ }
+ }
+ if err := tb.Err(); err != wantErr {
+ t.Errorf("Err: want %#v, got %#v", wantErr, err)
+ }
+ if wantDead && seemsDead {
+ waitErr := tb.Wait()
+ switch {
+ case waitErr == tomb.ErrStillAlive:
+ t.Errorf("Wait should not return ErrStillAlive")
+ case !reflect.DeepEqual(waitErr, wantErr):
+ t.Errorf("Wait: want %#v, got %#v", wantErr, waitErr)
+ }
+ }
+}