112 lines
2.1 KiB
Go
112 lines
2.1 KiB
Go
package flock
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestLock_basic(t *testing.T) {
|
|
const path = "/tmp/fsutil-test-lock"
|
|
|
|
f, err := Lock(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// locked is closed once the goroutine acquires the lock.
|
|
locked := make(chan struct{})
|
|
go func() {
|
|
f2, err := Lock(path) // blocks until f is unlocked
|
|
if err != nil {
|
|
t.Error(err)
|
|
return
|
|
}
|
|
close(locked)
|
|
Unlock(f2)
|
|
}()
|
|
|
|
// Goroutine should be blocked while we hold the lock.
|
|
select {
|
|
case <-locked:
|
|
t.Fatal("goroutine acquired lock while we hold it")
|
|
case <-time.After(50 * time.Millisecond):
|
|
}
|
|
|
|
Unlock(f)
|
|
|
|
// Now the goroutine should unblock and acquire the lock.
|
|
select {
|
|
case <-locked:
|
|
case <-time.After(time.Second):
|
|
t.Fatal("goroutine never acquired lock after release")
|
|
}
|
|
}
|
|
|
|
func TestLock_badPath(t *testing.T) {
|
|
_, err := Lock("./dne/file.lock")
|
|
if err == nil {
|
|
t.Fatal("expected error for bad path")
|
|
}
|
|
}
|
|
|
|
func TestTryLock(t *testing.T) {
|
|
const path = "/tmp/fsutil-test-lock"
|
|
|
|
f, err := TryLock(path)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer Unlock(f)
|
|
|
|
// While f holds the lock, TryLock should return ErrLocked.
|
|
_, err = TryLock(path)
|
|
if !errors.Is(err, ErrLocked) {
|
|
t.Fatalf("expected ErrLocked, got %v", err)
|
|
}
|
|
|
|
// After unlocking, TryLock should succeed.
|
|
if err := Unlock(f); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
f2, err := TryLock(path)
|
|
if err != nil {
|
|
t.Fatalf("expected lock after unlock, got %v", err)
|
|
}
|
|
Unlock(f2)
|
|
}
|
|
|
|
func TestTryLockFile(t *testing.T) {
|
|
const path = "/tmp/fsutil-test-lockfile"
|
|
|
|
f, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0600)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer f.Close()
|
|
|
|
if err := TryLockFile(f); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
f2, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR, 0600)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer f2.Close()
|
|
|
|
if err := TryLockFile(f2); !errors.Is(err, ErrLocked) {
|
|
t.Fatalf("expected ErrLocked, got %v", err)
|
|
}
|
|
|
|
if err := Unlock(f); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := TryLockFile(f2); err != nil {
|
|
t.Fatalf("expected lock after unlock, got %v", err)
|
|
}
|
|
}
|