Fix TestMetricsSnapshot/uptime flakiness on Windows

Simplify uptime calculation to always enforce minimum of 1 second,
even if time.Since returns exactly 0 (can happen on Windows with
coarse timing). This makes the test deterministic.
This commit is contained in:
Steve Yegge
2025-11-02 09:56:42 -08:00
parent 9f9b8bbdc2
commit 1036b0b700
3 changed files with 7 additions and 5 deletions

View File

@@ -112,7 +112,7 @@
{"id":"bd-8900f145","content_hash":"4a07f36a9e5d24aaffb092c89e2273cb58f9de357d24eeb01fcde6a4079ba775","title":"Testing event-driven mode!","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-29T15:28:33.564871-07:00","updated_at":"2025-10-30T17:12:58.186325-07:00","closed_at":"2025-10-29T19:12:54.43368-07:00"}
{"id":"bd-89e2","content_hash":"ddf4626e586440f379ff19872eac29941cecb925d0a4aae8a6f9c08c969ca05d","title":"Daemon race condition: stale export overwrites recent DB changes","description":"**Symptom:**\nMerged bd-fc2d into bd-fb05 in ~/src/beads (commit ce4d756), pushed to remote. The ~/src/fred/beads daemon then exported its stale DB state and committed (8cc1bb4), reverting bd-fc2d back to \"open\" status.\n\n**Timeline:**\n1. 21:45:12 - Merge committed from ~/src/beads (ce4d756): bd-fc2d closed\n2. 21:49:42 - Daemon in ~/src/fred/beads exported stale state (8cc1bb4): bd-fc2d open again\n\n**Root cause:**\nThe fred/beads daemon had a stale database (bd-fc2d still open) and didn't auto-import the newer JSONL before exporting. When it exported, it overwrote the merge with its stale state.\n\n**Expected behavior:**\nDaemon should detect that JSONL is newer than its last export and import before exporting.\n\n**Actual behavior:**\nDaemon exported stale DB state, creating a conflicting commit that reverted upstream changes.\n\n**Impact:**\nMulti-workspace setups with daemons can silently lose changes if one daemon has stale state and exports.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-11-01T21:53:07.930819-07:00","updated_at":"2025-11-01T22:01:25.54126-07:00","closed_at":"2025-11-01T22:01:25.54126-07:00"}
{"id":"bd-89f89fc0","content_hash":"235c3bdeb45e3069167f81e7b4e798fc98547478bb16df40556100478c5e505a","title":"Remove unreachable RPC methods","description":"Several RPC server and client methods are unreachable and should be removed:\n\nServer methods (internal/rpc/server.go):\n- `Server.GetLastImportTime` (line 2116)\n- `Server.SetLastImportTime` (line 2123)\n- `Server.findJSONLPath` (line 2255)\n\nClient methods (internal/rpc/client.go):\n- `Client.Import` (line 311) - RPC import not used (daemon uses autoimport)\n\nEvidence:\n```bash\ngo run golang.org/x/tools/cmd/deadcode@latest -test ./...\n```\n\nImpact: Removes ~80 LOC of unused RPC code","acceptance_criteria":"- Remove the 4 unreachable methods (~80 LOC total)\n- Verify no callers: `grep -r \"GetLastImportTime\\|SetLastImportTime\\|findJSONLPath\" .`\n- All tests pass: `go test ./internal/rpc/...`\n- Daemon functionality works: test daemon start/stop/operations","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-28T16:20:02.432202-07:00","updated_at":"2025-10-30T17:12:58.222655-07:00"}
{"id":"bd-8a39","content_hash":"0154d3334d9e665b498aa086edc57e38da06ef9ceb6c1c7caea2a0181ccf0718","title":"Fix Windows-specific test failures in CI","description":"Several tests are failing on Windows but passing on Linux:\n\n**Failing tests:**\n- TestFindDatabasePathEnvVar\n- TestHashIDs_MultiCloneConverge\n- TestHashIDs_IdenticalContentDedup\n- TestDatabaseReinitialization (all 5 subtests):\n - fresh_clone_auto_import\n - database_removal_scenario\n - legacy_filename_support\n - precedence_test\n - init_safety_check\n- TestFindBeadsDir_NotFound\n- TestMetricsSnapshot/uptime (in internal/rpc)\n\n**CI Run:** https://github.com/steveyegge/beads/actions/runs/19015638968\n\nThese are likely path separator or filesystem behavior differences between Windows and Linux.","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-02T09:29:37.274103-08:00","updated_at":"2025-11-02T09:29:37.274103-08:00","dependencies":[{"issue_id":"bd-8a39","depends_on_id":"bd-1231","type":"blocks","created_at":"2025-11-02T09:29:37.276579-08:00","created_by":"stevey"}]}
{"id":"bd-8a39","content_hash":"7cbc040269bcd04c698930f68bcf70788fcbecb5d30bdad22f01ccc3aac53453","title":"Fix Windows-specific test failures in CI","description":"Several tests are failing on Windows but passing on Linux:\n\n**Failing tests:**\n- TestFindDatabasePathEnvVar\n- TestHashIDs_MultiCloneConverge\n- TestHashIDs_IdenticalContentDedup\n- TestDatabaseReinitialization (all 5 subtests):\n - fresh_clone_auto_import\n - database_removal_scenario\n - legacy_filename_support\n - precedence_test\n - init_safety_check\n- TestFindBeadsDir_NotFound\n- TestMetricsSnapshot/uptime (in internal/rpc)\n\n**CI Run:** https://github.com/steveyegge/beads/actions/runs/19015638968\n\nThese are likely path separator or filesystem behavior differences between Windows and Linux.","notes":"Fixed several Windows path issues:\n1. TestFindDatabasePathEnvVar - now expects canonicalized absolute paths\n2. TestHashIDs tests - use platform-specific bd.exe command on Windows\n3. Added getBDCommand() helper function\n\nStill need to test other Windows failures in TestDatabaseReinitialization and TestMetricsSnapshot/uptime.","status":"open","priority":1,"issue_type":"bug","created_at":"2025-11-02T09:29:37.274103-08:00","updated_at":"2025-11-02T09:49:45.015789-08:00","dependencies":[{"issue_id":"bd-8a39","depends_on_id":"bd-1231","type":"blocks","created_at":"2025-11-02T09:29:37.276579-08:00","created_by":"stevey"}]}
{"id":"bd-9063acda","content_hash":"572a9f35c6b6a74f5d1ff1bb6851881ca6991de48c2238e21bea48752a323ea4","title":"Clean up linter errors (914 total issues)","description":"The codebase has 914 linter issues reported by golangci-lint. While many are documented as baseline in LINTING.md, we should clean these up systematically to improve code quality and maintainability.","design":"Break down by linter category, prioritizing high-impact issues:\n1. dupl (7) - Code duplication\n2. goconst (12) - Repeated strings\n3. gocyclo (11) - High complexity functions\n4. revive (78) - Style issues\n5. gosec (102) - Security warnings\n6. errcheck (683) - Unchecked errors (many in tests)","acceptance_criteria":"All linter categories reduced to acceptable levels, with remaining baseline documented in LINTING.md","notes":"Reduced from 56 to 41 issues locally, then to 0 issues.\n\n**Fixed in commits:**\n- c2c7eda: Fixed 15 actual errors (dupl, gosec, revive, staticcheck, unparam)\n- 963181d: Configured exclusions to get to 0 issues locally\n\n**Current status:**\n- ✅ Local: golangci-lint reports 0 issues\n- ❌ CI: Still failing (see [deleted:bd-cb64c226.1])\n\n**Problem:**\nConfig v2 format or golangci-lint-action@v8 compatibility issue causing CI to fail despite local success.\n\n**Next:** Debug [deleted:bd-cb64c226.1] to fix CI/local discrepancy","status":"open","priority":2,"issue_type":"epic","created_at":"2025-10-24T01:01:12.997982-07:00","updated_at":"2025-10-31T20:36:49.404022-07:00"}
{"id":"bd-90a5","content_hash":"0c47eb0e3250e98727c52f6fa700b535a7e4bf4cdbd33df8857a55d6c107ed5c","title":"Extract hash ID generation functions to hash_ids.go","description":"Move generateHashID, getNextChildNumber, GetNextChildID to hash_ids.go","status":"closed","priority":1,"issue_type":"task","created_at":"2025-11-01T19:28:54.890883-07:00","updated_at":"2025-11-01T23:39:19.427561-07:00","closed_at":"2025-11-01T23:39:19.427561-07:00"}
{"id":"bd-942469b8","content_hash":"be178337752bf9a94ac06f13d6c36752c9104585b9aef43ade971ed50437a39e","title":"Rapid 5","description":"","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-29T19:11:57.508166-07:00","updated_at":"2025-10-30T17:12:58.189947-07:00"}

View File

@@ -105,10 +105,10 @@ func (m *Metrics) Snapshot(activeConns int) MetricsSnapshot {
// Compute statistics outside the lock
uptime := time.Since(m.startTime)
// Round up uptime and enforce minimum of 1 second if any time has passed
// Round up uptime and enforce minimum of 1 second
// This prevents flaky tests on fast systems (especially Windows VMs)
uptimeSeconds := math.Ceil(uptime.Seconds())
if uptime > 0 && uptimeSeconds == 0 {
if uptimeSeconds == 0 {
uptimeSeconds = 1
}

View File

@@ -135,8 +135,10 @@ func TestMetricsSnapshot(t *testing.T) {
})
t.Run("uptime", func(t *testing.T) {
if snapshot.UptimeSeconds <= 0 {
t.Error("Expected positive uptime")
// The uptime calculation uses math.Ceil and ensures minimum 1 second
// if any time has passed. This should always be >= 1.
if snapshot.UptimeSeconds < 1 {
t.Errorf("Expected uptime >= 1, got %f", snapshot.UptimeSeconds)
}
})