Skip to content

[nightshift] Test Gap Analysis #28

@Microck

Description

@Microck

Test Gap Analysis — Microck/tailstick

Task: test-gap | Category: analysis | Severity: P2 (Medium)

Summary

tailstick has 3,156 lines of Go across 12 packages. 5 packages have test files covering ~610 test lines. 7 packages have zero tests. Overall estimated test coverage: ~35-40% of source code.

Untested Packages (Critical Gaps)

🔴 P1 — internal/state (82 lines, 0 test lines)

Risk: State persistence is the canonical source of truth for lease data.

  • Load() — handles file-not-found, JSON parse errors, schema defaults
  • Save() — atomic write with tmp file, directory creation
  • UpsertRecord() — update-or-append logic for lease records
  • AppendAudit() — append-only audit log writer

Recommended tests:

  • TestLoad_NoFile — returns empty state with defaults
  • TestLoad_InvalidJSON — returns parse error
  • TestSave_CreatesDir — creates parent directories
  • TestSave_AtomicWrite — tmp file renamed on success
  • TestUpsertRecord_Insert — appends new record
  • TestUpsertRecord_Update — replaces existing by LeaseID
  • TestAppendAudit — appends JSON line to file

🟡 P2 — internal/platform (216 lines, 0 test lines)

Risk: OS detection, path resolution, privilege checking.

  • Detect() — gathers host context (OS, arch, boot ID, exe path)
  • sanitizeHost() — hostname sanitization (special chars, empties)
  • StatePath()/LogPath()/LocalSecretPath() — platform-specific paths
  • IsElevated() — checks root/admin status
  • RequireSupportedLinux() — validates distro support
  • Runner.Run() — command execution with dry-run support

Recommended tests:

  • TestSanitizeHost — various inputs: empty, special chars, unicode, dots
  • TestStatePath_Linux — returns /var/lib/tailstick/state.json
  • TestRunner_DryRun — returns formatted dry-run string
  • TestRunner_EmptyArgs — returns error

🟡 P2 — internal/model (133 lines, 0 test lines)

Risk: Domain types with JSON tags — serialization correctness.

  • All types use JSON tags; invalid serialization could corrupt state files.

Recommended tests:

  • TestLeaseRecordJSON_Roundtrip — marshal/unmarshal preserves fields
  • TestLocalJSON_EmptyRecords — nil Records → empty array
  • TestConfigJSON_RequiredFields — verify required fields present

🟢 P3 — internal/logging (63 lines, 0 test lines)

Risk: Low. Simple file logger with mutex.

  • New() — creates log file with parent dirs
  • Info()/Error() — formatted output to file and stdout
  • Close() — double-close safety

Recommended tests:

  • TestLogger_InfoWritesToFile — output appears in file
  • TestLogger_CloseTwice — no panic on double close

⚪ P4 — cmd/* (4 entry points, 11 lines each)

Tiny main() wrappers — not worth testing directly.

Existing Test Coverage Assessment

Package Source Lines Test Lines Ratio
internal/app 1,532 533 35%
internal/gui 356 132 37%
internal/tailscale 415 145 35%
internal/crypto 161 33 20%
internal/config 154 38 25%
internal/state 82 0 0%
internal/platform 216 0 0%
internal/model 133 0 0%
internal/logging 63 0 0%

Priority Recommendations

  1. Add tests for internal/state — highest value per line. State corruption = data loss.
  2. Add sanitizeHost table-driven tests — hostname edge cases are easy to get wrong.
  3. Add JSON roundtrip tests for internal/model — catches tag typos early.
  4. Increase internal/crypto coverage — only 33 test lines for 161 source lines with encryption logic.
  5. Consider go test -coverprofile in CI — add to .github/workflows/ci.yml.

Files Referenced

  • internal/state/store.go (82 lines, 0 tests)
  • internal/platform/platform.go (175 lines, 0 tests)
  • internal/platform/exec.go (41 lines, 0 tests)
  • internal/model/types.go (133 lines, 0 tests)
  • internal/logging/logger.go (63 lines, 0 tests)
  • internal/crypto/secret.go (128 lines, 33 test lines — low coverage)
  • .github/workflows/ci.yml (no coverage step)

Generated by Nightshift v3 — GLM 5.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions