@@ -92,22 +92,34 @@ func (tlc *TestLogCollector) DoPrint() {
9292// MatchFunc is a slice of functions that check the logs for a specific condition
9393// use in WaitForLogMatchFunc
9494type MatchFunc struct {
95- completed atomic.Bool
96- F func (lstring string ) bool
97- matches []string
98- found chan struct {} // channel to notify when match is found, will be closed
99- done func ()
95+ completed atomic.Bool
96+ F func (lstring string ) bool
97+ matches []string
98+ matchesMu sync.Mutex // protects matches slice
99+ found chan struct {} // channel to notify when match is found, will be closed
100+ done func ()
100101}
101102
102103func (tlc * TestLogCollector ) Printf (_ context.Context , format string , v ... interface {}) {
103104 tlc .mu .Lock ()
104- defer tlc .mu .Unlock ()
105105 lstr := fmt .Sprintf (format , v ... )
106- if len (tlc .matchFuncs ) > 0 {
106+
107+ // Check if there are match functions to process
108+ // Use matchFuncsMutex to safely read matchFuncs
109+ tlc .matchFuncsMutex .Lock ()
110+ hasMatchFuncs := len (tlc .matchFuncs ) > 0
111+ // Create a copy of matchFuncs to avoid holding the lock while processing
112+ matchFuncsCopy := make ([]* MatchFunc , len (tlc .matchFuncs ))
113+ copy (matchFuncsCopy , tlc .matchFuncs )
114+ tlc .matchFuncsMutex .Unlock ()
115+
116+ if hasMatchFuncs {
107117 go func (lstr string ) {
108- for _ , matchFunc := range tlc . matchFuncs {
118+ for _ , matchFunc := range matchFuncsCopy {
109119 if matchFunc .F (lstr ) {
120+ matchFunc .matchesMu .Lock ()
110121 matchFunc .matches = append (matchFunc .matches , lstr )
122+ matchFunc .matchesMu .Unlock ()
111123 matchFunc .done ()
112124 return
113125 }
@@ -118,6 +130,7 @@ func (tlc *TestLogCollector) Printf(_ context.Context, format string, v ...inter
118130 fmt .Println (lstr )
119131 }
120132 tlc .l = append (tlc .l , fmt .Sprintf (format , v ... ))
133+ tlc .mu .Unlock ()
121134}
122135
123136func (tlc * TestLogCollector ) WaitForLogContaining (searchString string , timeout time.Duration ) bool {
@@ -170,7 +183,12 @@ func (tlc *TestLogCollector) WaitForLogMatchFunc(mf func(string) bool, timeout t
170183
171184 select {
172185 case <- matchFunc .found :
173- return matchFunc .matches [0 ], true
186+ matchFunc .matchesMu .Lock ()
187+ defer matchFunc .matchesMu .Unlock ()
188+ if len (matchFunc .matches ) > 0 {
189+ return matchFunc .matches [0 ], true
190+ }
191+ return "" , false
174192 case <- time .After (timeout ):
175193 return "" , false
176194 }
0 commit comments