Files
woodpecker/test/integration/utils/service.go
2025-12-19 16:39:21 +01:00

71 lines
1.3 KiB
Go

package utils
import (
"fmt"
"os"
"os/exec"
"time"
)
type Service struct {
cmd *exec.Cmd
env map[string]string
}
func NewService(cmdName string, args ...string) *Service {
cmd := exec.Command(cmdName, args...)
return &Service{
cmd: cmd,
env: make(map[string]string),
}
}
func (s *Service) Start() error {
// Inherit parent environment
env := os.Environ()
for key, value := range s.env {
env = append(env, fmt.Sprintf("%s=%s", key, value))
}
s.cmd.Env = env
// Capture output for debugging
s.cmd.Stdout = os.Stdout
s.cmd.Stderr = os.Stderr
return s.cmd.Start()
}
func (s *Service) Stop() error {
if s.cmd == nil || s.cmd.Process == nil {
return fmt.Errorf("process not found / running")
}
// Try graceful shutdown first
if err := s.cmd.Process.Signal(os.Interrupt); err != nil {
// If interrupt fails, force kill
return s.cmd.Process.Kill()
}
// Wait for graceful shutdown with timeout
done := make(chan error, 1)
go func() {
done <- s.cmd.Wait()
}()
select {
case <-time.After(5 * time.Second):
// Force kill after timeout
return s.cmd.Process.Kill()
case err := <-done:
return err
}
}
func (s *Service) SetEnv(key, value string) *Service {
s.env[key] = value
return s
}
func (s *Service) WorkDir(workDir string) *Service {
s.cmd.Dir = workDir
return s
}