MCPcopy Index your code
hub / github.com/crossplane-contrib/xprin

github.com/crossplane-contrib/xprin @v0.2.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.2.0 ↗ · + Follow
381 symbols 1,854 edges 71 files 245 documented · 64% updated 12d agov0.2.0 · 2026-04-30★ 4311 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

xprin

CI Release

xprin logo

A Crossplane testing framework that leverages crossplane render and crossplane beta validate commands to test if Compositions render correctly against Claims or XRs, and if the rendered manifests validate against their schemas.

Features

  • Version Agnostic: Works with any Crossplane CLI version and supports any Composition and Function implementation
  • Local Testing: Runs entirely locally with no running Kubernetes cluster required. Only requires a running Docker daemon for Composition Functions
  • Multiple Input Types: Supports both XR (Composite Resource) and Claim inputs
  • XR Patching: Apply patches on the inputs
  • Template Variables: Dynamic content using Go template syntax
  • Hooks Support: Pre-test and post-test shell command execution
  • Assertions: Validate rendered resources with declarative assertions (count, existence, field checks)
  • Test Chaining: Export testcase outputs as artifacts for use in follow-up tests to better emulate the reconciliation process
  • CI/CD Ready: Easy integration into any system or pipeline

FAQ

Why was xprin created?

To bridge the testing gap between function-level testing and full e2e testing: you can run render and validate locally with real Compositions and Functions, without a live cluster or real resource creation. It was originally developed by Elastic, where it is currently being used for mock/integration testing of a large infrastructure.

What are typical use cases?

  • Composition testing: Run crossplane render using various combinations of XRs/Claims, Compositions and Functions, and assert on the output.
  • Schema validation: Validate various combinations of (mock or production) manifests with CRDs via crossplane beta validate.
  • Reconciliation emulation: Chain tests with exported artifacts so later tests consume prior outputs (e.g. observed resources, status).
  • Advanced render inputs: Drive render with extra resources, observed resources, additional context, environment configs, in multiple tests run one after the other.
  • Upgrades: Validate upgrades of Crossplane itself, providers, functions before or after adoption.

Can I test using my production XRs/Claims or data?

Yes. xprin runs entirely locally in a mock environment. It does not create or modify real resources; it only runs crossplane render and crossplane beta validate on the inputs you provide, so you can safely point at production data.

What is the purpose of patching?

To extend coverage, by creating as many test cases we need without having to provide testdata for each one of them.

How does it look like?

The testsuite files are in YAML

tests:
- name: "Successful test with hooks, validation, and assertions"
  patches:
    xrd: ../../aws/xrd.yaml
  inputs:
    xr: ../../aws/xr.yaml
    composition: ../../aws/composition.yaml
    functions: ../../aws/functions.yaml
    observed-resources: ../../aws/observed
    crds:
    - ../../aws/xrd.yaml
    - ../../aws/crossplane.yaml
  hooks:
    pre-test:
    - name: "this is a pre-test hook"
      run: echo "hello"
    post-test:
    - name: "this is a post-test hook"
      run: echo "bye"
  assertions:
    xprin:
    - name: "Number of resources"
      type: "Count"
      value: 3
    - name: "SecurityGroup should exist"
      type: "Exists"
      resource: "SecurityGroup/platform-aws-sg"
    diff:
    - name: "Full render matches golden (using diff)"
      expected: golden_full_render.yaml

The output is similar to go test

➜ xprin test simple_test_xprin.yaml -v --show-render --show-validate --show-assertions --show-hooks
=== RUN   Successful test with hooks, validation, and assertions
--- PASS: Successful test with hooks, validation, and assertions (1.31s)
    Pre-test Hooks:
        [✓] this is a pre-test hook
            hello
    Render:
        ├── XAWSInfrastructure/platform-aws
        ├── Cluster/platform-aws-rds
        └── SecurityGroup/platform-aws-sg
    Validate:
        [✓] aws.example.com/v1, Kind=XAWSInfrastructure, platform-aws validated successfully
        [✓] rds.aws.upbound.io/v1beta1, Kind=Cluster, platform-aws-rds validated successfully
        [✓] ec2.aws.upbound.io/v1beta1, Kind=SecurityGroup, platform-aws-sg validated successfully
        Total 3 resources: 0 missing schemas, 3 success cases, 0 failure cases
    Assertions:
        [✓] Number of resources - found 3 resources (as expected)
        [✓] SecurityGroup should exist - resources found: SecurityGroup/platform-aws-sg
        [✓] Full render matches golden (using diff) - files match
        Total: 3 assertions, 3 successful, 0 failed, 0 errors
    Post-test Hooks:
        [✓] this is a post-test hook
            bye
