lightninglabs / lightninglabs/taproot-assets

itest: aperture harness uses machine-global sqlite DB

Open Beginner friendly
#2,233 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug itests
Dominant language
Go
Stars
525
Forks
150
Avg merge
2d 15h
Merged PRs (30d)
31

Description

(N.b., not terribly pressing but definitely wrong/should be fixed. Opus's summary follows.)

## Summary

`NewApertureHarness` builds a per-test temp directory for aperture but then configures the sqlite backend with `aperture.DefaultSqliteConfig()`, whose `DatabaseFileName` points at a fixed, machine-global path. Every hashmail-courier itest therefore reads and writes one shared database outside the test sandbox, persisting across runs and shared between concurrently running tranches.

## Affected code

`itest/aperture_harness.go:30-55`:

```go
// Create a temporary directory for the aperture service to use.
baseDir := filepath.Join(t.TempDir(), "aperture")
...
cfg := &aperture.Config{
...
DatabaseBackend: "sqlite",
Sqlite: aperture.DefaultSqliteConfig(),
...
BaseDir: baseDir,
}
```

`BaseDir` is correctly sandboxed, but the sqlite path is not. In aperture v0.4.0 (`go.mod`), `DefaultSqliteConfig` resolves to:

```go
apertureDataDir = btcutil.AppDataDir("aperture", false)
defaultSqliteDatabasePath = filepath.Join(apertureDataDir, "aperture.db")
```

which is `~/Library/Application Support/Aperture/aperture.db` on macOS
and `~/.aperture/aperture.db` on Linux.

## Observed failure

On a machine where that file was previously created by a *newer* aperture, all five `*_hashmail_courier` tests fail during harness startup, before any tapd logic runs:

```
Error: Received unexpected error:
unable to connect to sqlite: no migration found for version 7:
read down for version 7 sqlc/migrations: file does not exist
Messages: aperture proof courier harness
```

The stale DB is stamped `schema_migrations = 7` and contains tables (`l402_transactions`, `mpp_sessions`, `services`) that do not exist in aperture v0.4.0, which ships only three migrations. `applyMigrations` calls `sqlMigrate.Up()`, the source has no version 7, and startup fails.

Tests affected (one per tranche, in an 8-way `make itest-parallel` run):

- `basic_send_unidirectional_hashmail_courier`
- `resume_pending_package_send_hashmail_courier`
- `reattempt_failed_send_hashmail_courier`
- `sending_multi_asset_groups_hashmail_courier`
- `offline_receiver_eventually_receives_hashmail_courier`

The tell that the state is not test-owned: the file predates the code under test by weeks, and nothing in the repo creates or cleans it.

## Why this matters beyond the migration error

The migration mismatch is the visible symptom; the underlying problem is that the itests depend on machine-wide mutable state.

- **Not hermetic.** Results depend on whatever aperture last touched the developer's home directory. CI passes and local runs fail, or vice versa, for reasons invisible in the diff.
- **Shared across parallel tranches.** `make itest-parallel` runs eight tranches concurrently and five of them exercise a hashmail test, so five processes open the same sqlite file at once. WAL mode plus the 5s busy timeout mostly hides this, but it is a latent source of flakes and lock contention rather than a guarantee.
- **Leaks between runs.** Rows written by one test run are visible to the next, and the file is never cleaned by `clean-itest-logs`.
- **Pollutes a real install.** If the developer also runs aperture locally, the itests write into that daemon's production database.

## Suggested fix

Point the sqlite file at the temp dir the harness already creates:

```go
sqliteCfg := aperture.DefaultSqliteConfig()
sqliteCfg.DatabaseFileName = filepath.Join(baseDir, "aperture.db")

cfg := &aperture.Config{
...
Sqlite: sqliteCfg,
...
}
```

`DefaultSqliteConfig` returns a pointer, so this needs no new import and leaves `SkipMigrations` at its default. Each harness instance then gets a fresh database under `t.TempDir()`, cleaned up automatically, and the migration state always matches the pinned aperture version.

## Environment

- taproot-assets `v0.8.1` (also reproduces on `main`; the harness code is unchanged there)
- aperture `v0.4.0`
- macOS (`darwin`), sqlite backend

Contributor guide

No contributing guide indexed for this repository

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 in itest/aperture_harness.go:30-55 and inspect how NewApertureHarness builds its temporary directory and SQLite configuration. Run the affected hashmail-courier itests, especially under make itest-parallel, to reproduce the machine-global database behavior. Done means each harness uses a database inside its own temporary directory and the listed tests pass without depending on home-directory state.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend, testing-qa
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
88/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.