Coder Social home page Coder Social logo

goleak's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

goleak's Issues

这个示例经测试,未能检测出泄漏

// 1.调用第三方接口由于没有设置超时时间,导致请求阻塞着
func err3() {
	httpClient := http.Client{
		//Timeout: time.Second * 2, // todo 设置httpClicent的超时时间,否则由于响应慢而一直堵塞
	}
	for {
		go func() {
			resp, err := httpClient.Get("https://www.google.com/")
			if err != nil {
				fmt.Printf("http.Get err: %v\n", err)
			} else {
				fmt.Println(resp.Status)
			}
		}()
		time.Sleep(time.Second * 1)
		fmt.Println("goroutines: ", runtime.NumGoroutine())
	}
}

support for gRPC ?

with a gRPC client test, there are so many leaks, is it OK or too early to use goleak ?

Running tool: /usr/local/bin/go test -timeout 30s my_project/test -run ^TestListAddresses$

PASS
goleak: Errors on successful test run: found unexpected goroutines:
[Goroutine 20 in state select, with my_project/vendor/go.opencensus.io/stats/view.(*worker).start on top of the stack:

 Goroutine 40 in state select, with my_project/vendor/google.golang.org/grpc.(*addrConn).transportMonitor on top of the stack:

 Goroutine 39 in state select, with my_project/vendor/google.golang.org/grpc.(*ccBalancerWrapper).watcher on top of the stack:

 Goroutine 27 in state select, with my_project/vendor/google.golang.org/grpc.(*ccResolverWrapper).watcher on top of the stack:

 Goroutine 55 in state select, with my_project/vendor/google.golang.org/grpc.(*ccBalancerWrapper).watcher on top of the stack:

 Goroutine 28 in state select, with my_project/vendor/google.golang.org/grpc.(*ccResolverWrapper).watcher on top of the stack:

 Goroutine 56 in state select, with my_project/vendor/google.golang.org/grpc.(*addrConn).transportMonitor on top of the stack:

 Goroutine 45 in state select, with my_project/vendor/google.golang.org/grpc/transport.(*controlBuffer).get on top of the stack:

 Goroutine 69 in state select, with my_project/vendor/google.golang.org/grpc/transport.(*controlBuffer).get on top of the stack:

FAIL	my_project/test	1.621s

Error: Tests failed.

Running tests with `-trace` is failing for new versions of go

Problem:
Using goleak with trace flag in earlier versions of go (go1.13.10) is working fine due to fixed issue #39.

But in recent version of go (go1.17.1) testing simple programs with trace flag is failing again. I think the stack trace has now hidden the call to runtime.goparkunlock

func Test(t *testing.T) {
	defer goleak.VerifyNone(t)
}
make test:
        [Goroutine 18 in state trace reader (blocked), with runtime.ReadTrace on top of the stack:
        goroutine 18 [trace reader (blocked)]:
        runtime.ReadTrace()
        	/usr/local/go/src/runtime/trace.go:412 +0xd2
        runtime/trace.Start.func1()
        	/usr/local/go/src/runtime/trace/trace.go:129 +0x47
        created by runtime/trace.Start
        	/usr/local/go/src/runtime/trace/trace.go:127 +0xf4

Possible Solution:
Removing this piece of code:

goleak/options.go

Lines 159 to 161 in 1e9de54

if f := s.FirstFunction(); f != "runtime.goparkunlock" {
return false
}

Goleak detects leaked goroutines from other tests

Description

We've found an interesting thing during using goleak on our CI, that goleak can detect leaked goroutine from other tests.

Steps to reproduce

  1. Use go1.14.1 darwin/amd64
  2. Use goleak v1.0.0
  3. Run test file below
    goleak_test.go
package goleak_test

import (
	"go.uber.org/goleak"
	"testing"
	"time"
)

func TestA(t *testing.T) {
	go func() {
		for {
			<-time.After(time.Millisecond * 100)
		}
	}()
}

func TestB(t *testing.T) {
	defer goleak.VerifyNone(t)
}

Expected: TestB should pass
Actual: TestB fails with error "found unexpected goroutines:"

Please drop unmaintained golang.org/x/lint dependency from go.mod

The golang.org/x/lint library is marked as deprecated / unmaintained / readonly

This library takes an explicit dependency on it in https://github.com/uber-go/goleak/blob/master/tools_test.go in order to record a specific version of it in go.mod, for use with go install in the make lint target.

The same result could be achieved by installing the same version explicitly in make lint with go install golang.org/x/lint/[email protected], and the tools_test.go and go.mod reference could be dropped, to avoid propagating an unmaintained dependency into downstreams that use this library.

Using goleak on Go benchmarks.

It would be amazing to have goleak working on Benchmarks as well. However, I think some functions might needed to be filtered by default. Repro:

func BenchmarkGoroutines(b *testing.B) {
	defer goleak.VerifyNone(b)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		wg := sync.WaitGroup{}
		wg.Add(2)

		go func() {
			defer wg.Done()
		}()
		go func() {
			defer wg.Done()
		}()

		wg.Wait()
	}
}

Output:

BenchmarkGoroutines
    leaks.go:78: found unexpected goroutines:
        [Goroutine 1 in state chan receive, with testing.(*B).run1 on top of the stack:
        goroutine 1 [chan receive]:
        testing.(*B).run1(0xc00016a240)
        	/home/bwplotka/.gvm/gos/go1.18.3/src/testing/benchmark.go:235 +0xb2
        testing.(*B).Run(0xc00016a480, {0x6f69de?, 0x0?}, 0x722460)
        	/home/bwplotka/.gvm/gos/go1.18.3/src/testing/benchmark.go:676 +0x445
        testing.runBenchmarks.func1(0xc00016a480?)
        	/home/bwplotka/.gvm/gos/go1.18.3/src/testing/benchmark.go:550 +0x6e
        testing.(*B).runN(0xc00016a480, 0x1)
        	/home/bwplotka/.gvm/gos/go1.18.3/src/testing/benchmark.go:193 +0x102
        testing.runBenchmarks({0x6ffdf2, 0x28}, 0x945c20?, {0x909c80, 0x2, 0x40?})
        	/home/bwplotka/.gvm/gos/go1.18.3/src/testing/benchmark.go:559 +0x3f2
        testing.(*M).Run(0xc000132f00)
        	/home/bwplotka/.gvm/gos/go1.18.3/src/testing/testing.go:1726 +0x811
        main.main()
        	_testmain.go:57 +0x1aa
        ]
--- FAIL: BenchmarkGoroutines
FAIL

Process finished with the exit code 1

Tested on both Go version 1.18.3 and 1.19

Parse stack traces to avoid string contains checks

We have a couple of strings.Contains checks , e.g.,

return strings.Contains(s.Full(), "runtime.ensureSigM")

We should parse the stack trace and filter on specific parts of the trace (E.g., only function name) rather than doing a string comparison against the entire stack trace which contains filesystem paths etc.

time.Tick leak not detected

time.Tick[1] is documented as having a leak;

be aware that without a way to shut it down the underlying 
Ticker cannot be recovered by the garbage collector; it "leaks"

I expected go.uber.org/goleak to be able to uncover such a leak but it didn't seem to.

Here's my example program:

  1. main.go
package main

import (
	"fmt"
	"time"
)

func hello() string {
	t := time.Tick(3 * time.Second)      //leak
	final := time.Tick(10 * time.Second) //another leak

	for {
		select {
		case <-t:
			fmt.Println("ticked")
		case <-final:
			fmt.Println("FINAL ticked")
			return "final hello"
		default:
			fmt.Println("NOT ticked")
			time.Sleep(1 * time.Second)
		}
	}
}
  1. main_test.go
package main

import (
	"testing"
	"go.uber.org/goleak"
)

func TestHello(t *testing.T) {
	defer goleak.VerifyNone(t)
	res := hello()
	t.Log(res)
}

then I run tests as;
go test -v -race -count=1 ./...

ref:

  1. https://pkg.go.dev/time?tab=doc#Tick
  2. go version
    go version go1.13.1 darwin/amd64

License?

Hi, can you clarify a license for this project? Thank you.

unexpected goroutines when `ReadAll(response.body)` - false positive?

The issue came from a quite common scenario, which is to read all bytes from response body after a HTTP method call.

To demonstrate the issue, run the following test code with go test, which gives found unexpected goroutines:

package main

import (
	"io"
	"net/http"
	"testing"

	"go.uber.org/goleak"
	"gotest.tools/v3/assert"
)

func TestLeak(t *testing.T) {
	defer goleak.VerifyNone(t)

	request, err := http.NewRequest(http.MethodGet, "https://google.com", nil)
	assert.NilError(t, err)

	client := http.Client{}

	response, err := client.Do(request)
	assert.NilError(t, err)

	defer response.Body.Close()

	_, err = io.ReadAll(response.Body)

	assert.NilError(t, err)
}

full test output:

$ go test
--- FAIL: TestLeak (1.26s)
    main_test.go:28: found unexpected goroutines:
        [Goroutine 14 in state IO wait, with internal/poll.runtime_pollWait on top of the stack:
        goroutine 14 [IO wait]:
        internal/poll.runtime_pollWait(0x7f945c1e0398, 0x72)
                /home/wxh/.local/go/src/runtime/netpoll.go:305 +0x89
        internal/poll.(*pollDesc).wait(0xc000154280?, 0xc0000ca000?, 0x0)
                /home/wxh/.local/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
        internal/poll.(*pollDesc).waitRead(...)
                /home/wxh/.local/go/src/internal/poll/fd_poll_runtime.go:89
        internal/poll.(*FD).Read(0xc000154280, {0xc0000ca000, 0x2000, 0x2000})
                /home/wxh/.local/go/src/internal/poll/fd_unix.go:167 +0x25a
        net.(*netFD).Read(0xc000154280, {0xc0000ca000?, 0xc00017edd8?, 0xc0004d5808?})
                /home/wxh/.local/go/src/net/fd_posix.go:55 +0x29
        net.(*conn).Read(0xc00009c000, {0xc0000ca000?, 0xc0000c68f0?, 0x2c?})
                /home/wxh/.local/go/src/net/net.go:183 +0x45
        crypto/tls.(*atLeastReader).Read(0xc0002d4138, {0xc0000ca000?, 0x0?, 0x29f6540f238f2947?})
                /home/wxh/.local/go/src/crypto/tls/conn.go:787 +0x3d
        bytes.(*Buffer).ReadFrom(0xc0000a0278, {0x7c3860, 0xc0002d4138})
                /home/wxh/.local/go/src/bytes/buffer.go:202 +0x98
        crypto/tls.(*Conn).readFromUntil(0xc0000a0000, {0x7c3b80?, 0xc00009c000}, 0xc0000a41c0?)
                /home/wxh/.local/go/src/crypto/tls/conn.go:809 +0xe5
        crypto/tls.(*Conn).readRecordOrCCS(0xc0000a0000, 0x0)
                /home/wxh/.local/go/src/crypto/tls/conn.go:616 +0x116
        crypto/tls.(*Conn).readRecord(...)
                /home/wxh/.local/go/src/crypto/tls/conn.go:582
        crypto/tls.(*Conn).Read(0xc0000a0000, {0xc0001cf000, 0x1000, 0x11?})
                /home/wxh/.local/go/src/crypto/tls/conn.go:1287 +0x16f
        bufio.(*Reader).Read(0xc0001af1a0, {0xc0001aad60, 0x9, 0xc0004d5d18?})
                /home/wxh/.local/go/src/bufio/bufio.go:237 +0x1bb
        io.ReadAtLeast({0x7c3760, 0xc0001af1a0}, {0xc0001aad60, 0x9, 0x9}, 0x9)
                /home/wxh/.local/go/src/io/io.go:332 +0x9a
        io.ReadFull(...)
                /home/wxh/.local/go/src/io/io.go:351
        net/http.http2readFrameHeader({0xc0001aad60?, 0x9?, 0xc0004d5df0?}, {0x7c3760?, 0xc0001af1a0?})
                /home/wxh/.local/go/src/net/http/h2_bundle.go:1565 +0x6e
        net/http.(*http2Framer).ReadFrame(0xc0001aad20)
                /home/wxh/.local/go/src/net/http/h2_bundle.go:1829 +0x95
        net/http.(*http2clientConnReadLoop).run(0xc0004d5f98)
                /home/wxh/.local/go/src/net/http/h2_bundle.go:8875 +0x130
        net/http.(*http2ClientConn).readLoop(0xc00009e180)
                /home/wxh/.local/go/src/net/http/h2_bundle.go:8771 +0x6f
        created by net/http.(*http2Transport).newClientConn
                /home/wxh/.local/go/src/net/http/h2_bundle.go:7478 +0xaaa
        
         Goroutine 37 in state IO wait, with internal/poll.runtime_pollWait on top of the stack:
        goroutine 37 [IO wait]:
        internal/poll.runtime_pollWait(0x7f945c1e02a8, 0x72)
                /home/wxh/.local/go/src/runtime/netpoll.go:305 +0x89
        internal/poll.(*pollDesc).wait(0xc0003ca000?, 0xc000202000?, 0x0)
                /home/wxh/.local/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
        internal/poll.(*pollDesc).waitRead(...)
                /home/wxh/.local/go/src/internal/poll/fd_poll_runtime.go:89
        internal/poll.(*FD).Read(0xc0003ca000, {0xc000202000, 0x1300, 0x1300})
                /home/wxh/.local/go/src/internal/poll/fd_unix.go:167 +0x25a
        net.(*netFD).Read(0xc0003ca000, {0xc000202000?, 0xc0004e6798?, 0xc0004c0808?})
                /home/wxh/.local/go/src/net/fd_posix.go:55 +0x29
        net.(*conn).Read(0xc000014028, {0xc000202000?, 0xc000136630?, 0x2c?})
                /home/wxh/.local/go/src/net/net.go:183 +0x45
        crypto/tls.(*atLeastReader).Read(0xc000276288, {0xc000202000?, 0x0?, 0x150fbb8ccb566149?})
                /home/wxh/.local/go/src/crypto/tls/conn.go:787 +0x3d
        bytes.(*Buffer).ReadFrom(0xc0000a0978, {0x7c3860, 0xc000276288})
                /home/wxh/.local/go/src/bytes/buffer.go:202 +0x98
        crypto/tls.(*Conn).readFromUntil(0xc0000a0700, {0x7c3b80?, 0xc000014028}, 0xc0004cc2c0?)
                /home/wxh/.local/go/src/crypto/tls/conn.go:809 +0xe5
        crypto/tls.(*Conn).readRecordOrCCS(0xc0000a0700, 0x0)
                /home/wxh/.local/go/src/crypto/tls/conn.go:616 +0x116
        crypto/tls.(*Conn).readRecord(...)
                /home/wxh/.local/go/src/crypto/tls/conn.go:582
        crypto/tls.(*Conn).Read(0xc0000a0700, {0xc00023c000, 0x1000, 0x11?})
                /home/wxh/.local/go/src/crypto/tls/conn.go:1287 +0x16f
        bufio.(*Reader).Read(0xc00022a2a0, {0xc00020e2e0, 0x9, 0xc0004c0d18?})
                /home/wxh/.local/go/src/bufio/bufio.go:237 +0x1bb
        io.ReadAtLeast({0x7c3760, 0xc00022a2a0}, {0xc00020e2e0, 0x9, 0x9}, 0x9)
                /home/wxh/.local/go/src/io/io.go:332 +0x9a
        io.ReadFull(...)
                /home/wxh/.local/go/src/io/io.go:351
        net/http.http2readFrameHeader({0xc00020e2e0?, 0x9?, 0xc0004c0df0?}, {0x7c3760?, 0xc00022a2a0?})
                /home/wxh/.local/go/src/net/http/h2_bundle.go:1565 +0x6e
        net/http.(*http2Framer).ReadFrame(0xc00020e2a0)
                /home/wxh/.local/go/src/net/http/h2_bundle.go:1829 +0x95
        net/http.(*http2clientConnReadLoop).run(0xc0004c0f98)
                /home/wxh/.local/go/src/net/http/h2_bundle.go:8875 +0x130
        net/http.(*http2ClientConn).readLoop(0xc00019e300)
                /home/wxh/.local/go/src/net/http/h2_bundle.go:8771 +0x6f
        created by net/http.(*http2Transport).newClientConn
                /home/wxh/.local/go/src/net/http/h2_bundle.go:7478 +0xaaa
        ]
FAIL
exit status 1

Does anyone know how to address this issue?

Thanks!

goleak finds goroutine leak in not enabled test case

If you have a module with a leak in func leak():

package foo

import (
	"sync"
	"time"
)

type O struct {
	once *sync.Once
	quit chan struct{}
}

func NewO() *O {
	o := &O{
		once: &sync.Once{},
		quit: make(chan struct{}),
	}
	return o
}

func (o *O) leak() {
	go func() {
		d := 100 * time.Millisecond
		for {
			select {
			case <-o.quit:
				return
			case <-time.After(2 * d):
				time.Sleep(d)
			}

		}

	}()
}

func (o *O) close() {
	o.once.Do(func() {
		close(o.quit)
	})
}

func (*O) run(d time.Duration) {
	time.Sleep(d)
}

and tests checking for leaks by running defer goleak.VerifyNone(t), that don't run leak(), it will show a leak in TestC, even if the leak is in TestB without defer goleak.VerifyNone(t):

package foo

import (
	"testing"
	"time"

	"go.uber.org/goleak"
)

func TestA(t *testing.T) {
	defer goleak.VerifyNone(t)

	o := NewO()
	defer o.close()
	o.run(time.Second)
}

func TestB(t *testing.T) {
	o := NewO()
	o.leak()
	o.run(time.Second)
}

func TestC(t *testing.T) {
	defer goleak.VerifyNone(t)

	o := NewO()
	defer o.close()
	o.run(time.Second)
}

It depends on order of execution of tests.

Here a test run:

% go test .
--- FAIL: TestC (1.45s)
    foo_test.go:30: found unexpected goroutines:
        [Goroutine 6 in state select, with foo.(*O).leak.func1 on top of the stack:
        goroutine 6 [select]:
        foo.(*O).leak.func1()
                /tmp/go/goleak/foo.go:25 +0x85
        created by foo.(*O).leak
                /tmp/go/goleak/foo.go:22 +0x56
        ]
FAIL
FAIL    foo     3.466s
FAIL

goleak.IgnoreAnyFunction not working for rollbar-go

Hi, I'm trying to skip reporting rollbar goroutine like below:

func TestMain(m *testing.M) {
	goleak.IgnoreAnyFunction("github.com/rollbar/rollbar-go.NewAsyncTransport.func1")
	goleak.IgnoreAnyFunction("github.com/rollbar/rollbar-go.NewAsyncTransport")
	goleak.VerifyTestMain(m)
	os.Exit(testMain(m))
}

but it still does report about the leak

=== RUN   TestE2E
Starting E2E test
--- PASS: TestE2E (1.00s)
PASS
goleak: Errors on successful test run: found unexpected goroutines:
[Goroutine 34 in state chan receive, with github.com/rollbar/rollbar-go.NewAsyncTransport.func1 on top of the stack:
github.com/rollbar/rollbar-go.NewAsyncTransport.func1()
	/Users/sagar/go/pkg/mod/github.com/rollbar/[email protected]/async_transport.go:74 +0x8a
created by github.com/rollbar/rollbar-go.NewAsyncTransport in goroutine 1
	/Users/sagar/go/pkg/mod/github.com/rollbar/[email protected]/async_transport.go:61 +0x198
]
FAIL

What possibly wrong Im doing?

fix security issue

Hello,

I am working at Manomano and we use gemnasium analyser to report securities issues.

We use zap logger and goleak is a dependency of zap.logger.
This little pr purpose you to update your yaml dependency to a fixed version.
Detail report:
| Severity | Unknown |
| Identifier | |
| URL | docker/cli#2117 |
| Scanner | Gemnasium |
| Message | XML Entity Expansion in gopkg.in/yaml.v2 |
| Package | gopkg.in/yaml.v2 v2.2.1 |
| Solution | Upgrade to version 2.2.3 or above. |
| File | go.sum |

PR link: #59

How could you define "leak"?

I just have a look the codes generally, my understanding is that check leak by compare goroutine number each time?

Could you make a doc what describe the theory or process of check leak? Thanks a lot

Support t.Parallel?

Hi, thanks for providing great package :)

