Files
hauler/pkg/log/gating_test.go
2026-08-05 16:34:41 -04:00

199 lines
5.7 KiB
Go

package log
import "testing"
// TestShouldShowProgress covers every disabling branch of shouldShowProgress
// plus the "would otherwise be true" baseline. isTerminal is passed directly
// so these tests bypass the real isatty check; NO_COLOR/TERM are read from
// the environment by shouldShowProgress itself, so tests that exercise those
// branches set them via t.Setenv and leave isTerminal true so only the
// branch under test can produce a false result.
func TestShouldShowProgress(t *testing.T) {
tests := []struct {
name string
isTerminal bool
noProgress bool
logLevel string
noColor string
term string
want bool
}{
{
name: "baseline: terminal, not disabled, non-debug level",
isTerminal: true,
noProgress: false,
logLevel: "info",
term: "xterm-256color",
want: true,
},
{
name: "noProgress disables regardless of terminal",
isTerminal: true,
noProgress: true,
logLevel: "info",
term: "xterm-256color",
want: false,
},
{
name: "non-terminal disables",
isTerminal: false,
noProgress: false,
logLevel: "info",
term: "xterm-256color",
want: false,
},
{
name: "debug log level disables",
isTerminal: true,
noProgress: false,
logLevel: "debug",
term: "xterm-256color",
want: false,
},
{
name: "debug log level disables regardless of case",
isTerminal: true,
noProgress: false,
logLevel: "DEBUG",
term: "xterm-256color",
want: false,
},
{
name: "empty log level does not disable",
isTerminal: true,
noProgress: false,
logLevel: "",
term: "xterm-256color",
want: true,
},
{
name: "NO_COLOR set disables",
isTerminal: true,
noProgress: false,
logLevel: "info",
noColor: "1",
term: "xterm-256color",
want: false,
},
{
name: "TERM=dumb disables",
isTerminal: true,
noProgress: false,
logLevel: "info",
term: "dumb",
want: false,
},
{
name: "TERM=DUMB disables regardless of case",
isTerminal: true,
noProgress: false,
logLevel: "info",
term: "DUMB",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Setenv("NO_COLOR", tt.noColor)
t.Setenv("TERM", tt.term)
if got := shouldShowProgress(tt.isTerminal, tt.noProgress, tt.logLevel); got != tt.want {
t.Errorf("shouldShowProgress(%v, %v, %q) = %v, want %v", tt.isTerminal, tt.noProgress, tt.logLevel, got, tt.want)
}
})
}
}
// TestShouldShowProgress_RealWrapperNonTerminal proves the exported
// ShouldShowProgress wrapper delegates its isTerminal check to the real
// isatty call. go test's stdout is never a terminal, so it must always
// return false here regardless of the other inputs.
func TestShouldShowProgress_RealWrapperNonTerminal(t *testing.T) {
if got := ShouldShowProgress(false, "info"); got != false {
t.Errorf("ShouldShowProgress(false, \"info\") under go test (non-terminal stdout) = %v, want false", got)
}
}
// TestIsDumbSink covers every branch of the shared isTerminal/NO_COLOR/
// TERM=dumb predicate that both shouldShowProgress and ShouldUseColor build
// on. isTerminal is passed directly to bypass the real isatty check;
// NO_COLOR/TERM are read from the environment by isDumbSink itself.
func TestIsDumbSink(t *testing.T) {
tests := []struct {
name string
isTerminal bool
noColor string
term string
want bool
}{
{
name: "terminal, no NO_COLOR, non-dumb TERM is not a dumb sink",
isTerminal: true,
term: "xterm-256color",
want: false,
},
{
name: "non-terminal is a dumb sink",
isTerminal: false,
term: "xterm-256color",
want: true,
},
{
name: "NO_COLOR set is a dumb sink even on a terminal",
isTerminal: true,
noColor: "1",
term: "xterm-256color",
want: true,
},
{
name: "TERM=dumb is a dumb sink even on a terminal",
isTerminal: true,
term: "dumb",
want: true,
},
{
name: "TERM=DUMB is a dumb sink regardless of case",
isTerminal: true,
term: "DUMB",
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Setenv("NO_COLOR", tt.noColor)
t.Setenv("TERM", tt.term)
if got := isDumbSink(tt.isTerminal); got != tt.want {
t.Errorf("isDumbSink(%v) = %v, want %v", tt.isTerminal, got, tt.want)
}
})
}
}
// TestShouldUseColor_RealWrapperNonTerminal is the ShouldUseColor analogue
// of TestShouldShowProgress_RealWrapperNonTerminal: go test's real stdout is
// never a terminal, so ShouldUseColor must always report false here.
func TestShouldUseColor_RealWrapperNonTerminal(t *testing.T) {
if got := ShouldUseColor(); got != false {
t.Errorf("ShouldUseColor() under go test (non-terminal stdout) = %v, want false", got)
}
}
// TestShouldUseColor_DebugLevelStillUsesColor proves colors are not gated on
// log level -- unlike shouldShowProgress, ShouldUseColor has no notion of
// logLevel at all, so debug-level logging on a real terminal should still be
// colored. This is exercised indirectly: ShouldUseColor takes no logLevel
// parameter, so there is nothing for a "debug" value to disable. This test
// documents that omission is intentional by asserting the function's
// isDumbSink-only behavior via a terminal=true case.
func TestShouldUseColor_TerminalWithoutDumbSignalsIsTrue(t *testing.T) {
t.Setenv("NO_COLOR", "")
t.Setenv("TERM", "xterm-256color")
if got := isDumbSink(true); got != false {
t.Errorf("isDumbSink(true) with no NO_COLOR/TERM=dumb = %v, want false (i.e. ShouldUseColor would be true on a real non-dumb terminal)", got)
}
}