Test Suite:
===========
A YAML test file consists of:
* an optional `setup` section, followed by
* one or more test sections
For instance:
setup:
- do: ....
- do: ....
---
"First test":
- do: ...
- match: ...
---
"Second test":
- do: ...
- match: ...
A `setup` section contains a list of commands to run before each test
section in order to setup the same environment for each test section.
A test section represents an independent test, containing multiple `do`
statements and assertions. The contents of a test section must be run in
order, but individual test sections may be run in any order, as follows:
1. run `setup` (if any)
2. reset the `response` var and the `stash` (see below)
2. run test contents
3. run teardown
The `teardown` should delete all indices and all templates.
Dot notation:
-------------
Dot notation is used for (1) method calls and (2) hierarchical data structures. For
instance, a method call like `cluster.health` would do the equivalent of:
client.cluster.health(...params...)
A test against `_tokens.1.token` would examine the `token` key, in the second element
of the `tokens` array, inside the `response` var (see below):
$val = $response->{tokens}[1]{token} # Perl syntax roolz!
If one of the levels (eg `tokens`) does not exist, it should return an undefined value.
If no field name is given (ie the empty string) then return the current
$val -- used for testing the whole response body.
Use \. to specify paths that actually contain '.' in the key name, for example
in the `indices.get_settings` API.
Skipping tests:
---------------
If a test section should only be run on certain versions of Elasticsearch,
then the first entry in the section (after the title) should be called
`skip`, and should contain the range of versions to be
skipped, and the reason why the tests are skipped. For instance:
....
"Parent":
- skip:
version: "0 - 0.90.2"
reason: Delete ignores the parent param
- do:
... test definitions ...
....
All tests in the file following the skip statement should be skipped if:
`min <= current <= max`.
The `version` range should always have an upper bound. Versions should
either have each version part compared numerically, or should be converted
to a string with sufficient digits to allow string comparison, eg
0.90.2 -> 000-090-002
Snapshot versions and versions of the form `1.0.0.Beta1` can be treated
as the rounded down version, eg `1.0.0`.
Required operators:
-------------------
=== `do`
The `do` operator calls a method on the client. For instance:
....
- do:
cluster.health:
level: shards
....
The response from the `do` operator should be stored in the `response` var, which
is reset (1) at the beginning of a file or (2) on the next `do`.
If the arguments to `do` include `catch`, then we are expecting an error, which should
be caught and tested. For instance:
....
- do:
catch: missing
get:
index: test
type: test
id: 1
....
The argument to `catch` can be any of:
[horizontal]
`missing`:: a 404 response from ES
`conflict`:: a 409 response from ES
`request`:: a generic error response from ES
`param`:: a client-side error indicating an unknown parameter has been passed
to the method
`/foo bar/`:: the text of the error message matches this regular expression
If `catch` is specified, then the `response` var must be cleared, and the test
should fail if no error is thrown.
=== `set`
For some tests, it is necessary to extract a value from the previous `response`, in
order to reuse it in a subsequent `do` and other tests. For instance, when
testing indexing a document without a specified ID:
....
- do:
index:
index: test
type: test
- set: { _id: id } # stash the value of `response._id` as `id`
- do:
get:
index: test
type: test
id: $id # replace `$id` with the stashed value
- match: { _id: $id } # the returned `response._id` matches the stashed `id`
....
The stash should be reset at the beginning of each test file.
=== `is_true`
The specified key exists and has a true value (ie not `0`, `false`, `undefined`, `null`
or the empty string), eg:
....
- is_true: fields._parent # the _parent key exists in the fields hash and is "true"
....
=== `is_false`
The specified key doesn't exist or has a false value (ie `0`, `false`, `undefined`,
`null` or the empty string), eg:
....
- is_false: fields._source # the _source key doesn't exist in the fields hash or is "false"
....
=== `match`
Used to compare two variables (could be scalars, arrays or hashes). The two variables
should be identical, eg:
....
- match: { _source: { foo: bar }}
....
=== `lt` and `gt`
Compares two numeric values, eg:
....
- lt: { fields._ttl: 10000 } # the `_ttl` value is less than 10,000
....
=== `length`
This depends on the datatype of the value being examined, eg:
....
- length: { _id: 22 } # the `_id` string is 22 chars long
- length: { _tokens: 3 } # the `_tokens` array has 3 elements
- length: { _source: 5 } # the `_source` hash has 5 keys
....