#!/usr/bin/env bash

test_description='daemon redirects'

. lib/test-lib.sh

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

test_begin_subtest "request INIT"
testioc ${IFO}:TEST- &
sleep .2
guardian --name=TEST TEST_redirect &
wait_node_ready TEST
cawait T1:GRD-TEST_STATUS DONE
camonitor -tn -F. T1:GRD-TEST_{STATE,REQUEST,STATUS} >OUTPUT_grd &
camonitor -tn -F. T1:TEST-{A,B,C} >OUTPUT_ezca &
sleep .2
caput T1:GRD-TEST_REQUEST C
cawait T1:TEST-C 1
sleep .2
caput T1:GRD-TEST_REQUEST INIT
sleep .2
cawait T1:TEST-C 1
cawait T1:GRD-TEST_STATUS RUN
kill_jobs
cat OUTPUT_{grd,ezca} > OUTPUT
cat <<EOF >EXPECTED
T1:GRD-TEST_STATE..INIT..
T1:GRD-TEST_REQUEST..NONE..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_REQUEST..C..
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..EDGE..
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..C..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_REQUEST..INIT..
T1:GRD-TEST_REQUEST..C..
T1:GRD-TEST_STATUS..REDIRECT..
T1:GRD-TEST_STATUS..EDGE..
T1:GRD-TEST_STATE..INIT..
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..EDGE..
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..C..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-A..1..
T1:TEST-A..0..
T1:TEST-B..1..
T1:TEST-C..1..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-A..1..
T1:TEST-A..0..
T1:TEST-B..1..
T1:TEST-C..1..
EOF
test_expect_equal_file OUTPUT EXPECTED

test_begin_subtest "goto from finished state"
testioc ${IFO}:TEST- &
sleep .2
guardian --name=TEST TEST_redirect &
wait_node_ready TEST
cawait T1:GRD-TEST_STATUS DONE
camonitor -tn -F. T1:GRD-TEST_{STATE,REQUEST,STATUS} >OUTPUT_grd &
camonitor -tn -F. T1:TEST-{A,B,C} >OUTPUT_ezca &
sleep .2
caput T1:GRD-TEST_REQUEST C
cawait T1:TEST-C 1
caput T1:TEST-C 0
sleep .2
caput T1:GRD-TEST_REQUEST B
cawait T1:GRD-TEST_STATE B
cawait T1:GRD-TEST_STATUS DONE
kill_jobs
cat OUTPUT_{grd,ezca} | uniq > OUTPUT
cat <<EOF >EXPECTED
T1:GRD-TEST_STATE..INIT..
T1:GRD-TEST_REQUEST..NONE..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_REQUEST..C..
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..EDGE..
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..C..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_REQUEST..B..
T1:GRD-TEST_STATUS..REDIRECT..
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..EDGE..
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:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-A..1..
T1:TEST-A..0..
T1:TEST-B..1..
T1:TEST-C..1..
T1:TEST-C..0..
T1:TEST-C..2..
T1:TEST-A..1..
T1:TEST-A..0..
EOF
test_expect_equal_file OUTPUT EXPECTED

test_begin_subtest "goto from unfinished state"
testioc ${IFO}:TEST- &
sleep .2
guardian --name=TEST TEST_redirect &
wait_node_ready TEST
cawait T1:GRD-TEST_STATUS DONE
camonitor -tn -F. T1:GRD-TEST_{STATE,REQUEST,STATUS} >OUTPUT_grd &
camonitor -tn -F. T1:TEST-{A,B,C} >OUTPUT_ezca &
sleep .2
caput T1:GRD-TEST_REQUEST C
cawait T1:TEST-C 1
sleep .2
caput T1:GRD-TEST_REQUEST B
cawait T1:GRD-TEST_STATE B
cawait T1:GRD-TEST_STATUS DONE
kill_jobs
cat OUTPUT_{grd,ezca} >OUTPUT
cat <<EOF >EXPECTED
T1:GRD-TEST_STATE..INIT..
T1:GRD-TEST_REQUEST..NONE..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_REQUEST..C..
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..EDGE..
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..C..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_REQUEST..B..
T1:GRD-TEST_STATUS..REDIRECT..
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..EDGE..
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:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-A..1..
T1:TEST-A..0..
T1:TEST-B..1..
T1:TEST-C..1..
T1:TEST-A..1..
T1:TEST-A..0..
EOF
test_expect_equal_file OUTPUT EXPECTED

