summaryrefslogtreecommitdiff
path: root/yarns.webapp/060-validation.yarn
diff options
context:
space:
mode:
Diffstat (limited to 'yarns.webapp/060-validation.yarn')
-rw-r--r--yarns.webapp/060-validation.yarn190
1 files changed, 190 insertions, 0 deletions
diff --git a/yarns.webapp/060-validation.yarn b/yarns.webapp/060-validation.yarn
new file mode 100644
index 0000000..989c80b
--- /dev/null
+++ b/yarns.webapp/060-validation.yarn
@@ -0,0 +1,190 @@
+Validation of CONFGIT
+=====================
+
+The CONFGIT repository contains two types of files we should validate:
+the `lorry-controller.conf` file, and the local Lorry files (specified
+by the former file in `lorries` sections).
+
+Validate `lorry-controller.conf`
+--------------------------------
+
+We'll start by validating the `lorry-controller.conf` file. There's
+several aspects here that need to be tested:
+
+* JSON syntax correctness: if the file doesn't parse as JSON, the
+ WEBAPP should cope and shouldn't change STATEDB in any way.
+* Semantic correctness: the file should contain a list of dicts, and
+ each dict should have the right fields with the right kind of
+ values. See the `README` for details. Other fields are also allowed,
+ though ignored. Again, if there's an error, WEBAPP should cope, and
+ probably shouldn't update STATEDB if there are any problems.
+
+The approach for testing this is to set up an empty STATEDB, then get
+WEBAPP to read a `lorry-controller.conf` with various kinds of
+brokenness, and after each read verify that STATEDB is still empty.
+This doesn't test that if the STATEDB wasn't empty it doesn't change
+existing data, but it seems like a reasonable assumption that an
+update happens regardless of previous contents of STATEDB, given how
+SQL transactions work.
+
+In summary:
+
+* Start WEBAPP without a STATEDB, and have it read its config. Verify
+ STATEDB is empty.
+* Add a `lorry-controller.conf` that is broken in some specific way.
+* Tell WEBAPP to re-read its config.
+* Verify that WEBAPP gives an error message.
+* Verify that STATEDB is still empty.
+
+Repeat this for each type of brokenness we want to ensure WEBAPP
+validates for.
+
+ SCENARIO validate lorry-controller.conf
+ GIVEN a new git repository in CONFGIT
+ AND WEBAPP uses CONFGIT as its configuration directory
+ AND a running WEBAPP
+
+First of all, have WEBAPP read CONFGIT. This should succeed even if
+the `lorry-controller.conf` file doesn't actually exist.
+
+ WHEN admin makes request POST /1.0/read-configuration with dummy=value
+ THEN response matches "Configuration has been updated"
+ AND STATEDB is empty
+
+Add an empty configuration file. This is different from a file
+containing an empty JSON list. It should be treated as an error.
+
+ GIVEN a lorry-controller.conf in CONFGIT containing ""
+ WHEN admin makes request POST /1.0/read-configuration with dummy=value
+ THEN response matches "ERROR"
+ AND STATEDB is empty
+
+Add a syntactically invalid JSON file.
+
+ GIVEN a lorry-controller.conf in CONFGIT containing "blah blah blah"
+ WHEN admin makes request POST /1.0/read-configuration with dummy=value
+ THEN response matches "ERROR"
+ AND STATEDB is empty
+
+Replace the bad JSON file with one that has an unknown section (no
+`type` field). Please excuse the non-escaping of double quotes: it's
+an artifact of how yarn steps are implemented and is OK.
+
+ GIVEN a lorry-controller.conf in CONFGIT containing "[{"foo": "bar"}]"
+ WHEN admin makes request POST /1.0/read-configuration with dummy=value
+ THEN response matches "ERROR"
+ AND STATEDB is empty
+
+What about a section that has a `type` field, but it's set to a
+non-sensical value?
+
+ GIVEN a lorry-controller.conf in CONFGIT containing "[{"type": "BACKUPS!"}]"
+ WHEN admin makes request POST /1.0/read-configuration with dummy=value
+ THEN response matches "ERROR"
+ AND STATEDB is empty
+
+Now we're getting to real sections. A `troves` section must have
+`trovehost`, `interval`, `ls-interval`, and `prefixmap` set, and may
+optionally have `ignore` set. The `trovehost` field can't really be
+checked, and `interval` and `ls-interval` don't need much checking: if
+they don't parse as sensible intervals, Lorry Controller will just use
+a default value.
+
+`prefixmap`, however, can have a reasonable check: it shouldn't map
+something to be under the Trove ID of the local Trove, otherwise Lorry
+won't be able to push the repositories. However, at this time, we do
+not have a reasonable way to get the Trove ID of the local Trove, so
+we're skipping implementing that test for now. (FIXME: fix this lack
+of testing.)
+
+Clean up at the end.
+
+ FINALLY WEBAPP terminates
+
+
+Validate local Lorry files
+--------------------------
+
+Lorry files (`.lorry`) are consumed by the Lorry program itself, but
+also by Lorry Controller. In fact, the ones that are in CONFGIT are
+only consumed by Lorry Controller: it reads them in, parses them,
+extracts the relevant information, puts that into STATEDB, and then
+generates a whole new (temporary) file for each Lorry run.
+
+Lorry Controller doesn't validate the Lorry files much, only
+enough that it can extract each separate Lorry specification and feed
+them to Lorry one by one. In other words:
+
+* The `.lorry` file must be valid JSON.
+* It must be a dict.
+* Each key must map to another dict.
+* Each inner dict must have a key `type`, which maps to a string.
+
+Everything else is left for Lorry itself. Lorry Controller only needs
+to handle Lorry not working, and it already does that.
+
+Firstly, some setup.
+
+ SCENARIO validate .lorry files
+ GIVEN a new git repository in CONFGIT
+ AND an empty lorry-controller.conf in CONFGIT
+ AND lorry-controller.conf in CONFGIT adds lorries *.lorry using prefix upstream
+ AND WEBAPP uses CONFGIT as its configuration directory
+ AND a running WEBAPP
+
+Make sure WEBAPP handles there not being any `.lorry` files.
+
+ WHEN admin makes request POST /1.0/read-configuration with dummy=value
+ THEN response matches "has been updated"
+ AND STATEDB is empty
+ WHEN admin makes request GET /1.0/list-queue
+ THEN response has queue set to []
+
+Add a `.lorry` file that contains broken JSON.
+
+ GIVEN Lorry file CONFGIT/notjson.lorry with THIS IS NOT JSON
+ WHEN admin makes request POST /1.0/read-configuration with dummy=value
+ THEN response matches "has been updated"
+ AND STATEDB is empty
+ WHEN admin makes request GET /1.0/list-queue
+ THEN response has queue set to []
+
+Add a `.lorry` file that is valid JSON, but is not a dict.
+
+ GIVEN Lorry file CONFGIT/notadict.lorry with [1,2,3]
+ WHEN admin makes request POST /1.0/read-configuration with dummy=value
+ THEN response matches "has been updated"
+ AND STATEDB is empty
+ WHEN admin makes request GET /1.0/list-queue
+ THEN response has queue set to []
+
+Add a `.lorry` that is a dict, but doesn't map keys to dicts.
+
+ GIVEN Lorry file CONFGIT/notadictofdicts.lorry with { "foo": 1 }
+ WHEN admin makes request POST /1.0/read-configuration with dummy=value
+ THEN response matches "has been updated"
+ AND STATEDB is empty
+ WHEN admin makes request GET /1.0/list-queue
+ THEN response has queue set to []
+
+Add a `.lorry` whose inner dict does not have a `type` field.
+
+ GIVEN Lorry file CONFGIT/notype.lorry with { "foo": { "bar": "yo" }}
+ WHEN admin makes request POST /1.0/read-configuration with dummy=value
+ THEN response matches "has been updated"
+ AND STATEDB is empty
+ WHEN admin makes request GET /1.0/list-queue
+ THEN response has queue set to []
+
+Add a `.lorry` that is A-OK. This should work even when there are some
+broken ones too.
+
+ GIVEN Lorry file CONFGIT/a-ok.lorry with { "foo": { "type": "git", "url": "git://example.com/foo" }}
+ WHEN admin makes request POST /1.0/read-configuration with dummy=value
+ THEN response matches "has been updated"
+ WHEN admin makes request GET /1.0/list-queue
+ THEN response has queue set to ["upstream/foo"]
+
+Clean up at the end.
+
+ FINALLY WEBAPP terminates