*o++
}
-func run(once *Once, o *one, c chan bool) {
+func run(t *testing.T, once *Once, o *one, c chan bool) {
once.Do(func() { o.Increment() })
+ if v := *o; v != 1 {
+ t.Errorf("once failed inside run: %d is not 1", v)
+ }
c <- true
}
c := make(chan bool)
const N = 10
for i := 0; i < N; i++ {
- go run(once, o, c)
+ go run(t, once, o, c)
}
for i := 0; i < N; i++ {
<-c
}
if *o != 1 {
- t.Errorf("once failed: %d is not 1", *o)
+ t.Errorf("once failed outside run: %d is not 1", *o)
+ }
+}
+
+func TestOncePanic(t *testing.T) {
+ once := new(Once)
+ for i := 0; i < 2; i++ {
+ func() {
+ defer func() {
+ if recover() == nil {
+ t.Fatalf("Once.Do() has not panic'ed")
+ }
+ }()
+ once.Do(func() {
+ panic("failed")
+ })
+ }()
}
+ once.Do(func() {})
+ once.Do(func() {
+ t.Fatalf("Once called twice")
+ })
}
func BenchmarkOnce(b *testing.B) {