mirror of
https://github.com/werbenhu/eventbus.git
synced 2025-09-26 20:41:48 +08:00
238 lines
4.1 KiB
Go
238 lines
4.1 KiB
Go
package eventbus
|
|
|
|
import (
|
|
"strconv"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func Test_NewCowMap(t *testing.T) {
|
|
m := NewCowMap()
|
|
assert.NotNil(t, m)
|
|
}
|
|
|
|
func Test_CowMapLoad(t *testing.T) {
|
|
m := NewCowMap()
|
|
for i := 0; i < 100; i++ {
|
|
m.Store(i, strconv.Itoa(i))
|
|
}
|
|
|
|
for i := 0; i < 100; i++ {
|
|
val, ok := m.Load(i)
|
|
assert.True(t, ok)
|
|
assert.Equal(t, strconv.Itoa(i), val.(string))
|
|
}
|
|
|
|
val, ok := m.Load(999999)
|
|
assert.False(t, ok)
|
|
assert.Equal(t, nil, val)
|
|
}
|
|
|
|
func Test_CowMapStore(t *testing.T) {
|
|
m := NewCowMap()
|
|
for i := 0; i < 100; i++ {
|
|
m.Store(i, strconv.Itoa(i))
|
|
}
|
|
|
|
assert.Equal(t, uint32(100), m.Len())
|
|
}
|
|
|
|
func Test_CowMapDelete(t *testing.T) {
|
|
m := NewCowMap()
|
|
for i := 0; i < 100; i++ {
|
|
m.Store(i, strconv.Itoa(i))
|
|
}
|
|
|
|
for i := 0; i < 50; i++ {
|
|
m.Delete(i)
|
|
}
|
|
|
|
for i := 0; i < 50; i++ {
|
|
val, ok := m.Load(i)
|
|
assert.False(t, ok)
|
|
assert.Equal(t, nil, val)
|
|
}
|
|
|
|
for i := 50; i < 100; i++ {
|
|
val, ok := m.Load(i)
|
|
assert.True(t, ok)
|
|
assert.Equal(t, strconv.Itoa(i), val.(string))
|
|
}
|
|
}
|
|
|
|
func Test_CowMapClear(t *testing.T) {
|
|
m := NewCowMap()
|
|
for i := 0; i < 100; i++ {
|
|
m.Store(i, strconv.Itoa(i))
|
|
}
|
|
|
|
m.Clear()
|
|
assert.Equal(t, uint32(0), m.Len())
|
|
}
|
|
|
|
func Test_CowMapLen(t *testing.T) {
|
|
m := NewCowMap()
|
|
for i := 0; i < 100; i++ {
|
|
m.Store(i, strconv.Itoa(i))
|
|
}
|
|
assert.Equal(t, uint32(100), m.Len())
|
|
}
|
|
|
|
func Test_CowMapRange(t *testing.T) {
|
|
m := NewCowMap()
|
|
expert := make([]bool, 100)
|
|
|
|
for i := 0; i < 100; i++ {
|
|
m.Store(i, strconv.Itoa(i))
|
|
}
|
|
m.Range(func(key any, value any) bool {
|
|
if value.(string) == strconv.Itoa(key.(int)) {
|
|
expert[key.(int)] = true
|
|
}
|
|
return true
|
|
})
|
|
|
|
for _, val := range expert {
|
|
assert.True(t, val)
|
|
}
|
|
}
|
|
|
|
func Test_CowMapRangeStop(t *testing.T) {
|
|
m := NewCowMap()
|
|
results := make([]bool, 100)
|
|
|
|
for i := 0; i < 100; i++ {
|
|
m.Store(i, strconv.Itoa(i))
|
|
}
|
|
|
|
count := 0
|
|
m.Range(func(key any, value any) bool {
|
|
// only range ten elements and then stop range
|
|
if count >= 10 {
|
|
return false
|
|
}
|
|
|
|
count++
|
|
if value.(string) == strconv.Itoa(key.(int)) {
|
|
results[key.(int)] = true
|
|
}
|
|
return true
|
|
})
|
|
|
|
expert := 0
|
|
for _, val := range results {
|
|
if val {
|
|
expert++
|
|
}
|
|
}
|
|
assert.Equal(t, count, expert)
|
|
}
|
|
|
|
func Test_CowMapConcurrentLoadPanic(t *testing.T) {
|
|
m := NewCowMap()
|
|
assert.NotPanics(t, func() {
|
|
for i := 0; i < 100; i++ {
|
|
go func() {
|
|
for j := 0; j < 100; j++ {
|
|
m.Store(j, strconv.Itoa(j))
|
|
}
|
|
}()
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test_CowMapConcurrentStorePanic(t *testing.T) {
|
|
m := NewCowMap()
|
|
for i := 0; i < 100; i++ {
|
|
m.Store(i, strconv.Itoa(i))
|
|
}
|
|
|
|
assert.NotPanics(t, func() {
|
|
for i := 0; i < 100; i++ {
|
|
go func() {
|
|
for j := 0; j < 100; j++ {
|
|
m.Load(j)
|
|
}
|
|
}()
|
|
}
|
|
})
|
|
}
|
|
|
|
func Test_CowMapStoreOrLoadConcurrent(t *testing.T) {
|
|
m := NewCowMap()
|
|
for i := 0; i < 100; i++ {
|
|
m.Store(i, i)
|
|
}
|
|
|
|
storewg := sync.WaitGroup{}
|
|
storewg.Add(100)
|
|
assert.NotPanics(t, func() {
|
|
for i := 0; i < 100; i++ {
|
|
go func(index int) {
|
|
for j := index * 100; j < (index+1)*100; j++ {
|
|
m.Store(j, j)
|
|
}
|
|
storewg.Done()
|
|
}(i)
|
|
}
|
|
})
|
|
storewg.Wait()
|
|
|
|
loadwg := sync.WaitGroup{}
|
|
loadwg.Add(100)
|
|
assert.NotPanics(t, func() {
|
|
for i := 0; i < 100; i++ {
|
|
go func(index int) {
|
|
for j := index * 100; j < (index+1)*100; j++ {
|
|
val, ok := m.Load(j)
|
|
assert.True(t, ok)
|
|
assert.Equal(t, j, val)
|
|
}
|
|
loadwg.Done()
|
|
}(i)
|
|
}
|
|
})
|
|
loadwg.Wait()
|
|
}
|
|
|
|
func Test_CowMapStoreAndLoadConcurrent(t *testing.T) {
|
|
m := NewCowMap()
|
|
for i := 0; i < 100; i++ {
|
|
m.Store(i, i)
|
|
}
|
|
|
|
assert.NotPanics(t, func() {
|
|
loadGoroutineSize := 100
|
|
loadWg := sync.WaitGroup{}
|
|
loadWg.Add(loadGoroutineSize)
|
|
|
|
for i := 0; i < loadGoroutineSize; i++ {
|
|
go func() {
|
|
for j := 0; j < 100; j++ {
|
|
val, ok := m.Load(j)
|
|
assert.True(t, ok)
|
|
assert.Equal(t, j, val)
|
|
}
|
|
loadWg.Done()
|
|
}()
|
|
}
|
|
|
|
storeGoroutineSize := 100
|
|
storeWg := sync.WaitGroup{}
|
|
storeWg.Add(storeGoroutineSize)
|
|
for i := 0; i < storeGoroutineSize; i++ {
|
|
go func(index int) {
|
|
for j := 0; j < 100; j++ {
|
|
m.Store(j, j)
|
|
}
|
|
storeWg.Done()
|
|
}(i)
|
|
}
|
|
|
|
storeWg.Wait()
|
|
loadWg.Wait()
|
|
})
|
|
}
|