Skip to main content

CACTUS Client

This is a set of tools for evaluating CSIP-Aus server test procedures defined at CACTUS Test Definitions.

image

Development

pip install -e .[dev,test]

Quickstart

Installing

CACTUS requires Python 3.12+

Install the latest version from pypi with: pip install cactus-client

If you're looking to update to the latest version: pip install --upgrade cactus-client

To ensure it's installed properly cactus --help

Working Directory Configuration

CACTUS requires two things:

  1. A configuration file - stored either in your home directory or elsewhere (will be created below).
  2. A working directory - Where all run outputs will be stored.

Portable Installation

If you're trying to keep CACTUS to a single working directory (and want all of your CACTUS operations to run out of that working directory):

  1. Create a new empty directory (eg mkdir cactus-wd)
  2. cd cactus-wd
  3. cactus setup -l .

Please note - all CACTUS commands will now require you to operate out of the ./cactus-wd/ directory

  1. cd cactus-wd
  2. cactus server

Global Installation

If you'd like your CACTUS commands to work from any directory (but still have the results all stored in the working directory):

  1. Create a new empty directory (eg mkdir cactus-wd)
  2. cactus setup -g cactus-wd
  3. cactus server

Client/Server Config

Setup the server connections details (dcap refers to your DeviceCapability URI)

  1. cactus server dcap https://your.server/dcap
  2. cactus server verify true
  3. cactus server serca path/to/serca.pem
  4. cactus server notification https://cactus.cecs.anu.edu.au/client-notifications/

Setup your first client - You will be prompted to populate each field (like below)

  1. cactus client myclient1 You should see output like the following
Would you like to create a new client with id 'myclient1' [y/n]: y
What sort of client will this act as? [device/aggregator]: device
File path to PEM encoded client certificate: ./testdevice.crt
File path to PEM encoded client key: ./testdevice.key.decrypt
Auto calculate lfdi/sfdi from certificate? [y/n]: y
lfdi=0F3078CFDDAEE28DC20B95635DC116CC2A6D877F
sfdi=40773583337
Client Private Enterprise Number (PEN) (used for mrid generation): 12345
Client PIN (used for matching EndDevice.Registration): 111115
The DERSetting.setMaxW and DERCapability.rtgMaxW value to use (in Watts): 5000
.cactus.yaml has been updated with a new client.
                         myclient1                                                  
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ key              ┃ value                                         ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ type             │ device                                        │
│ certificate_file │ ./testdevice.crt ✓                            │
│ key_file         │ ./testdevice.key.decrypt ✓                    │
│ lfdi             │ 0F3078CFDDAEE28DC20B95635DC116CC2A6D877F      │
│ sfdi             │ 40773583337                                   │
│ max_watts        │ 5000                                          │
│ pen              │ 123455                                        │
│ pin              │ 111115                                        │
│ user_agent       │ null                                          │
└──────────────────┴───────────────────────────────────────────────┘

To update individual client settings (eg to add a User-Agent header to requests) just specify the parameter to update and new value:

cactus client myclient1 user_agent "cactus client myclient1"

Discovering available tests

The command cactus tests will print out all available test cases...

                                                     Available Test Procedures                                                     
┏━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Id       ┃ Category     ┃ Description                                                ┃ Required Clients                         ┃
┡━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ S-ALL-01 │ Registration │ Discovery with Out-Of-Band registration                    │ 1 client(s) with type(s): any            │
│ S-ALL-02 │ Registration │ Discovery with In-Band Registration for Direct Clients     │ 1 client(s) with type(s): device         │
...

Running your first test

The following command will run the S-ALL-01 test with the client you created earlier:

cactus run S-ALL-01 myclient1

cactus run options

Flag Description
--headless Disable the terminal UI — logs are written to stderr instead. Useful for CI/scripted environments.
--timeout SECONDS Abort and fail the test if it exceeds this many seconds.
--strict Treat warnings as failures. The test will be marked FAIL if any warnings were emitted, even if all steps passed.
--allow-skips Permit admin plugins to waive individual steps that can't be set up in this environment (see Admin plugins). A run that only passed because of a waived step is reported as PASS*, not a clean pass.
-c PATH Override the config file location (defaults to ./.cactus.yaml then ~/.cactus.yaml).

Running all tests automatically

cactus autorun runs all (or a selected subset of) test procedures sequentially, assigning configured clients to each test automatically. It stops at the first failure.

cactus autorun
cactus autorun --include S-ALL-01 S-ALL-02
cactus autorun --include-file my-tests.txt --exclude S-DER-09
cactus autorun --strict --headless --timeout 120

