make test-e2eBuilds complyctl + complyctl-provider-test, then runs all e2e tests with an in-process mock OCI registry. No external services required.
Build tag: e2e.
| Test | Validates |
|---|---|
FullWorkflow |
get → list → generate → scan (oscal, pretty, sarif) |
PolicyCache |
OCI layout structure, state.json tracking |
MultiplePolicies |
Multi-policy fetch + list |
ScanDefaultFormat |
No --format = EvaluationLog only |
InvalidFormat |
--format pdf rejected |
MissingPolicy |
Uncached policy fails with clear message |
MockRegistryOCICompliance |
v2 endpoint, catalog, tags, manifests, 404s |
MockPluginDescribe |
Provider discovery + Describe + Generate RPC |
NestedPolicyID |
Slashed policy IDs (policies/nist-800-53-r5) handled correctly |
Help |
CLI help output structure |
Version |
Version command output |
ListFilterByPolicyID |
--policy-id filter on list |
The in-process mock registry (helpers_test.go) implements OCI Distribution Spec v2 endpoints with these seeded policies:
| Repository | Layers | Tags |
|---|---|---|
nist-800-53-r5 |
catalog + policy | v1.0.0, latest |
policies/nist-800-53-r5 |
catalog + policy | v1.0.0, latest |
cis-benchmark |
catalog | v2.0.0, latest |
The policy layer uses evaluator ID test, which routes to the complyctl-provider-test binary.
make build build-test-providermake mock-registrymkdir -p ~/.complytime/providers
cp bin/complyctl-provider-test ~/.complytime/providers/The test provider responds to all RPCs (Describe, Generate, Scan) with predefined pass results. Evaluator ID: test.
cat > complytime.yaml << 'EOF'
policies:
- url: http://localhost:8765/nist-800-53-r5
id: nist-800-53-r5
variables:
workspace: /tmp/manual-test
targets:
- id: local
policies:
- nist-800-53-r5
variables:
env: manual-test
EOFbin/complyctl getVerify:
ls ~/.complytime/policies/nist-800-53-r5/
cat ~/.complytime/state.json | jq .Expected: oci-layout file exists, state.json contains policy digest and version.
bin/complyctl listExpected: nist-800-53-r5 appears with cached version.
bin/complyctl generate --policy-id nist-800-53-r5Expected: Generation completed. output. Provider receives Generate RPC with assessment configurations extracted from the policy layer.
bin/complyctl scan --policy-id nist-800-53-r5Verify:
ls .complytime/scan/
cat .complytime/scan/evaluation-log-*.yamlExpected: Single evaluation-log-*.yaml file. No OSCAL, SARIF, or Markdown files.
rm -rf .complytime/scan
bin/complyctl scan --policy-id nist-800-53-r5 --format oscalVerify:
cat assessment-results-*.json | jq '.["assessment-results"].metadata'Expected: oscal-version: "1.1.3", results array with findings.
rm -rf .complytime/scan
bin/complyctl scan --policy-id nist-800-53-r5 --format prettyVerify:
cat report-*.mdExpected: Markdown with # Compliance Scan Report header, target sections, step results.
rm -rf .complytime/scan
bin/complyctl scan --policy-id nist-800-53-r5 --format sarifVerify:
cat scan-*.json | jq '.version'Expected: SARIF version "2.1.0".
# Invalid format
bin/complyctl scan --policy-id nist-800-53-r5 --format pdf
# Expected: error containing "invalid format"
# Missing policy (without running get)
rm -rf ~/.complytime/policies
bin/complyctl scan --policy-id nonexistent
# Expected: error containing "not in cache"rm -rf .complytime/scan complytime.yaml
rm -rf ~/.complytime/policies ~/.complytime/state.json
rm ~/.complytime/providers/complyctl-provider-test- Add a
TestE2E_*function ine2e_test.gousing helpers fromhelpers_test.go. - Use
startMockRegistry(t)for an isolated in-process registry per test. - Use
installTestPlugin(t, homeDir)to deploy the test provider. - Use
runComplytime(t, binary, workDir, env, args...)to execute commands. - Run:
make test-e2e