github.com/qlik-oss/gopherciser@v0.18.6/atomichandlers/counter_test.go (about)

     1  package atomichandlers
     2  
     3  import (
     4  	"sync"
     5  	"testing"
     6  )
     7  
     8  func TestCounters(t *testing.T) {
     9  	t.Parallel()
    10  
    11  	var counter AtomicCounter
    12  
    13  	var wg sync.WaitGroup
    14  	wg.Add(3)
    15  	for i := 0; i < 3; i++ {
    16  		go func() {
    17  			counter.Inc()
    18  			wg.Done()
    19  		}()
    20  	}
    21  	wg.Wait()
    22  	c := counter.Current()
    23  	if c != 3 {
    24  		t.Errorf("Unexpected counter value<%d>, expected<3>", c)
    25  	}
    26  
    27  	c = counter.Dec()
    28  	if c != 2 {
    29  		t.Errorf("Unexpected counter value<%d>, expected<2>", c)
    30  	}
    31  
    32  	c = counter.Add(3)
    33  	if c != 5 {
    34  		t.Errorf("Unexpected counter value<%d>, expected<5>", c)
    35  	}
    36  
    37  	counter.Reset()
    38  	c = counter.Current()
    39  	if c != 0 {
    40  		t.Errorf("Unexpected counter value<%d>, expected<0>", c)
    41  	}
    42  }
    43  
    44  func TestParallelCounters(t *testing.T) {
    45  	var counter AtomicCounter
    46  
    47  	var wg sync.WaitGroup
    48  
    49  	add := func(c int) {
    50  		for i := 0; i < c; i++ {
    51  			go func() {
    52  				defer wg.Done()
    53  				counter.Inc()
    54  			}()
    55  		}
    56  	}
    57  
    58  	sub := func(c int) {
    59  		for i := 0; i < c; i++ {
    60  			go func() {
    61  				defer wg.Done()
    62  				counter.Dec()
    63  			}()
    64  		}
    65  	}
    66  
    67  	addCount := 50
    68  	subCount := 40
    69  
    70  	//test concurrent increasing and decreasing
    71  	wg.Add(addCount)
    72  	add(addCount)
    73  
    74  	wg.Add(subCount)
    75  	sub(subCount)
    76  
    77  	wg.Wait()
    78  
    79  	current := counter.Current()
    80  	expected := uint64(addCount - subCount)
    81  	if current != expected {
    82  		t.Errorf("Expected counter<%d> got<%d>", expected, current)
    83  	}
    84  
    85  	counter.Reset()
    86  
    87  	//test reset during counting
    88  	wg.Add(addCount)
    89  	add(addCount)
    90  	counter.Reset()
    91  	wg.Wait()
    92  	t.Log(counter.Current())
    93  }
    94  
    95  func BenchmarkCounter(b *testing.B) {
    96  	var c AtomicCounter
    97  	for i := 0; i < b.N; i++ {
    98  		c.Inc()
    99  	}
   100  }
   101  
   102  type muC struct {
   103  	c  int64
   104  	mu sync.Mutex
   105  }
   106  
   107  func (c *muC) Inc() {
   108  	c.mu.Lock()
   109  	defer c.mu.Unlock()
   110  	c.c++
   111  }
   112  
   113  func BenchmarkMuCounter(b *testing.B) {
   114  	var c muC
   115  	for i := 0; i < b.N; i++ {
   116  		c.Inc()
   117  	}
   118  }
   119  
   120  func BenchmarkNonSafeCounter(b *testing.B) {
   121  	var c uint64
   122  	for i := 0; i < b.N; i++ {
   123  		c++
   124  	}
   125  }