BTW, I saw goleak internal source and found below switch...case:

case "testing.RunTests", "testing.(*T).Run":

But, I used t.Parallel func on my project testing. So, goleak suggested:

found unexpected goroutines

Is it the expected behavior? Or, Should I adding goleak.IgnoreTopFunction("testing.(*T).Parallel") to defer goleak.VerifyNoLeaks(t)? (and, is it correct use case?)

Friction for tinygo users

tinygo as of release 0.22 does not support goleak; this isn't particularly surprising, as tinygo still only provides stubs for several things goleak relies upon.

A number of apps - particularly, the one I'm trying to ship :-) - would pass tests under both go and tinygo if goleak sensed the tinygo build constraint and provided a minimal stub while tinygo matures.

This would be an elegant way to reduce friction for goleak users who must pass tests with both go and tinygo.

I'll provide a pull request with the simple change required. I think this is sufficient; works for my app, at least.

create v1.2.1 release

The go/lint dependency removal is important for Kubernetes. Can you perhaps tag a v1.2.1 release?

v1.2.0...master

#94 would also be useful, but not crucial - the current workaround is to loop around goleak.Find.

Consider use of t.Cleanup in goleak

Within a test, the recommendation is to use defer goleak.VerifyNone(t). However, this can't be used inside of a test helper. We may want to support t.Cleanup, possibly via a new method, so this issue is to investigate what we should do.

