Skip to content

PersonaFixture primitive with disk-persisted idempotent cleanup #211

@jaylfc

Description

@jaylfc

Follow-up to feedback from @m13v on #111. Building out the test-state primitive discussed there.

Problem

Persona-driven tests create persistent state — user accounts, OAuth grants, throwaway emails, SMS numbers, API tokens. A crashed test run leaves orphans that block the next run. Inline try/finally teardown works for the happy path but not for SIGKILL, OOM, or a developer hitting Ctrl-C mid-test.

Design: PersonaFixture

A primitive that owns all credentials for a persona across a test run and guarantees cleanup even after abrupt termination.

async with PersonaFixture("novice_sarah") as persona:
    email = await persona.disposable_email()
    phone = await persona.sms_number()
    token = await persona.oauth_grant("github")
    # ...test runs...
# On exit (success or abort), all resources reaped

Cleanup registry

Per-persona cleanup tasks are persisted to disk (e.g. .taos/test-fixtures/{run_id}.json) as they're created, not just kept in memory:

  • Start of test creates entry in registry
  • Each resource acquisition appends to the entry
  • Clean exit deletes the entry
  • A crashed process leaves the entry behind
  • Next test run's fixture startup sweeps orphaned entries older than N minutes and runs their cleanup

Makes cleanup genuinely idempotent: replaying a cleanup that's already run is a no-op.

Resource backends

Resource Backend Cleanup
Disposable email mail.tm or mailsac API Delete mailbox
SMS number sms-activate / twilio test numbers Release number
OAuth grant provider-specific test accounts Revoke token
User account API DELETE on test backend Drop user row

Each backend implements a uniform acquire() / release(token) interface so the fixture doesn't know about provider specifics.

Acceptance

  • PersonaFixture context manager exists in test infra
  • Registry persists to disk on resource acquisition
  • Orphan sweeper runs on fixture startup and reaps abandoned entries
  • Cleanup is idempotent — double-release is a no-op
  • At least 3 backends implemented (email, OAuth, user account)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestfeatureNew featureinfrastructureBuild system, CI, deploymentkilo-auto-fixAuto-generated label by Kilokilo-triagedAuto-generated label by KilotestingTesting and QA

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions