github.com/rkt/rkt@v1.30.1-0.20200224141603-171c416fac02/store/imagestore/main_test.go (about) 1 // Copyright 2013 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.BSD file, 4 // or at https://opensource.org/licenses/BSD-3-Clause 5 6 package imagestore 7 8 import ( 9 "fmt" 10 "os" 11 "runtime" 12 "sort" 13 "strings" 14 "testing" 15 "time" 16 ) 17 18 func interestingGoroutines() (gs []string) { 19 buf := make([]byte, 2<<20) 20 buf = buf[:runtime.Stack(buf, true)] 21 for _, g := range strings.Split(string(buf), "\n\n") { 22 sl := strings.SplitN(g, "\n", 2) 23 if len(sl) != 2 { 24 continue 25 } 26 stack := strings.TrimSpace(sl[1]) 27 if stack == "" || 28 strings.Contains(stack, "created by testing.RunTests") || 29 strings.Contains(stack, "testing.Main(") || 30 strings.Contains(stack, "runtime.goexit") || 31 strings.Contains(stack, "github.com/rkt/rkt/store/imagestore.interestingGoroutines") || 32 strings.Contains(stack, "created by runtime.gc") || 33 strings.Contains(stack, "runtime.MHeap_Scavenger") { 34 continue 35 } 36 gs = append(gs, stack) 37 } 38 sort.Strings(gs) 39 return 40 } 41 42 // Verify the other tests didn't leave any goroutines running. 43 func TestMain(m *testing.M) { 44 v := m.Run() 45 if v == 0 && goroutineLeaked() { 46 os.Exit(254) 47 } 48 os.Exit(v) 49 } 50 51 func goroutineLeaked() bool { 52 if testing.Short() { 53 // not counting goroutines for leakage in -short mode 54 return false 55 } 56 57 var stackCount map[string]int 58 for i := 0; i < 5; i++ { 59 n := 0 60 stackCount = make(map[string]int) 61 gs := interestingGoroutines() 62 for _, g := range gs { 63 stackCount[g]++ 64 n++ 65 } 66 if n == 0 { 67 return false 68 } 69 // Wait for goroutines to schedule and die off: 70 time.Sleep(100 * time.Millisecond) 71 } 72 fmt.Fprintf(os.Stderr, "Too many goroutines running after integration test(s).\n") 73 for stack, count := range stackCount { 74 fmt.Fprintf(os.Stderr, "%d instances of:\n%s\n", count, stack) 75 } 76 return true 77 }