package counter import ( "sync" "testing" ) // Counter is a thread-safe integer counter. type Counter struct { mu sync.Mutex value int64 } // Add increases the counter by delta. func (c *Counter) Add(delta int64) { c.mu.Lock() defer c.mu.Unlock() c.value += delta } // Inc increases the counter by one. func (c *Counter) Inc() { c.Add(1) } // Value returns the current counter value. func (c *Counter) Value() int64 { c.mu.Lock() defer c.mu.Unlock() return c.value } // Reset sets the counter back to zero. func (c *Counter) Reset() { c.mu.Lock() defer c.mu.Unlock() c.value = 0 } func TestCounterAddAndReset(t *testing.T) { var c Counter c.Inc() c.Add(4) if got := c.Value(); got != 5 { t.Fatalf("Value() = %d, want 5", got) } c.Reset() if got := c.Value(); got != 0 { t.Fatalf("Value() after Reset() = %d, want 0", got) } } func TestCounterConcurrent(t *testing.T) { var c Counter var wg sync.WaitGroup const goroutines = 50 const increments = 1000 wg.Add(goroutines) for range goroutines { go func() { defer wg.Done() for range increments { c.Inc() } }() } wg.Wait() want := int64(goroutines * increments) if got := c.Value(); got != want { t.Fatalf("Value() = %d, want %d", got, want) } }