]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Replace some raw nc usage in statschannel system test with curl
authorOndřej Surý <ondrej@isc.org>
Tue, 18 Oct 2022 19:46:16 +0000 (21:46 +0200)
committerOndřej Surý <ondrej@isc.org>
Thu, 20 Oct 2022 16:06:48 +0000 (18:06 +0200)
For tests where the TCP connection might get interrupted abruptly,
replace the nc with curl as the data sent from server to client might
get lost because of abrupt TCP connection.  This happens when the TCP
connection gets closed during sending the large request to the server.

As we already require curl for other system tests, replace the nc usage
in the statschannel test with curl that actually understands the
HTTP/1.1 protocol, so the same connection is reused for sending the
consequtive requests, but without client-side "pipelining".

For the record, the server doesn't support parallel processing of the
pipelined request, so it's a bit misnomer here, because what we are
actually testing is that we process all requests received in a single
TCP read callback.

(cherry picked from commit cd0e5c5784d040502565a671445f9952455e6b0a)

bin/tests/system/statschannel/clean.sh
bin/tests/system/statschannel/tests.sh

index a8bff6e19c6f5ca0d4f2452b16f0c6bb5936a71a..c1ec858a79ec07379123c79d381cee9e1ae3bfc1 100644 (file)
@@ -30,5 +30,4 @@ rm -f xml.*mem json.*mem
 rm -f xml.*stats json.*stats
 rm -f zones zones.out.* zones.json.* zones.xml.* zones.expect.*
 rm -rf ./__pycache__
-rm -f nc.out*
-rm -f send.in* send.out*
+rm -f nc.out* curl.out* header.in*
index 8f40db6a2408447e857ab1e756bd3c5d6c99a831..4a95dfb99a96a6d6b2508e55259e316e732afe61 100644 (file)
@@ -41,7 +41,7 @@ else
     echo_i "XML tests require XML::Simple; skipping" >&2
 fi
 
-if [ ! "$PERL_JSON" -a ! "$PERL_XML" ]; then
+if [ ! "$PERL_JSON" ] && [ ! "$PERL_XML" ]; then
     echo_i "skipping all tests"
     exit 0
 fi
@@ -135,29 +135,33 @@ status=$((status + ret))
 n=$((n + 1))
 
 echo_i "checking consistency between regular and compressed output ($n)"
-for i in 1 2 3 4 5; do
-       ret=0
-       if [ "$HAVEXMLSTATS" ];
-       then
-               URL=http://10.53.0.2:${EXTRAPORT1}/xml/v3/server
-               filter_str='s#<current-time>.*</current-time>##g'
-       else
-               URL=http://10.53.0.2:${EXTRAPORT1}/json/v1/server
-               filter_str='s#"current-time.*",##g'
-       fi
-       $CURL -D regular.headers $URL 2>/dev/null | \
-               sed -e "$filter_str" > regular.out
-       $CURL -D compressed.headers --compressed $URL 2>/dev/null | \
-               sed -e "$filter_str" > compressed.out
-       diff regular.out compressed.out >/dev/null || ret=1
-       if [ $ret != 0 ]; then
-               echo_i "failed on try $i, probably a timing issue, trying again"
-               sleep 1
-       else
-               break
-       fi
-done
-
+ret=0
+if [ -x "${CURL}" ] ; then
+    for i in 1 2 3 4 5; do
+        ret=0
+        if [ "$HAVEXMLSTATS" ];
+        then
+            URL="http://10.53.0.2:${EXTRAPORT1}/xml/v3/server"
+            filter_str='s#<current-time>.*</current-time>##g'
+        else
+            URL="http://10.53.0.2:${EXTRAPORT1}/json/v1/server"
+            filter_str='s#"current-time.*",##g'
+        fi
+        "${CURL}" -D regular.headers "$URL" 2>/dev/null | \
+            sed -e "$filter_str" > regular.out || ret=1
+        "${CURL}" -D compressed.headers --compressed "$URL" 2>/dev/null | \
+            sed -e "$filter_str" > compressed.out || ret=1
+        diff regular.out compressed.out >/dev/null || ret=1
+        if [ $ret != 0 ]; then
+            echo_i "failed on try $i, probably a timing issue, trying again"
+            sleep 1
+        else
+            break
+        fi
+    done
+else
+    echo_i "skipping test as curl not found"
+fi
 status=$((status + ret))
 n=$((n + 1))
 
