9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

goleakでgoroutine leakのリスクを減らす

Last updated at Posted at 2019-08-30

このページについて

uberが手掛けているgoleakを使ってgoroutine leakを検出できるか試してみました。簡単なデモコードではしっかりエラーにしてくれたので、使ってみてもよいのかなと思います。

現在(2019-08)α版 なのでもう少し待ってみてもいいかもしれませんが、、

内容

goroutine leakの起こる関数を書き、goleakを使って検出できるか試してみます。

関数

package helper

import (
	"fmt"
	"time"
)

func Leak(sleep int) {
	fmt.Println("leak test")
	go func() {
		fmt.Println("start goroutine")
		for {
            // leak しないパターンも試す
			if sleep == 0 {
				return
			}
			time.Sleep(time.Duration(sleep) * time.Second)
		}
	}()
}

テスト

leak_test.go
package helper

import "testing"

func TestLeak(t *testing.T) {
	type args struct {
		sleep int
	}
	tests := []struct {
		name string
		args args
	}{
		{
			name: "leak",
			args: args{
				sleep: 1,
			},
		},
		{
			name: "not leak",
			args: args{
				sleep: 0,
			},
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			Leak(tt.args.sleep)
		})
	}
}

goleakはパッケージ全体に適用したい場合はTestMainから動かすと良いみたいです

main_test.go
package helper

import (
	"testing"

	"go.uber.org/goleak"
)

func TestMain(m *testing.M) {
	goleak.VerifyTestMain(m)
}

これで準備は整いました。
テストを実行します


$ go test -v ./...
=== RUN   TestLeak
=== RUN   TestLeak/leak
leak test
start goroutine
=== RUN   TestLeak/not_leak
leak test
start goroutine
--- PASS: TestLeak (0.00s)
    --- PASS: TestLeak/leak (0.00s)
    --- PASS: TestLeak/not_leak (0.00s)
PASS
coverage: 100.0% of statements
goleak: Errors on successful test run: found unexpected goroutines:
[Goroutine 33 in state sleep, with runtime.goparkunlock on top of the stack:
goroutine 33 [sleep]:
runtime.goparkunlock(...)
	/usr/local/Cellar/go/1.12.1/libexec/src/runtime/proc.go:307
time.Sleep(0x3b9aca00)
	/usr/local/Cellar/go/1.12.1/libexec/src/runtime/time.go:105 +0x159
github.com/smith-30/ootd/helper.Leak.func1(0x1)
	/go/src/github.com/smith-30/ootd/helper/leak.go:16 +0xa0
created by github.com/smith-30/ootd/helper.Leak
	/go/src/github.com/smith-30/ootd/helper/leak.go:10 +0xa6
]
FAIL	github.com/smith-30/ootd/helper	0.457s
Error: Tests failed.

goroutineリークを検出してテストを落としてくれていますね!
もちろん、テストケースが not leak のみの場合はエラーで落ちません
goroutineをバリバリ使うデーモンや並列処理を使うAPIのメインロジックのe2eテストの際には使っていきたいと思っています。

9
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?