mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-19 19:01:42 +00:00
118 lines
2.7 KiB
Go
118 lines
2.7 KiB
Go
package utils
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"os"
|
||
"os/exec"
|
||
"strings"
|
||
"syscall"
|
||
"testing"
|
||
"time"
|
||
|
||
"github.com/stretchr/testify/assert"
|
||
)
|
||
|
||
func TestGeneratePidFile(t *testing.T) {
|
||
|
||
// Simulate a sample process running (e.g cat)
|
||
cmd := exec.Command("cat")
|
||
cmd.Start()
|
||
|
||
err := WritePidFile("utilsunittest", cmd.Process.Pid)
|
||
|
||
assert.NoError(t, err)
|
||
|
||
// Read the PID file and verify contents
|
||
pid, err := ReadPidFile("utilsunittest")
|
||
|
||
assert.NoError(t, err)
|
||
assert.Equal(t, cmd.Process.Pid, pid)
|
||
|
||
// Test attempt to read a PID file that doesn't exist
|
||
_, err = ReadPidFile("nonexistentpidfile")
|
||
assert.Error(t, err)
|
||
|
||
// Cleanup
|
||
err = RemovePidFile("utilsunittest")
|
||
assert.NoError(t, err)
|
||
|
||
// Give some time before killing the process
|
||
//time.Sleep(2 * time.Second)
|
||
|
||
// Simulate process ending
|
||
|
||
}
|
||
|
||
func TestGenerateSocketFile(t *testing.T) {
|
||
|
||
socketPath := fmt.Sprintf("%s/%s", os.TempDir(), "utilsunittest")
|
||
|
||
name, err := GenerateSocketFile(socketPath)
|
||
|
||
assert.NoError(t, err)
|
||
|
||
assert.True(t, strings.HasSuffix(name, "utilsunittest.sock"))
|
||
|
||
// Test empty socket path
|
||
_, err = GenerateSocketFile("")
|
||
|
||
assert.Error(t, err)
|
||
|
||
}
|
||
|
||
func TestExecProcessAndKill(t *testing.T) {
|
||
|
||
// Simulate a sample process running (e.g sleep, 30 secs)
|
||
cmd := exec.Command("sleep", "30")
|
||
|
||
// Detach: new process group, no controlling terminal.
|
||
cmd.SysProcAttr = &syscall.SysProcAttr{
|
||
Setpgid: true, // put child in new process group
|
||
}
|
||
|
||
// Make it fully background-friendly:
|
||
// - close stdio so parent doesn’t block on pipes
|
||
cmd.Stdin = nil
|
||
cmd.Stdout = nil
|
||
cmd.Stderr = nil
|
||
|
||
// Start (non-blocking). If command is missing, error.
|
||
if err := cmd.Start(); err != nil {
|
||
assert.Fail(t, "Failed to start command", err)
|
||
}
|
||
|
||
// IMPORTANT: reap the child to avoid zombies.
|
||
// Since we’re “backgrounding” it, do Wait() in a goroutine.
|
||
go func(c *exec.Cmd) {
|
||
t.Log("Waiting for command to finish...")
|
||
_ = c.Wait() // ignore error; ensures kernel reaps the process
|
||
t.Log("Command finished.")
|
||
}(cmd)
|
||
|
||
err := WritePidFile("utilsunittest", cmd.Process.Pid)
|
||
|
||
log.Print("Started process with PID: ", cmd.Process.Pid)
|
||
|
||
assert.NoError(t, err)
|
||
|
||
// Test PID file removed
|
||
err = WaitForPidFileRemoval("utilsunittest", 100*time.Millisecond)
|
||
assert.Error(t, err) // Should timeout since file should still exist
|
||
|
||
time.Sleep(500 * time.Millisecond)
|
||
|
||
// Kill the process
|
||
err = StopProcess("utilsunittest")
|
||
assert.NoError(t, err)
|
||
|
||
// Test PID file removed
|
||
err = WaitForPidFileRemoval("utilsunittest", 1*time.Second)
|
||
assert.NoError(t, err) // Should timeout since file should still exist
|
||
|
||
// Verify process is killed
|
||
err = cmd.Process.Signal(syscall.Signal(0))
|
||
assert.Error(t, err) // Should return an error since process is killed
|
||
|
||
}
|