Implementing test case executors
The code
block within the leonidas_aws
section should contain the Python code necessary to execute a given test case within AWS. Typically, this will involve calling out to the AWS APIs via a boto3 client. This document outlines the libraries available and variables that are pre-populated for you, and how to correctly return the results such that they appear in the HTTP API response and also in the logs.
Example AWS test case code
Available Variables and Objects
clients
A python dictionary containing each boto3 client defined by the clients
parameter in the definition YAML.
Behind the scenes, Leonidas will handle assuming any roles or using any AWS access keys that are passed as parameters to the request. The clients available to the code are instantiated using the identity defined by the role or access key parameters. If none are supplied, it defaults to the role the lambda function is assigned (or the default profile specified in ~/.aws/config
if run locally)
identity
A python dictionary defining the following fields:
This should generally not be used directly, as the framework uses this data to construct the boto3 clients available in the clients
dictionary. It is, however, available if required.
Case-specific input arguments
Arguments for a given test case are defined in the input_arguments
field in the test case definition. These are made available to the test case code as local variables with the same names as the name used in the input_arguments
block.
Under the hood, the generated API code sets the value of a given variable to the value passed to the API call, unless no value is passed in. If no value is supplied, the default value defined in the input_arguments
block is used.
Returning Data
The result
variable should be set to the test case results. This is returned as a response to the HTTP request made to the API, and also logged as part of the case execution log by the function. The test case itself should not include a return
statement, as this will interfere with Leonidas’ logging and auditing capabilities.
Implementing Kubernetes test cases
The Kubernetes test cases result to shell invocations of the kubectl
binary. This method of interaction was selected in order to make definition writing easier and to leverage the computation logic performed by these binaries behind the scenes, a feature which the currently existing Python libraries do not offer.
As such, the code
block of the sh
executor is processed for the test case, and any leonidas_kube
field othen than the implemented
flag will be ignored. The code
block should therefore contain the shell commands necessary to execute a given test case against a kubernetes cluster. Typically, this will involve making calls to the Kubernetes APIs, by executing binaries such as kubectl
.
Example Kubernetes test case code
Available Variables and Objects
Case-specific input arguments
Arguments for a given test case are defined in the input_arguments
field in the test case definition. These are made available to the test case code as local variables with the same names as the name used in the input_arguments
block.
Under the hood, the generated Python code sets the value of a given variable to the value passed to the API call, unless no value is passed in. If no value is supplied, the default value defined in the input_arguments
block is used.
Returning Data
Behind the scenes, the executors.sh.code
set of commands is passed to Python’s subprocess.run
. The standard output and error streams of the spawned process are all collected, along with the return code, and returned in the result
dictionary.
The test case itself should not include a return
statement, as this will interfere with Leonidas’ logging and auditing capabilities.
Implementing Azure Test Cases
Not yet supported
Implementing Google Cloud Test Cases
Not yet supported