AgentStack
SKILL verified MIT Self-run

Go Blackbox

skill-sgaunet-claude-plugins-go-blackbox · by sgaunet

Detect white box Go tests and propose conversion to black box tests (package foo_test). Internal skill used by golang-pro agent to enforce black box testing conventions.

No reviews yet
0 installs
15 views
0.0% view→install

Install

$ agentstack add skill-sgaunet-claude-plugins-go-blackbox

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Go Blackbox? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Go Black Box Test Enforcement

Detect Go test files using white box testing (same package name) and propose conversion to black box testing (package foo_test). Creates export_test.go bridge files when internal symbols need external test access.

When to Use

  • Creating new test files (enforce black box from the start)
  • Reviewing existing test files in a Go project
  • User asks to audit or improve test quality
  • The golang-pro agent encounters *_test.go files during implementation
  • The golang-pro agent encounters goroutine-spawning code while writing or reviewing tests

Prerequisites

  1. go.mod exists: Abort if missing.
  2. Go source files exist: At least one .go file and one *_test.go file to analyze.

Workflow: Detect White Box Tests

Step 1: Scan Test Files

Use Glob to find all test files:

**/*_test.go

Exclude vendor/ and export_test.go files from analysis.

Step 2: Classify Each Test File

For each *_test.go file, read the package declaration (first non-comment, non-blank line starting with package).

Classification rules:

| Package declaration | Source package | Classification | |---|---|---| | package foo_test | foo | Black box (correct) | | package foo | foo | White box (needs conversion) | | package foo_test | N/A (no source) | Black box (standalone) |

To determine the source package: look for non-test .go files in the same directory and read their package declaration.

Step 3: Check for export_test.go

For each directory containing test files, check whether an export_test.go already exists.

Step 4: Report Findings

Present a summary table:

| File | Package | Classification | export_test.go | |---|---|---|---| | calc_test.go | calculator | White box | No | | math_test.go | calculator_test | Black box | N/A | | internal_test.go | parser | White box | Yes |

Workflow: Convert White Box to Black Box

For each white box test file identified:

Step 1: Analyze Unexported Symbol Usage

Read the test file and identify references to unexported symbols (lowercase-initial identifiers) from the package under test:

  • Unexported functions/methods called directly
  • Unexported types used in variable declarations or assertions
  • Unexported struct fields accessed directly
  • Unexported constants/variables referenced

Step 2: Determine Conversion Strategy

Case A — No unexported symbols used:

  • Change package foo to package foo_test
  • Add import for the package under test
  • Prefix exported symbol references with the package name (e.g., Add(1, 2)calculator.Add(1, 2))

Case B — Unexported symbols used:

  • Change package foo to package foo_test in the test file
  • Add import for the package under test
  • Create or update export_test.go in the same directory with package foo (no _test suffix) that exports needed internals:
package foo

// Exported for testing in foo_test package.
var (
    TestableInternalFunc = internalFunc
    TestableInternalVar  = internalVar
)
  • Update test file to use the exported aliases via the package import

Case C — Heavy internal coupling (>10 unexported references):

  • Flag for manual review rather than automatic conversion
  • Suggest refactoring the API to export what tests need, or keeping this specific file as white box with a justifying comment

Step 3: Validate

After conversion, run:

go test ./...
go vet ./...

If tests fail, diagnose: missing imports, renamed references, or unexported symbols not yet bridged via export_test.go.

Workflow: Add Goroutine Leak Detection

After conversion (or during new test creation), detect test functions that exercise goroutine-spawning code and add go.uber.org/goleak verification.

Step 1: Identify Goroutine-Spawning Source Code

For each package under test, scan the non-test .go source files for goroutine launches:

Grep pattern: `go\s+func\s*\(|go\s+[a-zA-Z]`

This matches:

  • go func() { ... }() — anonymous goroutine
  • go myFunction(...) — named function goroutine
  • go obj.Method(...) — method goroutine

Exclude vendor/ and generated files. Record which exported functions/methods directly or transitively spawn goroutines.

Step 2: Map Tests to Goroutine-Spawning Functions

For each test file in the package, identify test functions that call (directly or via helpers) the goroutine-spawning functions found in Step 1.

Classification:

| Test Function | Calls Goroutine-Spawning Code | Action | |---|---|---| | TestWorkerPool | Yes (StartWorkers uses go) | Add goleak.VerifyNone(t) | | TestParseConfig | No | Skip — no goroutine risk | | TestServerStart | Yes (Serve uses go) | Add goleak.VerifyNone(t) |

Step 3: Add goleak to Test Functions

For each test function classified as needing leak detection:

  1. Add the defer call as the first statement in the test function body:
func TestWorkerPool(t *testing.T) {
    defer goleak.VerifyNone(t)
    // ... rest of test
}
  1. Add the import to the test file if not already present:
import (
    "testing"

    "go.uber.org/goleak"
)
  1. Install the module if not already in go.mod:
go get go.uber.org/goleak@latest
go mod tidy

Step 4: Handle goleak Options

Some goroutines are expected and should not trigger false positives. Common cases:

| Scenario | Option | |---|---| | Known background goroutine from a dependency | goleak.IgnoreTopFunction("package.function") | | Goroutine matching a pattern | goleak.IgnoreAnyFunction("package.glob*") |

If goleak.VerifyNone(t) fails due to known background goroutines (e.g., from net/http or logging libraries), add options:

defer goleak.VerifyNone(t,
    goleak.IgnoreTopFunction("net/http.(*Server).Serve"),
)

Do not suppress unknown goroutines — investigate them first.

Step 5: Validate

Run the tests with the race detector to confirm no leaks and no regressions:

go test -race -count=1 ./...

If goleak.VerifyNone reports leaked goroutines:

  1. Check if the tested code properly shuts down goroutines (context cancellation, channel close, sync.WaitGroup)
  2. If the goroutine is from a third-party dependency and cannot be controlled, add a targeted goleak.IgnoreTopFunction option
  3. Never blanket-ignore all goroutines — each ignore must be specific and documented

export_test.go Conventions

  1. File name: Always export_test.go (Go convention)
  2. Package: Same as the source package (NOT _test suffix) — this is what makes it a bridge
  3. Build constraint: None needed — Go includes export_test.go only during go test
  4. Naming: Prefix exported aliases with Testable or use the capitalized form of the original name
  5. Comment: Add // Exported for testing in _test package. header comment
  6. Scope: Export only what tests actually need — do not blanket-export all internals

Error Handling

| Condition | Action | |-----------|--------| | No go.mod found | Abort: "Not a Go module." | | No test files found | Report: "No test files found. Nothing to analyze." | | All tests already black box | Report: "All test files use black box naming. No conversion needed." | | Test compilation fails after conversion | Diagnose missing imports or unexported references. Attempt fix (max 2 retries). | | go vet fails after conversion | Display errors and suggest manual review. | | go get go.uber.org/goleak fails | Display error. Check network connectivity and module proxy settings. | | goleak.VerifyNone reports leaked goroutines | Investigate source. Fix goroutine lifecycle first; use IgnoreTopFunction only for third-party goroutines that cannot be controlled. | | No goroutine-spawning code found in package | Skip goleak workflow: "No goroutine usage detected. Goroutine leak detection not needed." |

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.