github.com/april1989/origin-go-tools@v0.0.32/internal/stack/stacktest/stacktest.go (about)

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package stacktest
     6  
     7  import (
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/april1989/origin-go-tools/internal/stack"
    12  )
    13  
    14  //this is only needed to support pre 1.14 when golibexec_testing.TB did not have Cleanup
    15  type withCleanup interface {
    16  	Cleanup(func())
    17  }
    18  
    19  // the maximum amount of time to wait for goroutines to clean themselves up.
    20  const maxWait = time.Second
    21  
    22  // NoLeak checks that a test (or benchmark) does not leak any goroutines.
    23  func NoLeak(t testing.TB) {
    24  	c, ok := t.(withCleanup)
    25  	if !ok {
    26  		return
    27  	}
    28  	before := stack.Capture()
    29  	c.Cleanup(func() {
    30  		var delta stack.Delta
    31  		start := time.Now()
    32  		delay := time.Millisecond
    33  		for {
    34  			after := stack.Capture()
    35  			delta = stack.Diff(before, after)
    36  			if len(delta.After) == 0 {
    37  				// no leaks
    38  				return
    39  			}
    40  			if time.Since(start) > maxWait {
    41  				break
    42  			}
    43  			time.Sleep(delay)
    44  			delay *= 2
    45  		}
    46  		// it's been long enough, and leaks are still present
    47  		summary := stack.Summarize(delta.After)
    48  		t.Errorf("goroutine leak detected:\n%+v", summary)
    49  	})
    50  }