1 // Copyright 2015 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.
5 #include "base/message_loop/message_loop_proxy.h"
6 #include "content/child/service_worker/service_worker_dispatcher.h"
7 #include "content/child/service_worker/web_service_worker_impl.h"
8 #include "content/child/service_worker/web_service_worker_registration_impl.h"
9 #include "content/child/thread_safe_sender.h"
10 #include "content/common/service_worker/service_worker_messages.h"
11 #include "content/common/service_worker/service_worker_types.h"
12 #include "ipc/ipc_sync_message_filter.h"
13 #include "ipc/ipc_test_sink.h"
14 #include "testing/gtest/include/gtest/gtest.h"
18 class ServiceWorkerTestSender
: public ThreadSafeSender
{
20 explicit ServiceWorkerTestSender(IPC::TestSink
* ipc_sink
)
21 : ThreadSafeSender(nullptr, nullptr),
22 ipc_sink_(ipc_sink
) {}
24 bool Send(IPC::Message
* message
) override
{
25 return ipc_sink_
->Send(message
);
29 ~ServiceWorkerTestSender() override
{}
31 IPC::TestSink
* ipc_sink_
;
33 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTestSender
);
36 class ServiceWorkerDispatcherTest
: public testing::Test
{
38 ServiceWorkerDispatcherTest() {}
40 void SetUp() override
{
41 sender_
= new ServiceWorkerTestSender(&ipc_sink_
);
42 dispatcher_
.reset(new ServiceWorkerDispatcher(sender_
.get()));
45 void CreateObjectInfoAndVersionAttributes(
46 ServiceWorkerRegistrationObjectInfo
* info
,
47 ServiceWorkerVersionAttributes
* attrs
) {
49 info
->registration_id
= 20;
51 attrs
->active
.handle_id
= 100;
52 attrs
->active
.version_id
= 200;
53 attrs
->waiting
.handle_id
= 101;
54 attrs
->waiting
.version_id
= 201;
55 attrs
->installing
.handle_id
= 102;
56 attrs
->installing
.version_id
= 202;
59 WebServiceWorkerRegistrationImpl
* FindOrCreateRegistration(
60 const ServiceWorkerRegistrationObjectInfo
& info
,
61 const ServiceWorkerVersionAttributes
& attrs
) {
62 return dispatcher_
->FindOrCreateRegistration(info
, attrs
);
65 bool ContainsServiceWorker(int handle_id
) {
66 return ContainsKey(dispatcher_
->service_workers_
, handle_id
);
69 bool ContainsRegistration(int registration_handle_id
) {
70 return ContainsKey(dispatcher_
->registrations_
, registration_handle_id
);
73 ServiceWorkerDispatcher
* dispatcher() { return dispatcher_
.get(); }
74 IPC::TestSink
* ipc_sink() { return &ipc_sink_
; }
77 IPC::TestSink ipc_sink_
;
78 scoped_ptr
<ServiceWorkerDispatcher
> dispatcher_
;
79 scoped_refptr
<ServiceWorkerTestSender
> sender_
;
81 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcherTest
);
84 // TODO(nhiroki): Add tests for message handlers especially to receive reference
85 // counts like OnAssociateRegistration().
86 TEST_F(ServiceWorkerDispatcherTest
, GetServiceWorker
) {
87 ServiceWorkerRegistrationObjectInfo info
;
88 ServiceWorkerVersionAttributes attrs
;
89 CreateObjectInfoAndVersionAttributes(&info
, &attrs
);
91 // Should return a worker object newly created with incrementing refcount.
92 bool adopt_handle
= false;
93 scoped_ptr
<WebServiceWorkerImpl
> worker(
94 dispatcher()->GetServiceWorker(attrs
.installing
, adopt_handle
));
96 EXPECT_TRUE(ContainsServiceWorker(attrs
.installing
.handle_id
));
97 EXPECT_EQ(1UL, ipc_sink()->message_count());
98 EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID
,
99 ipc_sink()->GetMessageAt(0)->type());
101 ipc_sink()->ClearMessages();
103 // Should return the existing worker object.
104 adopt_handle
= false;
105 WebServiceWorkerImpl
* existing_worker
=
106 dispatcher()->GetServiceWorker(attrs
.installing
, adopt_handle
);
107 EXPECT_EQ(worker
, existing_worker
);
108 EXPECT_EQ(0UL, ipc_sink()->message_count());
110 // Should return the existing worker object with adopting refcount.
113 dispatcher()->GetServiceWorker(attrs
.installing
, adopt_handle
);
114 EXPECT_EQ(worker
, existing_worker
);
115 ASSERT_EQ(1UL, ipc_sink()->message_count());
116 EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID
,
117 ipc_sink()->GetMessageAt(0)->type());
119 ipc_sink()->ClearMessages();
121 // Should return another worker object newly created with adopting refcount.
123 scoped_ptr
<WebServiceWorkerImpl
> another_worker(
124 dispatcher()->GetServiceWorker(attrs
.waiting
, adopt_handle
));
125 EXPECT_NE(worker
.get(), another_worker
.get());
126 EXPECT_TRUE(ContainsServiceWorker(attrs
.waiting
.handle_id
));
127 EXPECT_EQ(0UL, ipc_sink()->message_count());
129 // Should return nullptr when a given object info is invalid.
130 adopt_handle
= false;
131 WebServiceWorkerImpl
* invalid_worker
=
132 dispatcher()->GetServiceWorker(ServiceWorkerObjectInfo(), adopt_handle
);
133 EXPECT_FALSE(invalid_worker
);
134 EXPECT_EQ(0UL, ipc_sink()->message_count());
138 dispatcher()->GetServiceWorker(ServiceWorkerObjectInfo(), adopt_handle
);
139 EXPECT_FALSE(invalid_worker
);
140 EXPECT_EQ(0UL, ipc_sink()->message_count());
143 TEST_F(ServiceWorkerDispatcherTest
, CreateServiceWorkerRegistration
) {
144 ServiceWorkerRegistrationObjectInfo info
;
145 ServiceWorkerVersionAttributes attrs
;
146 CreateObjectInfoAndVersionAttributes(&info
, &attrs
);
148 // Should return a registration object newly created with incrementing
150 bool adopt_handle
= false;
151 scoped_ptr
<WebServiceWorkerRegistrationImpl
> registration(
152 dispatcher()->CreateServiceWorkerRegistration(info
, adopt_handle
));
153 EXPECT_TRUE(registration
);
154 EXPECT_TRUE(ContainsRegistration(info
.handle_id
));
155 ASSERT_EQ(1UL, ipc_sink()->message_count());
156 EXPECT_EQ(ServiceWorkerHostMsg_IncrementRegistrationRefCount::ID
,
157 ipc_sink()->GetMessageAt(0)->type());
159 registration
.reset();
160 EXPECT_FALSE(ContainsRegistration(info
.handle_id
));
161 ipc_sink()->ClearMessages();
163 // Should return another registration object newly created with adopting
166 scoped_ptr
<WebServiceWorkerRegistrationImpl
> another_registration(
167 dispatcher()->CreateServiceWorkerRegistration(info
, adopt_handle
));
168 EXPECT_TRUE(another_registration
);
169 EXPECT_TRUE(ContainsRegistration(info
.handle_id
));
170 EXPECT_EQ(0UL, ipc_sink()->message_count());
172 another_registration
.reset();
173 ipc_sink()->ClearMessages();
175 // should return nullptr when a given object info is invalid.
176 adopt_handle
= false;
177 scoped_ptr
<WebServiceWorkerRegistrationImpl
> invalid_registration(
178 dispatcher()->CreateServiceWorkerRegistration(
179 ServiceWorkerRegistrationObjectInfo(), adopt_handle
));
180 EXPECT_FALSE(invalid_registration
);
181 EXPECT_FALSE(ContainsRegistration(info
.handle_id
));
182 EXPECT_EQ(0UL, ipc_sink()->message_count());
185 invalid_registration
.reset(dispatcher()->CreateServiceWorkerRegistration(
186 ServiceWorkerRegistrationObjectInfo(), adopt_handle
));
187 EXPECT_FALSE(invalid_registration
);
188 EXPECT_FALSE(ContainsRegistration(info
.handle_id
));
189 EXPECT_EQ(0UL, ipc_sink()->message_count());
192 TEST_F(ServiceWorkerDispatcherTest
, FindOrCreateRegistration
) {
193 ServiceWorkerRegistrationObjectInfo info
;
194 ServiceWorkerVersionAttributes attrs
;
195 CreateObjectInfoAndVersionAttributes(&info
, &attrs
);
197 // Should return a registration object newly created with adopting refcounts.
198 scoped_ptr
<WebServiceWorkerRegistrationImpl
> registration(
199 FindOrCreateRegistration(info
, attrs
));
200 EXPECT_TRUE(registration
);
201 EXPECT_EQ(info
.registration_id
, registration
->registration_id());
202 EXPECT_EQ(0UL, ipc_sink()->message_count());
204 // Should return the existing registration object with adopting refcounts.
205 WebServiceWorkerRegistrationImpl
* existing_registration
=
206 FindOrCreateRegistration(info
, attrs
);
207 EXPECT_EQ(registration
, existing_registration
);
208 ASSERT_EQ(4UL, ipc_sink()->message_count());
209 EXPECT_EQ(ServiceWorkerHostMsg_DecrementRegistrationRefCount::ID
,
210 ipc_sink()->GetMessageAt(0)->type());
211 EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID
,
212 ipc_sink()->GetMessageAt(1)->type());
213 EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID
,
214 ipc_sink()->GetMessageAt(2)->type());
215 EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID
,
216 ipc_sink()->GetMessageAt(3)->type());
219 } // namespace content