Testing Playground
Overview of the playground
The Testing Playground is a new testing system added to the Ersilia testing pipeline. It aims to advance the testing pipeline using the ersilia CLI commands. It provides a flexible and robust framework for validating and profiling CLI commands that are being used for managing Ersilia models from various sources, such as GitHub, DockerHub, and local directories.
Why its needed?
Recently we have faced a few issues with the model hub as well the model themselves. It was difficult to trace back the error at deeper level when several failures happened. So playground CLI testing intended to check ersilia system using a CLI with user based rules and expected behavior such as what do we expect after we perform some CLI commands. This make sure that everything is running or executed as we expected it to be.
Playground Key Features
Enhanced Testing for CLI Commands:
Supports five CLI commands currently:
delete
,fetch
,serve
,run
,close
.Ensures accurate validation of model and CLI behavior and performance.
Customizable Rules:
Users can define custom rules using the
rules.py
file, leveraging theRegistry Design Pattern
to make sure single instance of rule instantiated.Rules can specify expected behavior and perform checks after each command execution.
Resource Profiling:
After a single check performed, its memory usage, execution time, and check pass or fail of our expected behavior will be captured.
Logs errors and exceptions to assist with debugging.
Pytest Integration: -Every checks are using pytest and expecetd to pass several assertions.
Collects test results in a shared list (
shared.py
) for aggregation since pytest does not allow a direct or nice reporting display in the pytest code.A global config file defined in
conftest.py
at the root of project directory which displays results in a Rich table with memory, runtime, and status information with pytest printhook (pytest_terminal_summary(terminalreporter, exitstatus, config)
).
Configurable Execution:
The playground has
config.yml
file that supports several configureable options including single or multiple commdand execution of models, selecting command type, and more.
Nox Integration:
The playground is powered by
nox
.nox
run tests in isolated or existing Python environments usingnox
sessions. All the sessions are defined in thenoxfile.py
.
How It Works?
PLayground folder structure
The playground folder structure are given below, one folder that wont't be explained anyhere in detail is `files`. It is simply used for input, output, and error logs files to be stored, to make the playgroud folder a bit cleaner.
Defining Rules:
The user creates rules in `rules.py` to validate some expected behavior. These rules are executed after each CLI command is executed. For instance we want to check folder eixtence after we fetch a model, this rule is going to get executed after the fetch command is done. Our expected behaviour is ```True``` in this case, we want the folder of the model exists. The rule structure mainly contains `rule registry`, `the rule it self` and a function to access registered rules (`get_rules`).
Here is rule registry decorator looks like:
Here is an example rule for checking folder existence for the fetched model. When the rule is defined the minimum structure has to be satified specially the exception or assertion handling part.
Run Commands:
The rule defined above will be registed in the `get_rule` function below. The design pattern for the rule definition ensures that onc instance of a single rule will be created and accessed.
In the
commands.py
we import our rules and put them in theapply_rules
function after the fetch section for our case and lets assume that we fetched from--from_dockerhub
:The `apply_rules` function will then be executed in `execute_commands` function like the snippet below. The `create_compund_input_csv` gets executed at the start of command of execution, helps to generate input example at run time to enable auto input example file generation at github workflow. But locally we can use our own file by specifying at the `config.yml` with `input_file` section and just remove this function. We may need some option for that in next update:
Then after this, we have a pytest function that does the tests for the commands. Here is the pytest code snippet for that.
Note that the `get_command_names` function provides all the five commands and structured and appropriate way to efficiently run them on pytest test function in parameterized way. This helper function is defined in `utils.py` file.
Capture Results and Display:
To be able to share data from a `commands.py` to a pytest print hook defined at the root in `conftest.py`, the `shared.py` was created. This file simple defined an empty list `result = []`, to store every necessary info from a pytest execution as below:
Then aggregated test outcomes in a
shared.py
list will be presented in a Rich table withinconftest.py
then to the terminal.Then the final thing is to call and run the pytest command file `commands.py` in the nox session runner `noxfile.py`. So by defualt ersilia has multiple selected models(defined in `config.yml` at `model_ids` section) and we run several tests on them. Those tests include, for a runner type `single` are `auto fetcher`: to fetch models automatically from a recommened source, `fetch from github`, `fetch from docker hub`, `serve the fetched model` and run either **Conventional Runner** (its a runner that does a detail checkups on the input files schema but slower) and **Standard Runner** (which accepts standard input file and does a few checkups but faster) will be run. For runner type `multiple` fetching from a dockerhub for all `model_ids` at once and serve them in batch. Before that an example session code given for `fetching from github` and runner type `single` as below:
If we need to create another session we can update the config file using
update_yaml_values
such as changing the runner type or other things. To run a nox session, we need to go to the playground folder and type the following. To only run a custom session we type:To run all sessions
Or we can run them from any folder but by specifying the where the nox file existed using
-f /path/to/noxfile.py
. Below is an example of minimal terminal output
Configuration
The config.yml
file specifies various options for customizing the playground structured as below:
Github action workflow intergation
In addition to using the playground locally, its also a part of in Ersilia's CI/CD workflow. Its integrated at `test_and_cleanup.yml` workflow file. For a single runner, the sessions are independent so that they were implemented to be parallely executed. But for the multiple runner they are dependent on each other (we can not serve before fetch gets completed), they were implemented to run one after the other. Example codes below:
Last updated