Replace transient test labels with stable identifiers

This commit is contained in:
ms2k 2026-07-19 14:27:29 +09:00
commit d0b745950b
17 changed files with 63 additions and 38 deletions

2
.gitignore vendored
View file

@ -1,7 +1,5 @@
# Development scratchpad
scratchpad
# Development journal
docs/journal
# TLC working directories

View file

@ -90,7 +90,7 @@ impl Harness {
let coordination = CoordinationStore::connect(
&required_env("REMORA_COORDINATION_URL"),
format!(
"{}wp22:{}:",
"{}live-events:{}:",
required_env("REMORA_COORDINATION_NAMESPACE"),
nonce()
),

View file

@ -89,7 +89,7 @@ impl Harness {
let coordination = CoordinationStore::connect(
&required_env("REMORA_COORDINATION_URL"),
format!(
"{}wp21:{}:",
"{}public-api:{}:",
required_env("REMORA_COORDINATION_NAMESPACE"),
nonce()
),

View file

@ -63,7 +63,7 @@ impl Harness {
.unwrap();
let coordination = CoordinationStore::connect(
&coordination_url,
format!("{}wp18:{name}:{}:", coordination_namespace(), nonce()),
format!("{}worker-api:{name}:{}:", coordination_namespace(), nonce()),
StoreConfig {
global_limit: 16,
lease_ttl: Duration::from_secs(10),

View file

@ -37,7 +37,11 @@ impl Harness {
.await
.expect("connect postgres");
migrate_schema(&pool).await.expect("schema migrate");
let namespace = format!("{}wp15:{name}:{}:", coordination_namespace(), nonce());
let namespace = format!(
"{}attempt-authority:{name}:{}:",
coordination_namespace(),
nonce()
);
let coordination = CoordinationStore::connect(
&coordination_url,
namespace,

View file

@ -41,7 +41,11 @@ impl Harness {
migrate_schema(&pool).await.expect("schema migrate");
let coordination = CoordinationStore::connect(
&coordination_url,
format!("{}wp16:{name}:{}:", coordination_namespace(), nonce()),
format!(
"{}attempt-mutations:{name}:{}:",
coordination_namespace(),
nonce()
),
StoreConfig {
global_limit: 16,
lease_ttl: Duration::from_secs(10),

View file

@ -132,7 +132,11 @@ impl Harness {
.expect("reset recovery test state");
let coordination = CoordinationStore::connect(
&coordination_url,
format!("{}wp17:{name}:{}:", coordination_namespace(), nonce()),
format!(
"{}attempt-recovery:{name}:{}:",
coordination_namespace(),
nonce()
),
StoreConfig {
global_limit: 32,
lease_ttl: Duration::from_secs(10),
@ -460,7 +464,11 @@ async fn coordination_partition_rolls_back_and_restart_converges() {
let proxy_url = proxy.url();
let store = CoordinationStore::connect(
&proxy_url,
format!("{}wp17:partition:{}:", coordination_namespace(), nonce()),
format!(
"{}attempt-recovery:partition:{}:",
coordination_namespace(),
nonce()
),
StoreConfig::default(),
)
.await
@ -501,7 +509,11 @@ async fn coordination_partition_rolls_back_and_restart_converges() {
let resumed_proxy = CoordinationProxy::start(upstream, Some(address)).await;
let resumed_store = CoordinationStore::connect(
&resumed_proxy.url(),
format!("{}wp17:partition:{}:", coordination_namespace(), nonce()),
format!(
"{}attempt-recovery:partition:{}:",
coordination_namespace(),
nonce()
),
StoreConfig::default(),
)
.await

View file

@ -19,7 +19,7 @@ fn coordination_namespace(suite: &str) -> String {
.ok()
.filter(|value| !value.is_empty())
.unwrap_or_else(|| "remora:test:".into());
format!("{base}wp04:{suite}:")
format!("{base}coordination-substrate:{suite}:")
}
async fn test_store(

View file

@ -358,6 +358,6 @@ async fn object_source_and_destination_resume_matrix() {
.await
.expect("version purge");
} else if std::env::var("REMORA_TARGET_PROVIDER").as_deref() == Ok("versitygw") {
panic!("VersityGW must support version-pinned WP-12 qualification");
panic!("VersityGW must support version-pinned object-source qualification");
}
}

View file

@ -331,7 +331,9 @@ async fn version_addressed_and_stale_version_matrix() {
let provider =
std::env::var("REMORA_TARGET_PROVIDER").unwrap_or_else(|_| "unknown".into());
if provider == "versitygw" {
panic!("versitygw must support bucket versioning for WP-08 matrix");
panic!(
"versitygw must support bucket versioning for the target compatibility matrix"
);
}
}
eprintln!(

View file

@ -85,7 +85,11 @@ impl Harness {
.unwrap();
let coordination = CoordinationStore::connect(
&coordination_url,
format!("{}wp19:{name}:{}:", coordination_namespace(), nonce()),
format!(
"{}worker-runtime:{name}:{}:",
coordination_namespace(),
nonce()
),
StoreConfig {
global_limit: 16,
lease_ttl: Duration::from_secs(2),

View file

@ -29,6 +29,7 @@ Terms in this glossary are stable identifiers for use across Remora documentatio
| `StorageAdapter` | The service boundary through which workers write to the target object store. |
| `TargetStore` | The configured S3-compatible object store receiving downloaded objects. |
| `JobProtocol` | The TLA+ specification defining distributed job state, coordination semantics, and safety and liveness properties. |
| `TestComponent` | A repository-owned acceptance-test unit with its test code, runner image, manifest, acceptance command, and required compatibility families. |
## Scope

View file

@ -4,21 +4,21 @@ Backend integration and fault tests execute as Kubernetes `Job` resources inside
## Fixture lifecycle
`make check-dependencies` remains the dependency compatibility gate: it creates the full fixture, runs the released-image probes, and tears the fixture down. `make check-kind-sample` builds and loads a Remora-owned cargo-nextest runner, then exercises the full provider matrix around [`fixture-consumer-sample`](../../tests/kind/sample-job.yaml.in). Its init containers access the lane database, coordination namespace, OIDC discovery and signing keys, target bucket, and Vault path before cargo-nextest runs. That Job is the reference structure for a work-package test Job.
`make check-dependencies` remains the dependency compatibility gate: it creates the full fixture, runs the released-image probes, and tears the fixture down. `make check-kind-sample` builds and loads a Remora-owned cargo-nextest runner, then exercises the full provider matrix around [`fixture-consumer-sample`](../../tests/kind/sample-job.yaml.in). Its init containers access the lane database, coordination namespace, OIDC discovery and signing keys, target bucket, and Vault path before cargo-nextest runs. That Job is the reference structure for a `TestComponent` test Job.
For interactive work, `tests/kind/setup.sh` creates a ready fixture and leaves it running. `tests/kind/destroy.sh` removes it. Setup replaces any fixture left by an earlier run, teardown is idempotent, and a host-runtime lock shared across worktrees serializes lifecycle mutations around the single `remora-testbed` cluster and `remora-wp02` containerd namespace. `REMORA_TESTBED_RETAIN=1` retains a failed all-in-one run for inspection.
For interactive work, `tests/kind/setup.sh` creates a ready fixture and leaves it running. `tests/kind/destroy.sh` removes it. Setup replaces any fixture left by an earlier run, teardown is idempotent, and a host-runtime lock shared across worktrees serializes lifecycle mutations around the single `remora-testbed` cluster and `remora-dependency-testbed` containerd namespace. `REMORA_TESTBED_RETAIN=1` retains a failed all-in-one run for inspection.
The fixture owns an isolated kubeconfig at `tests/kind/.runtime/kubeconfig` and the `kind-remora-testbed` context. Every Kubernetes operation uses both explicitly. Package runners use the `kube` helper from `tests/kind/lib.sh`; they do not read or change the user's kubeconfig or current context.
## Package test Jobs
Each work package owns its test code, test-runner image, Job manifest, acceptance command, and required compatibility families. Its all-in-one runner follows [`run-sample-job.sh`](../../tests/kind/run-sample-job.sh): acquire the fixture lock, install a cleanup trap, call `setup_fixture <families...>`, load any package-owned image with `load_local_image <image> [containerd-namespace]`, and call `run_job_matrix <job-name> <manifest> <image> <families...>`. The image namespace defaults to `default`. A retained failure prints the isolated kubeconfig and context.
Each `TestComponent` owns its test code, test-runner image, Job manifest, acceptance command, and required compatibility families. Its all-in-one runner follows [`run-sample-job.sh`](../../tests/kind/run-sample-job.sh): acquire the fixture lock, install a cleanup trap, call `setup_fixture <families...>`, load any component-owned image with `load_local_image <image> [containerd-namespace]`, and call `run_job_matrix <job-name> <manifest> <image> <families...>`. The image namespace defaults to `default`. A retained failure prints the isolated kubeconfig and context.
The selectable families are `base`, `durable`, `coordination`, `oidc`, `target`, `secret`, and `all`. `base` provisions only the cluster and common namespace for suites whose controlled fixtures run inside their test pod. Individual implementations are not selectors. A suite that requests `coordination`, `oidc`, and `target` runs the unchanged cargo-nextest archive against the full Redis/DragonflyDB × Keycloak/ZITADEL × Garage/VersityGW Cartesian product. Lanes run sequentially and stop on the first failure.
Before each lane, the runner recreates a lane database, allocates unique coordination keys, provisions an OIDC tenant/client/user/role grant, creates a target bucket and prefix, and allocates a Vault path as required by the selected families. The resulting environment is exposed both through environment variables and a ConfigMap-mounted `/run/remora-fixture/profile.env`. Package manifests use `@@JOB_NAME@@`, `@@PROFILE_NAME@@`, and `@@TEST_IMAGE@@` placeholders so only the profile and lane identity vary between Jobs.
Released third-party dependencies are always the digest-pinned images loaded by the fixture. Work packages may build Remora test-runner images locally; they do not rebuild or wrap dependency images. The Job manifest names every loaded image exactly and sets `imagePullPolicy: Never`.
Released third-party dependencies are always the digest-pinned images loaded by the fixture. Test components may build Remora test-runner images locally; they do not rebuild or wrap dependency images. The Job manifest names every loaded image exactly and sets `imagePullPolicy: Never`.
A test Job:
@ -34,4 +34,4 @@ Package runners may create additional namespaced fixtures and fault injectors ne
Automated backend tests use cluster-local service discovery. Tests of Keycloak or ZITADEL issuer behavior use the `dnsPolicy` and `dnsConfig` pattern in [`fixture-consumer-sample`](../../tests/kind/sample-job.yaml.in) so discovery URLs and token issuers have one identity from every participating pod.
Port forwarding is for interactive diagnostics only and is not an acceptance-test transport. Ingress is introduced by deployment and system qualification, where routing is itself under test; substrate work packages do not install an ingress controller merely to reach fixture services.
Port forwarding is for interactive diagnostics only and is not an acceptance-test transport. Ingress is introduced by deployment and system qualification, where routing is itself under test; substrate test components do not install an ingress controller merely to reach fixture services.

View file

@ -10,7 +10,7 @@ FIXTURE_LOCK_DIR="${XDG_RUNTIME_DIR:-/tmp/remora-$(id -u)}"
FIXTURE_LOCK_PATH="$FIXTURE_LOCK_DIR/remora-testbed-kind.lock"
CONTEXT=kind-remora-testbed
CLUSTER=remora-testbed
NERDCTL_NAMESPACE=remora-wp02
NERDCTL_NAMESPACE=remora-dependency-testbed
FIXTURE_NAMESPACE=remora-testbed
set -a

View file

@ -4,7 +4,7 @@ metadata:
name: probe-payload
namespace: remora-testbed
data:
payload: remora-wp02-published-image-transfer
payload: remora-dependency-testbed-published-image-transfer
---
apiVersion: batch/v1
kind: Job
@ -34,28 +34,28 @@ spec:
- -v
- ON_ERROR_STOP=1
- -c
- "CREATE TABLE wp02_probe (value text NOT NULL)"
- "CREATE TABLE dependency_probe (value text NOT NULL)"
- -c
- "INSERT INTO wp02_probe VALUES ('passed')"
- "INSERT INTO dependency_probe VALUES ('passed')"
- -c
- "SELECT value = 'passed' FROM wp02_probe"
- "SELECT value = 'passed' FROM dependency_probe"
env:
- {name: PGPASSWORD, value: synthetic-postgres}
- name: redis
image: @@REDIS_IMAGE@@
imagePullPolicy: Never
command: [/bin/sh, -ec]
args: ["redis-cli -h redis SET wp02 passed && test \"$(redis-cli -h redis GET wp02)\" = passed"]
args: ["redis-cli -h redis SET dependency_probe passed && test \"$(redis-cli -h redis GET dependency_probe)\" = passed"]
- name: dragonfly
image: @@REDIS_IMAGE@@
imagePullPolicy: Never
command: [/bin/sh, -ec]
args: ["redis-cli -h dragonfly SET wp02 passed && test \"$(redis-cli -h dragonfly GET wp02)\" = passed"]
args: ["redis-cli -h dragonfly SET dependency_probe passed && test \"$(redis-cli -h dragonfly GET dependency_probe)\" = passed"]
- name: vault-write
image: @@VAULT_IMAGE@@
imagePullPolicy: Never
command: [vault]
args: [kv, put, secret/wp02, value=passed]
args: [kv, put, secret/dependency_probe, value=passed]
env:
- {name: VAULT_ADDR, value: "http://vault:8200"}
- {name: VAULT_TOKEN, value: synthetic-vault-token}
@ -64,7 +64,7 @@ spec:
image: @@VAULT_IMAGE@@
imagePullPolicy: Never
command: [/bin/sh, -ec]
args: ["test \"$(vault kv get -field=value secret/wp02)\" = passed && printf 'Vault write/read passed\\n'"]
args: ["test \"$(vault kv get -field=value secret/dependency_probe)\" = passed && printf 'Vault write/read passed\\n'"]
env:
- {name: VAULT_ADDR, value: "http://vault:8200"}
- {name: VAULT_TOKEN, value: synthetic-vault-token}

View file

@ -175,11 +175,11 @@ write_helm_values() {
fi
cat > "$RUNTIME/deployment-values.yaml" <<EOF
api:
image: {repository: remora-api, tag: wp25, digest: "", pullPolicy: Never}
image: {repository: remora-api, tag: local, digest: "", pullPolicy: Never}
worker:
image: {repository: remora-worker, tag: wp25, digest: "", pullPolicy: Never}
image: {repository: remora-worker, tag: local, digest: "", pullPolicy: Never}
web:
image: {repository: remora-web, tag: wp25, digest: "", pullPolicy: Never}
image: {repository: remora-web, tag: local, digest: "", pullPolicy: Never}
publicOrigin: $public_origin
apiUrl: /v1/
oidcClientId: remora-web
@ -432,17 +432,17 @@ validate_deployment_assets
"$REMORA_REAL_NERDCTL" --namespace default build \
--file "$ROOT/Dockerfile" \
--target api \
--tag remora-api:wp25 \
--tag remora-api:local \
"$ROOT"
"$REMORA_REAL_NERDCTL" --namespace default build \
--file "$ROOT/Dockerfile" \
--target worker \
--tag remora-worker:wp25 \
--tag remora-worker:local \
"$ROOT"
"$REMORA_REAL_NERDCTL" --namespace default build \
--file "$ROOT/Dockerfile" \
--target web \
--tag remora-web:wp25 \
--tag remora-web:local \
"$ROOT"
"$REMORA_REAL_NERDCTL" --namespace default build \
--file "$ROOT/Dockerfile.test" \
@ -462,9 +462,9 @@ setup_fixture durable coordination oidc target secret
if [[ "${REMORA_SYSTEM_QUALIFICATION:-0}" = 1 ]]; then
install_qualification_ingress
fi
load_local_image remora-api:wp25
load_local_image remora-worker:wp25
load_local_image remora-web:wp25
load_local_image remora-api:local
load_local_image remora-worker:local
load_local_image remora-web:local
load_local_image remora-kind-deployment:local
if [[ "${REMORA_SYSTEM_QUALIFICATION:-0}" = 1 ]]; then
load_local_image remora-kind-web-system:local

View file

@ -23,7 +23,7 @@ cleanup() {
status=1
fi
if [[ "$status" = 0 ]] && [[ "$SUCCEEDED" = true ]]; then
printf 'WP-02 hermetic dependency testbed passed\n'
printf 'hermetic dependency testbed passed\n'
fi
exit "$status"
}