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

Side by Side Diff: Source/web/tests/ServiceWorkerGlobalScopeProxyTest.cpp

Issue 383063008: Expose the ServiceWorker's v8 context to embedders. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@pinned
Patch Set: Add a test and some comments Created 6 years, 5 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 2014 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 "config.h"
6
7 #include "Source/web/ServiceWorkerGlobalScopeProxy.h"
8
9 #include "Source/bindings/core/v8/ScriptSourceCode.h"
10 #include "Source/core/dom/CrossThreadTask.h"
11 #include "platform/weborigin/KURL.cpp"
12 #include "public/platform/Platform.h"
13 #include "public/platform/WebThread.h"
14 #include "public/platform/WebUnitTestSupport.h"
15 #include "public/web/WebEmbeddedWorker.h"
16 #include "public/web/WebEmbeddedWorkerStartData.h"
17 #include "public/web/WebServiceWorkerContextClient.h"
18 #include "web/WebEmbeddedWorkerImpl.h"
19 #include "web/tests/URLTestHelpers.h"
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 #include <v8.h>
23
24 using namespace blink;
25 using namespace WebCore;
26
27 namespace {
28
29 class ServiceWorkerGlobalScopeProxyTest : public testing::Test {
30 protected:
31 ServiceWorkerGlobalScopeProxyTest()
32 : m_baseUrl("http://www.test.com/")
33 {
34 }
35
36 virtual ~ServiceWorkerGlobalScopeProxyTest()
37 {
38 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
39 }
40
41 // Remember to call serveAsynchronousMockedRequests() in order to handle the se mocked URLs.
42 void registerMockedHttpURLLoad(const std::string& fileName, const std::strin g& mimeType = "text/html")
43 {
44 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseU rl), WebString::fromUTF8(fileName), WebString::fromUTF8(mimeType));
45 }
46
47 const std::string m_baseUrl;
48 };
49
50 // Can repeatedly run the current thread's loop, but unlike Chrome's RunLoop, ca nnot be recursively reentered.
51 // QuitWhenIdle() must be called exactly once per Run() call.
52 class RunLoop {
Jeffrey Yasskin 2014/07/16 23:14:58 I was kind of shocked not to find anything like th
53 public:
54 RunLoop()
55 : m_thread(blink::Platform::current()->currentThread())
56 , m_isRunning(false)
57 , m_isQuitting(false)
58 {
59 }
60
61 // Starts the thread's run loop, and returns when QuitWhenIdle() is called.
62 void Run()
63 {
64 EXPECT_FALSE(m_isRunning);
65 m_isRunning = true;
66 m_thread->enterRunLoop();
67 EXPECT_TRUE(m_isQuitting);
68 m_isRunning = m_isQuitting = false;
69 }
70
71 // This can be called before Run() or concurrently with it from another thre ad.
72 // The loop will terminate when it's idle.
73 void QuitWhenIdle()
74 {
75 EXPECT_FALSE(m_isQuitting);
76 m_isQuitting = true;
77 m_thread->postTask(new QuitTask(this));
78 }
79
80 bool isQuitting()
81 {
82 return m_isQuitting;
83 }
84
85 private:
86 class QuitTask : public WebThread::Task {
87 public:
88 QuitTask(RunLoop* runLoop)
89 : m_runLoop(runLoop)
90 {
91 }
92 virtual void run()
93 {
94 EXPECT_TRUE(m_runLoop->m_isRunning);
95 EXPECT_TRUE(m_runLoop->m_isQuitting);
96 m_runLoop->m_thread->exitRunLoop();
97 }
98 RunLoop* m_runLoop;
99 };
100
101 WebThread* m_thread;
102 bool m_isRunning;
103 bool m_isQuitting;
104 };
105
106 // Continuously pumps the mocked-requests queue during the current execution of runLoop->Run(), or next if Run() isn't currently running.
107 class ServeAsyncRequestsTask : public WebThread::Task {
108 public:
109 ServeAsyncRequestsTask(RunLoop* runLoop)
110 : m_runLoop(runLoop)
111 {
112 }
113
114 virtual void run() OVERRIDE
115 {
116 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests( );
Jeffrey Yasskin 2014/07/16 23:14:58 This gets flagged by https://code.google.com/p/chr
117 // The RunLoop only finishes quitting when it has no tasks left, so this task has to end its chain explicitly.
118 if (!m_runLoop->isQuitting()) {
119 Platform::current()->currentThread()->postTask(new ServeAsyncRequest sTask(m_runLoop));
120 }
121 }
122
123 private:
124 RunLoop* m_runLoop;
125 };
126
127 class V8ContextTestSWContextClient : public WebServiceWorkerContextClient {
128 public:
129 virtual void workerContextFailedToStart()
130 {
131 ADD_FAILURE() << "workerContextFailedToStart";
132 m_runLoop->QuitWhenIdle();
133 }
134
135 virtual void reportException(const WebString& errorMessage, int lineNumber, int columnNumber, const WebString& sourceURL)
136 {
137 ADD_FAILURE() << sourceURL.utf8() << "(" << lineNumber << ":" << columnN umber << ") error: " << errorMessage.utf8();
138 m_runLoop->QuitWhenIdle();
139 }
140
141 virtual void workerContextStarted(WebServiceWorkerContextProxy* proxy)
142 {
143 m_proxy = proxy;
144 v8::HandleScope scope(v8::Isolate::GetCurrent());
145 EXPECT_TRUE(*m_proxy->v8Context()) << "The v8 context should be valid as soon as the worker is started.";
146 m_runLoop->QuitWhenIdle();
147 }
148
149 void checkContextAccessibleAfterClose()
150 {
151 v8::HandleScope scope(v8::Isolate::GetCurrent());
152 EXPECT_TRUE(*m_proxy->v8Context()) << "The v8 context should still be va lid.";
153 static_cast<ServiceWorkerGlobalScopeProxy*>(m_proxy)->evaluate(String::f romUTF8("self.close();"));
154 // The context continues to exist until non-cleanup tasks stop running.
155 checkContextStillExists();
156 // close() will eventually terminate the worker, which will quit the
157 // RunLoop through workerContextDestroyed.
158 }
159
160 void checkContextStillExists()
161 {
162 // The context isn't valid after willDestroyWorkerContext().
163 if (!m_proxy)
164 return;
165 v8::HandleScope scope(v8::Isolate::GetCurrent());
166 EXPECT_TRUE(*m_proxy->v8Context());
167 static_cast<WebEmbeddedWorkerImpl*>(m_worker)->postTask(createCrossThrea dTask(&V8ContextTestSWContextClient::checkContextStillExists, this));
168 }
169
170 virtual void willDestroyWorkerContext() OVERRIDE
171 {
172 m_proxy = 0;
173 }
174
175 virtual void workerContextDestroyed() OVERRIDE
176 {
177 // Now it's safe to finish the main test, which will destroy the WorkerT hread.
178 m_runLoop->QuitWhenIdle();
179 }
180
181 RunLoop* m_runLoop;
182 WebEmbeddedWorker* m_worker;
183 WebServiceWorkerContextProxy* m_proxy;
184 };
185
186 TEST_F(ServiceWorkerGlobalScopeProxyTest, V8ContextText)
187 {
188 V8ContextTestSWContextClient* contextClient = new V8ContextTestSWContextClie nt;
189
190 RunLoop runLoop;
191 contextClient->m_runLoop = &runLoop;
192
193 OwnPtr<WebEmbeddedWorker> worker = adoptPtr(WebEmbeddedWorker::create(contex tClient, 0));
194 contextClient->m_worker = worker.get();
195
196 WebEmbeddedWorkerStartData startData;
197 registerMockedHttpURLLoad("blank.js", "text/javascript");
198 startData.scriptURL = URLTestHelpers::toKURL(m_baseUrl + "blank.js");
199 worker->startWorkerContext(startData);
200 // Serve requests until the message loop quits.
201 Platform::current()->currentThread()->postTask(new ServeAsyncRequestsTask(&r unLoop));
202 runLoop.Run(); // Wait for workerContextStarted().
203
204 static_cast<WebEmbeddedWorkerImpl&>(*worker).postTask(
205 createCrossThreadTask(&V8ContextTestSWContextClient::checkContextAccessi bleAfterClose, contextClient));
206 runLoop.Run(); // Wait for workerContextDestroyed().
207 }
208
209 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698