mirror of
https://github.com/taigrr/bitcask
synced 2025-01-18 04:03:17 -08:00
* Refactored Save function for config * Refactored Save function for config * 'make bench' excluded the effect of test on the results
122 lines
2.7 KiB
Go
122 lines
2.7 KiB
Go
package flock
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
// WARNING : this test will delete the file located at "testLockPath". Choose an adequate temporary file name.
|
|
const testLockPath = "/tmp/bitcask_unit_test_lock" // file path to use for the lock
|
|
|
|
func TestTryLock(t *testing.T) {
|
|
// test that basic locking functionalities are consistent
|
|
|
|
// make sure there is no present lock when starting this test
|
|
os.Remove(testLockPath)
|
|
|
|
assert := assert.New(t)
|
|
|
|
lock1 := New(testLockPath)
|
|
lock2 := New(testLockPath)
|
|
|
|
// 1- take the first lock
|
|
locked1, err := lock1.TryLock()
|
|
assert.True(locked1)
|
|
assert.NoError(err)
|
|
|
|
// 2- check that the second lock cannot acquire the lock
|
|
locked2, err := lock2.TryLock()
|
|
assert.False(locked2)
|
|
assert.Error(err)
|
|
|
|
// 3- release the first lock
|
|
err = lock1.Unlock()
|
|
assert.NoError(err)
|
|
|
|
// 4- check that the second lock can acquire and then release the lock without error
|
|
locked2, err = lock2.TryLock()
|
|
assert.True(locked2)
|
|
assert.NoError(err)
|
|
|
|
err = lock2.Unlock()
|
|
assert.NoError(err)
|
|
}
|
|
|
|
func TestLock(t *testing.T) {
|
|
assert := assert.New(t)
|
|
|
|
// make sure there is no present lock when starting this test
|
|
os.Remove(testLockPath)
|
|
|
|
syncChan := make(chan bool)
|
|
|
|
// main goroutine: take lock on testPath
|
|
lock := New(testLockPath)
|
|
|
|
err := lock.Lock()
|
|
assert.NoError(err)
|
|
|
|
go func() {
|
|
// sub routine:
|
|
lock := New(testLockPath)
|
|
|
|
// before entering the block '.Lock()' call, signal we are about to do it
|
|
// see below : the main goroutine will wait for a small delay before releasing the lock
|
|
syncChan <- true
|
|
// '.Lock()' should ultimately return without error :
|
|
err := lock.Lock()
|
|
assert.NoError(err)
|
|
|
|
err = lock.Unlock()
|
|
assert.NoError(err)
|
|
|
|
close(syncChan)
|
|
}()
|
|
|
|
// wait for the "ready" signal from the sub routine,
|
|
<-syncChan
|
|
|
|
// after that signal wait for a small delay before releasing the lock
|
|
<-time.After(100 * time.Microsecond)
|
|
err = lock.Unlock()
|
|
assert.NoError(err)
|
|
|
|
// wait for the sub routine to finish
|
|
<-syncChan
|
|
}
|
|
|
|
func TestErrorConditions(t *testing.T) {
|
|
// error conditions implemented in this version :
|
|
// - you can't release a lock you do not hold
|
|
// - you can't lock twice the same lock
|
|
|
|
// -- setup
|
|
assert := assert.New(t)
|
|
|
|
// make sure there is no present lock when starting this test
|
|
os.Remove(testLockPath)
|
|
|
|
lock := New(testLockPath)
|
|
|
|
// -- run tests :
|
|
|
|
err := lock.Unlock()
|
|
assert.Error(err, "you can't release a lock you do not hold")
|
|
|
|
// take the lock once:
|
|
lock.TryLock()
|
|
|
|
locked, err := lock.TryLock()
|
|
assert.False(locked)
|
|
assert.Error(err, "you can't lock twice the same lock (using .TryLock())")
|
|
|
|
err = lock.Lock()
|
|
assert.Error(err, "you can't lock twice the same lock (using .Lock())")
|
|
|
|
// -- teardown
|
|
lock.Unlock()
|
|
}
|