Files
ezbookkeeping/pkg/duplicatechecker/in_memory_duplicate_checker_test.go

232 lines
7.2 KiB
Go

package duplicatechecker
import (
"fmt"
"sync"
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/mayswind/ezbookkeeping/pkg/settings"
"github.com/mayswind/ezbookkeeping/pkg/utils"
)
func TestSetAndGetSubmissionRemark(t *testing.T) {
checker, _ := NewInMemoryDuplicateChecker(&settings.Config{
DuplicateSubmissionsIntervalDuration: 100 * time.Second,
InMemoryDuplicateCheckerCleanupIntervalDuration: 100 * time.Second,
})
uid := int64(1234567890)
id := "2345678901"
expectedRemark := "0123456789"
checker.SetSubmissionRemark(DUPLICATE_CHECKER_TYPE_NEW_TRANSACTION, uid, id, expectedRemark)
found, actualRemark := checker.GetSubmissionRemark(DUPLICATE_CHECKER_TYPE_NEW_TRANSACTION, uid, id)
assert.Equal(t, true, found)
assert.Equal(t, expectedRemark, actualRemark)
}
func TestSetAndGetNotExistedSubmissionRemark(t *testing.T) {
checker, _ := NewInMemoryDuplicateChecker(&settings.Config{
DuplicateSubmissionsIntervalDuration: 100 * time.Second,
InMemoryDuplicateCheckerCleanupIntervalDuration: 100 * time.Second,
})
uid := int64(1234567890)
id := "2345678901"
expectedRemark := "0123456789"
checker.SetSubmissionRemark(DUPLICATE_CHECKER_TYPE_NEW_TRANSACTION, uid, id, expectedRemark)
found, actualRemark := checker.GetSubmissionRemark(DUPLICATE_CHECKER_TYPE_NEW_ACCOUNT, uid, id)
assert.Equal(t, false, found)
assert.Equal(t, "", actualRemark)
found, actualRemark = checker.GetSubmissionRemark(DUPLICATE_CHECKER_TYPE_NEW_TRANSACTION, uid, "")
assert.Equal(t, false, found)
assert.Equal(t, "", actualRemark)
found, actualRemark = checker.GetSubmissionRemark(DUPLICATE_CHECKER_TYPE_NEW_TRANSACTION, uid, "2345678900")
assert.Equal(t, false, found)
assert.Equal(t, "", actualRemark)
found, actualRemark = checker.GetSubmissionRemark(DUPLICATE_CHECKER_TYPE_NEW_TRANSACTION, int64(123456791), "")
assert.Equal(t, false, found)
assert.Equal(t, "", actualRemark)
}
func TestSetAndGetExpiredSubmissionRemark(t *testing.T) {
checker, _ := NewInMemoryDuplicateChecker(&settings.Config{
DuplicateSubmissionsIntervalDuration: time.Second,
InMemoryDuplicateCheckerCleanupIntervalDuration: time.Second,
})
uid := int64(1234567890)
id := "2345678901"
expectedRemark := "0123456789"
checker.SetSubmissionRemark(DUPLICATE_CHECKER_TYPE_NEW_TRANSACTION, uid, id, expectedRemark)
time.Sleep(time.Second * 2)
found, actualRemark := checker.GetSubmissionRemark(DUPLICATE_CHECKER_TYPE_NEW_TRANSACTION, uid, id)
assert.Equal(t, false, found)
assert.Equal(t, "", actualRemark)
}
func TestGetOrSetCronJobRunningInfo(t *testing.T) {
checker, _ := NewInMemoryDuplicateChecker(&settings.Config{
DuplicateSubmissionsIntervalDuration: time.Second,
InMemoryDuplicateCheckerCleanupIntervalDuration: time.Second,
})
jobName := "foo"
expectedRunningInfo := "bar"
found, actualRunningInfo := checker.GetOrSetCronJobRunningInfo(jobName, expectedRunningInfo, 100*time.Second)
assert.Equal(t, false, found)
assert.Equal(t, "", actualRunningInfo)
found, actualRunningInfo = checker.GetOrSetCronJobRunningInfo(jobName, expectedRunningInfo, 100*time.Second)
assert.Equal(t, true, found)
assert.Equal(t, expectedRunningInfo, actualRunningInfo)
checker.RemoveCronJobRunningInfo(jobName)
found, actualRunningInfo = checker.GetOrSetCronJobRunningInfo(jobName, expectedRunningInfo, 100*time.Second)
assert.Equal(t, false, found)
assert.Equal(t, "", actualRunningInfo)
}
func TestGetNotExistedRunningInfo(t *testing.T) {
checker, _ := NewInMemoryDuplicateChecker(&settings.Config{
DuplicateSubmissionsIntervalDuration: time.Second,
InMemoryDuplicateCheckerCleanupIntervalDuration: time.Second,
})
jobName := "foo"
expectedRunningInfo := "bar"
found, actualRunningInfo := checker.GetOrSetCronJobRunningInfo(jobName, expectedRunningInfo, 100*time.Second)
assert.Equal(t, false, found)
assert.Equal(t, "", actualRunningInfo)
found, actualRunningInfo = checker.GetOrSetCronJobRunningInfo("bar", expectedRunningInfo, 100*time.Second)
assert.Equal(t, false, found)
assert.Equal(t, "", actualRunningInfo)
}
func TestGetOrSetRunningInfoConcurrent(t *testing.T) {
checker, _ := NewInMemoryDuplicateChecker(&settings.Config{
DuplicateSubmissionsIntervalDuration: time.Second,
InMemoryDuplicateCheckerCleanupIntervalDuration: time.Second,
})
jobName := "foo"
concurrentCount := 10
var setRunningInfoCount atomic.Uint32
var waitGroup sync.WaitGroup
for routineIndex := 0; routineIndex < concurrentCount; routineIndex++ {
waitGroup.Add(1)
go func(currentRoutineIndex int) {
randomNumber, _ := utils.GetRandomInteger(10)
time.Sleep(time.Duration(int64(randomNumber) * int64(time.Millisecond)))
for cycle := 0; cycle < 100; cycle++ {
expectedRunningInfo := fmt.Sprintf("%d-%d", currentRoutineIndex, cycle)
found, _ := checker.GetOrSetCronJobRunningInfo(jobName, expectedRunningInfo, 100*time.Second)
if found {
setRunningInfoCount.Add(1)
} else {
fmt.Printf("routine#%d set cron job running info %s\n", currentRoutineIndex, expectedRunningInfo)
}
}
waitGroup.Done()
}(routineIndex)
}
waitGroup.Wait()
assert.Equal(t, uint32(999), setRunningInfoCount.Load())
}
func TestGetFailureCount(t *testing.T) {
checker, _ := NewInMemoryDuplicateChecker(&settings.Config{
DuplicateSubmissionsIntervalDuration: time.Second,
InMemoryDuplicateCheckerCleanupIntervalDuration: time.Second,
})
failureKey := "127.0.0.1"
failureCount := checker.GetFailureCount(failureKey)
assert.Equal(t, uint32(0), failureCount)
failureCount = checker.IncreaseFailureCount(failureKey)
assert.Equal(t, uint32(1), failureCount)
failureCount = checker.GetFailureCount(failureKey)
assert.Equal(t, uint32(1), failureCount)
}
func TestIncreaseFailureCount(t *testing.T) {
checker, _ := NewInMemoryDuplicateChecker(&settings.Config{
DuplicateSubmissionsIntervalDuration: time.Second,
InMemoryDuplicateCheckerCleanupIntervalDuration: time.Second,
})
failureKey := "127.0.0.1"
failureCount := checker.IncreaseFailureCount(failureKey)
assert.Equal(t, uint32(1), failureCount)
failureCount = checker.GetFailureCount(failureKey)
assert.Equal(t, uint32(1), failureCount)
failureCount = checker.IncreaseFailureCount(failureKey)
assert.Equal(t, uint32(2), failureCount)
failureCount = checker.GetFailureCount(failureKey)
assert.Equal(t, uint32(2), failureCount)
failureCount = checker.IncreaseFailureCount(failureKey)
assert.Equal(t, uint32(3), failureCount)
failureCount = checker.GetFailureCount(failureKey)
assert.Equal(t, uint32(3), failureCount)
}
func TestIncreaseFailureCountConcurrent(t *testing.T) {
checker, _ := NewInMemoryDuplicateChecker(&settings.Config{
DuplicateSubmissionsIntervalDuration: time.Second,
InMemoryDuplicateCheckerCleanupIntervalDuration: time.Second,
})
failureKey := "127.0.0.1"
concurrentCount := 10
var waitGroup sync.WaitGroup
for routineIndex := 0; routineIndex < concurrentCount; routineIndex++ {
waitGroup.Add(1)
go func(currentRoutineIndex int) {
for cycle := 0; cycle < 10; cycle++ {
checker.IncreaseFailureCount(failureKey)
}
waitGroup.Done()
}(routineIndex)
}
waitGroup.Wait()
failureCount := checker.GetFailureCount(failureKey)
assert.Equal(t, uint32(100), failureCount)
}