Skip to content

test: raise codex package coverage to ≥80%#24

Merged
aksOps merged 5 commits into
mainfrom
fix/codex-test-coverage
May 15, 2026
Merged

test: raise codex package coverage to ≥80%#24
aksOps merged 5 commits into
mainfrom
fix/codex-test-coverage

Conversation

@aksOps
Copy link
Copy Markdown
Contributor

@aksOps aksOps commented May 15, 2026

Summary

Adds targeted unit tests across the six packages introduced or modified by PR #23 to raise Sonar's "Coverage on New Code" gate from 55.1% to ≥80%. No production code changes.

Coverage delta (per package, statement-level)

Package Before After
internal/agent/codex 54.8% 92.6%
internal/procscan 0.0% 88.9%
internal/migrate 81.4% 86.0%
internal/health 55.7% 72.1%
internal/session 82.5% 84.4%
internal/config 75.0% 85.0%
Combined (coverpkg) 66.7% 86.1%

What got tested

  • procscan_test.go (new): IsAlive, FindChild, readStatus, isNumeric — empty/invalid/missing/self-PID, no-match scan, helper edge cases.
  • agent/codex/process_test.go (new): same shape against the codex copy of the /proc scanner.
  • agent/codex/discover_extra_test.go (new): dayDirsFor midnight-skew branch (00:02 UTC and the 00:05 boundary), newestMatchingRollout directory-shaped-rollout and non-jsonl skip branches.
  • health/agent_check_test.go (new): all four CheckWorkdir branches plus the non-ENOENT stat-error path (via unreadable parent, skipped on root).
  • config/config_test.go: HookTimeout zero/explicit, rewriteRequiredPathClaude missing-key / empty-raw / malformed-array / non-string-entry branches.
  • migrate/migrate_test.go: literal null JSON re-init, non-integer schema_version parse error.
  • session/state_more_test.go (new): UpdateAgentSessionID happy / idempotent-noop / not-found; stampAgentClaude no-sessions and malformed-sessions branches; rewriteClaudeToCodex no-sessions branch.

What is intentionally NOT covered

  • health.CheckAgentProcess (~46 statements) — takes *tmux.Client by concrete type and shells out to a live tmux server + walks /proc. Reaching this would require either a production refactor introducing an interface (out of scope per the task constraints) or a tmux integration harness. The CheckWorkdir half of the same file IS covered.
  • codex.IsCodexAlive FindCodexChild and procscan.FindChild success-when-matched branches that require synthesizing a child process with a controlled comm — fragile in CI, low value beyond the no-match scan already covered.

Constraints satisfied

  • No new dependencies.
  • No edits to sonar-project.properties or CI workflows.
  • No production code changes — test files only.
  • go build ./... clean, full go test ./... green (all prior tests + 50+ new test cases), govulncheck ./... reports 0 reachable vulns.

Test plan

  • go build ./...
  • go test -count=1 ./... (all packages pass)
  • govulncheck ./... (no reachable vulnerabilities)
  • Per-package coverage measured with go test -cover and confirmed ≥80% for the targeted set, except internal/health which is limited by an exec-bound function as documented above
  • Sonar quality gate re-evaluates on PR — expected to pass the new-code coverage threshold given the aggregate 86.1%

🤖 Generated with Claude Code

aksOps added 5 commits May 15, 2026 08:39
procscan had zero test coverage prior. Adds unit tests for both
public entry points and the unexported helpers:

- IsAlive: empty PID, non-numeric/non-positive PID, missing /proc/<pid>,
  and self-PID happy path
- FindChild: empty-input guard and no-match scan
- isNumeric: empty, all-digit, mixed, negative, non-ASCII rune cases
- readStatus: self path success and missing-file fallthrough

Brings package from 0.0% -> 88.9% statement coverage with no fakes
beyond the running test process itself.
process.go was at 0.0% coverage. Adds the same shape of unit tests as
procscan_test.go for the codex-package copy (IsCodexAlive,
FindCodexChild, isNumeric, readProcStatus), exercising the
validation / missing-PID / self-PID happy paths.

discover_extra_test.go fills three remaining gaps in discover.go:

- dayDirsFor's midnight-clock-skew branch (00:02 UTC -> includes
  yesterday) and the outside-the-window negative branch (12:00 UTC,
  00:05 UTC boundary)
- newestMatchingRollout: directory-shaped-like-a-rollout-file is
  skipped via the IsDir() guard
- newestMatchingRollout: non-.jsonl filename is skipped

Brings package from 54.8% -> 92.6%.
CheckWorkdir is the pure-stdlib half of agent_check.go; the sibling
CheckAgentProcess shells out to a live tmux server and walks /proc and
is intentionally left to integration tests (it takes *tmux.Client by
concrete type so no test seam is available without a production-code
refactor outside the scope of this change).

Covered branches:

- empty workdir -> fail with 'not set' message + Fix hint
- missing dir  -> fail with 'does not exist' + mkdir Fix hint
- file-not-dir -> fail with 'not a directory'
- happy path   -> pass with success message
- stat error   -> non-ENOENT path via unreadable parent (skipped on root)

Brings agent_check.go coverage roughly half-of-file (CheckAgentProcess
remains at 0%; documented above).
config/config.go: HookTimeout was uncovered. Adds tests for the
zero/negative -> default fallback and the explicit-seconds passthrough.

config.rewriteRequiredPathClaude: covers the early-return branches the
v1->v2 migration step needs to be defensive about:

- missing required_in_path key
- empty raw value
- malformed value (not a JSON array) -> step is no-op, not an error
- non-string entries inside the array are passed through verbatim
  alongside the targeted 'claude' -> 'codex' rewrite

migrate/migrate.go: adds two parser branches that were not exercised:

- literal JSON 'null' parses into a nil map; the runner must re-init
  to {} and stamp schema_version, not panic
- 'schema_version' present but not an integer -> clear parse error,
  not silent re-stamp

config 75.0% -> 85.0%; migrate 81.4% -> 86.0%.
UpdateAgentSessionID's idempotent-noop branch (id already equals
stored value) and not-found branch were the only uncovered branches.
Adds happy-path, no-op, and missing-row tests.

Migration step coverage:

- stampAgentClaude with no 'sessions' key (early-return)
- stampAgentClaude with a malformed 'sessions' blob (list instead of
  map) -> step surfaces a parse error
- rewriteClaudeToCodex with no 'sessions' key (idempotency)

Brings session package from 82.5% -> 84.4%.
@sonarqubecloud
Copy link
Copy Markdown

@aksOps aksOps merged commit 6fd0413 into main May 15, 2026
10 checks passed
@aksOps aksOps deleted the fix/codex-test-coverage branch May 15, 2026 08:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant