Skip to content

Commit

Permalink
add debounce tests
Browse files Browse the repository at this point in the history
  • Loading branch information
illia-li committed Nov 25, 2024
1 parent 0ad51b7 commit c13ca96
Showing 1 changed file with 134 additions and 0 deletions.
134 changes: 134 additions & 0 deletions debounce/simple_debouncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,151 @@ package debounce

import (
"runtime"
"sync"
"sync/atomic"
"testing"
"time"
)

// TestSimpleDebouncerRace tests SimpleDebouncer for the fact that it does not allow concurrent writing, reading.
func TestSimpleDebouncerRace(t *testing.T) {
operations := 1000
runs := 100
count := 3

d := NewSimpleDebouncer()
for r := 0; r < runs; r++ {
var counter atomic.Int32
var wg sync.WaitGroup
wg.Add(count)

results := make([]bool, count)
fails := make([]bool, count)
for c := range results {
result := &results[c]
fail := &fails[c]

go func() {
*result = d.Debounce(func() {
for i := 0; i < operations; i++ {
if counter.Add(1) != 1 {
*fail = true
}
time.Sleep(time.Microsecond)
counter.Add(-1)
}
})
wg.Done()
}()
}
wg.Wait()

// check results

finished := 0
for i, done := range results {
if done {
finished++
}
if fails[i] {
t.Fatalf("Simultaneous execution detected")
}
}
if finished < 2 {
t.Fatalf("In one run should be finished more than 2 `Debounce` method calls, but finished %d", finished)
}
}
}

// TestDebouncerExtreme tests SimpleDebouncer in the conditions fast multi `Debounce` method calls and fast execution of the `debounced function`.
func TestDebouncerExtreme(t *testing.T) {
type runResult struct {
executedN int32
done bool
}

runs := 10000
count := 20

d := NewSimpleDebouncer()
var wg sync.WaitGroup
for r := 0; r < runs; r++ {
var executionsC atomic.Int32
wg.Add(count)

results := make([]runResult, count)

for c := range results {
result := &results[c]

go func() {
result.done = d.Debounce(func() {
result.executedN = executionsC.Add(1)
})
wg.Done()
}()
}
wg.Wait()

// check results
finished := 0
for _, result := range results {
if result.done {
if result.executedN == 0 {
t.Fatalf("Wrong execution detected: \n%#v", result)
}
finished++
}
}
if finished < 2 {
t.Fatalf("In one run should be finished more than 2 `Debounce` method calls, but finished %d", finished)
}
}
}

// TestSimpleDebouncerCount tests SimpleDebouncer for the fact that it pended only one function call.
func TestSimpleDebouncerCount(t *testing.T) {
calls := 10

d := NewSimpleDebouncer()
var prepared, start, done sync.WaitGroup
prepared.Add(calls - 1)
start.Add(1)
done.Add(calls - 1)

finished := 0
for c := 0; c < calls-1; c++ {
go func() {
prepared.Done()
start.Wait()
d.Debounce(func() {
finished++
})
done.Done()
}()
}
d.Debounce(func() {
prepared.Wait()
start.Done()
finished++
time.Sleep(time.Second)
})
done.Wait()

// check results
if finished != 2 {
t.Fatalf("Should be finished more than 2 `Debounce` method calls, but finished %d", finished)
}
}

// TestDebouncer tests that the debouncer allows only one function to execute at a time
func TestSimpleDebouncer(t *testing.T) {
t.Skip("This test sometimes ends vai panic. Issue https://github.com/scylladb/gocql/pull/344")
d := NewSimpleDebouncer()
var executions int32
startedCh := make(chan struct{}, 1)
doneCh := make(chan struct{}, 1)

// Function to increment executions
fn := func() {
<-startedCh // Simulate work
Expand Down

0 comments on commit c13ca96

Please sign in to comment.