summaryrefslogtreecommitdiff
path: root/yarns.webapp/900-implementations.yarn
diff options
context:
space:
mode:
Diffstat (limited to 'yarns.webapp/900-implementations.yarn')
-rw-r--r--yarns.webapp/900-implementations.yarn119
1 files changed, 119 insertions, 0 deletions
diff --git a/yarns.webapp/900-implementations.yarn b/yarns.webapp/900-implementations.yarn
new file mode 100644
index 0000000..7bfb6bb
--- /dev/null
+++ b/yarns.webapp/900-implementations.yarn
@@ -0,0 +1,119 @@
+Implementations
+===============
+
+This chapter includes IMPLEMENTS sections for the various steps used
+in scenarios.
+
+Managing a WEBAPP instance
+--------------------------
+
+We're testing a web application (convenivently named WEBAPP, though
+the executable is `lorry-controller-webapp`), so we need to be able to
+start it and stop it in scenarios. We start it as a background
+process, and keep its PID in `$DATADIR/webapp.pid`. When it's time to
+kill it, we kill the process with the PID in that file. This is not
+perfect, though it's good enough for our purposes. It doesn't handle
+running multiple instances at the same time, which we don't need, and
+doens't handle the case of the process dying and the kernel re-using
+the PID for something else, which is quite unlikely.
+
+Start an instance of the WEBAPP, using a random port. Record the PID
+and the port. Listen only on localhost. We use `start-stop-daemon` to
+start the process, so that it can keep running in the background,
+but the shell doesn't wait for it to terminate. This way, WEBAPP will
+be running until it crashes or is explicitly killed.
+
+ IMPLEMENTS GIVEN a running WEBAPP
+ # Pick a random port beyond 1024 (i.e., an unreserved one).
+ port=0
+ while [ "$port" -le 1024 ]
+ do
+ port=$RANDOM
+ done
+ echo "$port" > "$DATADIR/webapp.port"
+
+ start-stop-daemon -S -x "$SRCDIR/lorry-controller-webapp" \
+ -b -p "$DATADIR/webapp.pid" -m --verbose \
+ -- \
+ --statedb "$DATADIR/webapp.db" \
+ --log-level debug \
+ --log "$DATADIR/webapp.log" \
+ --debug-host 127.0.0.1 \
+ --debug-port "$port"
+
+ # Wait for the WEBAPP to actually be ready, i.e., that it's
+ # listening on its assigned port.
+ "$SRCDIR/test-wait-for-port" 127.0.0.1 "$port"
+
+Kill the running WEBAPP, using the recorded PID. We need to do this
+both as a WHEN and a FINALLY step.
+
+ IMPLEMENTS WHEN WEBAPP is terminated
+ kill_daemon_using_pid_file "$DATADIR/webapp.pid"
+
+ IMPLEMENTS FINALLY WEBAPP terminates
+ kill_daemon_using_pid_file "$DATADIR/webapp.pid"
+
+Also test that WEBAPP isn't running.
+
+ IMPLEMENTS THEN WEBAPP isn't running
+ pid=$(head -n1 "$DATADIR/webapp.pid")
+ if kill -0 "$pid"
+ then
+ echo "process $pid is still running, but should'nt be" 1>&2
+ exit 1
+ fi
+
+Making and analysing GET requests
+---------------------------------
+
+Simple HTTP GET requests are simple. We make the request, and capture
+the response: HTTP status code, response headers, response body.
+
+We make the request using the `curl` command line program, which makes
+capturing the response quite convenient.
+
+HTTP requests can be made by various entities. For now, we assume
+they're all made by the admin.
+
+We check that the HTTP status indicates success, so that every
+scenario doesn't need ot check that separately.
+
+ IMPLEMENTS WHEN admin makes request GET (\S+)
+ rm -f "$DATADIR/response.headers"
+ rm -f "$DATADIR/response.body"
+ port=$(cat "$DATADIR/webapp.port")
+ curl \
+ -D "$DATADIR/response.headers" \
+ -o "$DATADIR/response.body" \
+ --silent --show-error \
+ "http://127.0.0.1:$port$MATCH_1"
+ cat "$DATADIR/response.headers"
+ cat "$DATADIR/response.body"
+ head -n1 "$DATADIR/response.headers" | grep '^HTTP/1\.[01] 200 '
+
+Check the Content-Type of the response is JSON.
+
+ IMPLEMENTS THEN response is JSON
+ cat "$DATADIR/response.headers"
+ grep -i '^Content-Type: application/json' "$DATADIR/response.headers"
+
+A JSON response can then be queried further. The JSON is expected to
+be a dict, so that values are accessed by name from the dict. The
+value is expresssed as a Python value in the step.
+
+ IMPLEMENTS THEN response has (\S+) set to (\S+)
+ cat "$DATADIR/response.body"
+ python -c "
+ import json, os, sys
+ data = json.load(sys.stdin)
+ key = os.environ['MATCH_1']
+ expected = eval(os.environ['MATCH_2']) # I feel dirty and evil.
+ value = data[key]
+ if value != expected:
+ sys.stderr.write(
+ 'Key {key} has value {value}, but '
+ '{expected} was expected'.format(
+ key=key, value=value, expected=expected))
+ sys.exit(1)
+ " < "$DATADIR/response.body"