@@ -166,11 +170,11 @@ echo_i "checking if compressed output is really compressed ($n)"
 if [ "$HAVEZLIB" ];
 then
     REGSIZE=`cat regular.headers | \
-       grep -i Content-Length | sed -e "s/.*: \([0-9]*\).*/\1/"`
+        grep -i Content-Length | sed -e "s/.*: \([0-9]*\).*/\1/"`
     COMPSIZE=`cat compressed.headers | \
-       grep -i Content-Length | sed -e "s/.*: \([0-9]*\).*/\1/"`
+        grep -i Content-Length | sed -e "s/.*: \([0-9]*\).*/\1/"`
     if [ ! $((REGSIZE / COMPSIZE)) -gt 2 ]; then
-       ret=1
+        ret=1
     fi
 else
     echo_i "skipped"
@@ -277,7 +281,6 @@ ksk13_id=`cat ns2/$zone.ksk13.id`
 zsk13_id=`cat ns2/$zone.zsk13.id`
 ksk14_id=`cat ns2/$zone.ksk14.id`
 zsk14_id=`cat ns2/$zone.zsk14.id`
-num_ids=$( (echo $ksk8_id; echo $zsk8_id; echo $ksk13_id; echo $zsk13_id; echo $ksk14_id; echo $zsk14_id;) | sort -u | wc -l)
 # The dnssec zone has 10 RRsets to sign (including NSEC) with the ZSKs and one
 # RRset (DNSKEY) with the KSKs. So starting named with signatures that expire
 # almost right away, this should trigger 10 zsk and 1 ksk sign operations per
@@ -298,20 +301,15 @@ cat zones.expect | sort > zones.expect.$n
 rm -f zones.expect
 # Fetch and check the dnssec sign statistics.
 echo_i "fetching zone '$zone' stats data after zone maintenance at startup ($n)"
-if test $num_ids -eq 6
-then
-    if [ $PERL_XML ]; then
-        getzones xml $zone x$n || ret=1
-        cmp zones.out.x$n zones.expect.$n || ret=1
-    fi
-    if [ $PERL_JSON ]; then
-        getzones json 2 j$n || ret=1
-        cmp zones.out.j$n zones.expect.$n || ret=1
-    fi
-    if [ $ret != 0 ]; then echo_i "failed"; fi
-else
-    echo_i "skipped: duplicate key id detected (fixed in BIND 9.19)"
+if [ $PERL_XML ]; then
+    getzones xml $zone x$n || ret=1
+    cmp zones.out.x$n zones.expect.$n || ret=1
 fi
+if [ $PERL_JSON ]; then
+    getzones json 2 j$n || ret=1
+    cmp zones.out.j$n zones.expect.$n || ret=1
+fi
+if [ $ret != 0 ]; then echo_i "failed"; fi
 status=$((status + ret))
 n=$((n + 1))
 
@@ -341,20 +339,15 @@ cat zones.expect | sort > zones.expect.$n
 rm -f zones.expect
 # Fetch and check the dnssec sign statistics.
 echo_i "fetching zone '$zone' stats data after dynamic update ($n)"
-if test $num_ids -eq 6
-then
-    if [ $PERL_XML ]; then
-        getzones xml $zone x$n || ret=1
-        cmp zones.out.x$n zones.expect.$n || ret=1
-    fi
-    if [ $PERL_JSON ]; then
-        getzones json 2 j$n || ret=1
-        cmp zones.out.j$n zones.expect.$n || ret=1
-    fi
-    if [ $ret != 0 ]; then echo_i "failed"; fi
-else
-    echo_i "skipped: duplicate key id detected (fixed in BIND 9.19)"
+if [ $PERL_XML ]; then
+    getzones xml $zone x$n || ret=1
+    cmp zones.out.x$n zones.expect.$n || ret=1
+fi
+if [ $PERL_JSON ]; then
+    getzones json 2 j$n || ret=1
+    cmp zones.out.j$n zones.expect.$n || ret=1
 fi
+if [ $ret != 0 ]; then echo_i "failed"; fi
 status=$((status + ret))
 n=$((n + 1))
 
@@ -387,10 +380,10 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
 status=$((status + ret))
 n=$((n + 1))
 
+echo_i "Check HTTP/1.1 client-side pipelined requests are handled (GET) ($n)"
+ret=0
 if [ -x "${NC}" ] ; then
