summaryrefslogtreecommitdiffstats
path: root/content/browser/service_worker
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-15 19:31:27 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-01-15 19:31:27 +0000
commit59f7d173f32295f6fd0bd4e2c99340632f68e2c9 (patch)
treef9b5488ec0773b8a3c7626f860f24bfe167acac9 /content/browser/service_worker
parentc8bb080c880d3e57ff15b0725341f8fcc3e30375 (diff)
downloadchromium_src-59f7d173f32295f6fd0bd4e2c99340632f68e2c9.zip
chromium_src-59f7d173f32295f6fd0bd4e2c99340632f68e2c9.tar.gz
chromium_src-59f7d173f32295f6fd0bd4e2c99340632f68e2c9.tar.bz2
Add basic browser test for EmbeddedWorker/ServiceWorker
This test does: - kick registerServiceWorker (primarily for installing ServiceWorkerProviderHost) - manually associate ServiceWorkerProviderHost to an EmbeddedWorker (eventually this should be done via ServiceWorkerVersion) - Start and stop the EmbeddedWorker, and observe OnStarted/OnStopped msgs are sent from the child process BUG=313530, 285976 TEST=ServiceWorkerBrowserTest.EmbeddedWorkerBasic Review URL: https://codereview.chromium.org/127573002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244960 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/service_worker')
-rw-r--r--content/browser/service_worker/embedded_worker_instance.cc10
-rw-r--r--content/browser/service_worker/embedded_worker_instance.h12
-rw-r--r--content/browser/service_worker/service_worker_browsertest.cc159
-rw-r--r--content/browser/service_worker/service_worker_context_core.cc15
-rw-r--r--content/browser/service_worker/service_worker_context_core.h5
5 files changed, 201 insertions, 0 deletions
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc
index 88c4b03..a376562 100644
--- a/content/browser/service_worker/embedded_worker_instance.cc
+++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -85,12 +85,22 @@ void EmbeddedWorkerInstance::OnStarted(int thread_id) {
DCHECK(status_ == STARTING);
status_ = RUNNING;
thread_id_ = thread_id;
+ FOR_EACH_OBSERVER(Observer, observer_list_, OnStarted());
}
void EmbeddedWorkerInstance::OnStopped() {
status_ = STOPPED;
process_id_ = -1;
thread_id_ = -1;
+ FOR_EACH_OBSERVER(Observer, observer_list_, OnStopped());
+}
+
+void EmbeddedWorkerInstance::AddObserver(Observer* observer) {
+ observer_list_.AddObserver(observer);
+}
+
+void EmbeddedWorkerInstance::RemoveObserver(Observer* observer) {
+ observer_list_.RemoveObserver(observer);
}
bool EmbeddedWorkerInstance::ChooseProcess() {
diff --git a/content/browser/service_worker/embedded_worker_instance.h b/content/browser/service_worker/embedded_worker_instance.h
index 5a992a2..fcc2c34 100644
--- a/content/browser/service_worker/embedded_worker_instance.h
+++ b/content/browser/service_worker/embedded_worker_instance.h
@@ -12,6 +12,7 @@
#include "base/gtest_prod_util.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
+#include "base/observer_list.h"
#include "content/common/content_export.h"
class GURL;
@@ -33,6 +34,13 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
STOPPING,
};
+ class Observer {
+ public:
+ virtual ~Observer() {}
+ virtual void OnStarted() = 0;
+ virtual void OnStopped() = 0;
+ };
+
~EmbeddedWorkerInstance();
// Starts the worker. It is invalid to call this when the worker is
@@ -63,6 +71,9 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
int process_id() const { return process_id_; }
int thread_id() const { return thread_id_; }
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
private:
friend class EmbeddedWorkerRegistry;
FRIEND_TEST_ALL_PREFIXES(EmbeddedWorkerInstanceTest, StartAndStop);
@@ -99,6 +110,7 @@ class CONTENT_EXPORT EmbeddedWorkerInstance {
int thread_id_;
ProcessRefMap process_refs_;
+ ObserverList<Observer> observer_list_;
DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstance);
};
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc
new file mode 100644
index 0000000..e4894bb
--- /dev/null
+++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -0,0 +1,159 @@
+// 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 "base/bind.h"
+#include "base/callback.h"
+#include "base/command_line.h"
+#include "base/location.h"
+#include "base/run_loop.h"
+#include "content/browser/service_worker/embedded_worker_instance.h"
+#include "content/browser/service_worker/embedded_worker_registry.h"
+#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/storage_partition.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/content_switches.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/content_browser_test.h"
+#include "content/test/content_browser_test_utils.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+
+namespace content {
+
+class ServiceWorkerBrowserTest : public ContentBrowserTest,
+ public EmbeddedWorkerInstance::Observer {
+ public:
+ typedef ServiceWorkerBrowserTest self;
+
+ ServiceWorkerBrowserTest()
+ : last_worker_status_(EmbeddedWorkerInstance::STOPPED) {}
+ virtual ~ServiceWorkerBrowserTest() {}
+
+ virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
+ command_line->AppendSwitch(switches::kEnableServiceWorker);
+ }
+
+ virtual void SetUpOnMainThread() OVERRIDE {
+ ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
+ StoragePartition* partition = BrowserContext::GetDefaultStoragePartition(
+ shell()->web_contents()->GetBrowserContext());
+ wrapper_ = partition->GetServiceWorkerContext();
+ }
+
+ virtual void TearDownOnMainThread() OVERRIDE {
+ base::RunLoop run_loop;
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&self::TearDownOnIOThread, this, run_loop.QuitClosure()));
+ run_loop.Run();
+ wrapper_ = NULL;
+ }
+
+ void TearDownOnIOThread(const base::Closure& done_closure) {
+ if (worker_) {
+ worker_->RemoveObserver(this);
+ worker_.reset();
+ }
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done_closure);
+ }
+
+ void StartEmbeddedWorkerOnIOThread() {
+ ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ worker_ = wrapper_->context()->embedded_worker_registry()->CreateWorker();
+ EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker_->status());
+ worker_->AddObserver(this);
+
+ // TODO(kinuko): this manual wiring should go away when this gets wired
+ // in the actual code path.
+ ServiceWorkerProviderHost* provider_host = GetRegisteredProviderHost();
+ worker_->AddProcessReference(provider_host->process_id());
+
+ const int64 service_worker_version_id = 33L;
+ const GURL script_url = embedded_test_server()->GetURL(
+ "/service_worker/worker.js");
+ const bool started = worker_->Start(service_worker_version_id, script_url);
+
+ last_worker_status_ = worker_->status();
+ EXPECT_TRUE(started);
+ EXPECT_EQ(EmbeddedWorkerInstance::STARTING, last_worker_status_);
+
+ if (!started && !done_closure_.is_null())
+ done_closure_.Run();
+ }
+
+ void StopEmbeddedWorkerOnIOThread() {
+ ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ EXPECT_EQ(EmbeddedWorkerInstance::RUNNING, worker_->status());
+
+ const bool stopped = worker_->Stop();
+
+ last_worker_status_ = worker_->status();
+ EXPECT_TRUE(stopped);
+ EXPECT_EQ(EmbeddedWorkerInstance::STOPPING, last_worker_status_);
+
+ if (!stopped && !done_closure_.is_null())
+ done_closure_.Run();
+ }
+
+ protected:
+ // Embe3ddedWorkerInstance::Observer overrides:
+ virtual void OnStarted() OVERRIDE {
+ ASSERT_TRUE(worker_ != NULL);
+ ASSERT_FALSE(done_closure_.is_null());
+ last_worker_status_ = worker_->status();
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done_closure_);
+ }
+ virtual void OnStopped() OVERRIDE {
+ ASSERT_TRUE(worker_ != NULL);
+ ASSERT_FALSE(done_closure_.is_null());
+ last_worker_status_ = worker_->status();
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, done_closure_);
+ }
+
+ ServiceWorkerProviderHost* GetRegisteredProviderHost() {
+ // Assumes only one provider host is registered at this point.
+ std::vector<ServiceWorkerProviderHost*> providers;
+ wrapper_->context()->GetAllProviderHosts(&providers);
+ DCHECK_EQ(1U, providers.size());
+ return providers[0];
+ }
+
+ scoped_refptr<ServiceWorkerContextWrapper> wrapper_;
+ scoped_ptr<EmbeddedWorkerInstance> worker_;
+ EmbeddedWorkerInstance::Status last_worker_status_;
+
+ // Called by EmbeddedWorkerInstance::Observer overrides so that
+ // test code can wait for the worker status notifications.
+ base::Closure done_closure_;
+};
+
+IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, EmbeddedWorkerBasic) {
+ // Navigate to the page to set up a provider.
+ NavigateToURLBlockUntilNavigationsComplete(
+ shell(), embedded_test_server()->GetURL("/service_worker/index.html"), 1);
+
+ // Start a worker and wait until OnStarted() is called.
+ base::RunLoop start_run_loop;
+ done_closure_ = start_run_loop.QuitClosure();
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&self::StartEmbeddedWorkerOnIOThread, this));
+ start_run_loop.Run();
+
+ ASSERT_EQ(EmbeddedWorkerInstance::RUNNING, last_worker_status_);
+
+ // Stop a worker and wait until OnStopped() is called.
+ base::RunLoop stop_run_loop;
+ done_closure_ = stop_run_loop.QuitClosure();
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ base::Bind(&self::StopEmbeddedWorkerOnIOThread, this));
+ stop_run_loop.Run();
+
+ ASSERT_EQ(EmbeddedWorkerInstance::STOPPED, last_worker_status_);
+}
+
+} // namespace content
diff --git a/content/browser/service_worker/service_worker_context_core.cc b/content/browser/service_worker/service_worker_context_core.cc
index 88897ac..0a30b7b 100644
--- a/content/browser/service_worker/service_worker_context_core.cc
+++ b/content/browser/service_worker/service_worker_context_core.cc
@@ -99,4 +99,19 @@ void ServiceWorkerContextCore::RegistrationComplete(
callback.Run(status, registration->id());
}
+void ServiceWorkerContextCore::GetAllProviderHosts(
+ std::vector<ServiceWorkerProviderHost*>* providers) {
+ DCHECK(providers);
+
+ ProcessToProviderMap::iterator map_iter(&providers_);
+ while (!map_iter.IsAtEnd()) {
+ ProviderMap::iterator iter(map_iter.GetCurrentValue());
+ while (!iter.IsAtEnd()) {
+ providers->push_back(iter.GetCurrentValue());
+ iter.Advance();
+ }
+ map_iter.Advance();
+ }
+}
+
} // namespace content
diff --git a/content/browser/service_worker/service_worker_context_core.h b/content/browser/service_worker/service_worker_context_core.h
index e911e4c..4ab4351 100644
--- a/content/browser/service_worker/service_worker_context_core.h
+++ b/content/browser/service_worker/service_worker_context_core.h
@@ -81,6 +81,8 @@ class CONTENT_EXPORT ServiceWorkerContextCore
}
private:
+ friend class ServiceWorkerBrowserTest;
+
typedef IDMap<ServiceWorkerProviderHost, IDMapOwnPointer> ProviderMap;
typedef IDMap<ProviderMap, IDMapOwnPointer> ProcessToProviderMap;
@@ -93,6 +95,9 @@ class CONTENT_EXPORT ServiceWorkerContextCore
ServiceWorkerRegistrationStatus status,
const scoped_refptr<ServiceWorkerRegistration>& registration);
+ // Used only for testing.
+ void GetAllProviderHosts(std::vector<ServiceWorkerProviderHost*>* providers);
+
ProcessToProviderMap providers_;
scoped_ptr<ServiceWorkerStorage> storage_;
scoped_ptr<ServiceWorkerJobCoordinator> job_coordinator_;