PASS
ok      examples/mytests/0_e2e/used_in_readme_xprin.yaml        1.314s

See Getting Started and Examples for more.

What does “xprin” mean?

Crossplane + πριν, before Crossplane! (backstory)

How it works

When xprin runs a test case, it follows this specific sequence:

  1. Setup - Set up environment, expand paths, collect inputs, and copy them to a temporary directory for patching
  2. Pre-test Hooks - Execute any pre-test hooks defined in the test case
  3. Convert Claim to XR (optional) - If using a Claim input, convert it to XR using xprin-helpers convert-claim-to-xr
  4. Patch XR (optional) - Apply patches (XRD defaults, connection secrets) using xprin-helpers patch-xr
  5. Crossplane Render - Run crossplane render with the XR, Composition, and Functions
  6. Crossplane Validate (optional) - If CRDs are provided, run crossplane beta validate on the rendered output
  7. Assertions (optional) - Validate rendered resources using declarative assertions (count, existence, field type/value checks)
  8. Post-test Hooks - Execute any post-test hooks defined in the test case
  9. Export Artifacts (optional) - If test case has an id, copy outputs to artifacts directory for cross-test references

Visual flow (high-level steps):

flowchart TD
    A["Setup

Pre-test Hooks"] --> B[Convert Claim to XR]
    A --> C[Patch XR]
    B --> D[Render]
    C --> D
    D --> E[Validate]
    D --> F[Assertions]
    E --> G[Post-test Hooks

Export Artifacts]
    F --> G

    style A fill:#3b82f6,stroke:#1e40af,stroke-width:2px,color:#fff
    style B fill:#f97316,stroke:#c2410c,stroke-width:2px,color:#fff
    style C fill:#f97316,stroke:#c2410c,stroke-width:2px,color:#fff
    style D fill:#a855f7,stroke:#7e22ce,stroke-width:2px,color:#fff
    style E fill:#a855f7,stroke:#7e22ce,stroke-width:2px,color:#fff
    style F fill:#10b981,stroke:#047857,stroke-width:2px,color:#fff
    style G fill:#3b82f6,stroke:#1e40af,stroke-width:2px,color:#fff

For the full flow with decision points and optional steps, see How It Works.

The flow ensures that: - Pre-test hooks can set up the environment, patch inputs or validate them before processing - Claims are automatically converted to XRs for compatibility with crossplane render - XRs can be enhanced with defaults and connection secrets before rendering - The rendered output is validated against schemas if CRDs are available - Assertions validate rendered resources declaratively (count, existence, field checks) after validation - Post-test hooks can clean up and perform additional validation after assertions - Test outputs can be exported as artifacts (when id is set) and referenced by later tests via .Tests.{test-id} template variables for test chaining

Documentation

Commands

# Test Compositions
xprin test <targets>

# Check dependencies and configuration
xprin check

# Show version
xprin version

Related Tools

xprin-helpers: Helper utilities for converting Claims to XRs and patching XRs - convert-claim-to-xr: Convert Claims to XRs - patch-xr: Apply patches to XRs

Requirements

See Installation for detailed requirements. At minimum: Crossplane CLI and Docker daemon.

License

Apache 2.0

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Run
called by 267
cmd/xprin/test/test.go
NewTestCaseResult
called by 77
internal/engine/testcaseresult.go
DebugPrintf
called by 62
internal/utils/messages.go
StatusPass
called by 59
internal/engine/status.go
StatusFail
called by 59
internal/engine/status.go
String
called by 56
internal/engine/status.go
newAssertionExecutor
called by 52
internal/testexecution/runner/assertions.go
NewAssertionResult
called by 50
internal/engine/assertionresult.go

Shape

Function 230
Method 111
Struct 39
Interface 1

Languages

Go100%

Modules by API surface

internal/api/api.go37 symbols
internal/engine/testcaseresult.go24 symbols
internal/testexecution/runner/runner_test.go23 symbols
internal/api/api_test.go19 symbols
internal/testexecution/runner/assertions_xprin.go17 symbols
internal/engine/testcaseresult_test.go14 symbols
internal/unittests/utils/io_test_helpers_test.go12 symbols
internal/testexecution/runner/hooks_test.go12 symbols
cmd/xprin-helpers/claimtoxr/converter_test.go11 symbols
internal/testexecution/runner/runner.go10 symbols
internal/testexecution/runner/assertions_xprin_test.go10 symbols
cmd/xprin-helpers/patchxr/patcher_test.go8 symbols

For agents

$ claude mcp add xprin \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page