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 <john.w.akre@intel.com>
This commit is contained in:
John Akre
2018-10-24 09:56:02 -07:00
committed by Otavio Pontes
parent 9002f69817
commit 897f5d44c8
5 changed files with 75 additions and 104 deletions
@@ -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
+54 -10
View File
@@ -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
+7 -5
View File
@@ -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] <server priv key> [-p] <server pub key> [-s]
Options:
start_web_server [-c] <client pub key> [-p] <server pub key> [-k] <server priv key> [-s]
start_web_server [-c] <client pub key> [-d] <file name> [-k] <server priv key> [-p] <server pub key> [-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" ;;
+12 -37
View File
@@ -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
}
@@ -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()