Tag releases

Is there any plan to create a new tag fallowing the semantic versioning? This since the latest tag (v0.10.0) was almost 2 years ago, which go get will use unless a commit is specified.
I see there is a V1 PR already merged (#27), but if V1 it's still not stable/ready, would it be possible to tag the bug fix for t.Paralell (#25) under something like v0.10.1 or v0.11.0?

Open contributions

Is this project accepting open contributions?
The vision of this project is great, we (contributors) can work towards making this better.

Support tracebackancestors?

I'd like to verify that there are no goroutines leaked in my test, but only for goroutines where my test itself is an ancestor goroutine. AFAIK, this is not what goleak currently does. It looks at all goroutines, which means it doesn't work in parallel, and it doesn't work for many globally initialized goroutines like those created in the init function of some imported package.

There is a tracebackancestors option that can be passed to the GODEBUG environment variable (documented here, withe the original accepted proposal here. This option adds ancestry metadata to goroutines, which should make the functionality I'm looking for possible.

Are there any plans to add this functionality to goleak?

goleak is no longer compatible with Go 1.5+

Readme explains this is compatible with Go 1.5+.
However, the latest version v1.2.0 only works on Go 1.18+.

Sample code:

package main

import (
	"testing"

	"go.uber.org/goleak"
)

func TestLeak(t *testing.T) {
	defer goleak.VerifyNone(t)
}
$ go version
go version go1.13.15 linux/amd64
$ go test
# go.uber.org/goleak
/go/pkg/mod/go.uber.org/[email protected]/options.go:115:3: undefined: isTraceStack
note: module requires Go 1.18
FAIL    example.com/foo [build failed]

The previous version v1.1.12 works expectedly. This seems due to #79.
Is current version only compatible with Go 1.18+?

[question]I'm literally confused about the result, why the test failed?

os platform: ubuntu 20.04
go version: 1.19.7

Can someone advise me how to pass the test?
Is the problem caused by the running time FAIL demo/test 1.169s?

package test

import (
	"fmt"
	"net/http"
	"testing"

	"go.uber.org/goleak"
)

func TestXxx(t *testing.T) {
	defer goleak.VerifyNone(t)

	resp, err := http.Get("https://www.microsoft.com")
	if err != nil {
		t.Fail()
	}
        defer resp.Body.Close()
	fmt.Println(resp.StatusCode)
}

OUTPUT:

go test 
200
--- FAIL: TestXxx (1.16s)
    m_test.go:19: found unexpected goroutines:
        [Goroutine 13 in state IO wait, with internal/poll.runtime_pollWait on top of the stack:
        goroutine 13 [IO wait]:
        internal/poll.runtime_pollWait(0x7f5fc173dff0, 0x72)
                /home/ubuntu/go/src/runtime/netpoll.go:305 +0x89
        internal/poll.(*pollDesc).wait(0xc0003b0480?, 0xc000284a00?, 0x0)
                /home/ubuntu/go/src/internal/poll/fd_poll_runtime.go:84 +0x32
        internal/poll.(*pollDesc).waitRead(...)
                /home/ubuntu/go/src/internal/poll/fd_poll_runtime.go:89
        internal/poll.(*FD).Read(0xc0003b0480, {0xc000284a00, 0x2500, 0x2500})
                /home/ubuntu/go/src/internal/poll/fd_unix.go:167 +0x25a
        net.(*netFD).Read(0xc0003b0480, {0xc000284a00?, 0xc00040ad60?, 0xc000285409?})
                /home/ubuntu/go/src/net/fd_posix.go:55 +0x29
        net.(*conn).Read(0xc000014008, {0xc000284a00?, 0x56?, 0x0?})
                /home/ubuntu/go/src/net/net.go:183 +0x45
        crypto/tls.(*atLeastReader).Read(0xc0002d0018, {0xc000284a00?, 0xc0003e1520?, 0x4e12a8?})
                /home/ubuntu/go/src/crypto/tls/conn.go:787 +0x3d
        bytes.(*Buffer).ReadFrom(0xc000798cf8, {0xb063e0, 0xc0002d0018})
                /home/ubuntu/go/src/bytes/buffer.go:202 +0x98
        crypto/tls.(*Conn).readFromUntil(0xc000798a80, {0xb06700?, 0xc000014008}, 0x1afc?)
                /home/ubuntu/go/src/crypto/tls/conn.go:809 +0xe5
        crypto/tls.(*Conn).readRecordOrCCS(0xc000798a80, 0x0)
                /home/ubuntu/go/src/crypto/tls/conn.go:616 +0x116
        crypto/tls.(*Conn).readRecord(...)
                /home/ubuntu/go/src/crypto/tls/conn.go:582
        crypto/tls.(*Conn).Read(0xc000798a80, {0xc00028f000, 0x1000, 0x670a80?})
                /home/ubuntu/go/src/crypto/tls/conn.go:1315 +0x16f
        bufio.(*Reader).Read(0xc0000aa720, {0xc0001de2e0, 0x9, 0x67e4a5?})
                /home/ubuntu/go/src/bufio/bufio.go:237 +0x1bb
        io.ReadAtLeast({0xb062e0, 0xc0000aa720}, {0xc0001de2e0, 0x9, 0x9}, 0x9)
                /home/ubuntu/go/src/io/io.go:332 +0x9a
        io.ReadFull(...)
                /home/ubuntu/go/src/io/io.go:351
        net/http.http2readFrameHeader({0xc0001de2e0?, 0x9?, 0xc0002ae060?}, {0xb062e0?, 0xc0000aa720?})
                /home/ubuntu/go/src/net/http/h2_bundle.go:1565 +0x6e
        net/http.(*http2Framer).ReadFrame(0xc0001de2a0)
                /home/ubuntu/go/src/net/http/h2_bundle.go:1829 +0x95
        net/http.(*http2clientConnReadLoop).run(0xc000063f98)
                /home/ubuntu/go/src/net/http/h2_bundle.go:8874 +0x130
        net/http.(*http2ClientConn).readLoop(0xc00017ed80)
                /home/ubuntu/go/src/net/http/h2_bundle.go:8770 +0x6f
        created by net/http.(*http2Transport).newClientConn
                /home/ubuntu/go/src/net/http/h2_bundle.go:7477 +0xaaa
        ]
FAIL
exit status 1
FAIL    demo/test       1.169s

Global way to ignore known leaks from a set of tests

Currently, every call to goleak.Verify* needs to specify any stacks to ignore. If there are known leaks which affect multiple packages, this results in duplication in each package specifying the same ignores.

We should investigate approaches to make this easier, as a strawman proposal:
Add AppendDefaultOptions as an exported function that allows appending a default set of ignores, that can be called in some init function, and can be shared for all tests by depending on the package that adds the default options.

Is these function in testing package should be filtered in default?

I got some FP with backtrace looks like this

        [Goroutine 1 in state chan receive, with testing.tRunner.func1 on top of the stack:
        goroutine 1 [chan receive]:
        testing.tRunner.func1()
        	C:/Users/Msk/go/go1.20rc3/src/testing/testing.go:1542 +0x4a5
        testing.tRunner(0xc0000376c0, 0xc000071c88)
        	C:/Users/Msk/go/go1.20rc3/src/testing/testing.go:1582 +0x144
        testing.runTests(0xc000055b80?, {0x16ac3a0, 0x1b, 0x1b}, {0xc00007c180?, 0x100c000071d10?, 0x0?})
        	C:/Users/Msk/go/go1.20rc3/src/testing/testing.go:2034 +0x489
        testing.(*M).Run(0xc000055b80)
        	C:/Users/Msk/go/go1.20rc3/src/testing/testing.go:1906 +0x63a
        main.main()
        	_testmain.go:101 +0x1aa
        ]

Indeed, these functions also occurs on the top of the stack, is them missed or by design?

testing.tRunner.func1"
"testing.(*F).Fuzz.func1"
"testing.runFuzzTests"
"testing.runFuzzing"

Add support for regex filter

Considering that we may depend on some other repositories, but we don't care too much about those repos. An alternative would be to support regex filter.

False positive with go test -trace=test.out

As stated in the title, when you invoke the test command with a trace option, the test always fails with a message concerning trace:

--- FAIL: TestAnd (0.45s)
leaks.go:78: found unexpected goroutines:
[Goroutine 6 in state trace reader (blocked), with runtime.goparkunlock on top of the stack:
goroutine 6 [trace reader (blocked)]:
runtime.goparkunlock(...)
c:/go/src/runtime/proc.go:310

Even when the test is empty like this one :

package main

import (
	"testing"

	"go.uber.org/goleak"
)

func TestAnd(t *testing.T) {
	defer goleak.VerifyNone(t)

}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.