refactor: simplify TestMain signal switch; note procsignal tech debt · Entire

refactor: simplify TestMain signal switch; note procsignal tech debt

464bf4d→main·

Soph·2w ago·2 files·+17 added/-10 removed

Post-review cleanup (no behavior change):

Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com

Sessions

0fa8a28fa29eView transcript

Changes

2

16 unmodified lines

17
18
19
20
21
22
23
24
25
26
27
28
29
20
21
22
23
24
25
26
27
28
29
30
31
32

16 unmodified lines

const dieFromSignalEnvVar = "ENTIRE_TEST_DIE_FROM_SIGNAL"

func TestMain(m *testing.M) {
    // Child mode: exercise dieFromSignal and let it terminate this process by
    // the signal. dieFromSignal never returns on success; the os.Exit below is
    // only reached if the re-raise couldn't be delivered.
    switch os.Getenv(dieFromSignalEnvVar) {
    case "INT":
        dieFromSignal(os.Interrupt)
        os.Exit(exitCodeForSignal(os.Interrupt))
    case "TERM":
        dieFromSignal(syscall.SIGTERM)
        os.Exit(exitCodeForSignal(syscall.SIGTERM))
    }
    // Child mode: exercise dieFromSignal for the named signal and let it
    // terminate this process. dieFromSignal only returns if the re-raise
    // couldn't be delivered, so the os.Exit fallback mirrors it.
    if name := os.Getenv(dieFromSignalEnvVar); name != "" {
        sig := os.Interrupt
        if name == "TERM" {
            sig = syscall.SIGTERM
        }
        dieFromSignal(sig)
        os.Exit(exitCodeForSignal(sig))
    }
    os.Exit(m.Run())
}

Mcmd/entire/main_test.go+10/-10

14 unmodified lines

15
16
17
18
19
20
21
22
23
24
25
26
27

14 unmodified lines

// user abort as a failure (and fail to break an enclosing shell loop).
// Recording the signal here — on the same goroutine that unwinds to the gate —
// removes that race.
//
// Tech debt: this shared global exists only because auth-go's Store interface
// (LoadTokens/SaveTokens) carries no context.Context, so the keyring path can't
// ride the root context and instead detects Ctrl-C via its own signal listener.
// Once that interface accepts a context, keyring cancellation can flow from the
// root context like everything else, the tokenstore signal listener can go
// away, and this package with it.
package procsignal

import (