-    echo_i "Check HTTP/1.1 pipelined requests are handled (GET) ($n)"
-    ret=0
-    ${NC} 10.53.0.3 ${EXTRAPORT1} << EOF > nc.out$n || ret=1
+    "${NC}" 10.53.0.3 "${EXTRAPORT1}" << EOF > nc.out$n || ret=1
 GET /xml/v3/status HTTP/1.1
 Host: 10.53.0.3:${EXTRAPORT1}
 
@@ -399,19 +392,19 @@ Host: 10.53.0.3:${EXTRAPORT1}
 Connection: close
 
 EOF
-    lines=$(grep -c "^HTTP/1.1" nc.out$n)
+    lines=$(grep -c "^<statistics version" nc.out$n)
     test "$lines" = 2 || ret=1
-    if [ $ret != 0 ]; then echo_i "failed"; fi
-    status=$((status + ret))
-    n=$((n + 1))
 else
     echo_i "skipping test as nc not found"
 fi
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+n=$((n + 1))
 
-echo_i "Check HTTP/1.1 pipelined requests are handled (POST) ($n)"
+echo_i "Check HTTP/1.1 client-side pipelined requests are handled (POST) ($n)"
 ret=0
-if [ -x "${NC}" ] ; then
-    ${NC} 10.53.0.3 ${EXTRAPORT1} << EOF > nc.out$n || ret=1
+if [ -x "${NC}" ]; then
+    "${NC}" 10.53.0.3 "${EXTRAPORT1}" << EOF > nc.out$n || ret=1
 POST /xml/v3/status HTTP/1.1
 Host: 10.53.0.3:${EXTRAPORT1}
 Content-Type: application/json
@@ -426,7 +419,7 @@ Connection: close
 
 {}
 EOF
-    lines=$(grep -c "^HTTP/1.1" nc.out$n)
+    lines=$(grep -c "^<statistics version" nc.out$n)
     test "$lines" = 2 || ret=1
 else
     echo_i "skipping test as nc not found"
@@ -435,76 +428,71 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
 status=$((status + ret))
 n=$((n + 1))
 
+if [ -x "${CURL}" ] && ! ("${CURL}" --next 2>&1 | grep 'option --next: is unknown'); then
+    CURL_NEXT="${CURL}"
+fi
+
 echo_i "Check HTTP with more than 10 headers ($n)"
 ret=0
 i=0
-# build input stream.
-printf 'GET /xml/v3/status HTTP/1.1\r\nHost: 10.53.0.3\r\n\r\n' > send.in$n
-printf 'GET /xml/v3/status HTTP/1.1\r\nHost: 10.53.0.3\r\n' >> send.in$n
-
-while test $i -lt 11
-do
-printf 'X-Bloat: VGhlIG1vc3QgY29tbW9uIHJlYXNvbiBmb3IgYmxvYXRpbmcgaXMgaGF2aW5nIGEgbG90IG9mIGdhcyBpbiB5b3VyIGd1dC4gCg==\r\n' >> send.in$n
-i=$((i+1))
-done
-printf '\r\n' >> send.in$n
-
-# send the requests then wait for named to close the socket.
-time1=$($PERL -e 'print time(), "\n";')
-${NC} 10.53.0.3 ${EXTRAPORT1} < send.in$n  > send.out$n
-time2=$($PERL -e 'print time(), "\n";')
-test $((time2 - time1)) -lt 5 || ret=1
-# we expect 1 request to be processed.
-lines=$(grep -c "^HTTP/1.1" send.out$n)
-test $lines = 1 || ret=1
+if [ -x "${CURL_NEXT}" ] ; then
+    # build input stream.
+    : > header.in$n
+    while test $i -lt 11
+    do
+        printf 'X-Bloat%d: VGhlIG1vc3QgY29tbW9uIHJlYXNvbiBmb3IgYmxvYXRpbmcgaXMgaGF2aW5nIGEgbG90IG9mIGdhcyBpbiB5b3VyIGd1dC4gCg==\r\n' $i >> header.in$n
+        i=$((i+1))
+    done
+    printf '\r\n' >> header.in$n
+
+    # send the requests then wait for named to close the socket.
+    URL="http://10.53.0.3:${EXTRAPORT1}/xml/v3/status"
+    "${CURL}" --silent --include --get "$URL" --next --get --header @header.in$n "$URL" > curl.out$n && ret=1
+    # we expect 1 request to be processed.
+    lines=$(grep -c "^<statistics version" curl.out$n)
+    test "$lines" = 1 || ret=1
+else
+    echo_i "skipping test as curl with --next support not found"
+fi
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=$((status + ret))
 n=$((n + 1))
 
