1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package sync_test 6 7 import ( 8 . "sync" 9 "testing" 10 ) 11 12 type one int 13 14 func (o *one) Increment() { 15 *o++ 16 } 17 18 func run(t *testing.T, once *Once, o *one, c chan bool) { 19 once.Do(func() { o.Increment() }) 20 if v := *o; v != 1 { 21 t.Errorf("once failed inside run: %d is not 1", v) 22 } 23 c <- true 24 } 25 26 func TestOnce(t *testing.T) { 27 o := new(one) 28 once := new(Once) 29 c := make(chan bool) 30 const N = 10 31 for i := 0; i < N; i++ { 32 go run(t, once, o, c) 33 } 34 for i := 0; i < N; i++ { 35 <-c 36 } 37 if *o != 1 { 38 t.Errorf("once failed outside run: %d is not 1", *o) 39 } 40 } 41 42 func TestOncePanic(t *testing.T) { 43 var once Once 44 func() { 45 defer func() { 46 if r := recover(); r == nil { 47 t.Fatalf("Once.Do did not panic") 48 } 49 }() 50 once.Do(func() { 51 panic("failed") 52 }) 53 }() 54 55 once.Do(func() { 56 t.Fatalf("Once.Do called twice") 57 }) 58 } 59 60 func BenchmarkOnce(b *testing.B) { 61 var once Once 62 f := func() {} 63 b.RunParallel(func(pb *testing.PB) { 64 for pb.Next() { 65 once.Do(f) 66 } 67 }) 68 } 69