testCases = append(testCases, patternTestCases...)
// Test cases must not panic or cause fatal exceptions.
- failStates := regexp.MustCompile(`fatal|panic`)
+ failStates := regexp.MustCompile(`fatal|panic|DATA RACE`)
testApp := func(exepath string, testCases []testCase) {
t.Errorf("Test %s produced no output. Is the goroutine leak profile collected?", tcase.name)
}
- // Zero tolerance policy for fatal exceptions or panics.
+ // Zero tolerance policy for fatal exceptions, panics, or data races.
if failStates.MatchString(runOutput) {
- t.Errorf("unexpected fatal exception or panic!\noutput:\n%s\n\n", runOutput)
+ t.Errorf("unexpected fatal exception or panic\noutput:\n%s\n\n", runOutput)
}
output += runOutput + "\n\n"
unexpectedLeaks := make([]string, 0, len(foundLeaks))
// Parse every leak and check if it is expected (maybe as a flaky leak).
- LEAKS:
+ leaks:
for _, leak := range foundLeaks {
// Check if the leak is expected.
// If it is, check whether it has been encountered before.
for flakyLeak := range tcase.flakyLeaks {
if flakyLeak.MatchString(leak) {
// The leak is flaky. Carry on to the next line.
- continue LEAKS
+ continue leaks
}
}
White paper: https://lujie.ac.cn/files/papers/GoBench.pdf
-The examples have been modified in order to run the goroutine leak
-profiler. Buggy snippets are moved from within a unit test to separate
-applications. Each is then independently executed, possibly as multiple
-copies within the same application in order to exercise more interleavings.
-Concurrently, the main program sets up a waiting period (typically 1ms), followed
-by a goroutine leak profile request. Other modifications may involve injecting calls
-to `runtime.Gosched()`, to more reliably exercise buggy interleavings, or reductions
-in waiting periods when calling `time.Sleep`, in order to reduce overall testing time.
-
-The resulting goroutine leak profile is analyzed to ensure that no unexpected leaks occurred,
-and that the expected leaks did occur. If the leak is flaky, the only purpose of the expected
-leak list is to protect against unexpected leaks.
+The examples have been modified in order to run the goroutine leak profiler.
+Buggy snippets are moved from within a unit test to separate applications.
+Each is then independently executed, possibly as multiple copies within the
+same application in order to exercise more interleavings. Concurrently, the
+main program sets up a waiting period (typically 1ms), followed by a goroutine
+leak profile request. Other modifications may involve injecting calls to
+`runtime.Gosched()`, to more reliably exercise buggy interleavings, or reductions
+in waiting periods when calling `time.Sleep`, in order to reduce overall testing
+time.
+
+The resulting goroutine leak profile is analyzed to ensure that no unexpecte
+leaks occurred, and that the expected leaks did occur. If the leak is flaky, the
+only purpose of the expected leak list is to protect against unexpected leaks.
+
+The examples have also been modified to remove data races, since those create flaky
+test failures, when really all we care about are leaked goroutines.
The entries below document each of the corresponding leaks.
. close(c.closed)
. <-c.dispatcherLoopStopped
---------------------G1,G2 leak-------------------------------
-```
\ No newline at end of file
+```