@@ -19,9 +19,10 @@ import (
1919)
2020
2121var (
22- prefix string
23- SlowTest = 10 * time .Second
24- SlowFlush = 5 * time .Second
22+ prefix string
23+ TestTimeout = 10 * time .Minute
24+ TestSlowRun = 10 * time .Second
25+ TestSlowFlush = 5 * time .Second
2526)
2627
2728var WriterCloser = & testLoggerWriterCloser {}
@@ -89,79 +90,92 @@ func (w *testLoggerWriterCloser) Reset() {
8990 w .Unlock ()
9091}
9192
93+ // Printf takes a format and args and prints the string to os.Stdout
94+ func Printf (format string , args ... any ) {
95+ if ! log .CanColorStdout {
96+ for i := 0 ; i < len (args ); i ++ {
97+ if c , ok := args [i ].(* log.ColoredValue ); ok {
98+ args [i ] = c .Value ()
99+ }
100+ }
101+ }
102+ _ , _ = fmt .Fprintf (os .Stdout , "\t " + format , args ... )
103+ }
104+
92105// PrintCurrentTest prints the current test to os.Stdout
93106func PrintCurrentTest (t testing.TB , skip ... int ) func () {
94107 t .Helper ()
95- start := time .Now ()
108+ runStart := time .Now ()
96109 actualSkip := util .OptionalArg (skip ) + 1
97110 _ , filename , line , _ := runtime .Caller (actualSkip )
98111
99- if log .CanColorStdout {
100- _ , _ = fmt .Fprintf (os .Stdout , "=== %s (%s:%d)\n " , fmt .Formatter (log .NewColoredValue (t .Name ())), strings .TrimPrefix (filename , prefix ), line )
101- } else {
102- _ , _ = fmt .Fprintf (os .Stdout , "=== %s (%s:%d)\n " , t .Name (), strings .TrimPrefix (filename , prefix ), line )
103- }
112+ Printf ("=== %s (%s:%d)\n " , log .NewColoredValue (t .Name ()), strings .TrimPrefix (filename , prefix ), line )
113+
104114 WriterCloser .pushT (t )
105- return func () {
106- took := time .Since (start )
107- if took > SlowTest {
108- if log .CanColorStdout {
109- _ , _ = fmt .Fprintf (os .Stdout , "+++ %s is a slow test (took %v)\n " , fmt .Formatter (log .NewColoredValue (t .Name (), log .Bold , log .FgYellow )), fmt .Formatter (log .NewColoredValue (took , log .Bold , log .FgYellow )))
110- } else {
111- _ , _ = fmt .Fprintf (os .Stdout , "+++ %s is a slow test (took %v)\n " , t .Name (), took )
115+ timeoutChecker := time .AfterFunc (TestTimeout , func () {
116+ l := 128 * 1024
117+ var stack []byte
118+ for {
119+ stack = make ([]byte , l )
120+ n := runtime .Stack (stack , true )
121+ if n <= l {
122+ stack = stack [:n ]
123+ break
112124 }
125+ l = n
113126 }
114- timer := time . AfterFunc ( SlowFlush , func () {
115- if log . CanColorStdout {
116- _ , _ = fmt . Fprintf ( os . Stdout , "+++ %s ... still flushing after %v ... \n " , fmt . Formatter ( log . NewColoredValue ( t . Name (), log . Bold , log . FgRed )), SlowFlush )
117- } else {
118- _ , _ = fmt . Fprintf ( os . Stdout , "+++ %s ... still flushing after %v ... \n " , t . Name (), SlowFlush )
119- }
127+ Printf ( "!!! %s ... timeout: %v ... stacktrace: \n %s \n \n " , log . NewColoredValue ( t . Name (), log . Bold , log . FgRed ), TestTimeout , string ( stack ))
128+ })
129+ return func () {
130+ flushStart := time . Now ()
131+ slowFlushChecker := time . AfterFunc ( TestSlowFlush , func () {
132+ Printf ( "+++ %s ... still flushing after %v ... \n " , log . NewColoredValue ( t . Name (), log . Bold , log . FgRed ), TestSlowFlush )
120133 })
121134 if err := queue .GetManager ().FlushAll (context .Background (), - 1 ); err != nil {
122135 t .Errorf ("Flushing queues failed with error %v" , err )
123136 }
124- timer .Stop ()
125- flushTook := time .Since (start ) - took
126- if flushTook > SlowFlush {
127- if log .CanColorStdout {
128- _ , _ = fmt .Fprintf (os .Stdout , "+++ %s had a slow clean-up flush (took %v)\n " , fmt .Formatter (log .NewColoredValue (t .Name (), log .Bold , log .FgRed )), fmt .Formatter (log .NewColoredValue (flushTook , log .Bold , log .FgRed )))
129- } else {
130- _ , _ = fmt .Fprintf (os .Stdout , "+++ %s had a slow clean-up flush (took %v)\n " , t .Name (), flushTook )
131- }
132- }
133- WriterCloser .popT ()
134- }
135- }
137+ slowFlushChecker .Stop ()
138+ timeoutChecker .Stop ()
136139
137- // Printf takes a format and args and prints the string to os.Stdout
138- func Printf (format string , args ... any ) {
139- if log .CanColorStdout {
140- for i := 0 ; i < len (args ); i ++ {
141- args [i ] = log .NewColoredValue (args [i ])
140+ runDuration := time .Since (runStart )
141+ flushDuration := time .Since (flushStart )
142+ if runDuration > TestSlowRun {
143+ Printf ("+++ %s is a slow test (run: %v, flush: %v)\n " , log .NewColoredValue (t .Name (), log .Bold , log .FgYellow ), runDuration , flushDuration )
142144 }
145+ WriterCloser .popT ()
143146 }
144- _ , _ = fmt .Fprintf (os .Stdout , "\t " + format , args ... )
145147}
146148
147149// TestLogEventWriter is a logger which will write to the testing log
148150type TestLogEventWriter struct {
149151 * log.EventWriterBaseImpl
150152}
151153
152- // NewTestLoggerWriter creates a TestLogEventWriter as a log.LoggerProvider
153- func NewTestLoggerWriter (name string , mode log.WriterMode ) log.EventWriter {
154+ // newTestLoggerWriter creates a TestLogEventWriter as a log.LoggerProvider
155+ func newTestLoggerWriter (name string , mode log.WriterMode ) log.EventWriter {
154156 w := & TestLogEventWriter {}
155157 w .EventWriterBaseImpl = log .NewEventWriterBase (name , "test-log-writer" , mode )
156158 w .OutputWriteCloser = WriterCloser
157159 return w
158160}
159161
160- func init () {
162+ func Init () {
161163 const relFilePath = "modules/testlogger/testlogger.go"
162164 _ , filename , _ , _ := runtime .Caller (0 )
163165 if ! strings .HasSuffix (filename , relFilePath ) {
164166 panic ("source code file path doesn't match expected: " + relFilePath )
165167 }
166168 prefix = strings .TrimSuffix (filename , relFilePath )
169+
170+ log .RegisterEventWriter ("test" , newTestLoggerWriter )
171+
172+ duration , err := time .ParseDuration (os .Getenv ("GITEA_TEST_SLOW_RUN" ))
173+ if err == nil && duration > 0 {
174+ TestSlowRun = duration
175+ }
176+
177+ duration , err = time .ParseDuration (os .Getenv ("GITEA_TEST_SLOW_FLUSH" ))
178+ if err == nil && duration > 0 {
179+ TestSlowFlush = duration
180+ }
167181}
0 commit comments