summaryrefslogtreecommitdiff
path: root/src/sync/once_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/sync/once_test.go')
-rw-r--r--src/sync/once_test.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/sync/once_test.go b/src/sync/once_test.go
new file mode 100644
index 000000000..1eec8d18e
--- /dev/null
+++ b/src/sync/once_test.go
@@ -0,0 +1,68 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sync_test
+
+import (
+ . "sync"
+ "testing"
+)
+
+type one int
+
+func (o *one) Increment() {
+ *o++
+}
+
+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
+}
+
+func TestOnce(t *testing.T) {
+ o := new(one)
+ once := new(Once)
+ c := make(chan bool)
+ const N = 10
+ for i := 0; i < N; i++ {
+ go run(t, once, o, c)
+ }
+ for i := 0; i < N; i++ {
+ <-c
+ }
+ if *o != 1 {
+ t.Errorf("once failed outside run: %d is not 1", *o)
+ }
+}
+
+func TestOncePanic(t *testing.T) {
+ var once Once
+ func() {
+ defer func() {
+ if r := recover(); r == nil {
+ t.Fatalf("Once.Do did not panic")
+ }
+ }()
+ once.Do(func() {
+ panic("failed")
+ })
+ }()
+
+ once.Do(func() {
+ t.Fatalf("Once.Do called twice")
+ })
+}
+
+func BenchmarkOnce(b *testing.B) {
+ var once Once
+ f := func() {}
+ b.RunParallel(func(pb *testing.PB) {
+ for pb.Next() {
+ once.Do(f)
+ }
+ })
+}