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 "content/child/service_worker/service_worker_dispatcher.h"
6 #include "content/child/service_worker/web_service_worker_impl.h"
7 #include "content/child/service_worker/web_service_worker_registration_impl.h"
8 #include "content/child/thread_safe_sender.h"
9 #include "content/common/service_worker/service_worker_messages.h"
10 #include "content/common/service_worker/service_worker_types.h"
11 #include "ipc/ipc_sync_message_filter.h"
12 #include "ipc/ipc_test_sink.h"
13 #include "testing/gtest/include/gtest/gtest.h"
17 class ServiceWorkerTestSender
: public ThreadSafeSender
{
19 explicit ServiceWorkerTestSender(IPC::TestSink
* ipc_sink
)
20 : ThreadSafeSender(nullptr, nullptr),
21 ipc_sink_(ipc_sink
) {}
23 bool Send(IPC::Message
* message
) override
{
24 return ipc_sink_
->Send(message
);
28 ~ServiceWorkerTestSender() override
{}
30 IPC::TestSink
* ipc_sink_
;
32 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTestSender
);
35 class ServiceWorkerDispatcherTest
: public testing::Test
{
37 ServiceWorkerDispatcherTest() {}
39 void SetUp() override
{
40 sender_
= new ServiceWorkerTestSender(&ipc_sink_
);
41 dispatcher_
.reset(new ServiceWorkerDispatcher(sender_
.get(), nullptr));
44 void CreateObjectInfoAndVersionAttributes(
45 ServiceWorkerRegistrationObjectInfo
* info
,
46 ServiceWorkerVersionAttributes
* attrs
) {
48 info
->registration_id
= 20;
50 attrs
->active
.handle_id
= 100;
51 attrs
->active
.version_id
= 200;
52 attrs
->waiting
.handle_id
= 101;
53 attrs
->waiting
.version_id
= 201;
54 attrs
->installing
.handle_id
= 102;
55 attrs
->installing
.version_id
= 202;
58 bool ContainsServiceWorker(int handle_id
) {
59 return ContainsKey(dispatcher_
->service_workers_
, handle_id
);
62 bool ContainsRegistration(int registration_handle_id
) {
63 return ContainsKey(dispatcher_
->registrations_
, registration_handle_id
);
66 ServiceWorkerDispatcher
* dispatcher() { return dispatcher_
.get(); }
67 IPC::TestSink
* ipc_sink() { return &ipc_sink_
; }
70 IPC::TestSink ipc_sink_
;
71 scoped_ptr
<ServiceWorkerDispatcher
> dispatcher_
;
72 scoped_refptr
<ServiceWorkerTestSender
> sender_
;
74 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerDispatcherTest
);
77 // TODO(nhiroki): Add tests for message handlers especially to receive reference
78 // counts like OnAssociateRegistration().
79 TEST_F(ServiceWorkerDispatcherTest
, GetServiceWorker
) {
80 ServiceWorkerRegistrationObjectInfo info
;
81 ServiceWorkerVersionAttributes attrs
;
82 CreateObjectInfoAndVersionAttributes(&info
, &attrs
);
84 // Should return a worker object newly created with incrementing refcount.
85 bool adopt_handle
= false;
86 scoped_ptr
<WebServiceWorkerImpl
> worker(
87 dispatcher()->GetServiceWorker(attrs
.installing
, adopt_handle
));
89 EXPECT_TRUE(ContainsServiceWorker(attrs
.installing
.handle_id
));
90 EXPECT_EQ(1UL, ipc_sink()->message_count());
91 EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID
,
92 ipc_sink()->GetMessageAt(0)->type());
94 ipc_sink()->ClearMessages();
96 // Should return the existing worker object.
98 WebServiceWorkerImpl
* existing_worker
=
99 dispatcher()->GetServiceWorker(attrs
.installing
, adopt_handle
);
100 EXPECT_EQ(worker
, existing_worker
);
101 EXPECT_EQ(0UL, ipc_sink()->message_count());
103 // Should return the existing worker object with adopting refcount.
106 dispatcher()->GetServiceWorker(attrs
.installing
, adopt_handle
);
107 EXPECT_EQ(worker
, existing_worker
);
108 ASSERT_EQ(1UL, ipc_sink()->message_count());
109 EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID
,
110 ipc_sink()->GetMessageAt(0)->type());
112 ipc_sink()->ClearMessages();
114 // Should return another worker object newly created with adopting refcount.
116 scoped_ptr
<WebServiceWorkerImpl
> another_worker(
117 dispatcher()->GetServiceWorker(attrs
.waiting
, adopt_handle
));
118 EXPECT_NE(worker
.get(), another_worker
.get());
119 EXPECT_TRUE(ContainsServiceWorker(attrs
.waiting
.handle_id
));
120 EXPECT_EQ(0UL, ipc_sink()->message_count());
122 // Should return nullptr when a given object info is invalid.
123 adopt_handle
= false;
124 WebServiceWorkerImpl
* invalid_worker
=
125 dispatcher()->GetServiceWorker(ServiceWorkerObjectInfo(), adopt_handle
);
126 EXPECT_FALSE(invalid_worker
);
127 EXPECT_EQ(0UL, ipc_sink()->message_count());
131 dispatcher()->GetServiceWorker(ServiceWorkerObjectInfo(), adopt_handle
);
132 EXPECT_FALSE(invalid_worker
);
133 EXPECT_EQ(0UL, ipc_sink()->message_count());
136 TEST_F(ServiceWorkerDispatcherTest
, CreateRegistration
) {
137 ServiceWorkerRegistrationObjectInfo info
;
138 ServiceWorkerVersionAttributes attrs
;
139 CreateObjectInfoAndVersionAttributes(&info
, &attrs
);
141 // Should return a registration object newly created with adopting refcount.
142 scoped_refptr
<WebServiceWorkerRegistrationImpl
> registration(
143 dispatcher()->AdoptRegistration(info
, attrs
));
144 EXPECT_TRUE(registration
);
145 EXPECT_EQ(info
.registration_id
, registration
->registration_id());
146 EXPECT_EQ(0UL, ipc_sink()->message_count());
148 // The registration dtor decrements the refcount.
149 registration
= nullptr;
150 ASSERT_EQ(4UL, ipc_sink()->message_count());
151 EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID
,
152 ipc_sink()->GetMessageAt(0)->type());
153 EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID
,
154 ipc_sink()->GetMessageAt(1)->type());
155 EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID
,
156 ipc_sink()->GetMessageAt(2)->type());
157 EXPECT_EQ(ServiceWorkerHostMsg_DecrementRegistrationRefCount::ID
,
158 ipc_sink()->GetMessageAt(3)->type());
160 ipc_sink()->ClearMessages();
162 // Should return a registration object newly created with incrementing
164 registration
= dispatcher()->CreateRegistration(info
, attrs
);
165 EXPECT_TRUE(registration
);
166 EXPECT_TRUE(ContainsRegistration(info
.handle_id
));
167 ASSERT_EQ(4UL, ipc_sink()->message_count());
168 EXPECT_EQ(ServiceWorkerHostMsg_IncrementRegistrationRefCount::ID
,
169 ipc_sink()->GetMessageAt(0)->type());
170 EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID
,
171 ipc_sink()->GetMessageAt(1)->type());
172 EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID
,
173 ipc_sink()->GetMessageAt(2)->type());
174 EXPECT_EQ(ServiceWorkerHostMsg_IncrementServiceWorkerRefCount::ID
,
175 ipc_sink()->GetMessageAt(3)->type());
177 ipc_sink()->ClearMessages();
179 // The registration dtor decrements the refcount.
180 registration
= nullptr;
181 ASSERT_EQ(4UL, ipc_sink()->message_count());
182 EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID
,
183 ipc_sink()->GetMessageAt(0)->type());
184 EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID
,
185 ipc_sink()->GetMessageAt(1)->type());
186 EXPECT_EQ(ServiceWorkerHostMsg_DecrementServiceWorkerRefCount::ID
,
187 ipc_sink()->GetMessageAt(2)->type());
188 EXPECT_EQ(ServiceWorkerHostMsg_DecrementRegistrationRefCount::ID
,
189 ipc_sink()->GetMessageAt(3)->type());
192 } // namespace content