test_begin_subtest "goto from protected state"
testioc ${IFO}:TEST- &
guardian --name=TEST TEST_redirect &
wait_node_ready TEST
cawait T1:GRD-TEST_STATUS DONE
camonitor -tn -F. T1:GRD-TEST_{STATE,REQUEST,STATUS} >OUTPUT_grd &
camonitor -tn -F. T1:TEST-{A,B,C} >OUTPUT_ezca &
sleep .2
caput T1:GRD-TEST_REQUEST E
cawait T1:GRD-TEST_STATE D
sleep .2
caput T1:GRD-TEST_REQUEST B
# FIXME: we have to wait here since we don't have a good way to know
# that we're not progressing because the state is protected
sleep 2
caput T1:TEST-C 3
cawait T1:GRD-TEST_STATE B
cawait T1:GRD-TEST_STATUS DONE
kill_jobs
cat OUTPUT_{grd,ezca} >OUTPUT
cat <<EOF >EXPECTED
T1:GRD-TEST_STATE..INIT..
T1:GRD-TEST_REQUEST..NONE..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_REQUEST..E..
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..EDGE..
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..D..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_REQUEST..B..
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..EDGE..
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:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-A..1..
T1:TEST-A..0..
T1:TEST-B..1..
T1:TEST-C..1..
T1:TEST-C..3..
T1:TEST-C..2..
T1:TEST-A..1..
T1:TEST-A..0..
EOF
test_expect_equal_file OUTPUT EXPECTED

test_begin_subtest "re-request current state"
testioc ${IFO}:TEST- &
guardian --name=TEST TEST_redirect &
wait_node_ready TEST
cawait T1:GRD-TEST_STATUS DONE
camonitor -tn -F. T1:GRD-TEST_{STATE,REQUEST,STATUS} >OUTPUT_grd &
camonitor -tn -F. T1:TEST-{A,B,C} >OUTPUT_ezca &
sleep .2
caput T1:GRD-TEST_REQUEST C
cawait T1:TEST-C 1
caput T1:TEST-C 3
cawait T1:GRD-TEST_STATUS DONE
caput T1:GRD-TEST_REQUEST C
sleep .2
cawait T1:GRD-TEST_STATUS RUN
kill_jobs
cat OUTPUT_{grd,ezca} | uniq >OUTPUT
cat <<EOF >EXPECTED
T1:GRD-TEST_STATE..INIT..
T1:GRD-TEST_REQUEST..NONE..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_REQUEST..C..
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..EDGE..
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..C..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..DONE..
T1:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-A..1..
T1:TEST-A..0..
T1:TEST-B..1..
T1:TEST-C..1..
T1:TEST-C..3..
T1:TEST-C..2..
EOF
test_expect_equal_file OUTPUT EXPECTED

test_begin_subtest "same-state redirect"
testioc ${IFO}:TEST- &
guardian --name=TEST TEST_redirect &
wait_node_ready TEST
cawait T1:GRD-TEST_STATUS DONE
camonitor -tn -F. T1:GRD-TEST_{STATE,REQUEST,STATUS} >OUTPUT_grd &
camonitor -tn -F. T1:TEST-{A,B,C} >OUTPUT_ezca &
sleep .2
caput T1:GRD-TEST_REQUEST F
cawait T1:TEST-C 1
caput T1:TEST-C 3
cawait T1:GRD-TEST_STATUS DONE
caput T1:GRD-TEST_REQUEST F
sleep .2
cawait T1:GRD-TEST_STATUS RUN
kill_jobs
cat OUTPUT_{grd,ezca} | uniq >OUTPUT
cat <<EOF >EXPECTED
T1:GRD-TEST_STATE..INIT..
T1:GRD-TEST_REQUEST..NONE..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_REQUEST..F..
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..EDGE..
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..F..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:GRD-TEST_STATUS..DONE..
T1:GRD-TEST_STATUS..REDIRECT..
T1:GRD-TEST_STATUS..ENTER..
T1:GRD-TEST_STATUS..MAIN..
T1:GRD-TEST_STATUS..RUN..
T1:TEST-A..0..
T1:TEST-B..0..
T1:TEST-C..0..
T1:TEST-A..1..
T1:TEST-A..0..
T1:TEST-B..1..
T1:TEST-C..1..
T1:TEST-C..3..
T1:TEST-C..2..
T1:TEST-C..1..
EOF
test_expect_equal_file OUTPUT EXPECTED

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

test_done
