// AfterTest gets the current goroutines and runs the returned function to // get the goroutines at that time to contrast wheter any goroutines leaked. // Usage: defer testleak.AfterTest(c)() // It can call with BeforeTest() at the beginning of check.Suite.TearDownSuite() or // call alone at the beginning of each test. func AfterTest(c *check.C) func() { if len(beforeTestGorountines) == 0 { for _, g := range interestingGoroutines() { beforeTestGorountines[g] = true } } return func() { defer func() { beforeTestGorountines = map[string]bool{} }() var leaked []string for i := 0; i < 50; i++ { for _, g := range interestingGoroutines() { if !beforeTestGorountines[g] { leaked = append(leaked, g) } } // 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 } return } for _, g := range leaked { c.Errorf("Test appears to have leaked: %v", g) } } }
func (s *FoundationS) TestFailureHeader(c *check.C) { output := String{} failHelper := FailHelper{} check.Run(&failHelper, &check.RunConf{Output: &output}) header := fmt.Sprintf(""+ "\n-----------------------------------"+ "-----------------------------------\n"+ "FAIL: check_test.go:%d: FailHelper.TestLogAndFail\n", failHelper.testLine) if strings.Index(output.value, header) == -1 { c.Errorf(""+ "Failure didn't print a proper header.\n"+ "... Got:\n%s... Expected something with:\n%s", output.value, header) } }
func (s *FoundationS) TestErrorf(c *check.C) { // Do not use checkState() here. It depends on Errorf() working. expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ " c.Errorf(\"Error %%v!\", \"message\")\n"+ "... Error: Error message!\n\n", getMyLine()+1) c.Errorf("Error %v!", "message") failed := c.Failed() c.Succeed() if log := c.GetTestLog(); log != expectedLog { c.Logf("Errorf() logged %#v rather than %#v", log, expectedLog) c.Fail() } if !failed { c.Logf("Errorf() didn't put the test in a failed state") c.Fail() } }
// Verify the state of the test. Note that since this also verifies if // the test is supposed to be in a failed state, no other checks should // be done in addition to what is being tested. func checkState(c *check.C, result interface{}, expected *expectedState) { failed := c.Failed() c.Succeed() log := c.GetTestLog() matched, matchError := regexp.MatchString("^"+expected.log+"$", log) if matchError != nil { c.Errorf("Error in matching expression used in testing %s", expected.name) } else if !matched { c.Errorf("%s logged:\n----------\n%s----------\n\nExpected:\n----------\n%s\n----------", expected.name, log, expected.log) } if result != expected.result { c.Errorf("%s returned %#v rather than %#v", expected.name, result, expected.result) } if failed != expected.failed { if failed { c.Errorf("%s has failed when it shouldn't", expected.name) } else { c.Errorf("%s has not failed when it should", expected.name) } } }