diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..9414382 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1 @@ +Dockerfile diff --git a/test/Makefile b/test/Makefile index dfe0b7b..911a799 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,11 +1,17 @@ #!/usr/bin/env make +TEST_IMAGE = "reaper/test" +CONFIG_TEST_IMAGE = "reaper/config-test" + all: tests test: tests tests: - (go build testpid1.go; docker build -t reaper/test .; ./runtests.sh) - - - + (go build testpid1.go; \ + cp docker-files/no-config/Dockerfile .; \ + docker build -t $(TEST_IMAGE) .; \ + ./runtests.sh; \ + cp docker-files/json-config/Dockerfile .; \ + docker build -t $(CONFIG_TEST_IMAGE) .; \ + ./runtests.sh "$(CONFIG_TEST_IMAGE)" ) diff --git a/test/config/reaper.json b/test/config/reaper.json new file mode 100644 index 0000000..829627d --- /dev/null +++ b/test/config/reaper.json @@ -0,0 +1,4 @@ +{ + "Pid": 0, + "Options": 0 +} diff --git a/test/Dockerfile b/test/docker-files/no-config/Dockerfile similarity index 100% rename from test/Dockerfile rename to test/docker-files/no-config/Dockerfile diff --git a/test/runtests.sh b/test/runtests.sh index 6de864a..64a8b51 100755 --- a/test/runtests.sh +++ b/test/runtests.sh @@ -4,6 +4,8 @@ readonly MAX_SLEEP_TIME=$((5 + 2)) readonly IMAGE="reaper/test" +logfile="/tmp/reaper_test.log" + function get_sleepers() { ps -ef -p $1 | grep sleep | grep -v grep @@ -32,14 +34,24 @@ function check_orphans() { function terminate_container() { + docker logs "$1" > "$logfile" + echo " - Container logs saved to $logfile" + echo " - Terminated container $(docker rm -f "$1")" } # End of function terminate_container. function run_tests() { - echo " - Starting docker container running image $IMAGE ..." - local elcid=$(docker run -dit $IMAGE) + local image=${1:-"${IMAGE}"} + + logfile="/tmp/$(echo ${image} | sed 's#/#_#g').log" + + echo " - Removing any existing log file $logfile ... " + rm -f "$logfile" + + echo " - Starting docker container running image ${image} ..." + local elcid=$(docker run -dit "${image}") echo " - Docker container name=$elcid" local pid1=$(docker inspect --format '{{.State.Pid}}' $elcid) diff --git a/test/testpid1.go b/test/testpid1.go index 07bf12a..e1f3de5 100644 --- a/test/testpid1.go +++ b/test/testpid1.go @@ -1,17 +1,53 @@ package main +import "encoding/json" import "fmt" import "os" import "os/signal" import "os/exec" import "path/filepath" import "syscall" +import "time" import reaper "github.com/ramr/go-reaper" +const NWORKERS = 3 +const REAPER_JSON_CONFIG = "/reaper/config/reaper.json" -const NWORKERS=3 +func sleeper_test(set_proc_attributes bool) { + fmt.Printf(" - Set process attributes: %+v\n", set_proc_attributes) + cmd := exec.Command("sleep", "1") + if set_proc_attributes { + cmd.SysProcAttr = &syscall.SysProcAttr{ + Setpgid: true, + Pgid: 0, + } + } + + err := cmd.Start() + if err != nil { + fmt.Printf(" - Error starting sleep command: %s\n", err) + return + } + + fmt.Printf("Set proc attributes: %+v\n", set_proc_attributes) + + // Sleep for a wee bit longer to allow the reaper to reap the + // command on a slow system. + time.Sleep(4 * time.Second) + + err = cmd.Wait() + if err != nil { + if set_proc_attributes { + fmt.Printf(" - Error waiting for command: %s\n", + err) + } else { + fmt.Printf(" - Expected wait failure: %s\n", err) + } + } + +} /* End of function sleeper_test. */ func start_workers() { // Starts up workers - which in turn start up kids that get @@ -28,34 +64,58 @@ func start_workers() { fmt.Printf(" - Error getting script - %s\n", scriptFile) return } - + var args = fmt.Sprintf("%d", NWORKERS) var cmd = exec.Command(script, args) cmd.Start() fmt.Printf(" - Started worker: %s %s\n", script, args) -} /* End of function start_workers. */ +} /* End of function start_workers. */ +func main() { + sig := make(chan os.Signal, 1) + signal.Notify(sig, syscall.SIGUSR1) + + useConfig := false + config := reaper.Config{} + + configFile, err := os.Open(REAPER_JSON_CONFIG) + if err == nil { + decoder := json.NewDecoder(configFile) + err = decoder.Decode(&config) + if err == nil { + useConfig = true + } else { + fmt.Printf(" - Error: Invalid json config: %s", err) + fmt.Printf(" - Using defaults ... ") + } + } + /* Start the grim reaper ... */ + if useConfig { + go reaper.Start(config) -func main() { - sig := make(chan os.Signal, 1) - signal.Notify(sig, syscall.SIGUSR1) + /* Run the sleeper test setting the process attributes. */ + go sleeper_test(true) - /* Start the grim reaper ... */ - go reaper.Reap() + /* And run test without setting process attributes. */ + go sleeper_test(false) - /* Start the initial set of workers ... */ - start_workers() + } else { + go reaper.Reap() + } - for { - select { - case <-sig: - fmt.Println(" - Got SIGUSR1, starting more workers ...") + /* Start the initial set of workers ... */ start_workers() - } - } /* End of while doomsday ... */ + for { + select { + case <-sig: + fmt.Println(" - Got SIGUSR1, adding workers ...") + start_workers() + } + + } /* End of while doomsday ... */ -} /* End of function main. */ +} /* End of function main. */