Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions internal/leakcheck/leakcheck_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@ import (
"fmt"
"strings"
"sync"

// "sync"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert this and below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

"testing"
"time"

"google.golang.org/grpc/internal"
// "google.golang.osrg/grpc/internal"
)

type testLogger struct {
Expand All @@ -47,16 +51,14 @@ func TestCheck(t *testing.T) {
for i := 0; i < leakCount; i++ {
go func() { time.Sleep(2 * time.Second) }()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you change this to not use Sleep? We should always avoid sleeps for correctness.

Instead do:

ch := make(chan struct{})
for i := 0; i < leakCount; i++ {
	go func() { <-ch }()
}

// test interestingGoroutines() and CheckGoroutines()

close(ch) // make goroutines exit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

}
if ig := interestingGoroutines(); len(ig) == 0 {
t.Error("blah")
if leaked := interestingGoroutines(); len(leaked) != leakCount {
t.Errorf("interestingGoroutines found %v leaks, want %v leaks", len(leaked), leakCount)
}
e := &testLogger{}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
CheckGoroutines(ctx, e)
if e.errorCount != leakCount {
if CheckGoroutines(ctx, e); e.errorCount == 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works, or you can do

Suggested change
if CheckGoroutines(ctx, e); e.errorCount == 0 {
if CheckGoroutines(ctx, e); ctx.Err() == nil {

Or even:

Suggested change
if CheckGoroutines(ctx, e); e.errorCount == 0 {
if CheckGoroutines(ctx, e); e.errorCount < 3 {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check expects that the goroutines spawned by time.Sleep() should still be alive.
I have not put e.errorcount == 3, because ctx can cause its goroutine live longer and it will cause a errorcount of 4 (Because of this the test was flaky)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not put e.errorcount == 3, because ctx can cause its goroutine live longer and it will cause a errorcount of 4

Right, which is why I suggested changing to failing if it's less than three. We should have at least three. Or we can just confirm the check failed by checking ctx.Err() and then not have to worry about all the complexity to track errorCount at all. Either way is fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, which is why I suggested changing to failing if it's less than three. We should have at least three. Or we can just confirm the check failed by checking ctx.Err() and then not have to worry about all the complexity to track errorCount at all. Either way is fine.

Right, make sense. Both works fine. I'm going with e.errorcount < 3for now.

t.Errorf("CheckGoroutines found %v leaks, want %v leaks", e.errorCount, leakCount)
t.Logf("leaked goroutines:\n%v", strings.Join(e.errors, "\n"))
}
ctx, cancel = context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
Expand All @@ -73,17 +75,15 @@ func TestCheckRegisterIgnore(t *testing.T) {
for i := 0; i < leakCount; i++ {
go func() { time.Sleep(2 * time.Second) }()
}
go func() { ignoredTestingLeak(3 * time.Second) }()
if ig := interestingGoroutines(); len(ig) == 0 {
t.Error("blah")
if leaked := interestingGoroutines(); len(leaked) != leakCount {
t.Errorf("interestingGoroutines found %v leaks, want %v leaks", len(leaked), leakCount)
}
go func() { ignoredTestingLeak(3 * time.Second) }()
e := &testLogger{}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
CheckGoroutines(ctx, e)
if e.errorCount != leakCount {
if CheckGoroutines(ctx, e); e.errorCount == 0 {
t.Errorf("CheckGoroutines found %v leaks, want %v leaks", e.errorCount, leakCount)
t.Logf("leaked goroutines:\n%v", strings.Join(e.errors, "\n"))
}
ctx, cancel = context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
Expand Down
Loading