-echo_i "Check HTTP/1.1 pipelined with truncated stream ($n)"
+echo_i "Check HTTP/1.1 keep-alive with truncated stream ($n)"
 ret=0
 i=0
-# build input stream.
-printf 'GET /xml/v3/status HTTP/1.1\r\nHost: 10.53.0.3\r\n\r\n' > send.in$n
-printf 'GET /xml/v3/status HTTP/1.1\r\nHost: 10.53.0.3\r\nX-Bloat:' >> send.in$n
-while test $i -lt 5000
-do
-printf '%s' "VGhlIG1vc3QgY29tbW9uIHJlYXNvbiBmb3IgYmxvYXRpbmcgaXMgaGF2aW5nIGEgbG90IG9mIGdhcyBpbiB5b3VyIGd1dC4gCg==" >> send.in$n
-i=$((i+1))
-done
-printf '\r\n' >> send.in$n
-printf '\r\n' >> send.in$n
-
-# send the requests then wait for named to close the socket.
-time1=$($PERL -e 'print time(), "\n";')
-${NC} 10.53.0.3 ${EXTRAPORT1} < send.in$n  > send.out$n
-time2=$($PERL -e 'print time(), "\n";')
-test $((time2 - time1)) -lt 5 || ret=1
-# we expect 1 request to be processed.
-lines=$(grep -c "^HTTP/1.1" send.out$n)
-test $lines = 1 || ret=1
+if [ -x "${CURL_NEXT}" ] ; then
+    # build input stream.
+    printf 'X-Bloat: ' > header.in$n
+    while test $i -lt 5000
+    do
+        printf '%s' "VGhlIG1vc3QgY29tbW9uIHJlYXNvbiBmb3IgYmxvYXRpbmcgaXMgaGF2aW5nIGEgbG90IG9mIGdhcyBpbiB5b3VyIGd1dC4gCg==" >> header.in$n
+        i=$((i+1))
+    done
+    printf '\r\n' >> header.in$n
+
+    # send the requests then wait for named to close the socket.
+    URL="http://10.53.0.3:${EXTRAPORT1}/xml/v3/status"
+    "${CURL}" --silent --include --get "$URL" --next --get --header @header.in$n "$URL" > curl.out$n && ret=1
+    # we expect 1 request to be processed.
+    lines=$(grep -c "^<statistics version" curl.out$n)
+    test "$lines" = 1 || ret=1
+else
+    echo_i "skipping test as curl with --next support not found"
+fi
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=$((status + ret))
 n=$((n + 1))
 
-echo_i "Check pipelined responses do not grow excessively ($n)"
+echo_i "Check that consequtive responses do not grow excessively ($n)"
 ret=0
 i=0
-if [ -x "${NC}" ] ; then
-    {
-        while test $i -lt 10; do
-            printf "GET /json/v1 HTTP/1.1\r\nHost: 10.53.0.3:%s\r\nAccept-Encoding: deflate, gzip, br, zstd\r\n\r\n" "${EXTRAPORT1}"
-            i=$((i + 1))
-        done
-    } | ${NC} 10.53.0.3 ${EXTRAPORT1} | grep -a Content-Length |
-        awk 'BEGIN { prev=0; }
-             { if (prev != 0 && $2 - prev > 100) {
-                   exit(1);
-               }
-               prev = $2;
-             }' || ret=1
+if [ -x "${CURL}" ] ; then
+    URL="http://10.53.0.3:${EXTRAPORT1}/json/v1"
+    "${CURL}" --silent --include --header "Accept-Encoding: deflate, gzip, br, zstd" "$URL" "$URL" "$URL" "$URL" "$URL" "$URL" "$URL" "$URL" "$URL" "$URL" > curl.out$n || ret=1
+    grep -a Content-Length curl.out$n | awk 'BEGIN { prev=0; } { if (prev != 0 && $2 - prev > 100) { exit(1); } prev = $2; }' || ret=1
 else
-    echo_i "skipping test as nc not found"
+    echo_i "skipping test as curl not found"
 fi
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=$((status + ret))