560305f601
- uses newer version of go-ethereum required for go1.11
115 lines
2.5 KiB
Go
115 lines
2.5 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|