Story: Keep the ores.iam eventing tests idempotent

Table of Contents

This page documents a story in Sprint 26. It captures the goal, current status, acceptance criteria, and the tasks that compose it.

1. Goal

ores.iam.core.tests passes twice in a row against the same database.

That is not what happens today. Three of the generated eventing tests – the seed profile and its two children – seed a parent profile in the system tenant and never remove it, and the synthetic code the generator fabricates for that parent repeats with every process, so the second run's insert is refused by seed_profiles_code_uniq_idx.

Every other generated eventing test isolates itself by tenant: the helper gives each run its own, the unique indexes start with tenant_id, and a key that repeats across runs is still unique. A seed profile cannot use that isolation, because the model states its code is one per deployment and the insert trigger forces the system tenant. In a shared scope uniqueness has to come from the key, and the key the generator fabricates is unique only within one process.

2. Status

Field Value
State DONE
Parent sprint Sprint 26
Now Nothing.
Waiting on Nothing.
Next Nothing.
Last touched 2026-09-30

3. Acceptance

  • ores.iam.core.tests passes twice in a row against the same database, with no manual cleanup between the runs.
  • A fabricated seed profile code is unique in the scope its unique index enforces: the deployment, not the process.
  • What the tests leave behind is recorded rather than silent.

4. Tasks

Task State Start End Description
Make the generated seed profile code unique per deployment DONE 2026-09-30 2026-09-30 The seed profile's code is unique per deployment, but the generator fabricates it from a process-static counter, so a second run against the same database reuses CD_profile-0 and the insert is refused. Make the fabricated code unique in the scope the model declares.

5. Decisions

  • A fabricated natural key is unique in the scope its table enforces. The generator template builds text keys from a process-static counter, which is enough when the unique index starts with tenant_id because the tenant supplies the rest. It is not enough for a table whose index is on the key alone, and the model already states that scope. The key is therefore made unique where its scope is declared, not repaired afterwards by cleanup: a cleanup only tidies a successful run, and the collision does not need one.

6. Out of scope

  • Removing the parent rows the generated eventing tests seed. Every generated test that seeds a parent leaves it active, and making them delete it is a change to the test template over many files. It is hygiene rather than idempotence, and it is captured on its own.

7. Result

The synthetic seed profile's code is unique per deployment, so ores.iam.core.tests passes twice in a row against one database: 425 assertions in 165 test cases, both runs. What the tests still leave behind is captured rather than silent.

Emacs 29.3 (Org mode 9.6.15)