Skip to content

Commit 944a705

Browse files
craig[bot]herkolategan
andcommitted
Merge #156951
156951: roachtest: task logger creation error handling r=DarrylWong,srosenberg a=herkolategan Previously, if a task failed to create a logger internally during the call to create a goroutine, the error would only be returned if the task (or task group) was waited on with `WaitE`. This could lead to a race condition in tests, since it's expected that the function passed to the `task.Go` call is executed. And if something within the test is waiting on results from that goroutine, it could end up waiting indefinitely. This change ensures the function passed to a `task.Go` call is always executed. The only way this could not happen currently was if an error occurred while trying to create a logger for the task. This has been updated to rather fall back to the root logger; and print an error to the root logger. Informs: #156635 Epic: None Co-authored-by: Herko Lategan <[email protected]>
2 parents 3442039 + 629f831 commit 944a705

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

pkg/cmd/roachtest/roachtestutil/task/manager.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ func (t *group) GoWithCancel(fn Func, opts ...Option) context.CancelFunc {
205205
t.ctxGroup.Go(func() error {
206206
l, err := opt.L(opt.Name)
207207
if err != nil {
208-
return err
208+
t.manager.logger.Errorf("WARN: defaulting to root logger after failing to create logger for task %q: %v", opt.Name, err)
209+
l = t.manager.logger
209210
}
210211
err = internalFunc(l)
211212
event := Event{

pkg/cmd/roachtest/roachtestutil/task/manager_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package task
77

88
import (
9+
"bytes"
910
"context"
1011
"io"
1112
"sync"
@@ -38,6 +39,39 @@ func TestPanicHandler(t *testing.T) {
3839
m.Terminate(nilLogger())
3940
}
4041

42+
func TestLoggerFallback(t *testing.T) {
43+
defer leaktest.AfterTest(t)()
44+
45+
stdoutBuf := &bytes.Buffer{}
46+
stderrBuf := &bytes.Buffer{}
47+
loggerConf := logger.Config{
48+
Stdout: stdoutBuf,
49+
Stderr: stderrBuf,
50+
}
51+
rootLogger, err := loggerConf.NewLogger("" /* path */)
52+
if err != nil {
53+
panic(err)
54+
}
55+
56+
ctx := context.Background()
57+
m := NewManager(ctx, rootLogger)
58+
59+
brokenLoggerSupplierFunc := func(name string) (*logger.Logger, error) {
60+
return nil, errors.New("logger error")
61+
}
62+
63+
m.Go(func(ctx context.Context, l *logger.Logger) error {
64+
l.Printf("this should be logged to the root logger")
65+
return nil
66+
}, LoggerFunc(brokenLoggerSupplierFunc), Name("def"))
67+
68+
e := <-m.CompletedEvents()
69+
require.Equal(t, "def", e.Name)
70+
require.Contains(t, stderrBuf.String(), "logger error")
71+
require.Contains(t, stdoutBuf.String(), "this should be logged to the root logger")
72+
m.Terminate(nilLogger())
73+
}
74+
4175
func TestErrorHandler(t *testing.T) {
4276
defer leaktest.AfterTest(t)()
4377
ctx := context.Background()

0 commit comments

Comments
 (0)