Commit 4577540b authored by Andrey Kosyakov's avatar Andrey Kosyakov Committed by Commit Bot

DevTools/VT: pause document loading while VT is paused

The should let us deprecate waitForNavigation parameter to
Emulation.setVirtualTimePolicy and make its contract a bit
more sensible: instead of virtual time being set in advance
and waiting to kick-in after the navigation, we let the
navigation wait for the virtual time budget to be granted
before the document is actually loaded. This removes the
race between document resources loading (and, conditionally,
consuming 10ms each) and the client granting the budget.

Change-Id: Iffc794a450dbb8cb6ae1d37100386f00c7638abf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2531363Reviewed-by: default avatarDmitry Gozman <dgozman@chromium.org>
Commit-Queue: Andrey Kosyakov <caseq@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826355}
parent 1dfc612d
Tests that document loading is paused while virtual time is paused
Request to https://test.com/index.html, type: Document
[page] time at eval while paused: 100000000
[page] time at inline script: 100000010
\ No newline at end of file
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
(async function(testRunner) {
const {page, session, dp} = await testRunner.startBlank(
'Tests that document loading is paused while virtual time is paused');
const FetchHelper = await testRunner.loadScriptAbsolute(
'../fetch/resources/fetch-test.js');
const helper = new FetchHelper(testRunner, dp);
await helper.enable();
const content = `
<html>
<script>
console.log("time at inline script: " + (new Date()).getTime());
</script>
</html>
`;
helper.onceRequest('https://test.com/index.html').fulfill(
FetchHelper.makeContentResponse(content));
await dp.Emulation.setVirtualTimePolicy({
policy: 'pause',
initialVirtualTime: 100000
});
await dp.Page.navigate({url: 'https://test.com/index.html'});
// The loader should be paused at this time, so no console.log()
// from the inline script is yet executed. Let's see if we can
// sneak in before it gets run.
await session.evaluate(`
console.log("time at eval while paused: " + (new Date()).getTime());
`);
dp.Emulation.setVirtualTimePolicy({
policy: 'pauseIfNetworkFetchesPending',
budget: 5000,
});
dp.Runtime.enable();
for (let i = 0; i < 2; ++i) {
const message = (await dp.Runtime.onceConsoleAPICalled()).params;
testRunner.log(`[page] ${message.args[0].value}`);
}
testRunner.completeTest();
});
...@@ -237,6 +237,8 @@ HEADLESS_PROTOCOL_TEST(VirtualTimeFetchKeepalive, ...@@ -237,6 +237,8 @@ HEADLESS_PROTOCOL_TEST(VirtualTimeFetchKeepalive,
"emulation/virtual-time-fetch-keepalive.js") "emulation/virtual-time-fetch-keepalive.js")
HEADLESS_PROTOCOL_TEST(VirtualTimeDisposeWhileRunning, HEADLESS_PROTOCOL_TEST(VirtualTimeDisposeWhileRunning,
"emulation/virtual-time-dispose-while-running.js") "emulation/virtual-time-dispose-while-running.js")
HEADLESS_PROTOCOL_TEST(VirtualTimePausesDocumentLoading,
"emulation/virtual-time-pauses-document-loading.js")
HEADLESS_PROTOCOL_TEST(PageBeforeUnload, "page/page-before-unload.js") HEADLESS_PROTOCOL_TEST(PageBeforeUnload, "page/page-before-unload.js")
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "third_party/blink/renderer/core/inspector/dev_tools_emulator.h" #include "third_party/blink/renderer/core/inspector/dev_tools_emulator.h"
#include "third_party/blink/renderer/core/inspector/locale_controller.h" #include "third_party/blink/renderer/core/inspector/locale_controller.h"
#include "third_party/blink/renderer/core/inspector/protocol/DOM.h" #include "third_party/blink/renderer/core/inspector/protocol/DOM.h"
#include "third_party/blink/renderer/core/loader/document_loader.h"
#include "third_party/blink/renderer/core/page/focus_controller.h" #include "third_party/blink/renderer/core/page/focus_controller.h"
#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/geometry/double_rect.h" #include "third_party/blink/renderer/platform/geometry/double_rect.h"
...@@ -431,6 +432,9 @@ void InspectorEmulationAgent::ApplyVirtualTimePolicy( ...@@ -431,6 +432,9 @@ void InspectorEmulationAgent::ApplyVirtualTimePolicy(
budget_amount, budget_amount,
WTF::Bind(&InspectorEmulationAgent::VirtualTimeBudgetExpired, WTF::Bind(&InspectorEmulationAgent::VirtualTimeBudgetExpired,
WrapWeakPersistent(this))); WrapWeakPersistent(this)));
for (DocumentLoader* loader : pending_document_loaders_)
loader->SetDefersLoading(false);
pending_document_loaders_.clear();
} }
if (new_policy.max_virtual_time_task_starvation_count) { if (new_policy.max_virtual_time_task_starvation_count) {
web_local_frame_->View()->Scheduler()->SetMaxVirtualTimeTaskStarvationCount( web_local_frame_->View()->Scheduler()->SetMaxVirtualTimeTaskStarvationCount(
...@@ -668,6 +672,16 @@ void InspectorEmulationAgent::GetDisabledImageTypes(HashSet<String>* result) { ...@@ -668,6 +672,16 @@ void InspectorEmulationAgent::GetDisabledImageTypes(HashSet<String>* result) {
result->insert(type); result->insert(type);
} }
void InspectorEmulationAgent::WillCommitLoad(LocalFrame*,
DocumentLoader* loader) {
if (virtual_time_policy_.Get() !=
protocol::Emulation::VirtualTimePolicyEnum::Pause) {
return;
}
loader->SetDefersLoading(true);
pending_document_loaders_.push_back(loader);
}
void InspectorEmulationAgent::ApplyAcceptLanguageOverride(String* accept_lang) { void InspectorEmulationAgent::ApplyAcceptLanguageOverride(String* accept_lang) {
if (!accept_language_override_.Get().IsEmpty()) if (!accept_language_override_.Get().IsEmpty())
*accept_lang = accept_language_override_.Get(); *accept_lang = accept_language_override_.Get();
...@@ -704,6 +718,7 @@ Response InspectorEmulationAgent::AssertPage() { ...@@ -704,6 +718,7 @@ Response InspectorEmulationAgent::AssertPage() {
void InspectorEmulationAgent::Trace(Visitor* visitor) const { void InspectorEmulationAgent::Trace(Visitor* visitor) const {
visitor->Trace(web_local_frame_); visitor->Trace(web_local_frame_);
visitor->Trace(pending_document_loaders_);
InspectorBaseAgent::Trace(visitor); InspectorBaseAgent::Trace(visitor);
} }
......
...@@ -100,6 +100,7 @@ class CORE_EXPORT InspectorEmulationAgent final ...@@ -100,6 +100,7 @@ class CORE_EXPORT InspectorEmulationAgent final
ResourceLoaderOptions&, ResourceLoaderOptions&,
ResourceType); ResourceType);
void GetDisabledImageTypes(HashSet<String>* result); void GetDisabledImageTypes(HashSet<String>* result);
void WillCommitLoad(LocalFrame*, DocumentLoader*);
// InspectorBaseAgent overrides. // InspectorBaseAgent overrides.
protocol::Response disable() override; protocol::Response disable() override;
...@@ -124,6 +125,7 @@ class CORE_EXPORT InspectorEmulationAgent final ...@@ -124,6 +125,7 @@ class CORE_EXPORT InspectorEmulationAgent final
Member<WebLocalFrameImpl> web_local_frame_; Member<WebLocalFrameImpl> web_local_frame_;
base::TimeTicks virtual_time_base_ticks_; base::TimeTicks virtual_time_base_ticks_;
HeapVector<Member<DocumentLoader>> pending_document_loaders_;
std::unique_ptr<TimeZoneController::TimeZoneOverride> timezone_override_; std::unique_ptr<TimeZoneController::TimeZoneOverride> timezone_override_;
......
...@@ -1061,13 +1061,8 @@ void DocumentLoader::StopLoading() { ...@@ -1061,13 +1061,8 @@ void DocumentLoader::StopLoading() {
void DocumentLoader::SetDefersLoading(bool defers) { void DocumentLoader::SetDefersLoading(bool defers) {
defers_loading_ = defers; defers_loading_ = defers;
if (body_loader_) { if (body_loader_)
body_loader_->SetDefersLoading(defers); body_loader_->SetDefersLoading(defers);
if (defers_loading_)
virtual_time_pauser_.UnpauseVirtualTime();
else
virtual_time_pauser_.PauseVirtualTime();
}
} }
void DocumentLoader::DetachFromFrame(bool flush_microtask_queue) { void DocumentLoader::DetachFromFrame(bool flush_microtask_queue) {
......
...@@ -120,6 +120,7 @@ ...@@ -120,6 +120,7 @@
"FrameStartedLoading", "FrameStartedLoading",
"PrepareRequest", "PrepareRequest",
"GetDisabledImageTypes", "GetDisabledImageTypes",
"WillCommitLoad",
] ]
}, },
InspectorLayerTreeAgent: { InspectorLayerTreeAgent: {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment