96 lines
2.5 KiB
Go
96 lines
2.5 KiB
Go
package lockfile_test
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"ekdns/lockfile"
|
|
)
|
|
|
|
// T006-1: Acquire succeeds and lock file exists on disk.
|
|
func TestAcquireSucceeds(t *testing.T) {
|
|
dir := t.TempDir()
|
|
lock, err := lockfile.Acquire(dir)
|
|
if err != nil {
|
|
t.Fatalf("Acquire returned unexpected error: %v", err)
|
|
}
|
|
defer lock.Release()
|
|
|
|
lockPath := filepath.Join(dir, ".ekdns.lock")
|
|
if _, err := os.Stat(lockPath); os.IsNotExist(err) {
|
|
t.Error("lock file does not exist after Acquire")
|
|
}
|
|
}
|
|
|
|
// T006-2: Release deletes the lock file.
|
|
func TestReleaseDeletesLockFile(t *testing.T) {
|
|
dir := t.TempDir()
|
|
lock, err := lockfile.Acquire(dir)
|
|
if err != nil {
|
|
t.Fatalf("Acquire returned unexpected error: %v", err)
|
|
}
|
|
|
|
if err := lock.Release(); err != nil {
|
|
t.Fatalf("Release returned unexpected error: %v", err)
|
|
}
|
|
|
|
lockPath := filepath.Join(dir, ".ekdns.lock")
|
|
if _, err := os.Stat(lockPath); !os.IsNotExist(err) {
|
|
t.Error("lock file still exists after Release")
|
|
}
|
|
}
|
|
|
|
// T006-3: Double acquire fails with timeout error.
|
|
func TestDoubleAcquireFails(t *testing.T) {
|
|
dir := t.TempDir()
|
|
lock, err := lockfile.Acquire(dir)
|
|
if err != nil {
|
|
t.Fatalf("first Acquire returned unexpected error: %v", err)
|
|
}
|
|
defer lock.Release()
|
|
|
|
_, err = lockfile.Acquire(dir)
|
|
if err == nil {
|
|
t.Fatal("second Acquire expected to fail, but it succeeded")
|
|
}
|
|
}
|
|
|
|
// T006-4: Stale lock file (>2 minutes old) is broken and Acquire succeeds.
|
|
func TestStaleLockBroken(t *testing.T) {
|
|
dir := t.TempDir()
|
|
lockPath := filepath.Join(dir, ".ekdns.lock")
|
|
|
|
// Manually create a lock file with a stale modification time.
|
|
if err := os.WriteFile(lockPath, []byte("99999\n"), 0644); err != nil {
|
|
t.Fatalf("failed to create stale lock file: %v", err)
|
|
}
|
|
staleTime := time.Now().Add(-3 * time.Minute)
|
|
if err := os.Chtimes(lockPath, staleTime, staleTime); err != nil {
|
|
t.Fatalf("failed to set stale mtime: %v", err)
|
|
}
|
|
|
|
lock, err := lockfile.Acquire(dir)
|
|
if err != nil {
|
|
t.Fatalf("Acquire over stale lock returned unexpected error: %v", err)
|
|
}
|
|
lock.Release()
|
|
}
|
|
|
|
// T006-5: Release is idempotent — calling twice does not return an error.
|
|
func TestReleaseIsIdempotent(t *testing.T) {
|
|
dir := t.TempDir()
|
|
lock, err := lockfile.Acquire(dir)
|
|
if err != nil {
|
|
t.Fatalf("Acquire returned unexpected error: %v", err)
|
|
}
|
|
|
|
if err := lock.Release(); err != nil {
|
|
t.Fatalf("first Release returned unexpected error: %v", err)
|
|
}
|
|
if err := lock.Release(); err != nil {
|
|
t.Fatalf("second Release returned unexpected error: %v", err)
|
|
}
|
|
}
|