Tests that exercise error paths in errLog/warn were causing GitHub Actions to annotate test output with 'Error: R] ...' (GHA eats '[ERRO' from '[ERROR]' lines and surfaces the rest as workflow errors), making real failures hard to distinguish from expected behavior. - issues.go: route logIssue output through issueLogWriter (io.Writer, defaults to os.Stdout). errorCount/issues/notices recording is unchanged so tests still assert via errorCount. - testmain_test.go: TestMain sets issueLogWriter = io.Discard for the whole test binary. - issues_test.go: TestIssuesLogging temporarily redirects issueLogWriter to a bytes.Buffer (replacing os.Pipe stdout capture). go test -v ./... now contains zero stray '[ERROR]' lines; real test failures remain visible and 'go test' still exits non-zero on failure, failing the workflow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
135 lines
2.9 KiB
Go
135 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestIssuesLogging(t *testing.T) {
|
|
defer resetMocks()
|
|
resetMocks()
|
|
|
|
// Capture issue log output via the injectable writer.
|
|
var buf bytes.Buffer
|
|
oldWriter := issueLogWriter
|
|
issueLogWriter = &buf
|
|
defer func() { issueLogWriter = oldWriter }()
|
|
|
|
warn("something is deprecated")
|
|
errLog("something failed")
|
|
notice("please restart shell")
|
|
|
|
output := buf.String()
|
|
|
|
if !strings.Contains(output, "[WARN] something is deprecated") {
|
|
t.Errorf("output missing warning: %q", output)
|
|
}
|
|
if !strings.Contains(output, "[ERROR] something failed") {
|
|
t.Errorf("output missing error: %q", output)
|
|
}
|
|
|
|
issuesMu.Lock()
|
|
issueLen := len(issues)
|
|
noticeLen := len(notices)
|
|
errCount := errorCount
|
|
issuesMu.Unlock()
|
|
|
|
if issueLen != 2 {
|
|
t.Errorf("expected 2 logged issues, got %d", issueLen)
|
|
}
|
|
if noticeLen != 1 {
|
|
t.Errorf("expected 1 notice, got %d", noticeLen)
|
|
}
|
|
if errCount != 1 {
|
|
t.Errorf("expected 1 error count, got %d", errCount)
|
|
}
|
|
if !hasErrors() {
|
|
t.Error("expected hasErrors() to return true after errLog call")
|
|
}
|
|
}
|
|
|
|
func TestWriteRunLog(t *testing.T) {
|
|
defer resetMocks()
|
|
|
|
tmp := t.TempDir()
|
|
_ = tmp
|
|
|
|
// Redirect path function or mock executable path
|
|
// In issues.go, we can define a package variable to override runLogPath if we want,
|
|
// or we can mock osWriteFile. Since we mocked osWriteFile, let's use that!
|
|
var writtenPath string
|
|
var writtenData []byte
|
|
osWriteFile = func(path string, data []byte, perm os.FileMode) error {
|
|
writtenPath = path
|
|
writtenData = data
|
|
return nil
|
|
}
|
|
|
|
// No issues case
|
|
writeRunLog()
|
|
if writtenPath != "" {
|
|
t.Error("expected run log not to be written when there are no issues")
|
|
}
|
|
|
|
// Add an issue
|
|
warn("test warning")
|
|
writeRunLog()
|
|
|
|
if writtenPath == "" {
|
|
t.Fatal("expected run log to be written")
|
|
}
|
|
if !strings.Contains(string(writtenData), "[WARN] test warning") {
|
|
t.Errorf("expected log to contain the warning, got: %s", string(writtenData))
|
|
}
|
|
}
|
|
|
|
func TestHasErrors(t *testing.T) {
|
|
defer resetMocks()
|
|
|
|
if hasErrors() {
|
|
t.Error("expected hasErrors() false with no errors logged")
|
|
}
|
|
|
|
warn("just a warning")
|
|
if hasErrors() {
|
|
t.Error("expected hasErrors() false after only a warning")
|
|
}
|
|
|
|
errLog("a real error")
|
|
if !hasErrors() {
|
|
t.Error("expected hasErrors() true after errLog call")
|
|
}
|
|
}
|
|
|
|
func TestPrintNotices(t *testing.T) {
|
|
defer resetMocks()
|
|
|
|
// Capture stdout
|
|
oldStdout := os.Stdout
|
|
r, w, _ := os.Pipe()
|
|
os.Stdout = w
|
|
|
|
printNotices() // Should be empty
|
|
|
|
notice("first notice")
|
|
notice("second notice")
|
|
printNotices()
|
|
|
|
w.Close()
|
|
os.Stdout = oldStdout
|
|
|
|
var buf bytes.Buffer
|
|
io.Copy(&buf, r)
|
|
output := buf.String()
|
|
|
|
if !strings.Contains(output, "Notices:") {
|
|
t.Error("stdout missing notices header")
|
|
}
|
|
if !strings.Contains(output, "first notice") || !strings.Contains(output, "second notice") {
|
|
t.Errorf("stdout missing notice contents: %q", output)
|
|
}
|
|
}
|