package pidlock import ( "os" "path/filepath" "strconv" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestAcquireAndRelease(t *testing.T) { tmpDir := t.TempDir() // Acquire lock lock, err := Acquire(tmpDir) require.NoError(t, err) require.NotNil(t, lock) // Verify PID file exists with our PID data, err := os.ReadFile(filepath.Join(tmpDir, "vaultik.pid")) require.NoError(t, err) pid, err := strconv.Atoi(string(data)) require.NoError(t, err) assert.Equal(t, os.Getpid(), pid) // Release lock err = lock.Release() require.NoError(t, err) // Verify PID file is gone _, err = os.Stat(filepath.Join(tmpDir, "vaultik.pid")) assert.True(t, os.IsNotExist(err)) } func TestAcquireBlocksSecondInstance(t *testing.T) { tmpDir := t.TempDir() // Acquire first lock lock1, err := Acquire(tmpDir) require.NoError(t, err) require.NotNil(t, lock1) defer func() { _ = lock1.Release() }() // Try to acquire second lock - should fail lock2, err := Acquire(tmpDir) assert.ErrorIs(t, err, ErrAlreadyRunning) assert.Nil(t, lock2) } func TestAcquireWithStaleLock(t *testing.T) { tmpDir := t.TempDir() // Write a stale PID file (PID that doesn't exist) stalePID := 999999999 // Unlikely to be a real process pidPath := filepath.Join(tmpDir, "vaultik.pid") err := os.WriteFile(pidPath, []byte(strconv.Itoa(stalePID)), 0600) require.NoError(t, err) // Should be able to acquire lock (stale lock is cleaned up) lock, err := Acquire(tmpDir) require.NoError(t, err) require.NotNil(t, lock) defer func() { _ = lock.Release() }() // Verify our PID is now in the file data, err := os.ReadFile(pidPath) require.NoError(t, err) pid, err := strconv.Atoi(string(data)) require.NoError(t, err) assert.Equal(t, os.Getpid(), pid) } func TestReleaseIsIdempotent(t *testing.T) { tmpDir := t.TempDir() lock, err := Acquire(tmpDir) require.NoError(t, err) // Release multiple times - should not error err = lock.Release() require.NoError(t, err) err = lock.Release() require.NoError(t, err) } func TestReleaseNilLock(t *testing.T) { var lock *Lock err := lock.Release() assert.NoError(t, err) } func TestAcquireCreatesDirectory(t *testing.T) { tmpDir := t.TempDir() nestedDir := filepath.Join(tmpDir, "nested", "dir") lock, err := Acquire(nestedDir) require.NoError(t, err) require.NotNil(t, lock) defer func() { _ = lock.Release() }() // Verify directory was created info, err := os.Stat(nestedDir) require.NoError(t, err) assert.True(t, info.IsDir()) }