once_test.go 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. package sync_test
  5. import (
  6. . "sync"
  7. "testing"
  8. )
  9. type one int
  10. func (o *one) Increment() {
  11. *o++
  12. }
  13. func run(t *testing.T, once *Once, o *one, c chan bool) {
  14. once.Do(func() { o.Increment() })
  15. if v := *o; v != 1 {
  16. t.Errorf("once failed inside run: %d is not 1", v)
  17. }
  18. c <- true
  19. }
  20. func TestOnce(t *testing.T) {
  21. o := new(one)
  22. once := new(Once)
  23. c := make(chan bool)
  24. const N = 10
  25. for i := 0; i < N; i++ {
  26. go run(t, once, o, c)
  27. }
  28. for i := 0; i < N; i++ {
  29. <-c
  30. }
  31. if *o != 1 {
  32. t.Errorf("once failed outside run: %d is not 1", *o)
  33. }
  34. }
  35. func TestOncePanic(t *testing.T) {
  36. var once Once
  37. func() {
  38. defer func() {
  39. if r := recover(); r == nil {
  40. t.Fatalf("Once.Do did not panic")
  41. }
  42. }()
  43. once.Do(func() {
  44. panic("failed")
  45. })
  46. }()
  47. once.Do(func() {
  48. t.Fatalf("Once.Do called twice")
  49. })
  50. }
  51. func BenchmarkOnce(b *testing.B) {
  52. var once Once
  53. f := func() {}
  54. b.RunParallel(func(pb *testing.PB) {
  55. for pb.Next() {
  56. once.Do(f)
  57. }
  58. })
  59. }