test(integration): add hermeticity tripwire (I-4) · Entire
test(integration): add hermeticity tripwire (I-4)
1756e7c→main·
Soph·1w ago·3 files·+96 added/-1 removed
Integration/unit tests have historically made live github.com fetches and triggered macOS keychain prompts when checkpoint-token / checkpoint_remote resolution was in play (#1463, 53bc37a88). This adds a TestMain-level tripwire.
When ENTIRE_TEST_GIT_HERMETIC is set (the integration TestMain sets it, plus GIT_TERMINAL_PROMPT=0), GitIsolatedEnv's global git config routes HTTPS transport to github.com/gitlab.com through a dead loopback proxy, so any test that accidentally dials those hosts fails fast instead of reaching the network or prompting for credentials.
The config lives in the file GIT_CONFIG_GLOBAL points at because GitIsolatedEnv strips inherited GIT_CONFIG_* env, so the GIT_CONFIG_COUNT-injected insteadOf approach would be filtered out for every spawned binary. A dead per-host proxy is used rather than url.insteadOf: insteadOf rewrites the effective URL git reports on read, which broke origin-URL forge detection (trail_resume). The proxy blocks transport only and is scoped per host, so the in-process 127.0.0.1 HTTPS test server and the checkpoint-token GIT_CONFIG_* injection are unaffected.
A self-test proves the tripwire fires: git ls-remote https://github.com/... fails fast (~20ms) without network or prompt.
Co-Authored-By: Claude Fable 5 noreply@anthropic.com Claude-Session: https://claude.ai/code/session_012yi3hHGAGepwfrfjPETjGq
Sessions
Changes
3
- cmd/entire/cli
- integration_test
- Ahermeticity_test.go+47
- Msetup_test.go+13
- testutil
- Mtestutil.go+36/-1
- integration_test
//go:build integration
package integration
import (
"context"
"os/exec"
"strings"
"testing"
"time"
"github.com/entireio/cli/cmd/entire/cli/testutil"
)
// TestHermeticityGuard_ExternalHostFailsFast proves the TestMain hermeticity
// tripwire fires: a git command that dials a real external host is redirected to
// an unroutable loopback address and fails fast, without reaching the network or
// prompting for credentials. Regression class: tests accidentally hitting live
// github.com / the macOS keychain (#1463, 53bc37a88).
func TestHermeticityGuard_ExternalHostFailsFast(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(t.Context(), 20*time.Second)
defer cancel()
// ls-remote against a public-looking github URL must be refused immediately
// by the insteadOf redirect to 127.0.0.1:1, not hang on DNS/network or block
// on a credential prompt.
cmd := exec.CommandContext(ctx, "git", "ls-remote", "https://github.com/example/example")
cmd.Env = testutil.GitIsolatedEnv()
start := time.Now()
out, err := cmd.CombinedOutput()
elapsed := time.Since(start)
if err == nil {
t.Fatalf("expected ls-remote to fail under the hermeticity guard, but it succeeded:\n%s", out)
}
if ctx.Err() != nil {
t.Fatalf("ls-remote did not fail fast (timed out after %s); the guard should refuse it immediately:\n%s", elapsed, out)
}
// The redirect target is the loopback refusal address, confirming the rewrite
// (not a real github.com dial) produced the failure.
if !strings.Contains(string(out), "127.0.0.1") {
t.Errorf("expected failure to mention the loopback redirect target 127.0.0.1, got:\n%s", out)
}
}