Files
dnshelper/lockfile/lockfile_test.go
T
dyoder f0ce5a4042 feat: Implement platform-specific hosts file path retrieval
- Created a new `platform` package to handle OS-specific hosts file paths.
- Added implementations for macOS, Linux, and Windows to retrieve the hosts file path.
- Introduced tests for the `GetHostsFilePath` function to ensure correct behavior across platforms.

feat: Add DNS resolver for IP lookups

- Implemented a `resolver` package for performing DNS lookups.
- Created a `DNSResolver` struct with a `LookupIP` method to handle A-record lookups and CNAME resolution.
- Added comprehensive tests for various DNS scenarios, including CNAME chains and error handling.

chore: Refactor project structure and update dependencies

- Restructured the project to follow Go's standard package layout.
- Updated `go.mod` to Go 1.20 and added `golang.org/x/net` dependency.
- Removed old source files and ensured a clean build with all tests passing.
2026-03-03 18:37:02 -05:00

96 lines
2.5 KiB
Go

package lockfile_test
import (
"os"
"path/filepath"
"testing"
"time"
"dns-helper/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, ".dns-helper.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, ".dns-helper.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, ".dns-helper.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)
}
}