From 6714afbad08f966980292641e5fa85537cb2391b Mon Sep 17 00:00:00 2001 From: illia-li Date: Thu, 21 Nov 2024 00:32:15 -0400 Subject: [PATCH] add `debounce` tests --- debounce/simple_debouncer2_test.go | 105 +++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 debounce/simple_debouncer2_test.go diff --git a/debounce/simple_debouncer2_test.go b/debounce/simple_debouncer2_test.go new file mode 100644 index 000000000..db2f7e425 --- /dev/null +++ b/debounce/simple_debouncer2_test.go @@ -0,0 +1,105 @@ +package debounce + +import ( + "sync" + "sync/atomic" + "testing" +) + +// TestSimpleDebouncerRace tests SimpleDebouncer for the fact that it does not allow concurrent writing, reading. +// So, if it`s not true `DATA RACE` will be detected. +func TestSimpleDebouncerRace(t *testing.T) { + operations := 1000000 + runs := 100 + count := 3 + + d := NewSimpleDebouncer() + for r := 0; r < runs; r++ { + var wg sync.WaitGroup + wg.Add(count) + + // The map it`s better choice for `DATA RACE` detection + item := make(map[int]int) + + dFunc := func() { + for i := 0; i < operations; i++ { + item[1] = 1 + tmp := item[1] + item[1] = tmp + 1 + } + } + + results := make([]bool, count) + for c := range results { + i := &results[c] + go func() { + *i = d.Debounce(dFunc) + wg.Done() + }() + } + wg.Wait() + + // check results + if len(item) == 0 { + t.Fatalf("The Debounce function was not executed") + } + + finished := 0 + for _, done := range results { + if done { + finished++ + } + } + 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 extreme conditions. +func TestDebouncerExtreme(t *testing.T) { + type runResult struct { + callN int32 + executedN int32 + done bool + } + + runs := 10000 + count := 20 + + d := NewSimpleDebouncer() + var wg sync.WaitGroup + for r := 0; r < runs; r++ { + var callsC, executionsC atomic.Int32 + wg.Add(count) + + results := make([]runResult, count) + + for c := range results { + i := &results[c] + + go func() { + i.callN = callsC.Add(1) + i.done = d.Debounce(func() { + i.executedN = executionsC.Add(1) + }) + wg.Done() + }() + } + wg.Wait() + + // check results + finished := 0 + for _, result := range results { + if result.done { + if result.executedN == 0 || result.callN == 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) + } + } +}