-
Notifications
You must be signed in to change notification settings - Fork 254
/
Webtest.sh
executable file
·174 lines (167 loc) · 8.78 KB
/
Webtest.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#! /bin/bash
# Copyright 2017 Fortio Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -x
# Check we can build the image
NATIVE_PLATFORM=$(docker buildx --builder default inspect | awk '/Platforms:/ {print $2}' | sed -e 's/,//g')
echo "Building for $NATIVE_PLATFORM"
make docker-internal TAG=webtest BUILDX_PLATFORMS="$NATIVE_PLATFORM" MODE=dev || exit 1
FORTIO_UI_PREFIX=/newprefix/ # test the non default prefix (not /fortio/)
FILE_LIMIT=25 # must be low to detect leaks, go 1.14 seems to need more than go1.8 (!)
LOGLEVEL=info # change to debug to debug
MAXPAYLOAD=8 # Max Payload size for echo?size= in kb
TIMEOUT=10s # need to be higher than test duration done through fetch
#CERT=/etc/ssl/certs/ca-certificates.crt
TEST_CERT_VOL=/etc/ssl/certs/fortio
DOCKERNAME=fortio_server
DOCKERSECNAME=fortio_secure_server
DOCKERSECVOLNAME=fortio_certs
FORTIO_BIN_PATH=fortio # /usr/bin/fortio is the full path but isn't needed
# Unresolvable should error out - #653
docker run fortio/fortio:webtest curl http://doesnt.exist.google.com/
if [[ $? == 0 ]]; then
echo "Error in curl should show up in status"
exit 1
fi
# Expect error with extra args: (timeout (brew install coreutils) returns 124
# for timeout) - #652
timeout 3 docker run fortio/fortio:webtest server -loglevel debug extra-arg
if [[ $? == 124 || $? == 0 ]]; then
echo "Unrecognized extra args/typo in flags should error out immediately"
exit 1
fi
DOCKERID=$(docker run -d --ulimit nofile=$FILE_LIMIT --net host --name $DOCKERNAME fortio/fortio:webtest server -ui-path $FORTIO_UI_PREFIX -loglevel $LOGLEVEL -maxpayloadsizekb $MAXPAYLOAD -timeout=$TIMEOUT -pprof)
function cleanup {
set +e # errors are ok during cleanup
# docker logs "$DOCKERID" # uncomment to debug
docker stop "$DOCKERID"
docker rm -f $DOCKERNAME
docker stop "$DOCKERSECID" # may not be set yet, it's ok
docker rm -f $DOCKERSECNAME
docker stop "$DOCKERCURLID"
docker rm -f $DOCKERSECVOLNAME
}
trap cleanup EXIT
set -e
set -o pipefail
docker ps
BASE_URL="http://localhost:8080"
BASE_FORTIO="$BASE_URL$FORTIO_UI_PREFIX"
LOGO=fortio-logo-gradient-no-bg.svg
CURL="docker exec $DOCKERNAME $FORTIO_BIN_PATH curl -loglevel $LOGLEVEL -timeout $TIMEOUT"
# Check https works (certs are in the image) - also tests autoswitch to std client for https
$CURL https://www.google.com/robots.txt > /dev/null
# Check that quiet is quiet. Issue #385.
QUIETCURLTEST="docker exec $DOCKERNAME $FORTIO_BIN_PATH curl -quiet -curl-stdout-headers www.google.com"
if [ "$($QUIETCURLTEST 2>&1 > /dev/null | wc -l)" -ne 0 ]; then
echo "Error, -quiet still outputs logs"
$QUIETCURLTEST > /dev/null
exit 1
fi
# Check we can connect, and run a http QPS test against ourselves through fetch
$CURL "${BASE_FORTIO}fetch/localhost:8080$FORTIO_UI_PREFIX?url=http://localhost:8080/debug&load=Start&qps=-1&json=on" | grep ActualQPS
# Check we can do it twice despite ulimit - check we get all 200s (exactly 80 of them (default is 8 connections->16 fds + a few))
$CURL "${BASE_FORTIO}fetch/localhost:8080$FORTIO_UI_PREFIX?url=http://localhost:8080/debug&load=Start&n=80&qps=-1&json=on" | grep '"200": 80'
# Same but using the rest api instead
$CURL "${BASE_FORTIO}fetch/localhost:8080${FORTIO_UI_PREFIX}rest/run?url=http://localhost:8080/debug&n=80&qps=-1" | grep '"200": 80'
# Check we can connect, and run a grpc QPS test against ourselves through fetch
$CURL "${BASE_FORTIO}fetch/localhost:8080$FORTIO_UI_PREFIX?url=localhost:8079&load=Start&qps=-1&json=on&n=100&runner=grpc" | grep '"SERVING": 100'
# Check we get the logo (need to remove the CR from raw headers)
VERSION=$(docker exec $DOCKERNAME $FORTIO_BIN_PATH version)
LOGO_TYPE=$($CURL "${BASE_FORTIO}${VERSION}/static/img/${LOGO}" 2>&1 >/dev/null | grep -i Content-Type: | tr -d '\r'| awk '{print $2}')
if [ "$LOGO_TYPE" != "image/svg+xml" ]; then
echo "Unexpected content type for the logo: $LOGO_TYPE"
exit 1
fi
# Check we can get the JS file through the proxy and it's > 50k
SIZE=$($CURL "${BASE_FORTIO}fetch/localhost:8080${FORTIO_UI_PREFIX}${VERSION}/static/js/Chart.min.js" |wc -c)
if [ "$SIZE" -lt 50000 ]; then
echo "Too small fetch for js: $SIZE"
exit 1
fi
# Check if max payload set to value passed in cmd line parameter -maxpayloadsizekb
SIZE=$($CURL "${BASE_URL}/echo?size=1048576" |wc -c)
# Payload is 8192 but between content chunking and headers fast client can return up to 8300 or so
if [ "$SIZE" -lt 8191 ] || [ "$SIZE" -gt 8400 ]; then
echo "-maxpayloadsizekb not working as expected"
exit 1
fi
# Check main, sync, browse pages
LOGOPATH="${VERSION}/static/img/${LOGO}"
for p in "" browse sync; do
# Check the page doesn't 404s
$CURL ${BASE_FORTIO}${p}
# Check that page includes the logo
LOGOS=$($CURL ${BASE_FORTIO}${p} | { grep -c "$LOGOPATH" || true; })
if [ "$LOGOS" -ne 1 ]; then
echo "*** Expected to find logo $LOGOPATH in the ${BASE_FORTIO}${p} page"
exit 1
fi
done
# Do a small http load using std client
docker exec $DOCKERNAME $FORTIO_BIN_PATH load -stdclient -qps 1 -t 2s -c 1 https://www.google.com/
# and with normal and with custom headers
docker exec $DOCKERNAME $FORTIO_BIN_PATH load -H Foo:Bar -H Blah:Blah -qps 1 -t 2s -c 2 http://www.google.com/
# Do a grpcping
docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping localhost
# Do a grpcping to a scheme-prefixed destination. Fortio should append port number
# Do a TLS grpcping. Fortio.org should use valid cert.
docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping https://grpc.fortio.org
docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping grpc.fortio.org # uses default non tls 8079
# Do a local grpcping. Fortio should append default grpc port number to destination
docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping localhost
# Do a local health ping
docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping -health localhost
docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping -health -healthservice ping localhost
# Do a failing on purpose check
if docker exec $DOCKERNAME $FORTIO_BIN_PATH grpcping -health -healthservice ping_down localhost; then
echo "*** Expecting grpcping -health to ping_down have exit with error/non zero status"
exit 1
fi
# pprof should be there, no 404/error
PPROF_URL="$BASE_URL/debug/pprof/heap?debug=1"
$CURL "$PPROF_URL" | grep -i TotalAlloc # should find this in memory profile
# creating dummy container to hold a volume for test certs due to remote docker bind mount limitation.
DOCKERCURLID=$(docker run -d -v $TEST_CERT_VOL --net host --name $DOCKERSECVOLNAME docker.io/fortio/fortio.build:v77@sha256:03af2e7202d5364fb3424c9ef28f372702081ee809b7f8dfbb2a1b649b0b4c2c sleep 120)
# while we have something with actual curl binary do
# Test for h2c upgrade (#562)
docker exec $DOCKERSECVOLNAME /usr/bin/curl -v --http2 -m 10 -d foo42 http://localhost:8080/debug | tee >(cat 1>&2) | grep foo42
# then resume the self signed CA tests
# copying cert files into the certs volume of the dummy container
for f in ca.crt server.crt server.key; do docker cp "$PWD/cert-tmp/$f" "$DOCKERSECVOLNAME:$TEST_CERT_VOL/$f"; done
# start server in secure grpc mode. uses non-default ports to avoid conflicts with fortio_server container.
# mounts certs volume from dummy container.
DOCKERSECID=$(docker run -d --ulimit nofile=$FILE_LIMIT --name $DOCKERSECNAME --volumes-from $DOCKERSECVOLNAME fortio/fortio:webtest server -cacert $TEST_CERT_VOL/ca.crt -cert $TEST_CERT_VOL/server.crt -key $TEST_CERT_VOL/server.key -grpc-port 8097 -http-port 8098 -redirect-port 8090 -loglevel $LOGLEVEL)
# run secure grpcping and load tests
docker exec $DOCKERSECNAME $FORTIO_BIN_PATH grpcping -cacert $TEST_CERT_VOL/ca.crt localhost:8097
docker exec $DOCKERSECNAME $FORTIO_BIN_PATH load -grpc -cacert $TEST_CERT_VOL/ca.crt localhost:8097
# switch to report mode
docker stop "$DOCKERID"
docker rm $DOCKERNAME
DOCKERNAME=fortio_report
# Even with pprof the report mode won't have pprof endpoint
DOCKERID=$(docker run -d --ulimit nofile=$FILE_LIMIT --name $DOCKERNAME fortio/fortio:webtest report -loglevel $LOGLEVEL -pprof)
docker ps
CURL="docker exec $DOCKERNAME $FORTIO_BIN_PATH curl -loglevel $LOGLEVEL"
if $CURL "$PPROF_URL" ; then
echo "pprof should 404 on report mode!"
exit 1
else
echo "expected pprof failure to access in report mode - good !"
fi
# base url should serve report only UI in report mode
$CURL $BASE_URL | grep "report only limited UI"
# we should get the tsv without error
$CURL $BASE_URL/data/index.tsv
# cleanup() will clean everything left even on success