New issue
Advanced search Search tips

Issue 622764 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Jun 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 3
Type: Bug



Sign in to add a comment

OOPIF: Some layout tests fail when using document.write after document finishes loading.

Project Member Reported by alex...@chromium.org, Jun 23 2016

Issue description

Affected tests:
http/tests/security/cross-origin-shared-worker-allowed.html
http/tests/security/cross-origin-worker-indexeddb-allowed.html

Repro steps:
third_party/WebKit/Tools/Scripts/run-webkit-tests -t gn-debug --additional-driver-flag=--site-per-process http/tests/security/cross-origin-shared-worker-allowed.html --driver-logging --full-results-html

These tests time out most of the time with --site-per-process.  After digging into this, I found that they're timing out because the top frame never finishes loading, and consequently BlinkTestRunner::TestFinished is never called.  

The reason for this appears to be in how they use document.write().  Both tests set up a A(B,A) hierarchy: main frame has two subframes, first is cross-site, second is same-site.  Both subframes perform some tests on workers, then use document.write() to write out the test result and signal the parent to finish the test.  The problem is that the document.write() happens after the document finishes loading, and in this case it implicitly calls document.open(), which dispatches a DidStartLoading for the frame, via this call stack:

0x7fc7b7f7d2d8 content::RenderFrameImpl::didStartLoading()
0x7fc7b009e184 blink::FrameLoaderClientImpl::didStartLoading()
0x7fc7ad4d3c6e blink::ProgressTracker::progressStarted()
0x7fc7ad4b2dab blink::FrameLoader::didExplicitOpen()
0x7fc7aca4c58d blink::Document::open()
0x7fc7aca54571 blink::Document::open()
0x7fc7aca56307 blink::Document::write()
0x7fc7aca564c4 blink::Document::write()
0x7fc7aca567e5 blink::Document::write()
0x7fc7ac7a7465 blink::DocumentV8Internal::writeMethod()
0x7fc7ac7a00f1 blink::DocumentV8Internal::writeMethodCallback()

What I see in the tests is that this happens in the second subframe before the first (OOP) subframe and thus the main frame finish loading, causing the main frame to never finish.  I.e., the sequence of events is (skipping a few details):

1. Main frame DidStartLoading
2. First subframe DidStartLoading
3. Second subframe DidStartLoading
4. Second subframe DidStopLoading (document load finished)
5. Second subframe DidStartLoading (due to document.write)
6. First subframe DidStopLoading

Step 6 is forwarded to the main frame renderer, and normally this causes the main frame to also perform a DidStopLoading, but now the main frame thinks that not all of its children are done loading, due to step 5.

AFAICT, there's no didStopLoading that's dispatched after post-load document.write.  And in fact, it appears that it's explicitly recommended to call document.close after the write to tell the browser to finish loading the page: https://developer.mozilla.org/en-US/docs/Web/API/Document/write.

So, overall, I don't think there's anything here to fix in the start/stop loading logic.  Assuming that dispatching didStartLoading on post-load document.write() is desirable (it does kind of make sense), I think we should just fix these tests: I confirmed that adding document.close() after those document.write() calls makes the tests pass.
 

Comment 1 by creis@chromium.org, Jun 23 2016

Cc: clamy@chromium.org japhet@chromium.org
Nice find!  Sounds like issue 617706.  I do wonder (as on that bug) if we should be robust against this as we are in default Chrome, but I agree with fixing the tests to to call document.close() is probably fine for now.
Project Member

Comment 2 by bugdroid1@chromium.org, Jun 23 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/4add5ff9d0fc7baec422201850dbfa829f516fb4

commit 4add5ff9d0fc7baec422201850dbfa829f516fb4
Author: alexmos <alexmos@chromium.org>
Date: Thu Jun 23 22:16:36 2016

Fix site-per-process layout tests timeouts due to document.write().

See detailed analysis in the bug.  When the document.write() happened
after document load, they implicitly called document.open() and
dispatched another DidStartLoading, which might have prevented the
main page (and the test) from finishing loading if it wasn't yet
loaded at that point (due to the OOP subframe not yet loaded).  Add a
document.close() so that there's always going to be a matching
DidStopLoading().

BUG= 622764 

Review-Url: https://codereview.chromium.org/2090343003
Cr-Commit-Position: refs/heads/master@{#401743}

[modify] https://crrev.com/4add5ff9d0fc7baec422201850dbfa829f516fb4/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
[modify] https://crrev.com/4add5ff9d0fc7baec422201850dbfa829f516fb4/third_party/WebKit/LayoutTests/http/tests/security/resources/cross-origin-iframe-for-shared-worker.html
[modify] https://crrev.com/4add5ff9d0fc7baec422201850dbfa829f516fb4/third_party/WebKit/LayoutTests/http/tests/security/resources/cross-origin-iframe-for-worker-indexeddb.html

Status: Fixed (was: Available)

Sign in to add a comment