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

Unified 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: Remove an unused v8::Isolate forward decl (but should the Proxy expose an Isolate?) 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 side-by-side diff with in-line comments
Download patch
Index: Source/web/tests/ServiceWorkerGlobalScopeProxyTest.cpp
diff --git a/Source/web/tests/ServiceWorkerGlobalScopeProxyTest.cpp b/Source/web/tests/ServiceWorkerGlobalScopeProxyTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ff476eb5047536013e38a1d7ca2b700e73a0ee91
--- /dev/null
+++ b/Source/web/tests/ServiceWorkerGlobalScopeProxyTest.cpp
@@ -0,0 +1,209 @@
+// Copyright 2014 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.
+
+#include "config.h"
+
+#include "Source/web/ServiceWorkerGlobalScopeProxy.h"
+
+#include "Source/bindings/core/v8/ScriptSourceCode.h"
+#include "Source/core/dom/CrossThreadTask.h"
+#include "platform/weborigin/KURL.cpp"
+#include "public/platform/Platform.h"
+#include "public/platform/WebThread.h"
+#include "public/platform/WebUnitTestSupport.h"
+#include "public/web/WebEmbeddedWorker.h"
+#include "public/web/WebEmbeddedWorkerStartData.h"
+#include "public/web/WebServiceWorkerContextClient.h"
+#include "web/WebEmbeddedWorkerImpl.h"
+#include "web/tests/URLTestHelpers.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <v8.h>
+
+using namespace blink;
+using namespace WebCore;
+
+namespace {
+
+class ServiceWorkerGlobalScopeProxyTest : public testing::Test {
+protected:
+ ServiceWorkerGlobalScopeProxyTest()
+ : m_baseUrl("http://www.test.com/")
+ {
+ }
+
+ virtual ~ServiceWorkerGlobalScopeProxyTest()
+ {
+ Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
+ }
+
+ // Remember to call serveAsynchronousMockedRequests() in order to handle these mocked URLs.
+ void registerMockedHttpURLLoad(const std::string& fileName, const std::string& mimeType = "text/html")
+ {
+ URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseUrl), WebString::fromUTF8(fileName), WebString::fromUTF8(mimeType));
+ }
+
+ const std::string m_baseUrl;
+};
+
+// Can repeatedly run the current thread's loop, but unlike Chrome's RunLoop, cannot be recursively reentered.
+// QuitWhenIdle() must be called exactly once per Run() call.
+class RunLoop {
+public:
+ RunLoop()
+ : m_thread(blink::Platform::current()->currentThread())
+ , m_isRunning(false)
+ , m_isQuitting(false)
+ {
+ }
+
+ // Starts the thread's run loop, and returns when QuitWhenIdle() is called.
+ void Run()
dominicc (has gone to gerrit) 2014/07/17 02:43:44 Run -> run
Jeffrey Yasskin 2014/07/17 16:19:33 Oops. Got my coding conventions confused.
+ {
+ EXPECT_FALSE(m_isRunning);
+ m_isRunning = true;
+ m_thread->enterRunLoop();
+ EXPECT_TRUE(m_isQuitting);
+ m_isRunning = m_isQuitting = false;
+ }
+
+ // This can be called before Run() or concurrently with it from another thread.
+ // The loop will terminate when it's idle.
+ void QuitWhenIdle()
dominicc (has gone to gerrit) 2014/07/17 02:43:44 quitWhenIdle.
Jeffrey Yasskin 2014/07/17 16:19:32 Done.
+ {
+ EXPECT_FALSE(m_isQuitting);
+ m_isQuitting = true;
+ m_thread->postTask(new QuitTask(this));
+ }
+
+ bool isQuitting()
+ {
+ return m_isQuitting;
+ }
+
+private:
+ class QuitTask : public WebThread::Task {
+ public:
+ QuitTask(RunLoop* runLoop)
+ : m_runLoop(runLoop)
+ {
+ }
+ virtual void run()
dominicc (has gone to gerrit) 2014/07/17 02:43:44 The lack of vertical whitespace here seems inconsi
Jeffrey Yasskin 2014/07/17 16:19:32 Done.
+ {
+ EXPECT_TRUE(m_runLoop->m_isRunning);
+ EXPECT_TRUE(m_runLoop->m_isQuitting);
+ m_runLoop->m_thread->exitRunLoop();
+ }
+ RunLoop* m_runLoop;
+ };
+
+ WebThread* m_thread;
+ bool m_isRunning;
+ bool m_isQuitting;
+};
+
+// Continuously pumps the mocked-requests queue during the current execution of runLoop->Run(), or next if Run() isn't currently running.
dominicc (has gone to gerrit) 2014/07/17 02:43:44 Run -> run, right?
Jeffrey Yasskin 2014/07/17 16:19:33 Done.
+class ServeAsyncRequestsTask : public WebThread::Task {
+public:
+ ServeAsyncRequestsTask(RunLoop* runLoop)
+ : m_runLoop(runLoop)
+ {
+ }
+
+ virtual void run() OVERRIDE
+ {
+ Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
+ // The RunLoop only finishes quitting when it has no tasks left, so this task has to end its chain explicitly.
+ if (!m_runLoop->isQuitting()) {
dominicc (has gone to gerrit) 2014/07/17 02:43:44 No {}s for single line bodies unless it is clearer
Jeffrey Yasskin 2014/07/17 16:19:32 After goto-fail, I've been more inclined to keep t
+ Platform::current()->currentThread()->postTask(new ServeAsyncRequestsTask(m_runLoop));
+ }
+ }
+
+private:
+ RunLoop* m_runLoop;
+};
+
+class V8ContextTestSWContextClient : public WebServiceWorkerContextClient {
dominicc (has gone to gerrit) 2014/07/17 02:43:44 SW -> ServiceWorker I am all for brevity but you
Jeffrey Yasskin 2014/07/17 16:19:33 If it's just TestContextClient, that'll make it ha
+public:
+ virtual void workerContextFailedToStart()
+ {
+ ADD_FAILURE() << "workerContextFailedToStart";
+ m_runLoop->QuitWhenIdle();
+ }
+
+ virtual void reportException(const WebString& errorMessage, int lineNumber, int columnNumber, const WebString& sourceURL)
+ {
+ ADD_FAILURE() << sourceURL.utf8() << "(" << lineNumber << ":" << columnNumber << ") error: " << errorMessage.utf8();
+ m_runLoop->QuitWhenIdle();
+ }
+
+ virtual void workerContextStarted(WebServiceWorkerContextProxy* proxy)
+ {
+ m_proxy = proxy;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ EXPECT_TRUE(*m_proxy->v8Context()) << "The v8 context should be valid as soon as the worker is started.";
+ m_runLoop->QuitWhenIdle();
+ }
+
+ void checkContextAccessibleAfterClose()
+ {
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ EXPECT_TRUE(*m_proxy->v8Context()) << "The v8 context should still be valid.";
+ static_cast<ServiceWorkerGlobalScopeProxy*>(m_proxy)->evaluate(String::fromUTF8("self.close();"));
+ // The context continues to exist until non-cleanup tasks stop running.
+ checkContextStillExists();
+ // close() will eventually terminate the worker, which will quit the
+ // RunLoop through workerContextDestroyed.
+ }
+
+ void checkContextStillExists()
+ {
+ // The context isn't valid after willDestroyWorkerContext().
+ if (!m_proxy)
+ return;
+ v8::HandleScope scope(v8::Isolate::GetCurrent());
+ EXPECT_TRUE(*m_proxy->v8Context());
+ static_cast<WebEmbeddedWorkerImpl*>(m_worker)->postTask(createCrossThreadTask(&V8ContextTestSWContextClient::checkContextStillExists, this));
+ }
+
+ virtual void willDestroyWorkerContext() OVERRIDE
+ {
+ m_proxy = 0;
+ }
+
+ virtual void workerContextDestroyed() OVERRIDE
+ {
+ // Now it's safe to finish the main test, which will destroy the WorkerThread.
+ m_runLoop->QuitWhenIdle();
+ }
+
+ RunLoop* m_runLoop;
+ WebEmbeddedWorker* m_worker;
+ WebServiceWorkerContextProxy* m_proxy;
+};
+
+TEST_F(ServiceWorkerGlobalScopeProxyTest, V8ContextText)
+{
+ V8ContextTestSWContextClient* contextClient = new V8ContextTestSWContextClient;
+
+ RunLoop runLoop;
+ contextClient->m_runLoop = &runLoop;
+
+ OwnPtr<WebEmbeddedWorker> worker = adoptPtr(WebEmbeddedWorker::create(contextClient, 0));
+ contextClient->m_worker = worker.get();
+
+ WebEmbeddedWorkerStartData startData;
+ registerMockedHttpURLLoad("blank.js", "text/javascript");
+ startData.scriptURL = URLTestHelpers::toKURL(m_baseUrl + "blank.js");
+ worker->startWorkerContext(startData);
+ // Serve requests until the message loop quits.
+ Platform::current()->currentThread()->postTask(new ServeAsyncRequestsTask(&runLoop));
+ runLoop.Run(); // Wait for workerContextStarted().
+
+ static_cast<WebEmbeddedWorkerImpl&>(*worker).postTask(
+ createCrossThreadTask(&V8ContextTestSWContextClient::checkContextAccessibleAfterClose, contextClient));
+ runLoop.Run(); // Wait for workerContextDestroyed().
+}
+
+} // namespace

Powered by Google App Engine
This is Rietveld 408576698