Why conformance tests?
Unit tests verify your plugin logic in isolation. Integration tests verify it works with real infrastructure. Conformance tests go further: they verify your plugin behaves correctly when orchestrated by the formae agent, which is how it will actually be used. Conformance tests exercise the full resource lifecycle through the same code paths used in production:What you need
Conformance tests require only PKL files, no Go test code needed. The test framework discovers your PKL files and runs the appropriate lifecycle operations.PklProject.deps.json file is auto-generated when you run the tests, so you don’t need to create it manually.
The config/ folder
Thetestdata/config/ folder is ignored by the conformance test framework. Use it for:
- Shared variables (
vars.pkl): common values like test prefixes, stack names - Target configurations (
target.pkl): reusable target definitions - Helper modules: any PKL files that support your tests but aren’t test cases
Test lifecycle steps
Step 1: Create
The test framework runsformae apply with your base PKL file (e.g., sftp-file.pkl). This creates the resource through your plugin’s Create method.
Step 2: Read and verify
After creation, the framework usesformae inventory to read the resource back and compares it to the expected state from formae eval. This verifies your Read method returns consistent data.
Step 3: Update (optional)
If you provide an update file (e.g.,sftp-file-update.pkl), the framework runs formae apply again with the modified properties. This exercises your plugin’s Update method.
Skip this step if your resource type has only immutable (createOnly) properties.
Step 4: Replace (optional)
If you provide a replace file (e.g.,sftp-file-replace.pkl) that changes a createOnly property, the framework verifies that formae correctly deletes and recreates the resource.
Step 5: Delete
The framework runsformae destroy to remove the resource, exercising your plugin’s Delete method.
Step 6: Discovery
Finally, the framework tests resource discovery:- Creates a resource directly via your plugin (bypassing formae)
- Runs discovery to verify formae detects the unmanaged resource
- Cleans up the resource
List method works correctly for discovery scenarios.
Test data files
Base file (sftp-file.pkl)
The base file defines the initial resource state:
FORMAE_TEST_RUN_ID environment variable is set by the test framework to ensure unique resource names across test runs.
Update file (sftp-file-update.pkl)
Changes mutable properties only:
Replace file (sftp-file-replace.pkl)
Changes a createOnly property, triggering delete + create:
PklProject
Thetestdata/PklProject file configures PKL dependencies:
Running conformance tests
Conformance tests consist of two types: CRUD tests that verify the resource lifecycle, and discovery tests that verify your plugin can find existing resources. By default, both are run together:Filtering tests
To run a specific test by name:TEST parameter filters tests by name pattern. This is useful when debugging a specific resource type.
Regex filters
Wrap a filter segment in/…/ delimiters to use a regular expression:
/…/) or a literal (exact match first, then substring fallback).
Running CRUD or discovery only
CRUD tests exercise the full resource lifecycle: create a resource, read it back, optionally update it, and delete it. These verify your plugin’s Create, Read, Update, and Delete operations work correctly with the formae agent. Discovery tests verify that your plugin can find existing resources that weren’t created through formae. The test creates a resource directly via your plugin, then runs discovery to confirm formae detects it. To run only CRUD lifecycle tests:TEST and VERSION parameters:
Targeting a specific version
To test against a specific formae version:- Testing compatibility with older formae versions
- Reproducing issues reported by users on specific versions
- Validating your plugin before upgrading formae
What happens
When you runmake conformance-test:
- Downloads the specified formae version (or latest)
- Updates PKL dependencies to match that version
- Builds and installs your plugin locally
- Runs
clean-environment.shto remove leftover test resources - Executes the conformance test suite
- Cleans up test resources
Environment variables
The conformance test framework reads several environment variables to control behavior:FORMAE_TEST_OOB_TIMEOUT vs FORMAE_TEST_OOB_DELETE_TIMEOUT. These bound different waits in different phases and are independent:
FORMAE_TEST_OOB_TIMEOUTcovers the slow part: your plugin’s Create/Delete RPC for the OOB resource finishing on the cloud side (e.g. EKS or OVH Kube cluster reaching a terminal state).FORMAE_TEST_OOB_DELETE_TIMEOUTcovers the much shorter wait after that RPC returns: the agent’s sync detecting the OOB deletion and tombstoning the inventory entry.
Environment cleanup
Thescripts/ci/clean-environment.sh script removes test resources before and after tests. Customize it for your infrastructure. The script should be idempotent (safe to run multiple times) and delete all resources matching the test prefix.
For our SFTP plugin, we list files matching the prefix, then delete them individually (wildcards don’t work reliably in sftp batch mode):
Verify
With the test data files in place, run the conformance tests:Next: 12 - CI Setup - Set up continuous integration for your plugin

