letsrunit-hq / letsrunit-hq/letsrunit

Cucumber store plugin can lock a fresh SQLite database in agent environments

Open
#150 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Summary

Running a Cucumber suite locally in an agent environment can fail before any scenario starts because LetsRunIt initializes the same fresh SQLite recorder database concurrently.

The same suite starts normally with CI=true, which disables the configured store plugin. This indicates an interaction between the agent formatter and the @letsrunit/cucumber/store plugin.

Environment

  • @letsrunit/cucumber 0.24.1
  • Node.js 24.16.0
  • Linux
  • Cucumber configuration:
const format = [
  isAgentEnvironment(process.env)
    ? '@letsrunit/cucumber/agent'
    : '@letsrunit/cucumber/progress',
];

export default {
  format,
  plugin: ['@letsrunit/cucumber/store'],
  pluginOptions: {
    letsrunitStore: {
      directory: '.letsrunit',
      enabled: process.env.CI !== 'true',
    },
  },
};

Actual result

On a clean checkout, including after deleting .letsrunit/letsrunit.db, running:

yarn test:e2e

fails during plugin initialization, before scenarios:

Error: Plugin "@letsrunit/cucumber/store" errored when trying to init
[cause]: SQLite3Error: database is locked
    at Database.prepare
    at Database.run
    at runWithRetry
    at openStore
    at createRecorderContext
    at startStoreRecorder
    at plugin coordinator

No .lock, -journal, -wal, or -shm file remained, and no external process held the database after the failed invocation. The recreated database was zero bytes.

Evidence for an internal concurrent-open problem

The local agent environment selects @letsrunit/cucumber/agent and also enables @letsrunit/cucumber/store. Both paths appear to initialize the recorder store. Store initialization sets PRAGMA journal_mode = WAL and creates schema, operations that require a write lock even for a newly-created SQLite file.

With the exact same application stack running, this starts the suite instead:

CI=true yarn test:e2e

This keeps the agent formatter but disables the configured store plugin, and scenarios begin executing. GitHub Actions also runs with CI=true and reaches scenarios.

Expected result

A local agent-environment run with the store plugin configured should not lock a newly-created recorder database. The formatter and plugin should coordinate store ownership/use, or the package should prevent/configure duplicate initialization.

Reproduction

  1. Configure Cucumber as above.
  2. Ensure the environment is detected as an agent environment.
  3. Remove .letsrunit/letsrunit.db.
  4. Run yarn test:e2e.
  5. Observe SQLite3Error: database is locked before scenarios.
  6. Run CI=true yarn test:e2e; the suite proceeds past initialization.

I can provide a minimal repository if useful.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running yarn test:e2e on a clean checkout, then compare it with CI=true yarn test:e2e. Trace initialization through @letsrunit/cucumber/agent, @letsrunit/cucumber/store, createRecorderContext, and startStoreRecorder; done means the local agent run reaches scenarios without a SQLite database lock or duplicate initialization.

Written by the indexing model from the issue text.

Assessment

Tech stack
nodejs, sqlite, typescript
Domain
databases, testing-qa
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.