123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- package tomb_test
- import (
- "errors"
- "gopkg.in/tomb.v1"
- "reflect"
- "testing"
- )
- func TestNewTomb(t *testing.T) {
- tb := &tomb.Tomb{}
- testState(t, tb, false, false, tomb.ErrStillAlive)
- tb.Done()
- testState(t, tb, true, true, nil)
- }
- func TestKill(t *testing.T) {
- // a nil reason flags the goroutine as dying
- tb := &tomb.Tomb{}
- tb.Kill(nil)
- testState(t, tb, true, false, nil)
- // a non-nil reason now will override Kill
- err := errors.New("some error")
- tb.Kill(err)
- testState(t, tb, true, false, err)
- // another non-nil reason won't replace the first one
- tb.Kill(errors.New("ignore me"))
- testState(t, tb, true, false, err)
- tb.Done()
- testState(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)
- }
- testState(t, tb, true, false, err)
- // another non-nil reason won't replace the first one
- tb.Killf("ignore me")
- testState(t, tb, true, false, err)
- tb.Done()
- testState(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)
- testState(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)
- testState(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)
- }
- testState(t, tb, false, false, tomb.ErrStillAlive)
- }()
- tb.Kill(tomb.ErrDying)
- }
- func testState(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)
- }
- }
- }
|