github.com/maypok86/otter@v1.2.1/internal/stats/counter_test.go (about)

     1  // Copyright (c) 2023 Alexey Mayshev. All rights reserved.
     2  // Copyright (c) 2021 Andrey Pechkurov
     3  //
     4  // Copyright notice. This code is a fork of tests for xsync.Counter from this file with some changes:
     5  // https://github.com/puzpuzpuz/xsync/blob/main/counter_test.go
     6  //
     7  // Use of this source code is governed by a MIT license that can be found
     8  // at https://github.com/puzpuzpuz/xsync/blob/main/LICENSE
     9  
    10  package stats
    11  
    12  import (
    13  	"fmt"
    14  	"runtime"
    15  	"sync"
    16  	"testing"
    17  )
    18  
    19  func TestCounterIncrement(t *testing.T) {
    20  	c := newCounter()
    21  	for i := 0; i < 1000; i++ {
    22  		if v := c.value(); v != int64(i) {
    23  			t.Fatalf("got %v, want %d", v, i)
    24  		}
    25  		c.increment()
    26  	}
    27  }
    28  
    29  func TestCounterDecrement(t *testing.T) {
    30  	c := newCounter()
    31  	for i := 0; i < 1000; i++ {
    32  		if v := c.value(); v != int64(-i) {
    33  			t.Fatalf("got %v, want %d", v, -i)
    34  		}
    35  		c.decrement()
    36  	}
    37  }
    38  
    39  func TestCounterAdd(t *testing.T) {
    40  	c := newCounter()
    41  	for i := 0; i < 100; i++ {
    42  		if v := c.value(); v != int64(i*42) {
    43  			t.Fatalf("got %v, want %d", v, i*42)
    44  		}
    45  		c.add(42)
    46  	}
    47  }
    48  
    49  func TestCounterReset(t *testing.T) {
    50  	c := newCounter()
    51  	c.add(42)
    52  	if v := c.value(); v != 42 {
    53  		t.Fatalf("got %v, want %d", v, 42)
    54  	}
    55  	c.reset()
    56  	if v := c.value(); v != 0 {
    57  		t.Fatalf("got %v, want %d", v, 0)
    58  	}
    59  }
    60  
    61  func parallelIncrement(c *counter, incs int, wg *sync.WaitGroup) {
    62  	for i := 0; i < incs; i++ {
    63  		c.increment()
    64  	}
    65  	wg.Done()
    66  }
    67  
    68  func testParallelIncrement(t *testing.T, modifiers, gomaxprocs int) {
    69  	t.Helper()
    70  	runtime.GOMAXPROCS(gomaxprocs)
    71  	c := newCounter()
    72  	wg := &sync.WaitGroup{}
    73  	incs := 10_000
    74  	wg.Add(modifiers)
    75  	for i := 0; i < modifiers; i++ {
    76  		go parallelIncrement(c, incs, wg)
    77  	}
    78  	wg.Wait()
    79  	expected := int64(modifiers * incs)
    80  	if v := c.value(); v != expected {
    81  		t.Fatalf("got %d, want %d", v, expected)
    82  	}
    83  }
    84  
    85  func TestCounterParallelIncrementors(t *testing.T) {
    86  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
    87  
    88  	tests := []struct {
    89  		modifiers  int
    90  		gomaxprocs int
    91  	}{
    92  		{
    93  			modifiers:  4,
    94  			gomaxprocs: 2,
    95  		},
    96  		{
    97  			modifiers:  16,
    98  			gomaxprocs: 4,
    99  		},
   100  		{
   101  			modifiers:  64,
   102  			gomaxprocs: 8,
   103  		},
   104  	}
   105  
   106  	for i, tt := range tests {
   107  		t.Run(fmt.Sprintf("parallelIncrement-%d", i+1), func(t *testing.T) {
   108  			testParallelIncrement(t, tt.modifiers, tt.gomaxprocs)
   109  			testParallelIncrement(t, tt.modifiers, tt.gomaxprocs)
   110  			testParallelIncrement(t, tt.modifiers, tt.gomaxprocs)
   111  		})
   112  	}
   113  }