Source file src/sync/once_test.go

     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  

View as plain text