Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: third_party/WebKit/Source/core/workers/DedicatedWorkerTest.cpp

Issue 2124693002: Worker: Fix broken GC logic on Dedicated Worker while DOMTimer is set (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "core/dom/CrossThreadTask.h"
6 #include "core/events/MessageEvent.h"
7 #include "core/testing/DummyPageHolder.h"
8 #include "core/workers/DedicatedWorkerGlobalScope.h"
9 #include "core/workers/DedicatedWorkerThread.h"
10 #include "core/workers/InProcessWorkerMessagingProxy.h"
11 #include "core/workers/InProcessWorkerObjectProxy.h"
12 #include "core/workers/WorkerThread.h"
13 #include "core/workers/WorkerThreadStartupData.h"
14 #include "core/workers/WorkerThreadTestHelper.h"
15 #include "platform/testing/UnitTestHelpers.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include <memory>
19
20 namespace blink {
21
22 class DedicatedWorkerThreadForTest final : public DedicatedWorkerThread {
23 public:
24 DedicatedWorkerThreadForTest(
25 WorkerLoaderProxyProvider* workerLoaderProxyProvider,
26 InProcessWorkerObjectProxy& workerObjectProxy)
27 : DedicatedWorkerThread(WorkerLoaderProxy::create(workerLoaderProxyProvi der), workerObjectProxy, monotonicallyIncreasingTime())
28 {
29 m_workerBackingThread = WorkerBackingThread::createForTest("Test thread" );
30 }
31
32 WorkerGlobalScope* createWorkerGlobalScope(std::unique_ptr<WorkerThreadStart upData> startupData) override
33 {
34 return new DedicatedWorkerGlobalScope(startupData->m_scriptURL, startupD ata->m_userAgent, this, m_timeOrigin, std::move(startupData->m_starterOriginPriv ilegeData), std::move(startupData->m_workerClients));
35 };
36 };
37
38 class InProcessWorkerMessagingProxyForTest : public InProcessWorkerMessagingProx y {
39 public:
40 InProcessWorkerMessagingProxyForTest(ExecutionContext* executionContext)
41 : InProcessWorkerMessagingProxy(executionContext, nullptr, nullptr)
42 {
43 workerObjectProxy().m_maxDelayToCheckPendingActivityInMs = 1000; // 1 se c
44
45 m_mockWorkerLoaderProxyProvider = wrapUnique(new MockWorkerLoaderProxyPr ovider());
46 m_workerThread = wrapUnique(new DedicatedWorkerThreadForTest(m_mockWorke rLoaderProxyProvider.get(), workerObjectProxy()));
47
48 m_mockWorkerThreadLifecycleObserver = new MockWorkerThreadLifecycleObser ver(m_workerThread->getWorkerThreadLifecycleContext());
49 EXPECT_CALL(*m_mockWorkerThreadLifecycleObserver, contextDestroyed()).Ti mes(1);
50 }
51
52 ~InProcessWorkerMessagingProxyForTest() override
53 {
54 EXPECT_EQ(WaitUntilMode::DontWait, m_waitUntilMode);
55 m_workerThread->workerLoaderProxy()->detachProvider(m_mockWorkerLoaderPr oxyProvider.get());
56 }
57
58 enum class WaitUntilMode {
59 DontWait,
60 PendingActivityReported,
61 PendingActivityChanged,
62 ThreadTerminated,
63 };
64
65 // Blocks the main thread until a specified event happens.
66 void waitUntil(WaitUntilMode mode)
67 {
68 EXPECT_TRUE(isMainThread());
69 EXPECT_EQ(WaitUntilMode::DontWait, m_waitUntilMode);
70 m_waitUntilMode = mode;
71 testing::enterRunLoop();
72 }
73
74 void reportPendingActivity(bool hasPendingActivity) override
75 {
76 EXPECT_TRUE(isMainThread());
77 bool changed = m_workerThreadHadPendingActivity != hasPendingActivity;
78 InProcessWorkerMessagingProxy::reportPendingActivity(hasPendingActivity) ;
79
80 if (m_waitUntilMode == WaitUntilMode::PendingActivityReported || (m_wait UntilMode == WaitUntilMode::PendingActivityChanged && changed)) {
81 m_waitUntilMode = WaitUntilMode::DontWait;
82 testing::exitRunLoop();
83 }
84 }
85
86 void workerThreadTerminated() override
87 {
88 EXPECT_TRUE(isMainThread());
89 if (m_waitUntilMode != WaitUntilMode::ThreadTerminated)
90 return;
91 m_waitUntilMode = WaitUntilMode::DontWait;
92 testing::exitRunLoop();
93 }
94
95 std::unique_ptr<WorkerThread> createWorkerThread(double originTime) override
96 {
97 NOTREACHED();
98 return nullptr;
99 }
100
101 DedicatedWorkerThreadForTest* workerThread()
102 {
103 return static_cast<DedicatedWorkerThreadForTest*>(m_workerThread.get());
104 }
105
106 private:
107 std::unique_ptr<MockWorkerLoaderProxyProvider> m_mockWorkerLoaderProxyProvid er;
108 std::unique_ptr<DedicatedWorkerThreadForTest> m_workerThread;
109 Persistent<MockWorkerThreadLifecycleObserver> m_mockWorkerThreadLifecycleObs erver;
110
111 WaitUntilMode m_waitUntilMode = WaitUntilMode::DontWait;
112 };
113
114 using WaitUntilMode = InProcessWorkerMessagingProxyForTest::WaitUntilMode;
115
116 class DedicatedWorkerTest : public ::testing::Test {
117 public:
118 void SetUp() override
119 {
120 m_page = DummyPageHolder::create();
121 m_workerMessagingProxy = wrapUnique(new InProcessWorkerMessagingProxyFor Test(&m_page->document()));
122 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http:// fake.url/"));
123 }
124
125 void TearDown() override
126 {
127 workerThread()->terminate();
128 workerMessagingProxy()->waitUntil(WaitUntilMode::ThreadTerminated);
129 }
130
131 void startWithSourceCode(const String& source)
132 {
133 std::unique_ptr<Vector<CSPHeaderAndType>> headers = wrapUnique(new Vecto r<CSPHeaderAndType>());
134 CSPHeaderAndType headerAndType("contentSecurityPolicy", ContentSecurityP olicyHeaderTypeReport);
135 headers->append(headerAndType);
136 workerThread()->start(WorkerThreadStartupData::create(
137 KURL(ParsedURLString, "http://fake.url/"),
138 "fake user agent",
139 source,
140 nullptr /* cachedMetaData */,
141 DontPauseWorkerGlobalScopeOnStart,
142 headers.get(),
143 "" /* referrerPolicy */,
144 m_securityOrigin.get(),
145 nullptr /* workerClients */,
146 WebAddressSpaceLocal,
147 nullptr /* originTrialTokens */,
148 nullptr /* workerSettings */,
149 V8CacheOptionsDefault));
150 }
151
152 void dispatchMessageEventOnWorkerThread()
153 {
154 toWorkerGlobalScope(workerThread()->globalScope())->dispatchEvent(Messag eEvent::create(nullptr, SerializedScriptValue::create()));
155 }
156
157 InProcessWorkerMessagingProxyForTest* workerMessagingProxy()
158 {
159 return m_workerMessagingProxy.get();
160 }
161
162 DedicatedWorkerThreadForTest* workerThread()
163 {
164 return m_workerMessagingProxy->workerThread();
165 }
166
167 private:
168 RefPtr<SecurityOrigin> m_securityOrigin;
169 std::unique_ptr<DummyPageHolder> m_page;
170 std::unique_ptr<InProcessWorkerMessagingProxyForTest> m_workerMessagingProxy ;
171 };
172
173 TEST_F(DedicatedWorkerTest, PendingActivity_NoActivity)
174 {
175 const String sourceCode = "// Do nothing";
176 startWithSourceCode(sourceCode);
177 EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
178
179 // There should be no pending activities.
180 workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityReported);
181 EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
182 }
183
184 TEST_F(DedicatedWorkerTest, PendingActivity_SetTimeout)
185 {
186 // Start an oneshot timer on initial script evaluation.
187 const String sourceCode = "setTimeout(function() {}, 50);";
188
189 startWithSourceCode(sourceCode);
190 EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
191
192 // The initial report should be true because the active timer is counted as
193 // a pending activity.
194 workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityReported);
195 EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
196
197 // The timer is fired soon and there should be no pending activities after
198 // that.
199 workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityChanged);
200 EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
201 }
202
203 TEST_F(DedicatedWorkerTest, PendingActivity_SetInterval)
204 {
205 // Start a repeated timer on initial script evaluation, and stop it when a
206 // message is received.
207 const String sourceCode =
208 "var id = setInterval(function() {}, 1000);"
209 "addEventListener('message', function(event) { clearInterval(id); });";
210
211 startWithSourceCode(sourceCode);
212 EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
213
214 // The initial report should be true because the active timer is counted as
215 // a pending activity.
216 workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityReported);
217 EXPECT_TRUE(workerMessagingProxy()->hasPendingActivity());
218
219 // Stop the timer.
220 workerThread()->postTask(BLINK_FROM_HERE, createCrossThreadTask(&DedicatedWo rkerTest::dispatchMessageEventOnWorkerThread, crossThreadUnretained(this)));
221
222 // There should be no pending activities after the timer is stopped.
223 workerMessagingProxy()->waitUntil(WaitUntilMode::PendingActivityChanged);
224 EXPECT_FALSE(workerMessagingProxy()->hasPendingActivity());
225 }
226
227 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698