cactus autorun options

Flag Description
--include ID [ID ...] Only run these test procedure IDs (in the order given).
--include-file PATH Path to a text file listing test IDs to run, one per line (# lines are treated as comments). Merged with --include.
--exclude ID [ID ...] Skip these test procedure IDs. Applied after --include/--include-file.
--timeout SECONDS Per-test timeout in seconds. A test that times out is marked as failed and the run stops.
--strict Treat warnings as failures for every test in the run.
--allow-skips Permit admin plugins to waive individual steps for every test in the run. Overrides runner.allow_skips from config.
--headless Disable the terminal UI for all tests.
--quiet Only print the full result panel for failed tests — passed tests still get their per-test HTML report, just not the console panel. Useful for large suites where dozens of passed-test panels bury the failures.
-c PATH Override the config file location.

Persistent autorun config

All autorun options (except --headless and -c) can be stored in .cactus.yaml under the runner key so you don't need to pass them on every invocation. CLI flags always take precedence over the file.

runner:
  include: []          # list of test IDs to include (empty = all)
  include_file: null   # path to an include-file
  exclude: []          # list of test IDs to skip
  timeout: null        # per-test timeout in seconds
  strict: false        # treat warnings as failures
  allow_skips: false   # permit admin plugins to waive individual steps
  quiet: false          # only show the result panel for failed tests

Viewing the compliance report

After running tests, print a summary of the latest result for each test procedure:

cactus report

This scans the configured output_dir and shows a table of every test procedure with its most recent PASS/FAIL result and timestamp. The same report is printed automatically at the end of cactus autorun.

Admin plugins

Some test procedures include admin_instruction steps — directives for an out-of-band admin agent to perform setup on the server under test (e.g. registering end devices, issuing DER controls). These are handled by plugins loaded at runtime.

Plugins are built using apluggy, a simple async wrapper around pytest's pluggy. See plugins.py for the hookspecs your plugin can implement:

Hook When called
admin_setup Once before any test steps run
admin_teardown Once after all steps complete (or on failure) — always runs
admin_instruction Once per admin instruction, before the first attempt of the owning step

Plugins are discovered automatically via setuptools entry points — no code changes to cactus-client required:

# pyproject.toml
[project.entry-points."cactus_client.admin"]
my-plugin = "my_package.plugin:MyServerPlugin"

Install your plugin alongside cactus-client (pip install -e .) and it will be loaded on next invocation.

Waiving steps your plugin can't set up: You may want to skip certain test steps based on different server use cases (difficulty with state in certain environments like CI/CD). If admin_instruction returns ActionResult.skip_step("reason"), the step's action still runs, but its pass/fail judgement is waived — provided the run was started with --allow-skips / runner.allow_skips. Without that flag, a requested skip is treated as a normal step failure. A run containing waived steps is reported as PASS*, and the reason strings are recorded in .skips in the run's output directory. See the admin_instruction hookspec docstring in plugins.py for the full contract, including why skipping only makes sense on terminal/leaf steps.

Runs with --allow-skips set will not be considered suitable for compliance testing.

Reference implementation: cactus-client-envoy is a full worked example — it implements all three hooks against a local Envoy CSIP-Aus server via direct database access, and includes setup scripts and a complete quickstart guide.

Metadata

Release files for cactus-client 1.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cactus-client 1.3.0
File Size Uploaded
cactus_client-1.3.0.tar.gz 151.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cactus-client 1.3.0
File Interpreter ABI Platform
cactus_client-1.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 328.9 kB

Release files / cactus_client-1.3.0.tar.gz

Download URL cactus_client-1.3.0.tar.gz
Size 151.4 kB
Tags Source
SHA-256 checksum
How to use checksums
78ecf26f9c06218c44696130c4f0b5dbfe2e9929f081e0ad8e14fcb1b5f74d31
BLAKE2b-256 checksum
How to use checksums
5e075a8071d39db49eb078bb2901a72a53d6dff79d1d180d90ac15f6771643e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / cactus_client-1.3.0-py3-none-any.whl

Download URL cactus_client-1.3.0-py3-none-any.whl
Size 177.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c6e67009668264ca00862a20c5b224b192c2b43198e344af109375d7313f48c1
BLAKE2b-256 checksum
How to use checksums
6cb0177dc0baf71c2b85a5991f23af7c34ac0d50b82a1f6a4e9aa8dee74271b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

1.3.3

2 release files

1.3.2

2 release files

1.3.1

2 release files

This release

1.3.0 This release

2 release files

1.2.0

2 release files

1.1.3

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.10

2 release files

0.0.9

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page