Restconf native+http/1 + tls

Added command-line timeout -t <sec> to restconf
Example: Added programmable timeout to backend example
Test: updated for fcgi and native using internal timeouts
This commit is contained in:
Olof hagsand 2024-05-06 15:57:11 +02:00
parent 2b2a2ec1ad
commit 62a4b5feff
17 changed files with 577 additions and 318 deletions

View file

@ -21,19 +21,10 @@
# 2d) start sub 8s - replay from start -8s to stop +4s - expect 3 notifications
# 2e) start sub 8s - replay from -90s w retention 60s - expect 10 notifications
# Note the sleeps are mainly for valgrind usage
#
# XXX There is some state/timing issue introduced in 5.7, see test-pause and parallell
# Magic line must be first in script (see README.md)
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
# Skip it other than fcgi and http
#if [ "${WITH_RESTCONF}" != "fcgi" -o "$RCPROTO" = https ]; then
if false; then
rm -rf $dir
if [ "$s" = $0 ]; then exit 0; else return 0; fi # skip
fi
# Dont run this test with valgrind
if [ $valgrindtest -ne 0 ]; then
echo "...skipped "
@ -41,15 +32,18 @@ if [ $valgrindtest -ne 0 ]; then
return 0 # skip
fi
# Degraded does not work at all
#rm -rf $dir
#if [ "$s" = $0 ]; then exit 0; else return 0; fi # skip
: ${SLEEP2:=1}
SLEEP5=.5
APPNAME=example
: ${clixon_util_stream:=clixon_util_stream}
: ${TIMEOUT:=10}
: ${PERIOD:=2}
# Lower and upper bound on number of intervals
LBOUND=$((${TIMEOUT}/${PERIOD} - 1))
UBOUND=$((${TIMEOUT}/${PERIOD} + 1))
# Ensure UTC
DATE=$(date -u +"%Y-%m-%d")
@ -128,13 +122,55 @@ module example {
}
EOF
# Temporary pause between tests to make state timeout
# XXX This should not really be here, there is some state/timing issue introduced in 5.7
function test-pause()
# Run stream test
# Args:
# 1: extra curlopt
function runtest()
{
sleep 5
# -m 1 means 1 sec timeout
curl -Ssik --http1.1 -X GET -m 1 -H "Accept: text/event-stream" -H "Cache-Control: no-cache" -H "Connection: keep-alive" "http://localhost/streams/EXAMPLE" 2>&1 > /dev/null
extra=$1
expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*Z</eventTime><event xmlns=\"urn:example:clixon\"><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>"
new "2a) start $extra timeout:${TIMEOUT}s - expect ${LBOUND}-${UBOUND} notifications"
ret=$(curl $CURLOPTS $extra -X GET -H "Accept: text/event-stream" -H "Cache-Control: no-cache" -H "Connection: keep-alive" $RCPROTO://localhost/streams/EXAMPLE)
match=$(echo "$ret" | grep -Eo "$expect")
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
nr=$(echo "$ret" | grep -c "data:")
if [ $nr -lt ${LBOUND} -o $nr -gt ${UBOUND} ]; then
err "[${LBOUND},$[UBOUND]]" "$nr"
fi
LB=$((5/${PERIOD} - 1))
UB=$((5/${PERIOD} + 1))
time1=$(date -u -d"5 second now" +'%Y-%m-%dT%H:%M:%SZ')
new "2b) start $extra timeout:${TIMEOUT} stop after 5s - expect ${LB}-${UB} notifications"
ret=$(curl $CURLOPTS $extra -X GET -H "Accept: text/event-stream" -H "Cache-Control: no-cache" -H "Connection: keep-alive" $RCPROTO://localhost/streams/EXAMPLE?stop-time=${time1})
match=$(echo "$ret" | grep -Eo "$expect")
if [ -z "$match" ]; then
err "$expect" "$ret"
fi
nr=$(echo "$ret" | grep -c "data:")
if [ $nr -lt ${LB} -o $nr -gt ${UB} ]; then
err "[${LB},$[UB]]" "$nr"
fi
if false; then # Does not work yet
time1=$(date -u -d"-5 second now" +'%Y-%m-%dT%H:%M:%SZ')
LB=$(((5+${TIMEOUT})/${PERIOD} - 1))
UB=$(((5+${TIMEOUT})/${PERIOD} + 1))
new "2c) start sub 8s - replay from start -8s - expect 3-4 notifications"
echo "curl $CURLOPTS $extra -X GET -H \"Accept: text/event-stream\" -H \"Cache-Control: no-cache\" -H \"Connection: keep-alive\" $RCPROTO://localhost/streams/EXAMPLE?start-time=${time1}"
ret=$(curl $CURLOPTS $extra -X GET -H "Accept: text/event-stream" -H "Cache-Control: no-cache" -H "Connection: keep-alive" $RCPROTO://localhost/streams/EXAMPLE?start-time=${time1})
fi
unset LB
unset UB
unset time1
}
new "test params: -f $cfg"
@ -145,8 +181,9 @@ if [ $BE -ne 0 ]; then
if [ $? -ne 0 ]; then
err
fi
new "start backend -s init -f $cfg -- -n"
start_backend -s init -f $cfg -- -n # create example notification stream
new "start backend -s init -f $cfg -- -n ${PERIOD}"
# create example notification stream with periodic timeout ${PERIOD} seconds
start_backend -s init -f $cfg -- -n ${PERIOD}
fi
new "wait backend"
@ -156,15 +193,15 @@ if [ $RC -ne 0 ]; then
new "kill old restconf daemon"
stop_restconf_pre
new "start restconf daemon"
start_restconf -f $cfg
new "start restconf daemon -f $cfg -t ${TIMEOUT}"
start_restconf -f $cfg -t ${TIMEOUT}
fi
new "wait restconf"
wait_restconf
new "netconf event stream discovery RFC8040 Sec 6.2"
expecteof_netconf "$clixon_netconf -D $DBG -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get><filter type=\"xpath\" select=\"r:restconf-state/r:streams\" xmlns:r=\"urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring\"/></get></rpc>" "" "<rpc-reply $DEFAULTNS><data><restconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring\"><streams><stream><name>EXAMPLE</name><description>Example event stream</description><replay-support>true</replay-support><access><encoding>xml</encoding><location>https://localhost/streams/EXAMPLE</location></access></stream></streams></restconf-state></data></rpc-reply>"
expecteof_netconf "$clixon_netconf -D $DBG -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get><filter type=\"xpath\" select=\"r:restconf-state/r:streams\" xmlns:r=\"urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring\"/></get></rpc>" "" "<rpc-reply $DEFAULTNS><data><restconf-state xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring\"><streams><stream><name>EXAMPLE</name><description>Example event stream</description><replay-support>true</replay-support><access><encoding>xml</encoding><location>$RCPROTO://localhost/streams/EXAMPLE</location></access></stream></streams></restconf-state></data></rpc-reply>"
# 1.2 Netconf stream subscription
@ -172,40 +209,30 @@ expecteof_netconf "$clixon_netconf -D $DBG -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DE
new "2. Restconf RFC8040 stream testing"
# 2.1 Stream discovery
new "restconf event stream discovery RFC8040 Sec 6.2"
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/ietf-restconf-monitoring:restconf-state/streams)" 0 "HTTP/$HVER 200" '{"ietf-restconf-monitoring:streams":{"stream":\[{"name":"EXAMPLE","description":"Example event stream","replay-support":true,"access":\[{"encoding":"xml","location":"https://localhost/streams/EXAMPLE"}\]}\]}'
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/ietf-restconf-monitoring:restconf-state/streams)" 0 "HTTP/$HVER 200" "{\"ietf-restconf-monitoring:streams\":{\"stream\":\[{\"name\":\"EXAMPLE\",\"description\":\"Example event stream\",\"replay-support\":true,\"access\":\[{\"encoding\":\"xml\",\"location\":\"$RCPROTO://localhost/streams/EXAMPLE\"}\]}\]}"
sleep $SLEEP2
new "restconf subscribe RFC8040 Sec 6.3, get location"
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/ietf-restconf-monitoring:restconf-state/streams/stream=EXAMPLE/access=xml/location)" 0 "HTTP/$HVER 200" '{"ietf-restconf-monitoring:location":"https://localhost/streams/EXAMPLE"}'
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/ietf-restconf-monitoring:restconf-state/streams/stream=EXAMPLE/access=xml/location)" 0 "HTTP/$HVER 200" "{\"ietf-restconf-monitoring:location\":\"$RCPROTO://localhost/streams/EXAMPLE\"}"
sleep $SLEEP2
# Restconf stream subscription RFC8040 Sec 6.3
# Start Subscription w error
new "restconf monitor event nonexist stream"
# Note cant use -S or -i here, the former dont know, latter because expectwait cant take
# partial returns like expectpart can
expectpart "$(curl $CURLOPTS -X GET -H "Accept: text/event-stream" -H "Cache-Control: no-cache" -H "Connection: keep-alive" $RCPROTO://localhost/streams/NOTEXIST)" 0 "HTTP/$HVER 400" '<errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\"><error><error-type>application</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>No such stream</error-message></error></errors>'
new "Try nonexist stream"
expectpart "$(curl $CURLOPTS -X GET -H "Accept: text/event-stream" -H "Cache-Control: no-cache" -H "Connection: keep-alive" $RCPROTO://localhost/streams/NOTEXIST)" 0 "HTTP/$HVER 400" "<errors xmlns=\"urn:ietf:params:xml:ns:yang:ietf-restconf\"><error><error-type>application</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>No such stream</error-message></error></errors>"
# 2a) start subscription 8s - expect 1-2 notifications
new "2a) start subscriptions 8s - expect 1-2 notifications"
echo "curl $CURLOPTS --no-buffer -X GET -H \"Accept: text/event-stream\" -H \"Cache-Control: no-cache\" -H \"Connection: keep-alive\" $RCPROTO://localhost/streams/EXAMPLE"
#curl $CURLOPTS --no-buffer -X GET -H "Accept: text/event-stream" -H "Cache-Control: no-cache" -H "Connection: keep-alive" $RCPROTO://localhost/streams/EXAMPLE
exit
ret=$($clixon_util_stream -u $RCPROTO://localhost/streams/EXAMPLE -t 8)
expect="data: <notification xmlns=\"urn:ietf:params:xml:ns:netconf:notification:1.0\"><eventTime>${DATE}T[0-9:.]*Z</eventTime><event xmlns=\"urn:example:clixon\"><event-class>fault</event-class><reportingEntity><card>Ethernet0</card></reportingEntity><severity>major</severity></event>"
match=$(echo "$ret" | grep -Eo "$expect")
if [ -z "$match" ]; then
err "$expect" "$ret"
if ${HAVE_HTTP1}; then
runtest --http1.1
fi
nr=$(echo "$ret" | grep -c "data:")
if [ $nr -lt 1 -o $nr -gt 2 ]; then
err 2 "$nr"
if [ "${WITH_RESTCONF}" = "fcgi" ]; then
runtest ""
fi
exit
if [ "${WITH_RESTCONF}" = "native" ]; then
if false; then # XXX native + http/2 dont work yet
# if ${HAVE_LIBNGHTTP2}; then
runtest --http2
fi
fi
if false; then # NYI
test-pause
# 2b) start subscription 8s - stoptime after 5s - expect 1-2 notifications
@ -274,7 +301,6 @@ fi
test-pause
sleep 5
# Try parallell
# start background job
curl $CURLOPTS -X GET -H "Accept: text/event-stream" -H "Cache-Control: no-cache" -H "Connection: keep-alive" "$RCPROTO://localhost/streams/EXAMPLE" & # > /dev/null &
@ -297,14 +323,11 @@ fi # XXX
kill $PID
#--------------------------------------------------------------------
# NCHAN Need manual testing
echo "Nchan streams requires manual testing"
echo "Add <CLICON_STREAM_PUB>http://localhost/pub</CLICON_STREAM_PUB> to config"
echo "Eg: curl $CURLOPTS -H \"Accept: text/event-stream\" -s -X GET $RCPROTO://localhost/sub/EXAMPLE"
#-----------------
sleep $SLEEP5
fi # XXX
if [ $RC -ne 0 ]; then
new "Kill restconf daemon"
stop_restconf