Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 37 additions & 27 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@

This guide provides essential knowledge for AI agents performing updates, refactorings, and debugging of OpenTDF libraries and applications under test.

## Repository Layout

| Path | Purpose | Has its own AGENTS.md? |
|------|---------|------------------------|
| `xtest/` | pytest integration tests (the main test suite) | yes |
| `otdf-sdk-mgr/` | Python CLI that installs SDK CLIs from releases or source (see `otdf-sdk-mgr/README.md`) | no |
| `otdf-local/` | Python CLI that runs/stops the platform + KAS instances locally | yes |
| `vulnerability/` | Playwright UI test suite (run with `npx playwright test`) | no |
| `xtest/sdk/{go,java,js}/dist/` | Built SDK CLI wrappers, produced by `otdf-sdk-mgr install` (or by `cd xtest/sdk && make` for source builds) | |
Comment thread
dmihalcik-virtru marked this conversation as resolved.
Outdated

## Test Framework Overview

### Structure
- **Test Directory**: `xtest/` - pytest-based integration tests
- **SDK Distributions**: `xtest/sdk/{go,java,js}/dist/` - built SDK distributions with CLI wrappers
- **SDK Configuration**: `otdf-sdk-mgr install` - installs SDK CLIs from released artifacts or delegates to source builds
- **SDK Version Lookup**: `otdf-sdk-mgr versions list` - lists released artifacts across registries (Go git tags, npm, Maven Central, GitHub Releases)
- **Platform**: `platform/` - OpenTDF platform service
- **Test Runner**: pytest with custom CLI options
### Test Runner
pytest with custom CLI options. Most work happens in `xtest/`.

### Configuring SDK Artifacts

Expand Down Expand Up @@ -207,6 +212,29 @@ Restart the platform service after making changes.
- **Helper functions**: Used across multiple test files
- **Conftest.py**: Session-scoped fixtures, careful with modifications

### Before Committing Python Changes

**REQUIRED**: Run lint, format, and type-check on any Python package you touched
(`xtest/`, `otdf-sdk-mgr/`, `otdf-local/`, etc.) before `git commit`. `cd` into
the package directory first so the tools see the project's venv:

```bash
cd otdf-sdk-mgr # or xtest, otdf-local, etc.
uv run ruff check . # lint — must pass
uv run ruff format . # auto-format — re-stage any reformatted files
uv run pyright # type-check — must pass
```

Use `uv run`, not `uvx`. `uvx` runs the tool in an isolated env that can't
see the project's dependencies, so `pyright` will produce dozens of spurious
`Import "foo" could not be resolved` errors. `uv run` uses the project venv
(after `uv sync` has installed the `dev` dependency group), which is what CI
does.

Run all three. Don't skip steps because "it's a small change" — CI runs them
and a failed check round-trips the PR. If `ruff format` rewrites a file you
already staged, `git add` it again before committing.

## Test File Organization

### Key Test Files
Expand Down Expand Up @@ -242,24 +270,6 @@ curl localhost:8080/healthz
yq e '.services.kas.root_key' platform/opentdf-dev.yaml
```

## Summary

### Preferred Workflow

1. **Build SDK CLIs**: `cd xtest/sdk && make`
2. **Configure environment**: `cd xtest && set -a && source test.env && set +a`
3. **Run tests**: `uv run pytest --sdks go -v`
4. **Restart after config changes**: Restart the affected platform/KAS services

### When Debugging Test Failures

1. Read error messages carefully - they guide you to the root cause
2. Check platform configuration matches expected test behavior
3. Verify all KAS instances have consistent keys
4. Ensure services are running and healthy
5. Check service logs for errors
6. Reproduce issues manually when possible
7. Always restart services after config changes
8. Read before writing - understand existing code patterns
## Closing Note

The test failures are usually symptoms of configuration mismatches, not SDK bugs. Focus on ensuring the local environment matches what the tests expect.
The test failures are usually symptoms of configuration mismatches, not SDK bugs. Focus on ensuring the local environment matches what the tests expect. See the per-package guides in `xtest/`, `otdf-sdk-mgr/`, and `otdf-local/` for sub-system specifics.
Comment thread
dmihalcik-virtru marked this conversation as resolved.
Outdated
2 changes: 1 addition & 1 deletion otdf-local/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ When using `otdf-local up` or `otdf-local restart platform`, golden keys are aut
3. The key is added to `cryptoProvider.standard.keys` in the platform config
4. A legacy keyring entry is added to `services.kas.keyring`

**Manual configuration** (if not using otdf-local):
**Manual configuration** (emergency fallback only — drifts from current platform schema; check `platform/opentdf-dev.yaml.example` if this fails):

Add to `platform/opentdf-dev.yaml`:
```yaml
Expand Down
77 changes: 77 additions & 0 deletions xtest/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# xtest - Agent Guide

