Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
|
Sami
2015/04/09 10:52:29
If we want to make this patch smaller, landing thi
alex clarke (OOO till 29th)
2015/04/10 15:29:39
Acknowledged.
| |
| 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 "config.h" | |
| 6 #include "core/workers/WorkerThread.h" | |
| 7 | |
| 8 #include "bindings/core/v8/ScriptWrappable.h" | |
| 9 #include "core/inspector/ConsoleMessage.h" | |
| 10 #include "core/workers/SharedWorkerGlobalScope.h" | |
| 11 #include "core/workers/SharedWorkerThread.h" | |
| 12 #include "core/workers/WorkerGlobalScope.h" | |
| 13 #include "core/workers/WorkerReportingProxy.h" | |
| 14 #include "core/workers/WorkerThreadStartupData.h" | |
| 15 #include <gmock/gmock.h> | |
| 16 #include <gtest/gtest.h> | |
| 17 | |
| 18 using testing::_; | |
| 19 using testing::Invoke; | |
| 20 using testing::Return; | |
| 21 | |
| 22 namespace blink { | |
| 23 | |
| 24 namespace { | |
| 25 class MockWorkerLoaderProxy : public WorkerLoaderProxy { | |
| 26 public: | |
| 27 MockWorkerLoaderProxy() : WorkerLoaderProxy(nullptr) { } | |
| 28 ~MockWorkerLoaderProxy() override { } | |
| 29 | |
| 30 MOCK_METHOD1(postTaskToLoader, void(PassOwnPtr<ExecutionContextTask>)); | |
| 31 MOCK_METHOD1(postTaskToWorkerGlobalScope, bool(PassOwnPtr<ExecutionContextTa sk>)); | |
| 32 }; | |
| 33 | |
| 34 class MockWorkerReportingProxy : public WorkerReportingProxy { | |
| 35 public: | |
| 36 MockWorkerReportingProxy() { } | |
| 37 ~MockWorkerReportingProxy() override { } | |
| 38 | |
| 39 MOCK_METHOD5(reportException, void(const String& errorMessage, int lineNumbe r, int columnNumber, const String& sourceURL, int exceptionId)); | |
| 40 MOCK_METHOD1(reportConsoleMessage, void(PassRefPtrWillBeRawPtr<ConsoleMessag e>)); | |
| 41 MOCK_METHOD1(postMessageToPageInspector, void(const String&)); | |
| 42 MOCK_METHOD0(postWorkerConsoleAgentEnabled, void()); | |
| 43 MOCK_METHOD1(didEvaluateWorkerScript, void(bool success)); | |
| 44 MOCK_METHOD1(workerGlobalScopeStarted, void(WorkerGlobalScope*)); | |
| 45 MOCK_METHOD0(workerGlobalScopeClosed, void()); | |
| 46 MOCK_METHOD0(workerThreadTerminated, void()); | |
| 47 MOCK_METHOD0(willDestroyWorkerGlobalScope, void()); | |
| 48 }; | |
| 49 | |
| 50 class FakeWorkerGlobalScope : public WorkerGlobalScope { | |
| 51 public: | |
| 52 typedef WorkerGlobalScope Base; | |
| 53 | |
| 54 FakeWorkerGlobalScope(const KURL& url, const String& userAgent, WorkerThread * thread, const SecurityOrigin* starterOrigin, PassOwnPtrWillBeRawPtr<WorkerClie nts> workerClients) | |
| 55 : WorkerGlobalScope(url, userAgent, thread, monotonicallyIncreasingTime( ), starterOrigin, workerClients) | |
| 56 { | |
| 57 } | |
| 58 | |
| 59 ~FakeWorkerGlobalScope() override | |
| 60 { | |
| 61 } | |
| 62 | |
| 63 virtual bool isSharedWorkerGlobalScope() const override { return true; } | |
| 64 | |
| 65 // EventTarget | |
| 66 virtual const AtomicString& interfaceName() const override | |
| 67 { | |
| 68 return EventTargetNames::SharedWorkerGlobalScope; | |
| 69 } | |
| 70 | |
| 71 virtual void logExceptionToConsole(const String&, int , const String&, int, int, PassRefPtrWillBeRawPtr<ScriptCallStack>) override | |
| 72 { | |
| 73 } | |
| 74 | |
| 75 // Setters/Getters for attributes in SharedWorkerGlobalScope.idl | |
| 76 DEFINE_ATTRIBUTE_EVENT_LISTENER(connect); | |
| 77 String name() const { return "FakeWorkerGlobalScope"; } | |
| 78 | |
| 79 DECLARE_VIRTUAL_TRACE(); | |
| 80 }; | |
| 81 | |
| 82 DEFINE_TRACE(FakeWorkerGlobalScope) | |
| 83 { | |
| 84 WorkerGlobalScope::trace(visitor); | |
| 85 } | |
| 86 | |
| 87 class WorkerThreadForTest : public WorkerThread { | |
| 88 public: | |
| 89 WorkerThreadForTest( | |
| 90 WorkerLoaderProxy* mockWorkerLoaderProxy, | |
| 91 WorkerReportingProxy& mockWorkerReportingProxy, | |
| 92 PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> workerThreadStartupData) | |
| 93 : WorkerThread(mockWorkerLoaderProxy, mockWorkerReportingProxy, workerTh readStartupData) | |
| 94 { | |
| 95 } | |
| 96 | |
| 97 ~WorkerThreadForTest() override { } | |
| 98 | |
| 99 using WorkerThread::threadForTesting; | |
| 100 using WorkerThread::setMinQuietPeriodBeforeDoingIdleGcForTesting; | |
| 101 | |
| 102 MOCK_METHOD1(doIdleGc, bool(double deadlineSeconds)); | |
| 103 | |
| 104 PassRefPtrWillBeRawPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtr <WorkerThreadStartupData> startupData) override | |
| 105 { | |
| 106 return adoptRefWillBeNoop(new FakeWorkerGlobalScope(startupData->m_scrip tURL, startupData->m_userAgent, this, startupData->m_starterOrigin, startupData- >m_workerClients.release())); | |
| 107 } | |
| 108 }; | |
| 109 | |
| 110 class WakeupTask : public WebThread::Task { | |
| 111 public: | |
| 112 WakeupTask() { } | |
| 113 | |
| 114 ~WakeupTask() override { } | |
| 115 | |
| 116 void run() override { } | |
| 117 }; | |
| 118 | |
| 119 class PostDelayedWakeupTask : public WebThread::Task { | |
| 120 public: | |
| 121 PostDelayedWakeupTask(WebThreadSupportingGC* gc, long long delay) : m_gc(gc) , m_delay(delay) { } | |
| 122 | |
| 123 ~PostDelayedWakeupTask() override { } | |
| 124 | |
| 125 void run() override | |
| 126 { | |
| 127 m_gc->postDelayedTask(FROM_HERE, new WakeupTask(), m_delay); | |
| 128 } | |
| 129 | |
| 130 WebThreadSupportingGC* m_gc; | |
| 131 long long m_delay; | |
| 132 }; | |
| 133 | |
| 134 } // namespace | |
| 135 | |
| 136 class WorkerThreadTest : public testing::Test { | |
| 137 public: | |
| 138 void SetUp() override | |
| 139 { | |
| 140 m_mockWorkerLoaderProxy = new MockWorkerLoaderProxy(); | |
| 141 m_mockWorkerReportingProxy = adoptPtr(new MockWorkerReportingProxy()); | |
| 142 m_securityOrigin = SecurityOrigin::create(KURL(ParsedURLString, "http:// fake.url/")); | |
| 143 m_workerThread = adoptRef(new WorkerThreadForTest( | |
| 144 m_mockWorkerLoaderProxy.get(), | |
| 145 *m_mockWorkerReportingProxy, | |
| 146 WorkerThreadStartupData::create( | |
| 147 KURL(ParsedURLString, "http://fake.url/"), | |
| 148 "fake user agent", | |
| 149 "//fake source code", | |
| 150 nullptr, | |
| 151 DontPauseWorkerGlobalScopeOnStart, | |
| 152 "contentSecurityPolicy", | |
| 153 ContentSecurityPolicyHeaderTypeReport, | |
| 154 m_securityOrigin.get(), | |
| 155 WorkerClients::create(), | |
| 156 V8CacheOptionsDefault))); | |
| 157 } | |
| 158 | |
| 159 RefPtr<SecurityOrigin> m_securityOrigin; | |
| 160 RefPtr<MockWorkerLoaderProxy> m_mockWorkerLoaderProxy; | |
| 161 OwnPtr<MockWorkerReportingProxy> m_mockWorkerReportingProxy; | |
| 162 RefPtr<WorkerThreadForTest> m_workerThread; | |
| 163 }; | |
| 164 | |
| 165 TEST_F(WorkerThreadTest, GcOccursWhileIdle) | |
| 166 { | |
| 167 bool gcDone = false; | |
| 168 | |
| 169 ON_CALL(*m_workerThread, doIdleGc(_)).WillByDefault(Invoke( | |
| 170 [&gcDone](double) | |
| 171 { | |
| 172 gcDone = true; | |
| 173 return false; | |
| 174 })); | |
| 175 | |
| 176 EXPECT_CALL(*m_workerThread, doIdleGc(_)).Times(1); | |
| 177 EXPECT_CALL(*m_mockWorkerReportingProxy, workerGlobalScopeStarted(_)).Times( 1); | |
|
Sami
2015/04/09 10:52:29
Could these be moved to a helper setup function? T
alex clarke (OOO till 29th)
2015/04/10 15:29:38
Done.
| |
| 178 EXPECT_CALL(*m_mockWorkerReportingProxy, didEvaluateWorkerScript(true)).Time s(1); | |
| 179 EXPECT_CALL(*m_mockWorkerReportingProxy, workerThreadTerminated()).Times(1); | |
| 180 EXPECT_CALL(*m_mockWorkerReportingProxy, willDestroyWorkerGlobalScope()).Tim es(1); | |
| 181 | |
| 182 m_workerThread->setMinQuietPeriodBeforeDoingIdleGcForTesting(100ul); | |
| 183 m_workerThread->start(); | |
| 184 WebThreadSupportingGC* thread = m_workerThread->threadForTesting(); | |
| 185 | |
| 186 // The idle task will get posted on an after wake up queue, so we need anoth er task | |
| 187 // posted at the right time to wake the system up. We don't know the right delay here | |
| 188 // since the thread can take a variable length of time to be responsive, how ever this | |
| 189 // isn't a problem when posting a delayed task from within a task on the wor ker thread. | |
| 190 thread->postTask(FROM_HERE, new PostDelayedWakeupTask(thread, 110ul)); | |
| 191 | |
| 192 while (!gcDone) | |
| 193 Platform::current()->yieldCurrentThread(); | |
| 194 | |
| 195 m_workerThread->terminateAndWait(); | |
| 196 }; | |
| 197 | |
| 198 } // namespace blink | |
| OLD | NEW |