Close deferred reporting before final delivery

This commit is contained in:
2026-11-07 15:40:01 +00:00
parent c82235100e
commit 1fc6409f95
7 changed files with 123 additions and 56 deletions

View File

@@ -13,7 +13,7 @@ func TestHiddenSimpleDeferredMessagesDoNotAccumulate(t *testing.T) {
for _, mode := range []reportingMode{modeOrdinary, modeQuiet} {
t.Run(fmt.Sprint(mode), func(t *testing.T) {
reporter := newReporter(Streams{})
reporter.setVisibility(mode, false, false)
setReporterVisibility(reporter, mode, false, false)
for index := 0; index < 256; index++ {
if err := reporter.AtEnd().Debug(fmt.Sprintf("hidden %d", index), nil); err != nil {
t.Fatal(err)
@@ -45,7 +45,7 @@ func TestHiddenSimpleDeferredMessagesDoNotAccumulate(t *testing.T) {
func TestHiddenDeferredDetailsRemainDeferredAndCaptured(t *testing.T) {
var diagnostics bytes.Buffer
reporter := newReporter(Streams{Err: &diagnostics})
reporter.setVisibility(modeQuiet, false, false)
setReporterVisibility(reporter, modeQuiet, false, false)
failure := errors.New("hidden rendering failed")
var order []string
details := []Detail{func(w io.Writer) error {
@@ -67,3 +67,57 @@ func TestHiddenDeferredDetailsRemainDeferredAndCaptured(t *testing.T) {
t.Fatalf("hidden content leaked or queue retained: %q", diagnostics.String())
}
}
type gatedDiagnosticWriter struct {
bytes.Buffer
entered chan struct{}
release chan struct{}
}
func (w *gatedDiagnosticWriter) Write(p []byte) (int, error) {
if w.entered != nil {
close(w.entered)
w.entered = nil
<-w.release
}
return w.Buffer.Write(p)
}
func TestReporterDeferredAcceptanceEndsBeforeDelivery(t *testing.T) {
writer := &gatedDiagnosticWriter{entered: make(chan struct{}), release: make(chan struct{})}
entered := writer.entered
reporter := newReporter(Streams{Err: writer})
setReporterVisibility(reporter, modeVerbose, false, false)
deferred := reporter.AtEnd()
if err := deferred.Warn("accepted"); err != nil {
t.Fatal(err)
}
completionEntered, finishCompletion := make(chan struct{}), make(chan struct{})
done := make(chan Outcome, 1)
go func() {
done <- reporter.finalize(Failure("terminal"), func(r *Reporter) {
close(completionEntered)
<-finishCompletion
_ = r.Info("completion")
})
}()
<-entered
late := make(chan error, 1)
go func() { late <- deferred.Warn("late") }()
close(writer.release)
<-completionEntered
if err := <-late; !errors.Is(err, ErrReporterClosed) {
t.Errorf("late submission = %v", err)
}
if err := deferred.Debug(""); !errors.Is(err, ErrReporterClosed) {
t.Errorf("empty hidden submission = %v", err)
}
close(finishCompletion)
outcome := <-done
if got := writer.String(); got != "WARN: accepted\ncompletion\nERROR: terminal\n" {
t.Errorf("diagnostics = %q", got)
}
if outcome.Presentation.Diagnostics.State != DeliveryComplete {
t.Fatalf("outcome = %#v", outcome)
}
}