From 897f5d44c896bcd7f5a8048e262ff1c131db88fa Mon Sep 17 00:00:00 2001 From: John Akre Date: Mon, 22 Oct 2018 14:55:12 -0700 Subject: [PATCH] test: consolidate test web server implementations There were two web server implementations in the functional tests and the test library's slow server implementation was not functional. These issues were addressed by the following changes: - Consolidate test web server implementations into test library - Add partial download support to start_web_server test library function - Fix test library slow server functionality. Signed-off-by: John Akre --- .../checkupdate/chk-update-slow-server.bats | 7 +- test/functional/server.py | 64 ++++++++++++++++--- test/functional/testlib.bash | 12 ++-- .../functional/update/update-slow-server.bats | 49 ++++---------- test/functional/update/update_slow_server.py | 47 -------------- 5 files changed, 75 insertions(+), 104 deletions(-) delete mode 100755 test/functional/update/update_slow_server.py diff --git a/test/functional/checkupdate/chk-update-slow-server.bats b/test/functional/checkupdate/chk-update-slow-server.bats index a18a264e..d7ac168d 100755 --- a/test/functional/checkupdate/chk-update-slow-server.bats +++ b/test/functional/checkupdate/chk-update-slow-server.bats @@ -5,6 +5,7 @@ load "../testlib" global_setup() { create_test_environment "$TEST_NAME" + create_version "$TEST_NAME" 99990 10 staging # start slow response web server start_web_server -s @@ -28,11 +29,7 @@ global_teardown() { @test "check-update with a slow server" { - # Pre-req: create a web server that can serve as a slow content download server - slow_opts="-p $TEST_NAME/target-dir -F staging -u http://localhost:$PORT/" - - # test - run sudo sh -c "$SWUPD check-update $slow_opts" + run sudo sh -c "$SWUPD check-update $SWUPD_OPTS_HTTP_NO_CERT" assert_status_is 0 expected_output=$(cat <<-EOM Current OS version: 10 diff --git a/test/functional/server.py b/test/functional/server.py index 85be18fa..f33c2317 100755 --- a/test/functional/server.py +++ b/test/functional/server.py @@ -2,22 +2,57 @@ import argparse import http.server as server +import os import ssl import sys import time -class SlowResponse(server.BaseHTTPRequestHandler): - """Handler that returns data with a set delay between writes""" +partial_download_file = "" +slow_server = False + +class TestServer(server.BaseHTTPRequestHandler): + first_time = True + + """Handler that returns data with a set delay between writes and/or + simulates a partial download on the first download attempt for the + file specified by partial_download_file.""" def do_GET(self): - self.send_response(200) + try: + f = open(os.getcwd() + self.path, 'rb') + except: + self.send_response(404) + self.end_headers() + return + + #Simulate partial download + partial_download = False + split_paths = os.path.split(self.path) + + if split_paths[1] == partial_download_file and TestServer.first_time: + partial_download = True + TestServer.first_time = False + self.send_response(206) + else: + self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() - response = "99990" - delay = 0.00001 # seconds - for c in response: - self.wfile.write(str.encode(c)) + while True: + b = f.read(1) + if b == b'': + break + + self.wfile.write(b) + if partial_download: + break; + + # Insert delay for slow server + if slow_server: + delay = 0.00001 # seconds + time.sleep(delay) + self.wfile.flush() + f.close() if __name__ == '__main__': @@ -25,6 +60,11 @@ if __name__ == '__main__': parser.add_argument('--client_cert', help='client public key') + parser.add_argument('--partial_download_file', default="", + help='file name to download partially. On first download \ + fail with partial download error and succeed on 2nd \ + download.') + parser.add_argument('--port_file', help='File path to write port used by web server') @@ -40,9 +80,13 @@ if __name__ == '__main__': # host web server on localhost with available port addr = ('localhost', 0) - # server with delay or normal - if args.slow_server: - request_handler = SlowResponse + partial_download_file = args.partial_download_file + slow_server = args.slow_server + + # The TestServer is used when simulating a slow server and/or a + # partial file download. Otherwise use the simple HTTP server. + if slow_server or partial_download_file: + request_handler = TestServer else: request_handler = server.SimpleHTTPRequestHandler diff --git a/test/functional/testlib.bash b/test/functional/testlib.bash index fac4e86e..8c533b9a 100644 --- a/test/functional/testlib.bash +++ b/test/functional/testlib.bash @@ -280,6 +280,8 @@ set_env_variables() { # swupd_function PORT=$(cat "$PORT_FILE") export PORT export SWUPD_OPTS_HTTPS="-S $path/$env_name/state -p $path/$env_name/target-dir -F staging -u https://localhost:$PORT/$env_name/web-dir -C $FUNC_DIR/Swupd_Root.pem -I" + export SWUPD_OPTS_HTTP="-S $path/$env_name/state -p $path/$env_name/target-dir -F staging -u http://localhost:$PORT/$env_name/web-dir -C $FUNC_DIR/Swupd_Root.pem -I" + export SWUPD_OPTS_HTTP_NO_CERT="-S $path/$env_name/state -p $path/$env_name/target-dir -F staging -u http://localhost:$PORT/$env_name/web-dir/" fi if [ -f "$SERVER_PID_FILE" ]; then @@ -1398,13 +1400,12 @@ start_web_server() { # swupd_function cb_usage() { echo $(cat <<-EOF Usage: - start_web_server [-k] [-p] [-s] - - Options: - start_web_server [-c] [-p] [-k] [-s] + start_web_server [-c] [-d] [-k] [-p] [-s] Options: -c Path to public key to be used for client certificate authentication + -d File name that will be partially downloaded on the first attempt and successfully + downloaded on the second attempt. -k Path to server private key which must correspond to the provided server public key -p Path to server public key which enables SSL authentication -s Use a slow update server @@ -1424,9 +1425,10 @@ start_web_server() { # swupd_function ) } - while getopts :c:k:p:s opt; do + while getopts :c:d:k:p:s opt; do case "$opt" in c) server_args="$server_args --client_cert $OPTARG" ;; + d) server_args="$server_args --partial_download_file $OPTARG" ;; k) server_args="$server_args --server_key $OPTARG" ;; p) server_args="$server_args --server_cert $OPTARG" ;; s) server_args="$server_args --slow_server" ;; diff --git a/test/functional/update/update-slow-server.bats b/test/functional/update/update-slow-server.bats index 8dfa0ee9..305af92d 100755 --- a/test/functional/update/update-slow-server.bats +++ b/test/functional/update/update-slow-server.bats @@ -6,7 +6,7 @@ server_pid="" port="" THEME_DIRNAME="$FUNC_DIR/update" -test_setup() { +global_setup() { # Skip this test if not running in Travis CI, because test takes too long for # local development. To run this locally do: TRAVIS=true make check @@ -18,15 +18,22 @@ test_setup() { create_version -p "$TEST_NAME" 100 10 update_bundle "$TEST_NAME" test-bundle --update /foo/bar + start_web_server -d pack-test-bundle-from-10.tar -s +} + +test_setup() { + return } test_teardown() { + return +} + +global_teardown() { # teardown only if in travis CI if [ -n "${TRAVIS}" ]; then - print "terminating web server (PID: $server_pid)..." - kill "$server_pid" >&3 - print "server killed" + destroy_web_server destroy_test_environment "$TEST_NAME" fi @@ -34,12 +41,7 @@ test_teardown() { @test "update --download with a slow server" { - # Pre-req: create a web server that can serve as a slow content download server - print "starting web server..." - start_web_server - slow_opts="-u http://localhost:$port/" - - run sudo sh -c "$SWUPD update $slow_opts $SWUPD_OPTS" + run sudo sh -c "$SWUPD update $SWUPD_OPTS_HTTP" assert_status_is 0 expected_output=$(cat <<-EOM @@ -72,30 +74,3 @@ test_teardown() { assert_file_exists "$TARGETDIR"/foo/bar } - -start_web_server() { - - for i in {8081..8181}; do - "$THEME_DIRNAME"/update_slow_server.py $i & - sleep .5 - server_pid=$! - if [ -d /proc/$server_pid ]; then - port=$i - break - fi - done - - # wait until server becomes available by expecting a successful curl - for i in $(seq 1 10); do - flag=true - curl http://localhost:"$port"/ || flag=false - if [ "$flag" == false ]; then - sleep .5 - continue - else - print "server up" - break - fi - done - -} diff --git a/test/functional/update/update_slow_server.py b/test/functional/update/update_slow_server.py deleted file mode 100755 index a9c5579d..00000000 --- a/test/functional/update/update_slow_server.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python3 - -import http.server as server -import sys -import time - -class SlowResponse(server.BaseHTTPRequestHandler): - first_time = True - - """Handler that returns data with a set delay between writes""" - def do_GET(self): - try: - f = open('update-slow-server/web-dir/' + self.path, 'rb') - except: - self.send_response(404) - self.end_headers() - return - - #Simulate partial download - partial_download = False - if self.path == "//100/pack-test-bundle-from-10.tar" and SlowResponse.first_time: - partial_download = True - SlowResponse.first_time = False - self.send_response(206) - else: - self.send_response(200) - self.send_header("Content-type", "text/html") - self.end_headers() - delay = 0.00001 # seconds - - while True: - b = f.read(100) - if b == b'': - break - - self.wfile.write(b) - if partial_download: - break; - time.sleep(delay) - self.wfile.flush() - f.close() - -if __name__ == '__main__': - print(sys.argv) - addr = ('', int(sys.argv[1])) - httpd = server.HTTPServer(addr, SlowResponse) - httpd.serve_forever()