Configuration¶
Directory Structure¶
An etr
test module is similar to a wtools
module structure but it has an etr.yaml
file
instead of wscript
in the root:
<root> # module root
|-- etr.yaml # main configuration file
`-- src # source directory for test files
A minmum example using Robot Framework:
<root>
|-- etr.yaml
`-- src
`-- tests.robot
Contents of etr.yaml
:
version: "1.0"
plugins:
- etr.plugins.robot
robot:
tests:
- src/tests.robot
Main Configuration File¶
The etr.yaml
configuration file has the following basic schema:
version: "1.0"
# Optional config, by default it's True
randomize: True|False
# List of plugins to load
plugins:
- <plugin>
Then each loaded plugin might have their own schema with a root node. For example the robot plugin etr.plugins.robot
has the following schema:
version: "1.0"
plugins:
- etr.plugins.robot
robot:
tests:
- src/my-test.robot
- src/my-other-test.robot
Note
By default test execution order, as specified in the configuration file, is randomized.
For robot this means that one should write the robot test suite files without expectation
that other test suites have been executed. This has the benefit of being able to execute
a subset of tests without them breaking which is useful for speed.
If this is infeasible the randomize: False
can be set.
Plugins¶
Most of the heavy lifting in etr is done with plugins, where the core application just schedules execution of plugins. This chapter documents the built in plugins and how they are configured.
Note
The plugin execution order is determined by the plugins themselves using a fixed ordering value. The order of plugins in the configuration files does not make a difference.
etr.plugins.robot
¶
This is the plugin that enables the running of Robot tests.
The etr.yaml
configuration is as follows:
version: "1.0"
plugins:
- etr.plugins.robot
robot:
tests:
- "src/my-test.robot"
- "src/my-other-test.robot"
Where the list under tests specifies the robot test files to be executed.
etr.plugins.resources
¶
To acquire test resources automatically a the plugin etr.plugins.resources
can be used.
Test resources can be anything and etr
does not use it directly. But attributes from acquired
resources can be used to process configuration files using the etr.plugins.jinja2
plugin for
example.
Resources can come from two sources:
- Local configuration files where configuration file must be provided with
$RESOURCE_FILE
or--resource-file
option. - Via the Resource Manager Web Service where the host must be provided with
$RESOURCE_HOST
or--resource-host
option.
Compared to the Resource Manager Web Service the local resources it does not provide any schema validation. So a specific resource type is not guaranteed to follow a specific schema.
To use local resources, create a file with the following structure:
version: "1.0"
resources:
<resource-id>:
type: <type>
tags:
- <tag>
- <tag>
attributes:
<attributes>
Where
<resource-id>
- is the identifier for the resource in the file,
<type>
- is the main resource type specifier.
<tag>
- is an optional list of tags that can be used for filtering purposes by clients.
<attributes>
- is the resource attributes that is added to the
etr
execution contexts so they can be used by e.g. other plugins.
An example configuration of two opcua-shutter’s with some attributes. Tags are optional and has been left empty in shutter2 in this example:
version: "1.0"
resources:
"shutter1":
type: "opcua-shutter"
tags:
- "v1"
attributes:
"server": "opc.tcp://134.171.12.186:4840"
"namespace": 4
"prefix": "MAIN.Shutter1"
"shutter2":
type: "opcua-shutter"
attributes:
"server": "opc.tcp://134.171.12.186:4840"
"namespace": 4
"prefix": "MAIN.Shutter2"
Note
The resource ids “shutter1” and “shutter2” is the identifier for the resource and can be
anything in the character class [A-Za-z0-9_-]
. The resource id’s are only used for the
purpose of identifying locked resources and is not seen by the user.
To acquire and use a resource the etr.yaml
is updated to include request the resource “shutter”
with type “opcua-shutter”:
version: "1.0"
plugins:
- etr.plugins.robot
- etr.plugins.resources
# Robot plugin configuration
robot:
tests:
- src/test.robot
# Resources plugin configuration
resources:
"shutter":
type: "opcua-shutter"
Note
The resource name “shutter” is the user provided name for the resource once acquired. This
is used when populating the context environments as well. See the etr.plugins.jinja2
plugin for example.
etr.plugins.jinja2
¶
The etr.plugins.jinja2
plugin allows the processing of template files using the Jinja2 template
engine (c.f. the Jinja 2 documentation).
The etr.yaml configuration is simple and takes dictionary of files to process as "input" ->
"output"
files. An example that uses robot tests and jinja2 follows:
version: "1.0"
plugins:
- etr.plugins.jinja2
- etr.plugins.robot
- etr.plugins.resources
# Resources plugin configuration which acquires the
# requried resources
resources:
# My name/id for the acquired resource will be `shutter`.
"shutter":
type: "opcua-shutter"
# Jinja2 generates the src/test.robot file from the
# src/test.robot.j2 template file:
jinja2:
files:
"src/test.robot.j2": "src/test.robot"
# Robot finally runs the tests
robot:
tests:
- "src/test.robot"
The attributes for the acquired opcua-shutter with the provided name/id shutter can then for
example be used with the plugin which sets the attributes under the “resources” dictionary key, so
the variable {{ resources.shutter.server }}
will be expanded to
opc.tcp://134.171.12.186:4840
.
Note
The name provided for a resource in the configuration is the local name for the resource which is used as the primary key to look up that resource in the “resources” dictionary provided in the jinja2 template.
The resource will in addition have a corresponding identifier from where it was acquired, but that is of no concern.
The file src/test.robot.j2
might look like this:
*** Settings ***
Library Process
Library Shutter.py
*** Variable ***
${PLC_SERVER} {{ resources.shutter.server }}
${NAME_SPACE} {{ resources.shutter.namespace }}
${PREFIX_DEVICE1} {{ resources.shutter.prefix }}
${CMD_PORT} 5582
*** Test Cases ***
Reset PLC Controller
Reset Controller ${PLC_SERVER} ${NAME_SPACE} ${PREFIX_DEVICE1}
Reset Controller ${PLC_SERVER} ${NAME_SPACE} ${PREFIX_DEVICE2}
Sleep 2
And results in something like this (notice how the variables become populated):
*** Settings ***
Library Process
Library Shutter.py
*** Variable ***
${PLC_SERVER} opc.tcp://134.171.12.186:4840
${NAME_SPACE} 4
${PREFIX_DEVICE1} MAIN.Shutter1
${CMD_PORT} 5582
*** Test Cases ***
Reset PLC Controller
Reset Controller ${PLC_SERVER} ${NAME_SPACE} ${PREFIX_DEVICE1}
Reset Controller ${PLC_SERVER} ${NAME_SPACE} ${PREFIX_DEVICE2}
Sleep 2
etr.plugins.nomad
¶
The etr.plugins.nomad
plugin allows deployment using Nomad job specification files (c.f. the
Nomad documentation).
- During setup each job specification file in nomad.jobs list is:
- Registered (deployed) with Nomad (if the job already exists the registration will fail).
- etr will monitor the job and wait for it to become stable (all tasks are running).
- During teardown:
- Each job will be unregistered (undeployed) in reverse order.
The etr.yaml configuration is simple and takes dictionary of job specification files register (deploy). An example that uses nomad follows:
version: "1.0"
plugins:
- etr.plugins.nomad
nomad:
jobs:
- "src/services.nomad"
Note
- Currently support is limited to service job type.
- Service discovery after deployment can be performed by using e.g. Consul.