a73x

internal/agent/pidfile/pidfile_test.go

Ref:   Size: 2.6 KiB   History

package pidfile

import (
	"os"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func tmpPath(t *testing.T) string {
	t.Helper()
	return filepath.Join(t.TempDir(), "vm.pid")
}

func TestOwnedReturnsAPidWrittenInThisBoot(t *testing.T) {
	path := tmpPath(t)
	require.NoError(t, Write(path, 4242, "boot-a"))

	assert.Equal(t, 4242, Owned(path, "boot-a"))
}

func TestOwnedRefusesAPidFromAnEarlierBoot(t *testing.T) {
	path := tmpPath(t)
	require.NoError(t, Write(path, 4242, "boot-a"))

	// The state directory survives a reboot and pids are recycled, so this
	// number now names whatever happens to hold it. Signalling it would kill a
	// stranger; reporting it running would leave a dead guest looking alive.
	assert.Zero(t, Owned(path, "boot-b"))
}

func TestOwnedAcceptsAPidfileWithNoBootID(t *testing.T) {
	path := tmpPath(t)
	// What the agent being replaced during a rolling upgrade left behind.
	require.NoError(t, os.WriteFile(path, []byte("4242\n"), mode))

	// Refusing here would read every live guest as lost and boot a second
	// hypervisor onto its disk — worse than the recycled-pid window this
	// format closes, and the reason the answer is "ours".
	assert.Equal(t, 4242, Owned(path, "boot-a"))
}

func TestOwnedIsZeroWhenThereIsNothingToSignal(t *testing.T) {
	for name, write := range map[string]func(path string){
		"no file":     func(string) {},
		"empty":       func(p string) { require.NoError(t, os.WriteFile(p, nil, mode)) },
		"not a pid":   func(p string) { require.NoError(t, os.WriteFile(p, []byte("fnord\nboot-a\n"), mode)) },
		"blank first": func(p string) { require.NoError(t, os.WriteFile(p, []byte("\nboot-a\n"), mode)) },
	} {
		t.Run(name, func(t *testing.T) {
			path := tmpPath(t)
			write(path)

			// Zero is "signal nothing", and every caller reads it that way.
			assert.Zero(t, Owned(path, "boot-a"))
		})
	}
}

func TestWriteIsReadBackByOwned(t *testing.T) {
	path := tmpPath(t)
	require.NoError(t, Write(path, 1, ""))

	// An agent whose host cannot report a boot id (hostinfo is best-effort and
	// answers "" on failure) writes an empty one, which reads back as the
	// legacy shape — degraded to the old behaviour, never to a refusal.
	assert.Equal(t, 1, Owned(path, "boot-a"))
}

func TestWriteReportsAPathItCannotUse(t *testing.T) {
	err := Write(filepath.Join(t.TempDir(), "no-such-dir", "vm.pid"), 1, "boot-a")

	// Boot treats this as fatal and kills the process it can no longer track,
	// so the error has to arrive rather than being swallowed.
	require.Error(t, err)
	assert.Contains(t, err.Error(), "write pidfile")
}