util/testleak: make it work right (#3414)

* fix testleak package
* provide "make leak" to makefile
This commit is contained in:
tiancaiamao
2017-06-07 20:39:44 +08:00
committed by GitHub
parent a623135bae
commit c1902e62c4
5 changed files with 43 additions and 1 deletions

View File

@ -121,6 +121,13 @@ race: parserlib
@export log_level=debug; \
$(GOTEST) -race $(PACKAGES)
leak: parserlib
@export log_level=debug; \
for dir in $(PACKAGES); do \
echo $$dir; \
$(GOTEST) -tags leak $$dir | awk 'END{if($$1=="FAIL") {exit 1}}' || exit 1; \
done;
tikv_integration_test: parserlib
$(GOTEST) ./store/tikv/. -with-tikv=true

View File

@ -169,6 +169,7 @@ func (s *testBootstrapSuite) testBootstrapWithError(c *C) {
func (s *testBootstrapSuite) TestUpgrade(c *C) {
defer testleak.AfterTest(c)()
store := newStoreWithBootstrap(c, s.dbName)
defer store.Close()
se := newSession(c, store, s.dbName)
mustExecSQL(c, se, "USE mysql;")

View File

@ -254,6 +254,7 @@ func (s *testMainSuite) TestRetryOpenStore(c *C) {
func (s *testMainSuite) TestSchemaValidity(c *C) {
localstore.MockRemoteStore = true
store := newStoreWithBootstrap(c, s.dbName+"schema_validity")
defer store.Close()
dbName := "test_schema_validity"
se := newSession(c, store, dbName)
se1 := newSession(c, store, dbName)
@ -345,6 +346,7 @@ func (s *testMainSuite) TestSchemaValidity(c *C) {
func (s *testMainSuite) TestSysSessionPoolGoroutineLeak(c *C) {
// TODO: testleak package should be able to find this leak.
store := newStoreWithBootstrap(c, s.dbName+"goroutine_leak")
defer store.Close()
se, err := createSession(store)
c.Assert(err, IsNil)

27
util/testleak/fake.go Normal file
View File

@ -0,0 +1,27 @@
// Copyright 2017 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !leak
package testleak
import "github.com/pingcap/check"
// BeforeTest is a dummy implementation when build tag 'leak' is not set.
func BeforeTest() {
}
// AfterTest is a dummy implementation when build tag 'leak' is not set.
func AfterTest(c *check.C) func() {
return func() {
}
}

View File

@ -14,6 +14,7 @@
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
// +build leak
package testleak
@ -42,6 +43,10 @@ func interestingGoroutines() (gs []string) {
strings.Contains(stack, "localstore.(*dbStore).scheduler") ||
strings.Contains(stack, "ddl.(*ddl).start") ||
strings.Contains(stack, "domain.NewDomain") ||
strings.Contains(stack, "testing.(*T).Run") ||
strings.Contains(stack, "tidb.asyncGetTSWorker") || // TODO: remove it
strings.Contains(stack, "domain.(*Domain).LoadPrivilegeLoop") ||
strings.Contains(stack, "domain.(*Domain).UpdateTableStatsLoop") ||
strings.Contains(stack, "testing.Main(") ||
strings.Contains(stack, "runtime.goexit") ||
strings.Contains(stack, "created by runtime.gc") ||
@ -85,6 +90,7 @@ func AfterTest(c *check.C) func() {
var leaked []string
for i := 0; i < 50; i++ {
leaked = leaked[:0]
for _, g := range interestingGoroutines() {
if !beforeTestGorountines[g] {
leaked = append(leaked, g)
@ -93,7 +99,6 @@ func AfterTest(c *check.C) func() {
// Bad stuff found, but goroutines might just still be
// shutting down, so give it some time.
if len(leaked) != 0 {
leaked = leaked[:0]
time.Sleep(50 * time.Millisecond)
continue
}