// +build go1.7 package tomb_test import ( "context" "testing" "time" "gopkg.in/tomb.v2" ) func TestWithContext(t *testing.T) { parent1, cancel1 := context.WithCancel(context.Background()) tb, child1 := tomb.WithContext(parent1) if !tb.Alive() { t.Fatalf("WithContext returned dead tomb") } if tb.Context(parent1) != child1 { t.Fatalf("Context returned different context for same parent") } if tb.Context(nil) != child1 { t.Fatalf("Context returned different context for nil parent") } select { case <-child1.Done(): t.Fatalf("Tomb's child context was born dead") default: } parent2, cancel2 := context.WithCancel(context.WithValue(context.Background(), "parent", "parent2")) child2 := tb.Context(parent2) if tb.Context(parent2) != child2 { t.Fatalf("Context returned different context for same parent") } if child2.Value("parent") != "parent2" { t.Fatalf("Child context didn't inherit its parent's properties") } select { case <-child2.Done(): t.Fatalf("Tomb's child context was born dead") default: } cancel2() select { case <-child2.Done(): default: t.Fatalf("Tomb's child context didn't die after parent was canceled") } if !tb.Alive() { t.Fatalf("Canceling unrelated parent context killed tomb") } parent3 := context.WithValue(context.Background(), "parent", "parent3") child3 := tb.Context(parent3) if child3.Value("parent") != "parent3" { t.Fatalf("Child context didn't inherit its parent's properties") } select { case <-child3.Done(): t.Fatalf("Tomb's child context was born dead") default: } cancel1() select { case <-tb.Dying(): case <-time.After(5 * time.Second): t.Fatalf("Canceling parent context did not kill tomb") } if tb.Err() != context.Canceled { t.Fatalf("tomb should be %v, got %v", context.Canceled, tb.Err()) } if tb.Context(parent1) == child1 || tb.Context(parent3) == child3 { t.Fatalf("Tomb is dead and shouldn't be tracking children anymore") } select { case <-child3.Done(): default: t.Fatalf("Child context didn't die after tomb's death") } parent4 := context.WithValue(context.Background(), "parent", "parent4") child4 := tb.Context(parent4) select { case <-child4.Done(): default: t.Fatalf("Child context should be born canceled") } childnil := tb.Context(nil) select { case <-childnil.Done(): default: t.Fatalf("Child context should be born canceled") } } func TestContextNoParent(t *testing.T) { var tb tomb.Tomb parent2, cancel2 := context.WithCancel(context.WithValue(context.Background(), "parent", "parent2")) child2 := tb.Context(parent2) if tb.Context(parent2) != child2 { t.Fatalf("Context returned different context for same parent") } if child2.Value("parent") != "parent2" { t.Fatalf("Child context didn't inherit its parent's properties") } select { case <-child2.Done(): t.Fatalf("Tomb's child context was born dead") default: } cancel2() select { case <-child2.Done(): default: t.Fatalf("Tomb's child context didn't die after parent was canceled") } if !tb.Alive() { t.Fatalf("Canceling unrelated parent context killed tomb") } parent3 := context.WithValue(context.Background(), "parent", "parent3") child3 := tb.Context(parent3) if child3.Value("parent") != "parent3" { t.Fatalf("Child context didn't inherit its parent's properties") } select { case <-child3.Done(): t.Fatalf("Tomb's child context was born dead") default: } tb.Kill(nil) if tb.Context(parent3) == child3 { t.Fatalf("Tomb is dead and shouldn't be tracking children anymore") } select { case <-child3.Done(): default: t.Fatalf("Child context didn't die after tomb's death") } parent4 := context.WithValue(context.Background(), "parent", "parent4") child4 := tb.Context(parent4) select { case <-child4.Done(): default: t.Fatalf("Child context should be born canceled") } childnil := tb.Context(nil) select { case <-childnil.Done(): default: t.Fatalf("Child context should be born canceled") } }