@@ -25,6 +25,7 @@ import (
25
25
"runtime"
26
26
"strconv"
27
27
"strings"
28
+ "sync"
28
29
"sync/atomic"
29
30
"testing"
30
31
"time"
@@ -240,6 +241,70 @@ func TestServer(t *testing.T) {
240
241
t .Fatalf ("expected postgres URL to start with \" postgres://\" , got %q" , got )
241
242
}
242
243
})
244
+ t .Run ("SpammyLogs" , func (t * testing.T ) {
245
+ // The purpose of this test is to ensure we don't show excessive logs when the server starts.
246
+ t .Parallel ()
247
+ inv , cfg := clitest .New (t ,
248
+ "server" ,
249
+ "--in-memory" ,
250
+ "--http-address" , ":0" ,
251
+ "--access-url" , "http://localhost:3000/" ,
252
+ "--cache-dir" , t .TempDir (),
253
+ )
254
+ stdoutRW := syncReaderWriter {}
255
+ stderrRW := syncReaderWriter {}
256
+ inv .Stdout = io .MultiWriter (os .Stdout , & stdoutRW )
257
+ inv .Stderr = io .MultiWriter (os .Stderr , & stderrRW )
258
+ clitest .Start (t , inv )
259
+
260
+ // Wait for startup
261
+ _ = waitAccessURL (t , cfg )
262
+
263
+ // Wait a bit for more logs to be printed.
264
+ time .Sleep (testutil .WaitShort )
265
+
266
+ // Lines containing these strings are printed because we're
267
+ // running the server with a test config. They wouldn't be
268
+ // normally shown to the user, so we'll ignore them.
269
+ ignoreLines := []string {
270
+ "isn't externally reachable" ,
271
+ "install.sh will be unavailable" ,
272
+ "telemetry disabled, unable to notify of security issues" ,
273
+ }
274
+
275
+ countLines := func (fullOutput string ) int {
276
+ terminalWidth := 80
277
+ linesByNewline := strings .Split (fullOutput , "\n " )
278
+ countByWidth := 0
279
+ lineLoop:
280
+ for _ , line := range linesByNewline {
281
+ for _ , ignoreLine := range ignoreLines {
282
+ if strings .Contains (line , ignoreLine ) {
283
+ continue lineLoop
284
+ }
285
+ }
286
+ if line == "" {
287
+ // Empty lines take up one line.
288
+ countByWidth ++
289
+ } else {
290
+ countByWidth += (len (line ) + terminalWidth - 1 ) / terminalWidth
291
+ }
292
+ }
293
+ return countByWidth
294
+ }
295
+
296
+ stdout , err := io .ReadAll (& stdoutRW )
297
+ if err != nil {
298
+ t .Fatalf ("failed to read stdout: %v" , err )
299
+ }
300
+ stderr , err := io .ReadAll (& stderrRW )
301
+ if err != nil {
302
+ t .Fatalf ("failed to read stderr: %v" , err )
303
+ }
304
+
305
+ numLines := countLines (string (stdout )) + countLines (string (stderr ))
306
+ require .Less (t , numLines , 20 )
307
+ })
243
308
244
309
// Validate that a warning is printed that it may not be externally
245
310
// reachable.
@@ -2140,3 +2205,22 @@ func mockTelemetryServer(t *testing.T) (*url.URL, chan *telemetry.Deployment, ch
2140
2205
2141
2206
return serverURL , deployment , snapshot
2142
2207
}
2208
+
2209
+ // syncWriter provides a thread-safe io.ReadWriter implementation
2210
+ type syncReaderWriter struct {
2211
+ buf bytes.Buffer
2212
+ mu sync.Mutex
2213
+ }
2214
+
2215
+ func (w * syncReaderWriter ) Write (p []byte ) (n int , err error ) {
2216
+ w .mu .Lock ()
2217
+ defer w .mu .Unlock ()
2218
+ return w .buf .Write (p )
2219
+ }
2220
+
2221
+ func (w * syncReaderWriter ) Read (p []byte ) (n int , err error ) {
2222
+ w .mu .Lock ()
2223
+ defer w .mu .Unlock ()
2224
+
2225
+ return w .buf .Read (p )
2226
+ }
0 commit comments