Bug 196898

Summary: TestRunner::notifyDone() should be safely reentrant
Product: WebKit Reporter: Per Arne Vollan <pvollan>
Component: Tools / TestsAssignee: Per Arne Vollan <pvollan>
Status: RESOLVED FIXED    
Severity: Normal CC: ap, bfulgham, darin, jbedard, lforschler, ryanhaddad, sabouhallawa, webkit-bot-watchers-bugzilla, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
See Also: https://bugs.webkit.org/show_bug.cgi?id=177484
Attachments:
Description Flags
Patch
none
Patch
none
Patch darin: review+

Description Per Arne Vollan 2019-04-13 10:24:22 PDT
It is currently possible that TestRunner::notifyDone() will call itself, since notifyDone() will force a repaint, which can start executing JavaScript, which may call notifyDone() again. This can lead to test failures and flakiness.
Comment 1 Per Arne Vollan 2019-04-13 12:22:43 PDT
Created attachment 367389 [details]
Patch
Comment 2 Jonathan Bedard 2019-04-15 05:59:41 PDT
Any reason we aren't adding this to Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp too?
It also seems like forceImmediateCompletion() would have the same problem.

I need to look through how m_waitToDump is used, but I'm hesitant to say setting it before dump() is Ok. I think the reentrant point is valid, but I'm not convinced that silently making it work is the right approach, seems like doing this should cause an assertion error.
Comment 3 Jonathan Bedard 2019-04-15 06:02:58 PDT
(In reply to Jonathan Bedard from comment #2)
> ... like doing this should cause an assertion error.

Or something to that effect...I suppose we would want to surface this error in Release builds too.
Comment 4 Per Arne Vollan 2019-04-15 10:44:58 PDT
(In reply to Jonathan Bedard from comment #2)
> Any reason we aren't adding this to
> Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp too?

I haven't observed this issue for modern WebKit, but it is currently happening on Win EWS causing flakiness and many failures on every run.

> It also seems like forceImmediateCompletion() would have the same problem.
> 

Good point! I'll make the same change in this method.

> I need to look through how m_waitToDump is used, but I'm hesitant to say
> setting it before dump() is Ok. I think the reentrant point is valid, but
> I'm not convinced that silently making it work is the right approach, seems
> like doing this should cause an assertion error.

Since it is currently happening on every Win EWS run, we might not be able to assert, since the tests would fail then. Maybe we can print a message to stdout?

Thanks for reviewing!
Comment 5 Per Arne Vollan 2019-04-15 10:49:43 PDT
Created attachment 367425 [details]
Patch
Comment 6 Per Arne Vollan 2019-04-15 10:57:36 PDT
Created attachment 367427 [details]
Patch
Comment 7 Darin Adler 2019-04-15 11:01:15 PDT
Comment on attachment 367427 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=367427&action=review

> Tools/ChangeLog:3
> +        TestRunner::notifyDone() should not be reentrant

The terminology here is incorrect. If the function is called in a reentrant fashion then it *is* reentrant. What this code change does it make it safe to call it in a reentrant fashion. So the title should be "TestRunner::notifyDone() should be safely reentrant" or something like that.
Comment 8 Darin Adler 2019-04-15 11:03:50 PDT
Comment on attachment 367427 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=367427&action=review

Guess it’s OK. Lets give it a try.

> Tools/DumpRenderTree/mac/TestRunnerMac.mm:301
> +        fprintf(stderr, "TestRunner::notifyDone() called unexpectedly.");

So I guess it’s OK to do this since it won’t make tests fail? But it will fill our test results with "stderr output"; if a reentrant call is *not* actually unexpected.
Comment 9 Per Arne Vollan 2019-04-15 11:15:20 PDT
(In reply to Darin Adler from comment #8)
> Comment on attachment 367427 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=367427&action=review
> 
> Guess it’s OK. Lets give it a try.
> 
> > Tools/DumpRenderTree/mac/TestRunnerMac.mm:301
> > +        fprintf(stderr, "TestRunner::notifyDone() called unexpectedly.");
> 
> So I guess it’s OK to do this since it won’t make tests fail? But it will
> fill our test results with "stderr output"; if a reentrant call is *not*
> actually unexpected.

There are only a few tests which makes this happen. The big problem is that they make every subsequent test fail, since the output will be dumped twice, shifting the output of every following test by one.

Thanks for reviewing!
Comment 10 Per Arne Vollan 2019-04-15 11:31:04 PDT
Committed r244273: <https://trac.webkit.org/changeset/244273/webkit>
Comment 11 Radar WebKit Bug Importer 2019-04-15 11:31:29 PDT
<rdar://problem/49910600>
Comment 12 Jonathan Bedard 2019-04-15 14:30:06 PDT
(In reply to Jonathan Bedard from comment #2)
> ... I need to look through how m_waitToDump is used, but I'm hesitant to say
> setting it before dump() is Ok.

Looking through the code, we probably always should have set m_waitToDump before dumping.