|
1 | 1 | package quartz_test |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bytes" |
4 | 5 | "context" |
5 | 6 | "errors" |
6 | 7 | "fmt" |
| 8 | + "os" |
| 9 | + "runtime/pprof" |
| 10 | + "strings" |
7 | 11 | "testing" |
8 | 12 | "time" |
9 | 13 |
|
10 | 14 | "github.com/coder/quartz" |
11 | | - "go.uber.org/goleak" |
12 | 15 | ) |
13 | 16 |
|
14 | 17 | func TestTimer_NegativeDuration(t *testing.T) { |
@@ -579,5 +582,53 @@ func TestTickerStop_Go123(t *testing.T) { |
579 | 582 | } |
580 | 583 |
|
581 | 584 | func TestMain(m *testing.M) { |
582 | | - goleak.VerifyTestMain(m) |
| 585 | + verifyNoLeakTestMain(m) |
| 586 | +} |
| 587 | + |
| 588 | +func verifyNoLeakTestMain(m *testing.M) { |
| 589 | + before := snapshot() |
| 590 | + code := m.Run() |
| 591 | + now := time.Now() |
| 592 | + for { |
| 593 | + after := snapshot() |
| 594 | + if len(after) > len(before) { |
| 595 | + // Allow test cleanup to settle. |
| 596 | + if time.Since(now) < 200*time.Millisecond { |
| 597 | + time.Sleep(50 * time.Millisecond) |
| 598 | + continue |
| 599 | + } |
| 600 | + fmt.Fprintln(os.Stderr, "Possible goroutine leak(s):") |
| 601 | + fmt.Fprintln(os.Stderr, diff(before, after)) |
| 602 | + os.Exit(1) |
| 603 | + } |
| 604 | + os.Exit(code) |
| 605 | + } |
| 606 | +} |
| 607 | + |
| 608 | +func snapshot() []string { |
| 609 | + var buf bytes.Buffer |
| 610 | + _ = pprof.Lookup("goroutine").WriteTo(&buf, 2) |
| 611 | + var clean []string |
| 612 | + for _, s := range strings.Split(buf.String(), "\n\n") { |
| 613 | + if !strings.Contains(s, "runtime/pprof") { |
| 614 | + clean = append(clean, s) |
| 615 | + } |
| 616 | + } |
| 617 | + return clean |
| 618 | +} |
| 619 | + |
| 620 | +func diff(a, b []string) string { |
| 621 | + m := make(map[string]int) |
| 622 | + for _, s := range a { |
| 623 | + m[s]++ |
| 624 | + } |
| 625 | + var leaks []string |
| 626 | + for _, s := range b { |
| 627 | + if m[s] > 0 { |
| 628 | + m[s]-- |
| 629 | + continue |
| 630 | + } |
| 631 | + leaks = append(leaks, s) |
| 632 | + } |
| 633 | + return strings.Join(leaks, "\n\n") |
583 | 634 | } |
0 commit comments