Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b075d4f
fix(dependabot): bump typer from 0.26.5 to 0.26.6 in /otdf-sdk-mgr (#…
dependabot[bot] Jun 12, 2026
b3eb9c2
fix(dependabot): bump typer from 0.26.5 to 0.26.6 in /otdf-local (#498)
dependabot[bot] Jun 12, 2026
12524c2
feat(xtest): DPoP verification tests and CI wiring (DSPX-3397) (#505)
dmihalcik-virtru Jun 12, 2026
a70c3fc
chore(ci): Enables dependabot for actions (#506)
dmihalcik-virtru Jun 12, 2026
9bc04ce
chore(dependabot): bump ruff from 0.15.15 to 0.15.16 in /otdf-local (…
dependabot[bot] Jun 12, 2026
ff5fb51
chore(dependabot): update uv-build requirement from >=0.11.18 to >=0.…
dependabot[bot] Jun 12, 2026
6b24d98
fix(dependabot): bump ruff from 0.15.14 to 0.15.16 in /xtest (#515)
dependabot[bot] Jun 12, 2026
894c425
feat(otdf-local): multi-instance test environments (DSPX-3302)
dmihalcik-virtru May 15, 2026
c786f7e
feat(otdf-local): self-provision keys + opentdf.yaml at instance init
dmihalcik-virtru Jun 2, 2026
2781060
fix(otdf-local): translate scenario suite to pytest argv per actual s…
dmihalcik-virtru Jun 2, 2026
96a9e0c
style(otdf-local): apply ruff format
dmihalcik-virtru Jun 2, 2026
7b1d92a
fix(otdf-local): address review feedback — instance-aware up ports, c…
dmihalcik-virtru Jun 9, 2026
8e6c04c
fix(otdf-local): address pyright errors in cli and cli_instance
dmihalcik-virtru Jun 9, 2026
3093331
fix(otdf-local): address coderabbit review feedback
dmihalcik-virtru Jun 9, 2026
54a0947
fix(otdf-local): restore PKCS12→JKS flow in generate_ca_jks
dmihalcik-virtru Jun 9, 2026
c7d11e2
docs: add simplification design spec for multi-instance PR
dmihalcik-virtru Jun 9, 2026
1d5d24e
refactor(otdf-local): unify Ports.get_kas_port to always use KAS_OFFSETS
dmihalcik-virtru Jun 10, 2026
166500b
refactor(otdf-local): add resolve_binary_worktree() and cache load_in…
dmihalcik-virtru Jun 10, 2026
0ff23de
refactor(otdf-local): delegate KASService._instance_paths() to settin…
dmihalcik-virtru Jun 10, 2026
898f01d
refactor(otdf-local): delegate PlatformService._instance_dist_paths()…
dmihalcik-virtru Jun 10, 2026
6ddc0c0
refactor(otdf-local): delete _resolve_platform_worktree(), inline int…
dmihalcik-virtru Jun 10, 2026
f1c9510
fixup remove devlocal spec
dmihalcik-virtru Jun 10, 2026
f342707
fixup remove low value test that is triggering sonarcloud
dmihalcik-virtru Jun 10, 2026
c2bf705
fixup ruff check --fix
dmihalcik-virtru Jun 10, 2026
ee90b42
feat(otdf-local): multi-instance test environments (DSPX-3302)
dmihalcik-virtru May 15, 2026
8a22603
feat(xtest): --scenario and --instance flags for conftest (DSPX-3302)
dmihalcik-virtru May 15, 2026
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
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "chore(ci): "

- package-ecosystem: "uv"
directory: "/xtest"
cooldown:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/xtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ jobs:
--sdks-encrypt "${ENCRYPT_SDK}" \
--focus "$FOCUS_SDK" \
$skip_flag \
test_abac.py test_pqc.py
test_abac.py test_pqc.py test_dpop.py
working-directory: otdftests/xtest
env:
PLATFORM_DIR: "../../${{ steps.run-platform.outputs.platform-working-dir }}"
Expand Down
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,10 @@ xtest/sdk/java/cmdline.jar
/xtest/otdfctl/

/tmp/

# Multi-instance test harness state (DSPX-3302). Per-instance config, logs, and
# keys live under tests/instances/; otdf-sdk-mgr install scenario writes
# .installed.json next to each scenarios.yaml.
/instances/
xtest/scenarios/*.installed.json
.claude/tmp/
8 changes: 6 additions & 2 deletions otdf-local/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@ readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"httpx>=0.27.0",
"otdf-sdk-mgr",
"pydantic-settings>=2.14.1",
"rich>=15.0.0",
"ruamel.yaml>=0.18.0",
"typer>=0.26.5",
"typer>=0.26.6",
]

[tool.uv.sources]
otdf-sdk-mgr = { path = "../otdf-sdk-mgr", editable = true }

[dependency-groups]
dev = [
"pyright>=1.1.410",
"pytest>=9.0.3",
"ruff>=0.15.15",
"ruff>=0.15.16",
]

[project.scripts]
Expand Down
44 changes: 35 additions & 9 deletions otdf-local/src/otdf_local/cli.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"""Typer CLI for otdf_local - OpenTDF test environment management."""

import json
import os
import shutil
import sys
import time
from typing import Annotated

from typing import Annotated, Optional

import httpx
import typer
Expand Down Expand Up @@ -44,6 +46,18 @@
)


def _register_subapps() -> None:
"""Defer imports so the schema dependency only loads when needed."""
from otdf_local.cli_instance import instance_app
from otdf_local.cli_scenario import scenario_app

app.add_typer(instance_app, name="instance")
app.add_typer(scenario_app, name="scenario")


_register_subapps()


def _show_provision_error(result: ProvisionResult, target: str) -> None:
"""Display provisioning error with stderr details."""
print_error(f"{target} provisioning failed (exit code {result.return_code})")
Expand Down Expand Up @@ -75,9 +89,19 @@ def main(
is_eager=True,
),
] = False,
instance: Annotated[
Optional[str],
typer.Option(
"--instance",
help='Named instance under tests/instances/. Defaults to "default" (or $OTDF_LOCAL_INSTANCE_NAME).',
),
] = None,
) -> None:
"""OpenTDF test environment management CLI."""
pass
if instance is not None:
os.environ["OTDF_LOCAL_INSTANCE_NAME"] = instance
# Invalidate the cached Settings so subsequent commands see the new value
get_settings.cache_clear()


@app.command()
Expand Down Expand Up @@ -165,7 +189,7 @@ def up(
with status_spinner("Waiting for Platform..."):
try:
wait_for_health(
f"http://localhost:{Ports.PLATFORM}/healthz",
f"http://localhost:{settings.get_platform_port()}/healthz",
timeout=120,
service_name="Platform",
)
Expand Down Expand Up @@ -197,8 +221,8 @@ def up(
raise typer.Exit(1)

with status_spinner("Waiting for KAS instances..."):
for kas_name in Ports.all_kas_names():
port = Ports.get_kas_port(kas_name)
for kas_name in kas_manager.get_instance_names():
port = settings.get_kas_port(kas_name)
try:
wait_for_health(
f"http://localhost:{port}/healthz",
Expand Down Expand Up @@ -558,12 +582,14 @@ def env(

# Platform configuration
env_vars["PLATFORMURL"] = settings.platform_url
env_vars["PLATFORM_DIR"] = str(settings.platform_dir.resolve())
if settings.platform_dir is not None:
env_vars["PLATFORM_DIR"] = str(settings.platform_dir.resolve())

# Schema file for manifest validation
schema_file = settings.platform_dir / "sdk" / "schema" / "manifest.schema.json"
if schema_file.exists():
env_vars["SCHEMA_FILE"] = str(schema_file.resolve())
if settings.platform_dir is not None:
schema_file = settings.platform_dir / "sdk" / "schema" / "manifest.schema.json"
if schema_file.exists():
env_vars["SCHEMA_FILE"] = str(schema_file.resolve())

# Log file paths
platform_log = settings.logs_dir / "platform.log"
Expand Down
Loading
Loading