internal/agent/statelock/statelock_test.go
Ref: Size: 2.7 KiB History
package statelock
import (
"fmt"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// flock ownership belongs to the open file description, not the process, so two
// Acquires in this one test binary conflict exactly as two agents would.
func TestAcquireClaimsTheDirectoryAndNamesTheHolder(t *testing.T) {
dir := t.TempDir()
lk, err := Acquire(dir)
require.NoError(t, err)
t.Cleanup(func() { lk.Release() }) //nolint:errcheck
raw, err := os.ReadFile(filepath.Join(dir, lockName))
require.NoError(t, err)
assert.Equal(t, fmt.Sprintf("%d\n", os.Getpid()), string(raw),
"the lock file names the process holding it")
}
func TestASecondAgentIsRefusedAndToldWhichProcessHasIt(t *testing.T) {
dir := t.TempDir()
lk, err := Acquire(dir)
require.NoError(t, err)
t.Cleanup(func() { lk.Release() }) //nolint:errcheck
second, err := Acquire(dir)
assert.Nil(t, second)
require.Error(t, err)
assert.Equal(t, fmt.Sprintf("an agent is already running with this identity (pid %d)", os.Getpid()), err.Error())
}
func TestARefusalWithNoReadablePidStillRefuses(t *testing.T) {
dir := t.TempDir()
lk, err := Acquire(dir)
require.NoError(t, err)
t.Cleanup(func() { lk.Release() }) //nolint:errcheck
// An agent old enough to predate the pid, or one killed between taking the
// lock and writing it. The kernel still says the lock is held, which is the
// answer that counts; the message simply names nobody.
require.NoError(t, os.WriteFile(filepath.Join(dir, lockName), []byte("not a pid\n"), mode))
_, err = Acquire(dir)
require.Error(t, err)
assert.Equal(t, "an agent is already running with this identity", err.Error())
}
func TestReleasingLetsTheNextAgentIn(t *testing.T) {
dir := t.TempDir()
lk, err := Acquire(dir)
require.NoError(t, err)
require.NoError(t, lk.Release())
// An agent that has exited leaves nothing behind but a file: a restart, or
// the re-exec of a self-upgrade, must not be refused by its own predecessor.
next, err := Acquire(dir)
require.NoError(t, err)
assert.NoError(t, next.Release())
}
func TestTwoStateDirsAreTwoIdentities(t *testing.T) {
// One machine may legitimately run several agents, each enrolled separately.
// The lock is per state directory precisely so that stays possible.
a, err := Acquire(t.TempDir())
require.NoError(t, err)
t.Cleanup(func() { a.Release() }) //nolint:errcheck
b, err := Acquire(t.TempDir())
require.NoError(t, err)
assert.NoError(t, b.Release())
}
func TestAcquireFailsWhenTheDirectoryIsNotThere(t *testing.T) {
_, err := Acquire(filepath.Join(t.TempDir(), "no-such-dir"))
require.Error(t, err)
assert.Contains(t, err.Error(), "open agent lock")
}