diff --git a/src/codex.bash b/src/codex.bash index 91cc1fe..f444bb2 100644 --- a/src/codex.bash +++ b/src/codex.bash @@ -5,11 +5,24 @@ LIB_SRC=${LIB_SRC:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)} source "${LIB_SRC}/config.bash" # shellcheck source=./src/utils.bash source "${LIB_SRC}/utils.bash" +# shellcheck source=./src/procmon.bash +source "${LIB_SRC}/procmon.bash" _cdx_output=$(clh_output_folder "codex") _cdx_logs="${_cdx_output}/logs" _cdx_data="${_cdx_output}/data" -_cdx_binary="${CLH_CODEX_BINARY:-codex}" + +if [ -z "${CODEX_BINARY}" ]; then + run command -v codex + _cdx_binary="${output}" +else + _cdx_binary="${CODEX_BINARY}" +fi + +if [ ! -f "${_cdx_binary}" ]; then + echoerr "Error: no valid Codex binary found" + exit 1 +fi _cdx_base_api_port=8080 _cdx_base_disc_port=8190 @@ -17,6 +30,8 @@ _cdx_base_metrics_port=8290 _cdx_node_start_timeout=30 +declare -A _cdx_pids + cdx_cmdline() { local api_port\ disc_port\ @@ -58,7 +73,7 @@ cdx_cmdline() { # shellcheck disable=SC2140 echo "${cdx_cmd}"\ " --log-file=${_cdx_logs}/codex-${node_index}.log --data-dir=${_cdx_data}/codex-${node_index}"\ -" --api-port=${api_port} --disc-port=${disc_port} --loglevel=INFO" +" --api-port=${api_port} --disc-port=${disc_port} --log-level=INFO" } cdx_get_spr() { @@ -75,20 +90,42 @@ cdx_get_spr() { } cdx_launch_node() { - _check_codex_binary + _cdx_ensure_outputs 0 || return 1 local codex_cmd - codex_cmd=$(cdx_cmdline "$@") + codex_cmd=$(cdx_cmdline "$@") || return 1 ( $codex_cmd pm_job_exit $? )& pm_track_last_job + _cdx_pids[$1]=$! cdx_ensure_ready "$@" } +cdx_destroy_node() { + local node_index="$1" wipe_data="${2:-false}" pid + pid="${_cdx_pids[$node_index]}" + if [ -z "$pid" ]; then + echoerr "Error: no process ID for node $node_index" + return 1 + fi + + # Prevents the whole process group from dying. + pm_stop_tracking "$pid" + pm_kill_rec "$pid" + await "$pid" || return 1 + + unset "_cdx_pids[$node_index]" + + if [ "$wipe_data" = true ]; then + rm -rf "${_cdx_data}/codex-${node_index}" + rm -rf "${_cdx_logs}/codex-${node_index}.log" + fi +} + cdx_ensure_ready() { local node_index="$1" timeout=${2:-$_cdx_node_start_timeout} start="${SECONDS}" while true; do @@ -104,4 +141,10 @@ cdx_ensure_ready() { sleep 0.2 done +} + +_cdx_ensure_outputs() { + local node_index="$1" + mkdir -p "${_cdx_logs}" || return 1 + mkdir -p "${_cdx_data}/codex-${node_index}" || return 1 } \ No newline at end of file diff --git a/src/procmon.bash b/src/procmon.bash index 79f413b..300eb55 100644 --- a/src/procmon.bash +++ b/src/procmon.bash @@ -35,6 +35,11 @@ pm_start() { fi exit_code=$(cat "${_pm_output}/${pid}.pid") + if [ $? -ne 0 ]; then + echoerr "[procmon] ${pid} died with unknown exit code. Aborting." + _pm_halt "halted_no_return" + fi + if [ -z "$exit_code" ]; then echoerr "[procmon] ${pid} died with unknown exit code. Aborting." _pm_halt "halted_no_return" @@ -165,8 +170,13 @@ pm_join() { } pm_job_exit() { - exit_code=$1 - echo "$exit_code" > "${_pm_output}/${BASHPID}.pid" + local pid_file="${_pm_output}/${BASHPID}.pid" exit_code=$1 + # If the process is not tracked, don't write down an exit code. + if [ ! -f "$pid_file" ]; then + echoerr "[procmon] no PID file found for process $BASHPID" + else + echo "$exit_code" > "${_pm_output}/${BASHPID}.pid" + fi exit "$exit_code" } diff --git a/test/test_codex.bats b/test/test_codex.bats index 257d155..e692949 100755 --- a/test/test_codex.bats +++ b/test/test_codex.bats @@ -50,15 +50,26 @@ setup() { rm -rf "$data_dir" } -# @test "should launch a Codex node" { -# export CLH_CODEX_BINARY="${BATS_TEST_DIRNAME}/codex/build/codex" +@test "should launch a Codex node" { + pm_start -# assert cdx_launch_node 0 -# assert cdx_ensure_ready 0 1 + assert cdx_launch_node 0 + assert cdx_ensure_ready 0 3 -# # We should see a log file and a data directory. -# assert [ -f "${_cdx_output}/logs/codex-0.log" ] -# assert [ -d "${_cdx_output}/data/codex-0" ] + # We should see a log file and a data directory. + assert [ -f "${_cdx_output}/logs/codex-0.log" ] + assert [ -d "${_cdx_output}/data/codex-0" ] -# cdx_destroy_node 0 -# } \ No newline at end of file + pid="${_cdx_pids[0]}" + assert [ -n "$pid" ] + + cdx_destroy_node 0 true + + refute [ -d "${_cdx_output}/data/codex-0" ] + refute [ -f "${_cdx_output}/logs/codex-0.log" ] + assert [ -z "${_cdx_pids[0]}" ] + + assert $(! kill -0 "$pid") + + pm_stop +} diff --git a/test/test_helper/common_setup.bash b/test/test_helper/common_setup.bash index b29b421..5410157 100644 --- a/test/test_helper/common_setup.bash +++ b/test/test_helper/common_setup.bash @@ -4,10 +4,4 @@ common_setup() { load test_helper/bats-assert/load export LIB_SRC="${BATS_TEST_DIRNAME}/../src" - export CODEX_BINARY=${CODEX_BINARY:-"${BATS_TEST_DIRNAME}/codex/build/codex"} - - if [ ! -f "$CODEX_BINARY" ]; then - echo "Codex binary not found at $CODEX_BINARY" - exit 1 - fi -} \ No newline at end of file +}