The cross-client integration test suite. pytest with custom options that
fan out tests across SDK CLIs (`go`, `java`, `js`) and TDF container types.

For env-variable setup, audit-log details, and common-failure recipes,
see the root `AGENTS.md`. This guide focuses on test authoring and the
fixture system.

## Layout

| Path | Contents |
|------|----------|
| `test_*.py` | Test modules. One per concern: `test_tdfs.py` (core roundtrip), `test_abac.py` (ABAC), `test_legacy.py` (golden TDFs), `test_policytypes.py`, `test_self.py`, `test_audit_logs.py`, `test_pqc.py`. |
| `conftest.py` | `pytest_addoption` + the encrypt/decrypt SDK parametrization. Defines `--sdks`, `--sdks-encrypt`, `--sdks-decrypt`, `--containers`, `--no-audit-logs`. |
| `fixtures/` | Module-scoped pytest fixtures: `attributes.py`, `keys.py`, `audit.py`, `assertions.py`, `kas.py`, `encryption.py`, `obligations.py`. |
| `tdfs.py` | SDK abstraction layer — wraps the `cli.sh` shims under `sdk/<lang>/dist/<version>/`. |
| `sdk/{go,java,js}/dist/<version>/` | SDK CLI builds. Installed by `otdf-sdk-mgr install` (see `../otdf-sdk-mgr/README.md`). |
| `test.env` | Default endpoint and client-credential env vars. Source with `set -a && source test.env && set +a`. |

## Custom pytest Options (defined in `conftest.py`)

| Option | Purpose |
|--------|---------|
| `--sdks "go java js"` | Which SDKs to use for both encrypt and decrypt. |
| `--sdks-encrypt`, `--sdks-decrypt` | Asymmetric encrypt/decrypt SDK selection (use when reproducing cross-SDK interop bugs). |
| `--containers ztdf ztdf-ecwrap` | Which TDF container types to exercise. |
| `--no-audit-logs` | Skip audit-log assertions for this run. CLI equivalent of `DISABLE_AUDIT_ASSERTIONS=1`. |

## Authoring a New Test

1. Pick the right module — group by concern, not by SDK.
2. Use the existing fixtures wherever possible — they're already parametrized
by `--sdks` / `--containers`. Add a new fixture in `fixtures/` only if
the data is reused across modules.
3. If your test needs to skip in certain SDK combos, use
`pytest.skip(...)` with a clear reason — the parametrization will run
it once per combo, so the skip message tells the next reader why.
4. Audit-log assertions are **on by default**. If your test does not
exercise KAS, mark it with the existing `no_audit_logs` pattern; do
not silently drop the fixture.

## Audit-Log Fixture Quick Reference

`audit_logs` (in `fixtures/audit.py`) reads KAS log files (paths from
`PLATFORM_LOG_FILE` / `KAS_*_LOG_FILE` env vars, or auto-discovered under
`../platform/logs/`). It fails setup loudly if the logs aren't reachable.

- **Local dev, no services**: pass `--no-audit-logs` on the pytest command line.
- **CI without services**: set `DISABLE_AUDIT_ASSERTIONS=1` (preferred over
the flag in CI configs because it survives shell wrappers).
- **Real integration runs**: leave both unset. Failure to find logs is a
real signal that the local env is misconfigured.

## SDK CLI Abstraction (`tdfs.py`)

Every SDK exposes the same operations (`encrypt`, `decrypt`, etc.) via
`tdfs.py`. When a test fails for one SDK but not another, the divergence
is usually in either the CLI shim (`sdk/<lang>/dist/<version>/cli.sh`) or
the SDK's manifest emission, not the test. Reproduce manually with:

```bash
echo "hello" > /tmp/in.txt
sdk/go/dist/main/cli.sh encrypt /tmp/in.txt /tmp/out.tdf --attr https://example.com/attr/foo/value/bar
sdk/go/dist/main/cli.sh decrypt /tmp/out.tdf /tmp/out.txt
```

## Before Committing

```bash
uv run ruff check .
uv run ruff format .
uv run pyright
```

See the root `AGENTS.md` ("Before Committing Python Changes") for why
`uvx` is the wrong invocation for pyright.
1 change: 1 addition & 0 deletions xtest/CLAUDE.md
Loading