Ensure that the testlogger has its final test removal safely (#16907)

It is possible to get a data race right at the end of the TestMain
in integrations during the final removal of the test from the testlogger. This PR
uses a Reset function to remove any final tests but adds some extra
logging which will forcibly fail if there is an unclosed logger.

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
zeripath 2021-09-01 14:05:04 +01:00 committed by GitHub
parent de2e96e37b
commit 6e0e414f55
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 1 deletions

View file

@ -120,7 +120,7 @@ func TestMain(m *testing.M) {
} }
exitCode := m.Run() exitCode := m.Run()
writerCloser.t = nil writerCloser.Reset()
if err = util.RemoveAll(setting.Indexer.IssuePath); err != nil { if err = util.RemoveAll(setting.Indexer.IssuePath); err != nil {
fmt.Printf("util.RemoveAll: %v\n", err) fmt.Printf("util.RemoveAll: %v\n", err)

View file

@ -90,6 +90,21 @@ func (w *testLoggerWriterCloser) Close() error {
return nil return nil
} }
func (w *testLoggerWriterCloser) Reset() {
w.Lock()
if len(w.t) > 0 {
for _, t := range w.t {
if t == nil {
continue
}
fmt.Fprintf(os.Stdout, "Unclosed logger writer in test: %s", (*t).Name())
(*t).Errorf("Unclosed logger writer in test: %s", (*t).Name())
}
w.t = nil
}
w.Unlock()
}
// PrintCurrentTest prints the current test to os.Stdout // PrintCurrentTest prints the current test to os.Stdout
func PrintCurrentTest(t testing.TB, skip ...int) func() { func PrintCurrentTest(t testing.TB, skip ...int) func() {
start := time.Now() start := time.Now()