From 7bebf062be230dfaee8be46f02b43c3c17012c57 Mon Sep 17 00:00:00 2001 From: hailaz <739476267@qq.com> Date: Tue, 18 Jun 2019 11:46:43 +0800 Subject: [PATCH] Improve gmlock unit testing. --- g/os/gmlock/gmlock_unit_lock_test.go | 300 ++++++++++++++++++------- g/os/gmlock/gmlock_unit_mutex_test.go | 203 +++++++++++++++++ g/os/gmlock/gmlock_unit_rlock_test.go | 312 ++++++++++++++++++++++---- 3 files changed, 683 insertions(+), 132 deletions(-) create mode 100644 g/os/gmlock/gmlock_unit_mutex_test.go diff --git a/g/os/gmlock/gmlock_unit_lock_test.go b/g/os/gmlock/gmlock_unit_lock_test.go index 5d0ca1e63..5ca5c701d 100644 --- a/g/os/gmlock/gmlock_unit_lock_test.go +++ b/g/os/gmlock/gmlock_unit_lock_test.go @@ -7,93 +7,227 @@ package gmlock_test import ( - "github.com/gogf/gf/g/container/garray" - "github.com/gogf/gf/g/os/gmlock" - "github.com/gogf/gf/g/test/gtest" - "testing" - "time" + "testing" + "time" + + "github.com/gogf/gf/g/container/garray" + "github.com/gogf/gf/g/os/gmlock" + "github.com/gogf/gf/g/test/gtest" ) -func TestLocker_Lock_Unlock(t *testing.T) { - gtest.Case(t, func() { - key := "test1" - array := garray.New() - go func() { - gmlock.Lock(key) - array.Append(1) - time.Sleep(100*time.Millisecond) - array.Append(1) - gmlock.Unlock(key) - }() - go func() { - time.Sleep(10*time.Millisecond) - gmlock.Lock(key) - array.Append(1) - time.Sleep(200*time.Millisecond) - array.Append(1) - gmlock.Unlock(key) - }() - time.Sleep(50*time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(80*time.Millisecond) - gtest.Assert(array.Len(), 3) - time.Sleep(100*time.Millisecond) - gtest.Assert(array.Len(), 3) - time.Sleep(100*time.Millisecond) - gtest.Assert(array.Len(), 4) - }) +func Test_Locker_Lock(t *testing.T) { + //no expire + gtest.Case(t, func() { + key := "testLock" + array := garray.New() + go func() { + gmlock.Lock(key) + array.Append(1) + time.Sleep(100 * time.Millisecond) + array.Append(1) + gmlock.Unlock(key) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.Lock(key) + array.Append(1) + time.Sleep(200 * time.Millisecond) + array.Append(1) + gmlock.Unlock(key) + }() + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(80 * time.Millisecond) + gtest.Assert(array.Len(), 3) + time.Sleep(100 * time.Millisecond) + gtest.Assert(array.Len(), 3) + time.Sleep(100 * time.Millisecond) + gtest.Assert(array.Len(), 4) + }) + //expire + gtest.Case(t, func() { + key := "testLockExpire" + array := garray.New() + go func() { + gmlock.Lock(key, 100*time.Millisecond) + array.Append(1) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.Lock(key) + time.Sleep(100 * time.Millisecond) + array.Append(1) + gmlock.Unlock(key) + }() + time.Sleep(150 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(250 * time.Millisecond) + gtest.Assert(array.Len(), 2) + }) } -func TestLocker_Lock_Expire(t *testing.T) { - gtest.Case(t, func() { - key := "test2" - array := garray.New() - go func() { - gmlock.Lock(key, 100*time.Millisecond) - array.Append(1) - }() - go func() { - time.Sleep(10*time.Millisecond) - gmlock.Lock(key) - time.Sleep(100*time.Millisecond) - array.Append(1) - gmlock.Unlock(key) - }() - time.Sleep(150*time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(250*time.Millisecond) - gtest.Assert(array.Len(), 2) - }) +func Test_Locker_TryLock(t *testing.T) { + gtest.Case(t, func() { + key := "testTryLock" + array := garray.New() + go func() { + if gmlock.TryLock(key, 200*time.Millisecond) { + array.Append(1) + } + }() + go func() { + time.Sleep(100 * time.Millisecond) + if !gmlock.TryLock(key) { + array.Append(1) + } else { + gmlock.Unlock(key) + } + }() + go func() { + time.Sleep(300 * time.Millisecond) + if gmlock.TryLock(key) { + array.Append(1) + gmlock.Unlock(key) + } + }() + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(80 * time.Millisecond) + gtest.Assert(array.Len(), 2) + time.Sleep(350 * time.Millisecond) + gtest.Assert(array.Len(), 3) + }) } -func TestLocker_TryLock_Expire(t *testing.T) { - gtest.Case(t, func() { - key := "test3" - array := garray.New() - go func() { - gmlock.Lock(key, 200*time.Millisecond) - array.Append(1) - }() - go func() { - time.Sleep(100*time.Millisecond) - if !gmlock.TryLock(key) { - array.Append(1) - } else { - gmlock.Unlock(key) - } - }() - go func() { - time.Sleep(300*time.Millisecond) - if gmlock.TryLock(key) { - array.Append(1) - gmlock.Unlock(key) - } - }() - time.Sleep(50*time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(80*time.Millisecond) - gtest.Assert(array.Len(), 2) - time.Sleep(350*time.Millisecond) - gtest.Assert(array.Len(), 3) - }) +func Test_Locker_LockFunc(t *testing.T) { + //no expire + gtest.Case(t, func() { + key := "testLockFunc" + array := garray.New() + go func() { + gmlock.LockFunc(key, func() { + array.Append(1) + time.Sleep(200 * time.Millisecond) + }) // + }() + go func() { + time.Sleep(50 * time.Millisecond) + gmlock.LockFunc(key, func() { + array.Append(1) + }) + }() + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(100 * time.Millisecond) + gtest.Assert(array.Len(), 1) // + time.Sleep(350 * time.Millisecond) + gtest.Assert(array.Len(), 2) + }) + + //expire + gtest.Case(t, func() { + key := "testLockFuncExpire" + array := garray.New() + go func() { + gmlock.LockFunc(key, func() { + array.Append(1) + time.Sleep(200 * time.Millisecond) + }, 100*time.Millisecond) // + }() + go func() { + time.Sleep(50 * time.Millisecond) + gmlock.LockFunc(key, func() { + array.Append(1) + }) + }() + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(100 * time.Millisecond) + gtest.Assert(array.Len(), 2) // + time.Sleep(350 * time.Millisecond) + gtest.Assert(array.Len(), 2) + }) +} +func Test_Locker_TryLockFunc(t *testing.T) { + //no expire + gtest.Case(t, func() { + key := "testTryLockFunc" + array := garray.New() + go func() { + gmlock.TryLockFunc(key, func() { + array.Append(1) + time.Sleep(100 * time.Millisecond) + }) + }() + go func() { + time.Sleep(50 * time.Millisecond) + gmlock.TryLockFunc(key, func() { + array.Append(1) + }) + }() + go func() { + time.Sleep(150 * time.Millisecond) + gmlock.TryLockFunc(key, func() { + array.Append(1) + }) + }() + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(200 * time.Millisecond) + gtest.Assert(array.Len(), 2) + }) + //expire1 + gtest.Case(t, func() { + key := "testTryLockFuncExpire" + array := garray.New() + go func() { + gmlock.TryLockFunc(key, func() { + array.Append(1) + }, 200*time.Millisecond) + }() + go func() { + time.Sleep(50 * time.Millisecond) + gmlock.TryLockFunc(key, func() { + array.Append(1) + }) + }() + go func() { + time.Sleep(150 * time.Millisecond) + gmlock.TryLockFunc(key, func() { + array.Append(1) + }) + }() + time.Sleep(100 * time.Millisecond) + gtest.Assert(array.Len(), 2) + time.Sleep(200 * time.Millisecond) + gtest.Assert(array.Len(), 3) + }) + + //expire2 + gtest.Case(t, func() { + key := "testTryLockFuncExpire" + array := garray.New() + go func() { + gmlock.TryLockFunc(key, func() { + array.Append(1) + time.Sleep(300 * time.Millisecond) + }, 200*time.Millisecond) + }() + go func() { + time.Sleep(50 * time.Millisecond) + gmlock.TryLockFunc(key, func() { + array.Append(1) + }) + }() + go func() { + time.Sleep(150 * time.Millisecond) + gmlock.TryLockFunc(key, func() { + array.Append(1) + }) + }() + time.Sleep(100 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(200 * time.Millisecond) + gtest.Assert(array.Len(), 1) + }) } diff --git a/g/os/gmlock/gmlock_unit_mutex_test.go b/g/os/gmlock/gmlock_unit_mutex_test.go new file mode 100644 index 000000000..b1047649e --- /dev/null +++ b/g/os/gmlock/gmlock_unit_mutex_test.go @@ -0,0 +1,203 @@ +// Copyright 2019 gf Author(https://github.com/gogf/gf). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gmlock_test + +import ( + "testing" + "time" + + "github.com/gogf/gf/g/container/garray" + "github.com/gogf/gf/g/os/gmlock" + "github.com/gogf/gf/g/test/gtest" +) + +func Test_Mutex_Unlock(t *testing.T) { + gtest.Case(t, func() { + mu := gmlock.NewMutex() + array := garray.New() + go func() { + mu.LockFunc(func() { + array.Append(1) + time.Sleep(100 * time.Millisecond) + }) + }() + go func() { + time.Sleep(50 * time.Millisecond) + mu.LockFunc(func() { + array.Append(1) + }) + }() + go func() { + time.Sleep(50 * time.Millisecond) + mu.LockFunc(func() { + array.Append(1) + }) + }() + + go func() { + time.Sleep(60 * time.Millisecond) + mu.Unlock() + mu.Unlock() + mu.Unlock() + }() + + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 3) + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 3) + }) +} + +func Test_Mutex_LockFunc(t *testing.T) { + gtest.Case(t, func() { + mu := gmlock.NewMutex() + array := garray.New() + go func() { + mu.LockFunc(func() { + array.Append(1) + time.Sleep(100 * time.Millisecond) + }) + }() + go func() { + time.Sleep(50 * time.Millisecond) + mu.LockFunc(func() { + array.Append(1) + }) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 2) + }) +} + +func Test_Mutex_TryLockFunc(t *testing.T) { + gtest.Case(t, func() { + mu := gmlock.NewMutex() + array := garray.New() + go func() { + mu.LockFunc(func() { + array.Append(1) + time.Sleep(100 * time.Millisecond) + }) + }() + go func() { + time.Sleep(50 * time.Millisecond) + mu.TryLockFunc(func() { + array.Append(1) + }) + }() + go func() { + time.Sleep(110 * time.Millisecond) + mu.TryLockFunc(func() { + array.Append(1) + }) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 2) + }) +} + +func Test_Mutex_RLockFunc(t *testing.T) { + gtest.Case(t, func() { + mu := gmlock.NewMutex() + array := garray.New() + go func() { + mu.LockFunc(func() { + array.Append(1) + time.Sleep(100 * time.Millisecond) + }) + }() + go func() { + time.Sleep(50 * time.Millisecond) + mu.RLockFunc(func() { + array.Append(1) + time.Sleep(100 * time.Millisecond) + }) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 2) + }) + + gtest.Case(t, func() { + mu := gmlock.NewMutex() + array := garray.New() + go func() { + time.Sleep(50 * time.Millisecond) + mu.RLockFunc(func() { + array.Append(1) + time.Sleep(100 * time.Millisecond) + }) + }() + go func() { + time.Sleep(50 * time.Millisecond) + mu.RLockFunc(func() { + array.Append(1) + time.Sleep(100 * time.Millisecond) + }) + }() + go func() { + time.Sleep(50 * time.Millisecond) + mu.RLockFunc(func() { + array.Append(1) + time.Sleep(100 * time.Millisecond) + }) + }() + gtest.Assert(array.Len(), 0) + time.Sleep(80 * time.Millisecond) + gtest.Assert(array.Len(), 3) + }) +} + +func Test_Mutex_TryRLockFunc(t *testing.T) { + gtest.Case(t, func() { + mu := gmlock.NewMutex() + array := garray.New() + go func() { + mu.LockFunc(func() { + array.Append(1) + time.Sleep(100 * time.Millisecond) + }) + }() + go func() { + time.Sleep(50 * time.Millisecond) + mu.TryRLockFunc(func() { + array.Append(1) + }) + }() + go func() { + time.Sleep(110 * time.Millisecond) + mu.TryRLockFunc(func() { + array.Append(1) + }) + }() + go func() { + time.Sleep(110 * time.Millisecond) + mu.TryRLockFunc(func() { + array.Append(1) + }) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(50 * time.Millisecond) + gtest.Assert(array.Len(), 3) + }) +} diff --git a/g/os/gmlock/gmlock_unit_rlock_test.go b/g/os/gmlock/gmlock_unit_rlock_test.go index 176d375da..705ff11d0 100644 --- a/g/os/gmlock/gmlock_unit_rlock_test.go +++ b/g/os/gmlock/gmlock_unit_rlock_test.go @@ -7,57 +7,271 @@ package gmlock_test import ( - "github.com/gogf/gf/g/container/garray" - "github.com/gogf/gf/g/os/gmlock" - "github.com/gogf/gf/g/test/gtest" - "testing" - "time" + "testing" + "time" + + "github.com/gogf/gf/g/container/garray" + "github.com/gogf/gf/g/os/gmlock" + "github.com/gogf/gf/g/test/gtest" ) -func TestLocker_RLock1(t *testing.T) { - gtest.Case(t, func() { - key := "test100" - array := garray.New() - go func() { - gmlock.RLock(key) - array.Append(1) - time.Sleep(50*time.Millisecond) - array.Append(1) - gmlock.RUnlock(key) - }() - go func() { - time.Sleep(10*time.Millisecond) - gmlock.Lock(key) - array.Append(1) - gmlock.Unlock(key) - }() - time.Sleep(20*time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(80*time.Millisecond) - gtest.Assert(array.Len(), 3) - }) +func Test_Locker_RLock(t *testing.T) { + //RLock before Lock + gtest.Case(t, func() { + key := "testRLockBeforeLock" + array := garray.New() + go func() { + gmlock.RLock(key) + array.Append(1) + time.Sleep(50 * time.Millisecond) + array.Append(1) + gmlock.RUnlock(key) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.Lock(key) + array.Append(1) + gmlock.Unlock(key) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(80 * time.Millisecond) + gtest.Assert(array.Len(), 3) + }) + + //Lock before RLock + gtest.Case(t, func() { + key := "testLockBeforeRLock" + array := garray.New() + go func() { + gmlock.Lock(key) + array.Append(1) + time.Sleep(100 * time.Millisecond) + gmlock.Unlock(key) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.RLock(key) + array.Append(1) + gmlock.RUnlock(key) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(120 * time.Millisecond) + gtest.Assert(array.Len(), 2) + }) + + //Lock before RLocks + gtest.Case(t, func() { + key := "testLockBeforeRLocks" + array := garray.New() + go func() { + gmlock.Lock(key) + array.Append(1) + time.Sleep(100 * time.Millisecond) + gmlock.Unlock(key) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.RLock(key) + array.Append(1) + time.Sleep(200 * time.Millisecond) + gmlock.RUnlock(key) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.RLock(key) + array.Append(1) + time.Sleep(200 * time.Millisecond) + gmlock.RUnlock(key) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(120 * time.Millisecond) + gtest.Assert(array.Len(), 3) + }) } -func TestLocker_RLock2(t *testing.T) { - gtest.Case(t, func() { - key := "test200" - array := garray.New() - go func() { - gmlock.Lock(key) - array.Append(1) - time.Sleep(100*time.Millisecond) - gmlock.Unlock(key) - }() - go func() { - time.Sleep(10*time.Millisecond) - gmlock.RLock(key) - array.Append(1) - gmlock.RUnlock(key) - }() +func Test_Locker_TryRLock(t *testing.T) { + //Lock before TryRLock + gtest.Case(t, func() { + key := "testLockBeforeTryRLock" + array := garray.New() + go func() { + gmlock.Lock(key) + array.Append(1) + time.Sleep(100 * time.Millisecond) + gmlock.Unlock(key) + }() + go func() { + time.Sleep(10 * time.Millisecond) + if gmlock.TryRLock(key) { + array.Append(1) + gmlock.RUnlock(key) + } + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(120 * time.Millisecond) + gtest.Assert(array.Len(), 1) + }) - time.Sleep(20*time.Millisecond) - gtest.Assert(array.Len(), 1) - time.Sleep(120*time.Millisecond) - gtest.Assert(array.Len(), 2) - }) -} \ No newline at end of file + //Lock before TryRLocks + gtest.Case(t, func() { + key := "testLockBeforeTryRLocks" + array := garray.New() + go func() { + gmlock.Lock(key) + array.Append(1) + time.Sleep(100 * time.Millisecond) + gmlock.Unlock(key) + }() + go func() { + time.Sleep(10 * time.Millisecond) + if gmlock.TryRLock(key) { + array.Append(1) + gmlock.RUnlock(key) + } + }() + go func() { + time.Sleep(150 * time.Millisecond) + if gmlock.TryRLock(key) { + array.Append(1) + gmlock.RUnlock(key) + } + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(150 * time.Millisecond) + gtest.Assert(array.Len(), 2) + }) +} + +func Test_Locker_RLockFunc(t *testing.T) { + //RLockFunc before Lock + gtest.Case(t, func() { + key := "testRLockFuncBeforeLock" + array := garray.New() + go func() { + gmlock.RLockFunc(key, func() { + array.Append(1) + time.Sleep(50 * time.Millisecond) + array.Append(1) + }) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.Lock(key) + array.Append(1) + gmlock.Unlock(key) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(80 * time.Millisecond) + gtest.Assert(array.Len(), 3) + }) + + //Lock before RLockFunc + gtest.Case(t, func() { + key := "testLockBeforeRLockFunc" + array := garray.New() + go func() { + gmlock.Lock(key) + array.Append(1) + time.Sleep(100 * time.Millisecond) + gmlock.Unlock(key) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.RLockFunc(key, func() { + array.Append(1) + }) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(120 * time.Millisecond) + gtest.Assert(array.Len(), 2) + }) + + //Lock before RLockFuncs + gtest.Case(t, func() { + key := "testLockBeforeRLockFuncs" + array := garray.New() + go func() { + gmlock.Lock(key) + array.Append(1) + time.Sleep(100 * time.Millisecond) + gmlock.Unlock(key) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.RLockFunc(key, func() { + array.Append(1) + time.Sleep(200 * time.Millisecond) + }) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.RLockFunc(key, func() { + array.Append(1) + time.Sleep(200 * time.Millisecond) + }) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(120 * time.Millisecond) + gtest.Assert(array.Len(), 3) + }) +} + +func Test_Locker_TryRLockFunc(t *testing.T) { + //Lock before TryRLockFunc + gtest.Case(t, func() { + key := "testLockBeforeTryRLockFunc" + array := garray.New() + go func() { + gmlock.Lock(key) + array.Append(1) + time.Sleep(100 * time.Millisecond) + gmlock.Unlock(key) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.TryRLockFunc(key, func() { + array.Append(1) + }) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(120 * time.Millisecond) + gtest.Assert(array.Len(), 1) + }) + + //Lock before TryRLockFuncs + gtest.Case(t, func() { + key := "testLockBeforeTryRLockFuncs" + array := garray.New() + go func() { + gmlock.Lock(key) + array.Append(1) + time.Sleep(100 * time.Millisecond) + gmlock.Unlock(key) + }() + go func() { + time.Sleep(10 * time.Millisecond) + gmlock.TryRLockFunc(key, func() { + array.Append(1) + }) + }() + go func() { + time.Sleep(150 * time.Millisecond) + gmlock.TryRLockFunc(key, func() { + array.Append(1) + }) + }() + time.Sleep(20 * time.Millisecond) + gtest.Assert(array.Len(), 1) + time.Sleep(150 * time.Millisecond) + gtest.Assert(array.Len(), 2) + }) +}