◐ Off-By-One · answer catalog

go-test-build-tag-signature

1 answer(s)godocker

go-test-build-tag-signature

📦 Source in repository (JSON)

Answer

Root cause. login/login_integration_test.go is gated behind //go:build integration. When teamRepo was added to NewLoginService, this file was the only call site not updated — it still passed 8 arguments. Because go build/go vet/go test only compile files whose build constraints match the current (default, tag-less) context, the mismatch was never type-checked by the default toolchain and stayed latent until something compiled with -tags integration.

The fix — add the missing teamRepo argument (as the 2nd parameter, matching every other call site):

// login/login_integration_test.go   (//go:build integration)
//go:build integration

package login

import (
    "context"
    "testing"
)

func TestNewLoginServiceIntegration(t *testing.T) {
    svc := NewLoginService(
        fake{},   // userRepo
        fake{},   // teamRepo  <-- FIX: was missing, kept old 8-arg shape
        fake{},   // sessionRepo
        fake{},   // tokens
        fake{},   // hasher
        fake{},   // log
        fake{},   // metrics
        fake{},   // tracer
        Config{}, // cfg
    )
    if _, err := svc.Login(context.Background(), "<email>", "pw"); err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
}

Before the fix, go vet -tags integration ./... reported:

vet: login/login_integration_test.go:30:2: not enough arguments in call to NewLoginService
    have (fake, fake, fake, fake, fake, fake, fake, Config)
    want (UserRepo, TeamRepo, SessionRepo, TokenManager, PasswordHasher, Logger, Metrics, Tracer, Config)

The signature (9 args, teamRepo inserted 2nd):

func NewLoginService(
    userRepo UserRepo,
    teamRepo TeamRepo, // added later
    sessionRepo SessionRepo,
    tokens TokenManager,
    hasher PasswordHasher,
    log Logger,
    metrics Metrics,
    tracer Tracer,
    cfg Config,
) *LoginService

Secondary fix — secrets guard false positive. .gitleaks.toml allowlisted _test\.go$ and the direct run was clean, but the CI guard (which scans git history, unlike a working-tree detect) still flagged the fixture: a pre-rename commit held the same fake creds in login/fixtures.json, a filename the _test.go$ allowlist never covered. Fixed by broadening the allowlist to fixture filenames so history scans agree with working-tree scans:

[allowlist]
description = "test-only fixtures are not real secrets"
paths = [
  '''_test\.go$''',
  '''(testdata/|fixtures\.json$|fixtures\.ya?ml$)''',
]

Reproduction lives in /tmp/gtbs (fixed) and /tmp/gtbs-buggy (bug preserved for regression checks); the gitleaks history scenario in /tmp/glhist.

Evidence & signatures

Bug reproduced as latent, then caught:

| Check | Buggy copy | Fixed copy |
|---|---|---|
| `go vet ./...` (default) | exit 0 (latent — tagged file not compiled) | exit 0 |
| `go build ./...` (default) | exit 0 (latent) | exit 0 |
| `go vet -tags integration ./...` | **exit 1** — `not enough arguments in call to NewLoginService` (have 8, want 9) | exit 0 |
| `golangci-lint run --build-tags integration` | exit 1, exactly **1 typecheck** error | exit 0, **0 typecheck** errors |

Final-state verification battery (all pass):

- `go vet ./...` → exit 0
- `go vet -tags integration ./...` → exit 0
- `go build ./...` → exit 0
- `go build -tags integration,e2e ./...` → exit 0
- `go test ./...` (unit) → `ok example.com/gtbs/login`
- `go test -tags integration -run TestNewLoginServiceIntegration ./login/` → `ok`
- `golangci-lint run --build-tags integration ./...` → exit 0, 0 lines of output, `typecheck` error count = 0 (golangci-lint v1.64.8; the flag is `--build-tags`, not `--tags`)
- gitleaks working-tree scan (`detect --no-git`) → 0 findings
- gitleaks history scan (guard-style `detect`/`git` mode) → **2 findings before** the allowlist fix (both `login/fixtures.json` @ commit `44880b9`, rules `slack-bot-token`, `generic-api-key`), **0 after**

Edge cases tested:
- **Tag math**: verified the tagged file is genuinely excluded from default builds (both `go vet` and `go build` exit 0 while the bug is present), and that `go test -tags integration` compiles+runs it — so the bug only ever surfaces under the tag.
- **golangci-lint flag semantics**: confirmed `--tags` is rejected by v1.64.8 (`unknown flag: --tags`) and `--build-tags integration` is the correct invocation that type-checks tagged test files.
- **gitleaks invocation divergence**: proved config presence is what suppresses findings (renaming `.gitleaks.toml` away makes both invocations flag 3 leaks); the real guard/direct split is history vs working-tree scanning (`detect` in a git repo scans commits by default). Cwd-relative config discovery was *not* the discriminator in v8.24 — it resolved the config regardless of cwd.
- **Regression guard**: the buggy copy still fails `go vet -tags integration` (exit 1, 1 occurrence of `not enough arguments`), confirming the fix is what turned the gate green.
{"model": "deepseek-v4-flash", "problem_class": "go-test-build-tag-signature", "result": "passed", "tests": 11}
Generated from the verified corpus · MIT licensedBack to the catalog