Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / browser / service_worker / embedded_worker_instance_unittest.cc
1 // Copyright 2013 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 "base/basictypes.h"
6 #include "base/run_loop.h"
7 #include "base/stl_util.h"
8 #include "content/browser/service_worker/embedded_worker_instance.h"
9 #include "content/browser/service_worker/embedded_worker_registry.h"
10 #include "content/browser/service_worker/embedded_worker_test_helper.h"
11 #include "content/browser/service_worker/service_worker_context_core.h"
12 #include "content/browser/service_worker/service_worker_context_wrapper.h"
13 #include "content/common/service_worker/embedded_worker_messages.h"
14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17
18 namespace content {
19
20 static const int kRenderProcessId = 11;
21
22 class EmbeddedWorkerInstanceTest : public testing::Test {
23  protected:
24   EmbeddedWorkerInstanceTest()
25       : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
26
27   virtual void SetUp() OVERRIDE {
28     helper_.reset(new EmbeddedWorkerTestHelper(kRenderProcessId));
29   }
30
31   virtual void TearDown() OVERRIDE {
32     helper_.reset();
33   }
34
35   ServiceWorkerContextCore* context() { return helper_->context(); }
36
37   EmbeddedWorkerRegistry* embedded_worker_registry() {
38     DCHECK(context());
39     return context()->embedded_worker_registry();
40   }
41
42   IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); }
43
44   TestBrowserThreadBundle thread_bundle_;
45   scoped_ptr<EmbeddedWorkerTestHelper> helper_;
46
47  private:
48   DISALLOW_COPY_AND_ASSIGN(EmbeddedWorkerInstanceTest);
49 };
50
51 static void SaveStatusAndCall(ServiceWorkerStatusCode* out,
52                               const base::Closure& callback,
53                               ServiceWorkerStatusCode status) {
54   *out = status;
55   callback.Run();
56 }
57
58 TEST_F(EmbeddedWorkerInstanceTest, StartAndStop) {
59   scoped_ptr<EmbeddedWorkerInstance> worker =
60       embedded_worker_registry()->CreateWorker();
61   EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
62
63   const int64 service_worker_version_id = 55L;
64   const GURL pattern("http://example.com/");
65   const GURL url("http://example.com/worker.js");
66
67   // Simulate adding one process to the pattern.
68   helper_->SimulateAddProcessToPattern(pattern, kRenderProcessId);
69
70   // Start should succeed.
71   ServiceWorkerStatusCode status;
72   base::RunLoop run_loop;
73   worker->Start(
74       service_worker_version_id,
75       pattern,
76       url,
77       false,
78       base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
79   run_loop.Run();
80   EXPECT_EQ(SERVICE_WORKER_OK, status);
81   EXPECT_EQ(EmbeddedWorkerInstance::STARTING, worker->status());
82   base::RunLoop().RunUntilIdle();
83
84   // Worker started message should be notified (by EmbeddedWorkerTestHelper).
85   EXPECT_EQ(EmbeddedWorkerInstance::RUNNING, worker->status());
86   EXPECT_EQ(kRenderProcessId, worker->process_id());
87
88   // Stop the worker.
89   EXPECT_EQ(SERVICE_WORKER_OK, worker->Stop());
90   EXPECT_EQ(EmbeddedWorkerInstance::STOPPING, worker->status());
91   base::RunLoop().RunUntilIdle();
92
93   // Worker stopped message should be notified (by EmbeddedWorkerTestHelper).
94   EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
95
96   // Verify that we've sent two messages to start and terminate the worker.
97   ASSERT_TRUE(ipc_sink()->GetUniqueMessageMatching(
98       EmbeddedWorkerMsg_StartWorker::ID));
99   ASSERT_TRUE(ipc_sink()->GetUniqueMessageMatching(
100       EmbeddedWorkerMsg_StopWorker::ID));
101 }
102
103 TEST_F(EmbeddedWorkerInstanceTest, InstanceDestroyedBeforeStartFinishes) {
104   scoped_ptr<EmbeddedWorkerInstance> worker =
105       embedded_worker_registry()->CreateWorker();
106   EXPECT_EQ(EmbeddedWorkerInstance::STOPPED, worker->status());
107
108   const int64 service_worker_version_id = 55L;
109   const GURL pattern("http://example.com/");
110   const GURL url("http://example.com/worker.js");
111
112   ServiceWorkerStatusCode status;
113   base::RunLoop run_loop;
114   // Begin starting the worker.
115   context()->process_manager()->AddProcessReferenceToPattern(
116       pattern, kRenderProcessId);
117   worker->Start(
118       service_worker_version_id,
119       pattern,
120       url,
121       false,
122       base::Bind(&SaveStatusAndCall, &status, run_loop.QuitClosure()));
123   // But destroy it before it gets a chance to complete.
124   worker.reset();
125   run_loop.Run();
126   EXPECT_EQ(SERVICE_WORKER_ERROR_ABORT, status);
127
128   // Verify that we didn't send the message to start the worker.
129   ASSERT_FALSE(
130       ipc_sink()->GetUniqueMessageMatching(EmbeddedWorkerMsg_StartWorker::ID));
131 }
132
133 }  // namespace content