From d909f167ffad456e9cfbfc8afca24429a39bfe87 Mon Sep 17 00:00:00 2001 From: Klaus Post Date: Mon, 9 May 2022 09:55:52 -0700 Subject: [PATCH] tests: Add localLocker RUnlock test (#14882) --- cmd/local-locker_test.go | 93 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/cmd/local-locker_test.go b/cmd/local-locker_test.go index d920bc5d7..a8f0ea651 100644 --- a/cmd/local-locker_test.go +++ b/cmd/local-locker_test.go @@ -344,3 +344,96 @@ func Test_localLocker_expireOldLocksExpire(t *testing.T) { }) } } + +func Test_localLocker_RUnlock(t *testing.T) { + rng := rand.New(rand.NewSource(0)) + // Numbers of unique locks + for _, locks := range []int{1, 100, 1000, 1e6} { + if testing.Short() && locks > 100 { + continue + } + t.Run(fmt.Sprintf("%d-locks", locks), func(t *testing.T) { + // Number of readers per lock... + for _, readers := range []int{1, 10, 100} { + if locks > 1000 && readers > 1 { + continue + } + if testing.Short() && readers > 10 { + continue + } + t.Run(fmt.Sprintf("%d-read", readers), func(t *testing.T) { + l := newLocker() + for i := 0; i < locks; i++ { + var tmp [16]byte + rng.Read(tmp[:]) + res := []string{hex.EncodeToString(tmp[:])} + + for i := 0; i < readers; i++ { + rng.Read(tmp[:]) + ok, err := l.RLock(context.Background(), dsync.LockArgs{ + UID: uuid.NewString(), + Resources: res, + Source: hex.EncodeToString(tmp[:8]), + Owner: hex.EncodeToString(tmp[8:]), + Quorum: 0, + }) + if !ok || err != nil { + t.Fatal("failed:", err, ok) + } + } + } + + // Expire 50% + toUnLock := make([]dsync.LockArgs, 0, locks*readers) + for k, v := range l.lockMap { + for _, lock := range v { + if rng.Intn(2) == 0 { + toUnLock = append(toUnLock, dsync.LockArgs{Resources: []string{k}, UID: lock.UID}) + } + } + } + start := time.Now() + for _, lock := range toUnLock { + ok, err := l.ForceUnlock(context.Background(), lock) + if err != nil || !ok { + t.Fatal(err) + } + } + t.Logf("Expire 50%% took: %v. Left: %d/%d", time.Since(start).Round(time.Millisecond), len(l.lockUID), len(l.lockMap)) + + if len(l.lockUID) == locks*readers { + t.Fatalf("objects uids all remain, unlikely") + } + if len(l.lockMap) == 0 && locks > 10 { + t.Fatalf("objects all deleted, 0 remains") + } + if len(l.lockUID) != locks*readers-len(toUnLock) { + t.Fatalf("want %d objects uids all deleted, %d remains", len(l.lockUID), locks*readers-len(toUnLock)) + } + + toUnLock = toUnLock[:0] + for k, v := range l.lockMap { + for _, lock := range v { + toUnLock = append(toUnLock, dsync.LockArgs{Resources: []string{k}, UID: lock.UID, Owner: lock.Owner}) + } + } + start = time.Now() + for _, lock := range toUnLock { + ok, err := l.RUnlock(nil, lock) + if err != nil || !ok { + t.Fatal(err) + } + } + t.Logf("Expire rest took: %v. Left: %d/%d", time.Since(start).Round(time.Millisecond), len(l.lockUID), len(l.lockMap)) + + if len(l.lockMap) != 0 { + t.Fatalf("objects not deleted, want %d != got %d", 0, len(l.lockMap)) + } + if len(l.lockUID) != 0 { + t.Fatalf("objects not deleted, want %d != got %d", 0, len(l.lockUID)) + } + }) + } + }) + } +}