mirror of
https://github.com/hanzoai/tasks.git
synced 2026-10-04 02:04:03 +00:00
## What changed?
<!-- Describe what has changed in this PR -->
Remove license header from every file. Because it is really hard to
follow in this PR here is the summary:
1. License header is removed from all `.go` and `.proto` files
:fireworks::fireworks:🎆.
2. `LICENSE` file in the root directory has only Temporal and Uber
copyrights.
3. 5 other `LICENSE` files added to the packages which have copyrights
different from Temporal and Uber: Datadog, Xargin, "Mat Ryer, Tyler
Bunnell and contributors".
4. `license_file` flag is removed from all code generation tools.
5. `copyright_file` flag is removed from `go:generate mockgen`
directive.
6. All copyright related targets are removed from `Makefile`.
7. Updated Temporal copyright year to 2025 everywhere.
## Why?
<!-- Tell your future self why have you made these changes -->
I double checked with legal department that it is not needed to have
license header in every file. One file per repo is enough. I put all
copyrights to the root `LICENSE` file and removed header from all other
files. Also updated tools and `Makefile`.
232 lines
6.4 KiB
Go
232 lines
6.4 KiB
Go
package collection
|
|
|
|
import (
|
|
"errors"
|
|
"math/rand"
|
|
"sync"
|
|
"sync/atomic"
|
|
"testing"
|
|
|
|
"github.com/pborman/uuid"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/stretchr/testify/suite"
|
|
)
|
|
|
|
type (
|
|
ConcurrentTxMapSuite struct {
|
|
*require.Assertions // override suite.Suite.Assertions with require.Assertions; this means that s.NotNil(nil) will stop the test, not merely log an error
|
|
suite.Suite
|
|
}
|
|
boolType bool
|
|
intType int
|
|
)
|
|
|
|
func TestConcurrentTxMapSuite(t *testing.T) {
|
|
suite.Run(t, new(ConcurrentTxMapSuite))
|
|
}
|
|
|
|
func (s *ConcurrentTxMapSuite) SetupTest() {
|
|
s.Assertions = require.New(s.T()) // Have to define our overridden assertions in the test setup. If we did it earlier, s.T() will return nil
|
|
}
|
|
|
|
func (s *ConcurrentTxMapSuite) TestLen() {
|
|
testMap := NewShardedConcurrentTxMap(1, UUIDHashCode)
|
|
|
|
key1 := "0001"
|
|
testMap.Put(key1, boolType(true))
|
|
s.Equal(1, testMap.Len(), "Wrong concurrent map size")
|
|
|
|
testMap.Put(key1, boolType(false))
|
|
s.Equal(1, testMap.Len(), "Wrong concurrent map size")
|
|
|
|
key2 := "0002"
|
|
testMap.Put(key2, boolType(false))
|
|
s.Equal(2, testMap.Len(), "Wrong concurrent map size")
|
|
|
|
testMap.PutIfNotExist(key2, boolType(false))
|
|
s.Equal(2, testMap.Len(), "Wrong concurrent map size")
|
|
|
|
testMap.Remove(key2)
|
|
s.Equal(1, testMap.Len(), "Wrong concurrent map size")
|
|
|
|
testMap.Remove(key2)
|
|
s.Equal(1, testMap.Len(), "Wrong concurrent map size")
|
|
}
|
|
|
|
func (s *ConcurrentTxMapSuite) TestGetAndDo() {
|
|
testMap := NewShardedConcurrentTxMap(1, UUIDHashCode)
|
|
key := uuid.New()
|
|
var value intType
|
|
fnApplied := false
|
|
|
|
interf, ok, err := testMap.GetAndDo(key, func(key interface{}, value interface{}) error {
|
|
fnApplied = true
|
|
return nil
|
|
})
|
|
s.Nil(interf, "GetAndDo should return nil when key not found")
|
|
s.Nil(err, "GetAndDo should return nil when function not applied")
|
|
s.False(ok, "GetAndDo should return false when key not found")
|
|
s.False(fnApplied, "GetAndDo should not apply function when key not exixts")
|
|
|
|
value = intType(1)
|
|
testMap.Put(key, &value)
|
|
interf, ok, err = testMap.GetAndDo(key, func(key interface{}, value interface{}) error {
|
|
fnApplied = true
|
|
intValue := value.(*intType)
|
|
*intValue++
|
|
return errors.New("some err")
|
|
})
|
|
|
|
value1 := interf.(*intType)
|
|
s.Equal(*(value1), intType(2))
|
|
s.NotNil(err, "GetAndDo should return non nil when function applied")
|
|
s.True(ok, "GetAndDo should return true when key found")
|
|
s.True(fnApplied, "GetAndDo should apply function when key exixts")
|
|
}
|
|
|
|
func (s *ConcurrentTxMapSuite) TestPutOrDo() {
|
|
testMap := NewShardedConcurrentTxMap(1, UUIDHashCode)
|
|
key := uuid.New()
|
|
var value intType
|
|
fnApplied := false
|
|
|
|
value = intType(1)
|
|
interf, ok, err := testMap.PutOrDo(key, &value, func(key interface{}, value interface{}) error {
|
|
fnApplied = true
|
|
return errors.New("some err")
|
|
})
|
|
valueRetuern := interf.(*intType)
|
|
s.Equal(value, *valueRetuern)
|
|
s.Nil(err, "PutOrDo should return nil when function not applied")
|
|
s.False(ok, "PutOrDo should return false when function not applied")
|
|
s.False(fnApplied, "PutOrDo should not apply function when key not exixts")
|
|
|
|
anotherValue := intType(111)
|
|
interf, ok, err = testMap.PutOrDo(key, &anotherValue, func(key interface{}, value interface{}) error {
|
|
fnApplied = true
|
|
intValue := value.(*intType)
|
|
*intValue++
|
|
return errors.New("some err")
|
|
})
|
|
valueRetuern = interf.(*intType)
|
|
s.Equal(value, *valueRetuern)
|
|
s.NotNil(err, "PutOrDo should return non nil when function applied")
|
|
s.True(ok, "PutOrDo should return true when function applied")
|
|
s.True(fnApplied, "PutOrDo should apply function when key exixts")
|
|
}
|
|
|
|
func (s *ConcurrentTxMapSuite) TestRemoveIf() {
|
|
testMap := NewShardedConcurrentTxMap(1, UUIDHashCode)
|
|
key := uuid.New()
|
|
value := intType(1)
|
|
testMap.Put(key, &value)
|
|
|
|
removed := testMap.RemoveIf(key, func(key interface{}, value interface{}) bool {
|
|
intValue := value.(*intType)
|
|
return *intValue == intType(2)
|
|
})
|
|
s.Equal(1, testMap.Len(), "TestRemoveIf should only entry if condition is met")
|
|
s.False(removed, "TestRemoveIf should return false if key is not deleted")
|
|
|
|
removed = testMap.RemoveIf(key, func(key interface{}, value interface{}) bool {
|
|
intValue := value.(*intType)
|
|
return *intValue == intType(1)
|
|
})
|
|
s.Equal(0, testMap.Len(), "TestRemoveIf should only entry if condition is met")
|
|
s.True(removed, "TestRemoveIf should return true if key is deleted")
|
|
}
|
|
|
|
func (s *ConcurrentTxMapSuite) TestGetAfterPut() {
|
|
|
|
countMap := make(map[string]int)
|
|
testMap := NewShardedConcurrentTxMap(1, UUIDHashCode)
|
|
|
|
for i := 0; i < 1024; i++ {
|
|
key := uuid.New()
|
|
countMap[key] = 0
|
|
testMap.Put(key, boolType(true))
|
|
}
|
|
|
|
for k := range countMap {
|
|
v, ok := testMap.Get(k)
|
|
boolValue := v.(boolType)
|
|
s.True(ok, "Get after put failed")
|
|
s.True(bool(boolValue), "Wrong value returned from map")
|
|
}
|
|
|
|
s.Equal(len(countMap), testMap.Len(), "Size() returned wrong value")
|
|
|
|
it := testMap.Iter()
|
|
for entry := range it.Entries() {
|
|
countMap[entry.Key.(string)]++
|
|
}
|
|
it.Close()
|
|
|
|
for _, v := range countMap {
|
|
s.Equal(1, v, "Iterator test failed")
|
|
}
|
|
|
|
for k := range countMap {
|
|
testMap.Remove(k)
|
|
}
|
|
|
|
s.Equal(0, testMap.Len(), "Map returned non-zero size after deleting all entries")
|
|
}
|
|
|
|
func (s *ConcurrentTxMapSuite) TestPutIfNotExist() {
|
|
testMap := NewShardedConcurrentTxMap(1, UUIDHashCode)
|
|
key := uuid.New()
|
|
ok := testMap.PutIfNotExist(key, boolType(true))
|
|
s.True(ok, "PutIfNotExist failed to insert item")
|
|
ok = testMap.PutIfNotExist(key, boolType(true))
|
|
s.False(ok, "PutIfNotExist invariant failed")
|
|
}
|
|
|
|
func (s *ConcurrentTxMapSuite) TestMapConcurrency() {
|
|
nKeys := 1024
|
|
keys := make([]string, nKeys)
|
|
for i := 0; i < nKeys; i++ {
|
|
keys[i] = uuid.New()
|
|
}
|
|
|
|
var total int32
|
|
var startWG sync.WaitGroup
|
|
var doneWG sync.WaitGroup
|
|
testMap := NewShardedConcurrentTxMap(1024, UUIDHashCode)
|
|
|
|
startWG.Add(1)
|
|
|
|
for i := 0; i < 10; i++ {
|
|
|
|
doneWG.Add(1)
|
|
|
|
go func() {
|
|
startWG.Wait()
|
|
for n := 0; n < nKeys; n++ {
|
|
val := intType(rand.Int())
|
|
if testMap.PutIfNotExist(keys[n], val) {
|
|
atomic.AddInt32(&total, int32(val))
|
|
_, ok := testMap.Get(keys[n])
|
|
s.True(ok, "Concurrency Get test failed")
|
|
}
|
|
}
|
|
doneWG.Done()
|
|
}()
|
|
}
|
|
|
|
startWG.Done()
|
|
doneWG.Wait()
|
|
|
|
s.Equal(nKeys, testMap.Len(), "Wrong concurrent map size")
|
|
|
|
var gotTotal int32
|
|
for i := 0; i < nKeys; i++ {
|
|
v, ok := testMap.Get(keys[i])
|
|
s.True(ok, "Get failed to find previously inserted key")
|
|
intVal := v.(intType)
|
|
gotTotal += int32(intVal)
|
|
}
|
|
|
|
s.Equal(total, gotTotal, "Concurrent put test failed, wrong sum of values inserted")
|
|
}
|