#!/usr/bin/env bash

test_description='daemon jump transitions'

. lib/test-lib.sh

################################################################

test_begin_subtest "unmanaged jump"
testioc ${IFO}:TEST- &
sleep .1
guardian --ca-prefix=TEST --name=TEST TEST_jump &
wait_node_ready TEST
cawait T1:GRD-TEST_STATUS DONE
camonitor -tn -F. T1:GRD-TEST_{STATE,REQUEST,STATUS,STALLED} >OUTPUT_grd &
camonitor -tn -F. T1:TEST-{A,B,C,D} >OUTPUT_ezca &
sleep .3
caput T1:GRD-TEST_REQUEST A
cawait T1:GRD-TEST_STATUS DONE
caput T1:TEST-B 1
cawait T1:GRD-TEST_STATE B
caput T1:TEST-B 0
cawait T1:GRD-TEST_STATUS DONE
kill_jobs
cat OUTPUT_{grd,ezca} > OUTPUT
cat <<EOF >EXPECTED
T1:GRD-TEST_STATE..A..
T1:GRD-TEST_REQUEST..NONE..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_STALLED..False..
T1:GRD-TEST_REQUEST..A..
T1:GRD-TEST_STATUS..JUMP..
T1:GRD-TEST_STATE..B..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..EDGE..
T1:GRD-TEST_STATE..A..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..DONE..
T1:TEST-A..4..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-D..0..
T1:TEST-B..1..
T1:TEST-B..0..
T1:TEST-A..0..
T1:TEST-A..1..
T1:TEST-A..2..
T1:TEST-A..3..
T1:TEST-A..4..
EOF
test_expect_equal_file OUTPUT EXPECTED

test_begin_subtest "managed jump (stall)"
testioc ${IFO}:TEST- &
sleep .1
guardian --ca-prefix=TEST --name=TEST TEST_jump &
wait_node_ready TEST
cawait T1:GRD-TEST_STATUS DONE
caput T1:GRD-TEST_MANAGER TEST
camonitor -tn -F. T1:GRD-TEST_{STATE,REQUEST,STATUS,STALLED} >OUTPUT_grd &
camonitor -tn -F. T1:TEST-{A,B,C,D} >OUTPUT_ezca &
sleep .3
caput T1:GRD-TEST_REQUEST A
cawait T1:GRD-TEST_STATUS DONE
caput T1:TEST-B 1
cawait T1:GRD-TEST_STATE B
cawait T1:GRD-TEST_STATUS RUN
caput T1:TEST-B 0
cawait T1:GRD-TEST_STATUS DONE
# FIXME: wait here to make sure it doesn't advance without re-request
sleep 2
caput T1:GRD-TEST_REQUEST A
sleep .2
cawait T1:GRD-TEST_STATUS DONE
kill_jobs
cat OUTPUT_{grd,ezca} > OUTPUT
cat <<EOF >EXPECTED
T1:GRD-TEST_STATE..A..
T1:GRD-TEST_REQUEST..NONE..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_STALLED..False..
T1:GRD-TEST_REQUEST..A..
T1:GRD-TEST_STALLED..True..
T1:GRD-TEST_STATUS..JUMP..
T1:GRD-TEST_STATE..B..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_STALLED..False..
T1:GRD-TEST_STATUS..EDGE..
T1:GRD-TEST_STATE..A..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..DONE..
T1:TEST-A..4..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-D..0..
T1:TEST-B..1..
T1:TEST-B..0..
T1:TEST-A..0..
T1:TEST-A..1..
T1:TEST-A..2..
T1:TEST-A..3..
T1:TEST-A..4..
EOF
test_expect_equal_file OUTPUT EXPECTED

test_begin_subtest "managed jump to state with outbound goto"
testioc ${IFO}:TEST- &
sleep .1
guardian --ca-prefix=TEST --name=TEST TEST_jump &
wait_node_ready TEST
cawait T1:GRD-TEST_STATUS DONE
caput T1:GRD-TEST_MANAGER TEST
camonitor -tn -F. T1:GRD-TEST_{STATE,REQUEST,STATUS,STALLED} >OUTPUT_grd &
camonitor -tn -F. T1:TEST-{A,B,C,D} >OUTPUT_ezca &
sleep .3
caput T1:GRD-TEST_REQUEST A
cawait T1:GRD-TEST_STATUS DONE
caput T1:TEST-C 1
cawait T1:GRD-TEST_STATE C
cawait T1:GRD-TEST_STATUS RUN
# FIXME: wait to make sure stall overrides goto redirect
sleep 2
caput T1:GRD-TEST_REQUEST A
cawait T1:GRD-TEST_STATUS DONE
kill_jobs
cat OUTPUT_{grd,ezca} > OUTPUT
cat <<EOF >EXPECTED
T1:GRD-TEST_STATE..A..
T1:GRD-TEST_REQUEST..NONE..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_STALLED..False..
T1:GRD-TEST_REQUEST..A..
T1:GRD-TEST_STALLED..True..
T1:GRD-TEST_STATUS..JUMP..
T1:GRD-TEST_STATE..C..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STALLED..False..
T1:GRD-TEST_STATUS..REDIRECT..
T1:GRD-TEST_STATUS..EDGE..
T1:GRD-TEST_STATE..Z..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..EDGE..
T1:GRD-TEST_STATE..A..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..DONE..
T1:TEST-A..4..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-D..0..
T1:TEST-C..1..
T1:TEST-A..0..
T1:TEST-C..0..
T1:TEST-A..1..
T1:TEST-A..2..
T1:TEST-A..3..
T1:TEST-A..4..
EOF
test_expect_equal_file OUTPUT EXPECTED

test_begin_subtest "managed jump to protected state"
testioc ${IFO}:TEST- &
sleep .1
guardian --ca-prefix=TEST --name=TEST TEST_jump &
wait_node_ready TEST
cawait T1:GRD-TEST_STATUS DONE
caput T1:GRD-TEST_MANAGER TEST
camonitor -tn -F. T1:GRD-TEST_{STATE,REQUEST,STATUS,STALLED} >OUTPUT_grd &
camonitor -tn -F. T1:TEST-{A,B,C,D} >OUTPUT_ezca &
sleep .3
caput T1:GRD-TEST_REQUEST A
cawait T1:GRD-TEST_STATUS DONE
caput T1:TEST-D 1
cawait T1:GRD-TEST_STATE D
cawait T1:GRD-TEST_STATUS RUN
caput T1:GRD-TEST_REQUEST A
# FIXME: wait to make sure re-request (stall clear) doesn't override protection
sleep 2
caput T1:TEST-D 0
cawait T1:GRD-TEST_STATUS DONE
kill_jobs
cat OUTPUT_{grd,ezca} > OUTPUT
cat <<EOF >EXPECTED
T1:GRD-TEST_STATE..A..
T1:GRD-TEST_REQUEST..NONE..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_STALLED..False..
T1:GRD-TEST_REQUEST..A..
T1:GRD-TEST_STALLED..True..
T1:GRD-TEST_STATUS..JUMP..
T1:GRD-TEST_STATE..D..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STALLED..False..
T1:GRD-TEST_STATUS..EDGE..
T1:GRD-TEST_STATE..Z..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..EDGE..
T1:GRD-TEST_STATE..A..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..DONE..
T1:TEST-A..4..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-D..0..
T1:TEST-D..1..
T1:TEST-D..0..
T1:TEST-A..0..
T1:TEST-A..1..
T1:TEST-A..2..
T1:TEST-A..3..
T1:TEST-A..4..
EOF
test_expect_equal_file OUTPUT EXPECTED

################################################################

test_done
