53 lines
1.3 KiB
Go
53 lines
1.3 KiB
Go
package locks
|
|
|
|
import (
|
|
"sync"
|
|
"testing"
|
|
)
|
|
|
|
func TestGetShardIndex_Distribution(t *testing.T) {
|
|
t.Parallel()
|
|
const N = 1000
|
|
counts := make([]int, NumLockShards)
|
|
for i := 0; i < N; i++ {
|
|
key := "steam/depot/test/" + string(rune('a'+i%26)) + string(rune(i))
|
|
idx := GetShardIndex(key)
|
|
if idx < 0 || idx >= NumLockShards {
|
|
t.Fatalf("shard %d out of range", idx)
|
|
}
|
|
counts[idx]++
|
|
}
|
|
// Very rough: no shard should get 0 if N large (probabilistic)
|
|
zeros := 0
|
|
for _, c := range counts {
|
|
if c == 0 {
|
|
zeros++
|
|
}
|
|
}
|
|
if zeros > NumLockShards/2 {
|
|
t.Logf("shard counts: %v", counts)
|
|
t.Errorf("too many zero shards (%d); hash not distributing well?", zeros)
|
|
}
|
|
}
|
|
|
|
func TestGetKeyLock_SameKeySameLock(t *testing.T) {
|
|
t.Parallel()
|
|
keyLocks := make([]sync.Map, NumLockShards)
|
|
l1 := GetKeyLock(keyLocks, "foo/bar")
|
|
l2 := GetKeyLock(keyLocks, "foo/bar")
|
|
if l1 != l2 {
|
|
t.Error("same key must return identical *RWMutex pointer for sharded locking")
|
|
}
|
|
}
|
|
|
|
func TestGetKeyLock_DifferentKeysMayDiffer(t *testing.T) {
|
|
t.Parallel()
|
|
keyLocks := make([]sync.Map, NumLockShards)
|
|
l1 := GetKeyLock(keyLocks, "a")
|
|
l2 := GetKeyLock(keyLocks, "b")
|
|
// May or may not be same shard; just ensure non-nil
|
|
if l1 == nil || l2 == nil {
|
|
t.Error("locks must be non-nil")
|
|
}
|
|
}
|