Add Valid command to spawner and make executors check when opening
This commit is contained in:
parent
f36685c7d2
commit
2321bddf2e
|
@ -89,7 +89,7 @@ func (e *BasicExecutor) Open(id string) error {
|
|||
|
||||
// Setup the executor.
|
||||
e.spawn = &spawn
|
||||
return nil
|
||||
return e.spawn.Valid()
|
||||
}
|
||||
|
||||
func (e *BasicExecutor) Wait() error {
|
||||
|
|
|
@ -95,8 +95,7 @@ func (e *LinuxExecutor) Open(id string) error {
|
|||
e.groups = execID.Groups
|
||||
e.spawn = execID.Spawn
|
||||
e.taskDir = execID.TaskDir
|
||||
|
||||
return nil
|
||||
return e.spawn.Valid()
|
||||
}
|
||||
|
||||
func (e *LinuxExecutor) ID() (string, error) {
|
||||
|
|
|
@ -229,3 +229,33 @@ func Executor_Open(t *testing.T, command buildExecCommand, newExecutor func() Ex
|
|||
log.Panicf("Command output incorrectly: want %v; got %v", expected, act)
|
||||
}
|
||||
}
|
||||
|
||||
func Executor_Open_Invalid(t *testing.T, command buildExecCommand, newExecutor func() Executor) {
|
||||
task, alloc := mockAllocDir(t)
|
||||
e := command("echo", "foo")
|
||||
|
||||
if err := e.Limit(constraint); err != nil {
|
||||
log.Panicf("Limit() failed: %v", err)
|
||||
}
|
||||
|
||||
if err := e.ConfigureTaskDir(task, alloc); err != nil {
|
||||
log.Panicf("ConfigureTaskDir(%v, %v) failed: %v", task, alloc, err)
|
||||
}
|
||||
|
||||
if err := e.Start(); err != nil {
|
||||
log.Panicf("Start() failed: %v", err)
|
||||
}
|
||||
|
||||
id, err := e.ID()
|
||||
if err != nil {
|
||||
log.Panicf("ID() failed: %v", err)
|
||||
}
|
||||
|
||||
// Destroy the allocdir which removes the exit code.
|
||||
alloc.Destroy()
|
||||
|
||||
e2 := newExecutor()
|
||||
if err := e2.Open(id); err == nil {
|
||||
log.Panicf("Open(%v) should have failed", id)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -285,3 +285,18 @@ func (s *Spawner) readExitCode() (int, error) {
|
|||
|
||||
return exitStatus.ExitCode, nil
|
||||
}
|
||||
|
||||
// Valid checks that the state of the Spawner is valid and that a subsequent
|
||||
// Wait could be called. This is useful to call when reopening a Spawner
|
||||
// throught client restarts. If Valid a nil error is returned.
|
||||
func (s *Spawner) Valid() error {
|
||||
if s.Alive() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err := s.readExitCode(); err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("Spawner not alive and exit code not written")
|
||||
}
|
||||
|
|
|
@ -2,11 +2,17 @@
|
|||
|
||||
package spawn
|
||||
|
||||
import "syscall"
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (s *Spawner) Alive() bool {
|
||||
if s.spawn == nil {
|
||||
return false
|
||||
var err error
|
||||
if s.spawn, err = os.FindProcess(s.SpawnPid); err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
err := s.spawn.Signal(syscall.Signal(0))
|
||||
|
|
|
@ -298,3 +298,71 @@ func TestSpawn_DeadSpawnDaemon_NonParent(t *testing.T) {
|
|||
t.Fatalf("Wait() should have failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpawn_Valid_TaskRunning(t *testing.T) {
|
||||
f, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("TempFile() failed")
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
spawn := NewSpawner(f.Name())
|
||||
spawn.SetCommand(exec.Command("sleep", "2"))
|
||||
if err := spawn.Spawn(nil); err != nil {
|
||||
t.Fatalf("Spawn() failed %v", err)
|
||||
}
|
||||
|
||||
if err := spawn.Valid(); err != nil {
|
||||
t.Fatalf("Valid() failed: %v", err)
|
||||
}
|
||||
|
||||
if _, err := spawn.Wait(); err != nil {
|
||||
t.Fatalf("Wait() failed %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpawn_Valid_TaskExit_ExitCode(t *testing.T) {
|
||||
f, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("TempFile() failed")
|
||||
}
|
||||
defer os.Remove(f.Name())
|
||||
|
||||
spawn := NewSpawner(f.Name())
|
||||
spawn.SetCommand(exec.Command("echo", "foo"))
|
||||
if err := spawn.Spawn(nil); err != nil {
|
||||
t.Fatalf("Spawn() failed %v", err)
|
||||
}
|
||||
|
||||
if _, err := spawn.Wait(); err != nil {
|
||||
t.Fatalf("Wait() failed %v", err)
|
||||
}
|
||||
|
||||
if err := spawn.Valid(); err != nil {
|
||||
t.Fatalf("Valid() failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSpawn_Valid_TaskExit_NoExitCode(t *testing.T) {
|
||||
f, err := ioutil.TempFile("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("TempFile() failed")
|
||||
}
|
||||
|
||||
spawn := NewSpawner(f.Name())
|
||||
spawn.SetCommand(exec.Command("echo", "foo"))
|
||||
if err := spawn.Spawn(nil); err != nil {
|
||||
t.Fatalf("Spawn() failed %v", err)
|
||||
}
|
||||
|
||||
if _, err := spawn.Wait(); err != nil {
|
||||
t.Fatalf("Wait() failed %v", err)
|
||||
}
|
||||
|
||||
// Delete the file so that it can't find the exit code.
|
||||
os.Remove(f.Name())
|
||||
|
||||
if err := spawn.Valid(); err == nil {
|
||||
t.Fatalf("Valid() should have failed")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue