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

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: Don't #include .cpp files. :-P 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
« no previous file with comments | « Source/web/WebEmbeddedWorkerImpl.cpp ('k') | Source/web/tests/data/blank.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.h"
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 {
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
93 virtual void run()
94 {
95 EXPECT_TRUE(m_runLoop->m_isRunning);
96 EXPECT_TRUE(m_runLoop->m_isQuitting);
97 m_runLoop->m_thread->exitRunLoop();
98 }
99
100 RunLoop* m_runLoop;
101 };
102
103 WebThread* m_thread;
104 bool m_isRunning;
105 bool m_isQuitting;
106 };
107
108 // Continuously pumps the mocked-requests queue during the current execution of runLoop->run(), or next if run() isn't currently running.
109 class ServeAsyncRequestsTask : public WebThread::Task {
110 public:
111 ServeAsyncRequestsTask(RunLoop* runLoop)
112 : m_runLoop(runLoop)
113 {
114 }
115
116 virtual void run() OVERRIDE
117 {
118 Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests( );
Jeffrey Yasskin 2014/07/17 18:32:09 dcheng says that this call is probably the best we
119 // The RunLoop only finishes quitting when it has no tasks left, so this task has to end its chain explicitly.
120 if (!m_runLoop->isQuitting())
121 Platform::current()->currentThread()->postTask(new ServeAsyncRequest sTask(m_runLoop));
122 }
123
124 private:
125 RunLoop* m_runLoop;
126 };
127
128 class V8ContextTestContextClient : public WebServiceWorkerContextClient {
129 public:
130 virtual void workerContextFailedToStart()
131 {
132 ADD_FAILURE() << "workerContextFailedToStart";
133 m_runLoop->quitWhenIdle();
134 }
135
136 virtual void reportException(const WebString& errorMessage, int lineNumber, int columnNumber, const WebString& sourceURL)
137 {
138 ADD_FAILURE() << sourceURL.utf8() << "(" << lineNumber << ":" << columnN umber << ") error: " << errorMessage.utf8();
139 m_runLoop->quitWhenIdle();
140 }
141
142 virtual void workerContextStarted(WebServiceWorkerContextProxy* proxy)
143 {
144 m_proxy = proxy;
145 v8::HandleScope scope(v8::Isolate::GetCurrent());
146 EXPECT_TRUE(*m_proxy->v8Context()) << "The v8 context should be valid as soon as the worker is started.";
147 m_runLoop->quitWhenIdle();
148 }
149
150 void checkContextAccessibleAfterClose()
151 {
152 v8::HandleScope scope(v8::Isolate::GetCurrent());
153 EXPECT_TRUE(*m_proxy->v8Context()) << "The v8 context should still be va lid.";
154 static_cast<ServiceWorkerGlobalScopeProxy*>(m_proxy)->evaluate(String::f romUTF8("self.close();"));
155 // The context continues to exist until non-cleanup tasks stop running.
156 checkContextStillExists();
157 // close() will eventually terminate the worker, which will quit the
158 // RunLoop through workerContextDestroyed.
159 }
160
161 void checkContextStillExists()
162 {
163 // The context isn't valid after willDestroyWorkerContext().
164 if (!m_proxy)
165 return;
166 v8::HandleScope scope(v8::Isolate::GetCurrent());
167 EXPECT_TRUE(*m_proxy->v8Context());
168 static_cast<WebEmbeddedWorkerImpl*>(m_worker)->postTask(createCrossThrea dTask(&V8ContextTestContextClient::checkContextStillExists, this));
169 }
170
171 virtual void willDestroyWorkerContext() OVERRIDE
172 {
173 m_proxy = 0;
174 }
175
176 virtual void workerContextDestroyed() OVERRIDE
177 {
178 // Now it's safe to finish the main test, which will destroy the WorkerT hread.
179 m_runLoop->quitWhenIdle();
180 }
181
182 RunLoop* m_runLoop;
183 WebEmbeddedWorker* m_worker;
184 WebServiceWorkerContextProxy* m_proxy;
185 };
186
187 TEST_F(ServiceWorkerGlobalScopeProxyTest, V8ContextTest)
188 {
189 V8ContextTestContextClient* contextClient = new V8ContextTestContextClient;
190
191 RunLoop runLoop;
192 contextClient->m_runLoop = &runLoop;
193
194 OwnPtr<WebEmbeddedWorker> worker = adoptPtr(WebEmbeddedWorker::create(contex tClient, 0));
195 contextClient->m_worker = worker.get();
196
197 WebEmbeddedWorkerStartData startData;
198 registerMockedHttpURLLoad("blank.js", "text/javascript");
199 startData.scriptURL = URLTestHelpers::toKURL(m_baseUrl + "blank.js");
200 worker->startWorkerContext(startData);
201 // Serve requests until the message loop quits.
202 Platform::current()->currentThread()->postTask(new ServeAsyncRequestsTask(&r unLoop));
203 runLoop.run(); // Wait for workerContextStarted().
204
205 static_cast<WebEmbeddedWorkerImpl&>(*worker).postTask(
206 createCrossThreadTask(&V8ContextTestContextClient::checkContextAccessibl eAfterClose, contextClient));
207 runLoop.run(); // Wait for workerContextDestroyed().
208 }
209
210 } // namespace
OLDNEW
« no previous file with comments | « Source/web/WebEmbeddedWorkerImpl.cpp ('k') | Source/web/tests/data/blank.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698