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

Unified Diff: content/browser/shared_worker/shared_worker_service_impl_unittest.cc

Issue 187533002: Add SharedWorkerServiceImpl::CheckWorkerDependency(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ExternalClient
Patch Set: Add unit test for SharedWorkerServiceImpl Created 6 years, 9 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: content/browser/shared_worker/shared_worker_service_impl_unittest.cc
diff --git a/content/browser/shared_worker/shared_worker_service_impl_unittest.cc b/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..af51ae7099b4a6296991b3fbcc6c2912eea65170
--- /dev/null
+++ b/content/browser/shared_worker/shared_worker_service_impl_unittest.cc
@@ -0,0 +1,426 @@
+// 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 <map>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "base/strings/string16.h"
+#include "base/strings/utf_string_conversions.h"
+#include "content/browser/message_port_message_filter.h"
+#include "content/browser/shared_worker/shared_worker_message_filter.h"
+#include "content/browser/shared_worker/shared_worker_service_impl.h"
+#include "content/browser/worker_host/worker_storage_partition.h"
+#include "content/common/message_port_messages.h"
+#include "content/common/view_messages.h"
+#include "content/common/worker_messages.h"
+#include "content/public/test/test_browser_context.h"
+#include "content/public/test/test_browser_thread_bundle.h"
+#include "ipc/ipc_sync_message.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+namespace {
+
+class NumberGenerator : public base::RefCountedThreadSafe<NumberGenerator> {
kinuko 2014/03/10 04:25:43 You can probably use base::AtomicSequenceNumber in
horo 2014/03/10 11:48:31 Done.
+ public:
+ explicit NumberGenerator(int initial_no) : no_(initial_no) {}
+ int Next() { return ++no_; }
+
+ private:
+ friend class base::RefCountedThreadSafe<NumberGenerator>;
+ ~NumberGenerator() {}
+ int no_;
+};
+
+class MockMessagePortMessageFilter : public MessagePortMessageFilter {
+ public:
+ MockMessagePortMessageFilter(const NextRoutingIDCallback& callback,
+ ScopedVector<IPC::Message>* message_queue)
+ : MessagePortMessageFilter(callback), message_queue_(message_queue) {}
+
+ virtual bool Send(IPC::Message* message) OVERRIDE {
+ if (message_queue_)
+ message_queue_->push_back(message);
+ return true;
+ }
+
+ void Close() {
+ message_queue_ = NULL;
+ OnChannelClosing();
+ }
+
+ private:
+ virtual ~MockMessagePortMessageFilter() {}
+ ScopedVector<IPC::Message>* message_queue_;
+};
+
+class MockSharedWorkerMessageFilter : public SharedWorkerMessageFilter {
+ public:
+ MockSharedWorkerMessageFilter(int render_process_id,
+ ResourceContext* resource_context,
+ const WorkerStoragePartition& partition,
+ MessagePortMessageFilter* message_port_filter,
+ ScopedVector<IPC::Message>* message_queue)
+ : SharedWorkerMessageFilter(render_process_id,
+ resource_context,
+ partition,
+ message_port_filter),
+ message_queue_(message_queue) {}
+
+ virtual bool Send(IPC::Message* message) OVERRIDE {
+ if (message_queue_)
+ message_queue_->push_back(message);
+ return true;
+ }
+
+ void Close() {
+ message_queue_ = NULL;
+ OnChannelClosing();
+ }
+
+ private:
+ virtual ~MockSharedWorkerMessageFilter() {}
+ ScopedVector<IPC::Message>* message_queue_;
+};
+
+class MockRenderer {
+ public:
+ MockRenderer(int initial_no,
+ int process_no,
+ ResourceContext* resource_context,
+ const WorkerStoragePartition& partition)
+ : num_generator_(new NumberGenerator(initial_no)),
+ message_filter_(new MockMessagePortMessageFilter(
+ base::Bind(&NumberGenerator::Next, num_generator_),
+ &queued_messages_)),
+ worker_filter_(new MockSharedWorkerMessageFilter(process_no,
+ resource_context,
+ partition,
+ message_filter_.get(),
+ &queued_messages_)) {}
+
+ ~MockRenderer() {
+ message_filter_->Close();
+ worker_filter_->Close();
+ }
+
+ bool Post(IPC::Message* message) {
kinuko 2014/03/10 04:25:43 MockRenderer -> MockRendererProcessHost Post -> On
horo 2014/03/10 11:48:31 Done.
+ scoped_ptr<IPC::Message> msg(message);
+ bool message_was_ok = false;
+ const bool ret =
+ message_filter_->OnMessageReceived(*message, &message_was_ok) ||
+ worker_filter_->OnMessageReceived(*message, &message_was_ok);
+ if (message->is_sync()) {
+ CHECK(!queued_messages_.empty());
+ const IPC::Message* responce_msg = queued_messages_.back();
kinuko 2014/03/10 04:25:43 responce -> response
horo 2014/03/10 11:48:31 Done.
+ IPC::SyncMessage* sync_msg = static_cast<IPC::SyncMessage*>(message);
+ scoped_ptr<IPC::MessageReplyDeserializer> reply_serializer(
+ sync_msg->GetReplyDeserializer());
+ bool result = reply_serializer->SerializeOutputParameters(*responce_msg);
+ CHECK(result);
+ queued_messages_.pop_back();
+ }
+ return ret;
+ }
+
+ int QueuedMessageCount() { return queued_messages_.size(); }
kinuko 2014/03/10 04:25:43 nit: make it a const method It'd be better to ret
horo 2014/03/10 11:48:31 Done.
+
+ IPC::Message* PopMessage() {
kinuko 2014/03/10 04:25:43 Can this return scoped_ptr<Message> (and all Check
horo 2014/03/10 11:48:31 Done.
+ CHECK(queued_messages_.size());
+ IPC::Message* msg = *queued_messages_.begin();
+ queued_messages_.weak_erase(queued_messages_.begin());
+ return msg;
+ }
+
+ private:
+ ScopedVector<IPC::Message> queued_messages_;
+ scoped_refptr<NumberGenerator> num_generator_;
+ scoped_refptr<MockMessagePortMessageFilter> message_filter_;
+ scoped_refptr<MockSharedWorkerMessageFilter> worker_filter_;
+};
+
+void CreateMessagePortPair(MockRenderer* renderer,
+ int* route_1,
+ int* port_1,
+ int* route_2,
+ int* port_2) {
+ EXPECT_TRUE(renderer->Post(
+ new MessagePortHostMsg_CreateMessagePort(route_1, port_1)));
+ EXPECT_TRUE(renderer->Post(
+ new MessagePortHostMsg_CreateMessagePort(route_2, port_2)));
+ EXPECT_TRUE(
+ renderer->Post(new MessagePortHostMsg_Entangle(*port_1, *port_2)));
+ EXPECT_TRUE(
+ renderer->Post(new MessagePortHostMsg_Entangle(*port_2, *port_1)));
+}
+
+void PostCreateWorker(MockRenderer* renderer,
+ const std::string& url,
+ const std::string& name,
+ unsigned long long document_id,
+ int render_frame_route_id,
+ int* connector_route_id) {
+ ViewHostMsg_CreateWorker_Params params;
+ params.url = GURL(url);
+ params.name = base::ASCIIToUTF16(name);
+ params.content_security_policy = base::string16();
+ params.security_policy_type = blink::WebContentSecurityPolicyTypeReport;
+ params.document_id = document_id;
+ params.render_frame_route_id = render_frame_route_id;
+ EXPECT_TRUE(
+ renderer->Post(new ViewHostMsg_CreateWorker(params, connector_route_id)));
+}
+
+void CheckWorkerProcessMsgCreateWorker(
+ IPC::Message* msg,
+ const std::string& url,
+ const std::string& name,
+ blink::WebContentSecurityPolicyType security_policy_type,
+ int route_id) {
kinuko 2014/03/10 04:25:43 nit: it'd read better if these params are prefixed
horo 2014/03/10 11:48:31 Done.
+ scoped_ptr<IPC::Message> message(msg);
+ EXPECT_EQ(WorkerProcessMsg_CreateWorker::ID, msg->type());
+ Tuple1<WorkerProcessMsg_CreateWorker_Params> param;
+ EXPECT_TRUE(WorkerProcessMsg_CreateWorker::Read(msg, &param));
+ EXPECT_EQ(GURL(url), param.a.url);
+ EXPECT_EQ(base::ASCIIToUTF16(name), param.a.name);
+ EXPECT_EQ(security_policy_type, param.a.security_policy_type);
+ EXPECT_EQ(route_id, param.a.route_id);
+}
+
+void CheckViewMsgWorkerCreated(IPC::Message* msg, int msg_route_id) {
+ scoped_ptr<IPC::Message> message(msg);
+ EXPECT_EQ(ViewMsg_WorkerCreated::ID, msg->type());
+ EXPECT_EQ(msg_route_id, msg->routing_id());
+}
+
+void CheckMessagePortMsgMessagesQueued(IPC::Message* msg, int msg_route_id) {
+ scoped_ptr<IPC::Message> message(msg);
+ EXPECT_EQ(MessagePortMsg_MessagesQueued::ID, msg->type());
+ EXPECT_EQ(msg_route_id, msg->routing_id());
+}
+
+void CheckWorkerMsgConnect(IPC::Message* msg,
+ int msg_route_id,
+ int sent_message_port_id,
+ int routing_id) {
+ scoped_ptr<IPC::Message> message(msg);
+ EXPECT_EQ(WorkerMsg_Connect::ID, msg->type());
+ EXPECT_EQ(msg_route_id, msg->routing_id());
+ int port_id;
+ int port_route;
+ EXPECT_TRUE(WorkerMsg_Connect::Read(msg, &port_id, &port_route));
+ EXPECT_EQ(sent_message_port_id, port_id);
+ EXPECT_EQ(routing_id, port_route);
+}
+
+void CheckMessagePortMsgMessage(IPC::Message* msg,
+ int msg_route_id,
+ std::string expected_data) {
+ scoped_ptr<IPC::Message> message(msg);
+ EXPECT_EQ(MessagePortMsg_Message::ID, msg->type());
+ EXPECT_EQ(msg_route_id, msg->routing_id());
+ base::string16 data;
+ std::vector<int> sent_message_port_ids;
+ std::vector<int> new_routing_ids;
+ EXPECT_TRUE(MessagePortMsg_Message::Read(
+ msg, &data, &sent_message_port_ids, &new_routing_ids));
+ EXPECT_EQ(base::ASCIIToUTF16(expected_data), data);
+}
+
+void CheckViewMsgWorkerConnected(IPC::Message* msg, int msg_route_id) {
+ scoped_ptr<IPC::Message> message(msg);
+ EXPECT_EQ(ViewMsg_WorkerConnected::ID, msg->type());
+ EXPECT_EQ(msg_route_id, msg->routing_id());
+}
+
+std::vector<std::pair<std::vector<int>, std::vector<int> > >
+ g_worker_dependency_updates;
kinuko 2014/03/10 04:25:43 nit: I think just having two std::vector<int> woul
horo 2014/03/10 11:48:31 Done.
+
+void MockUpdateWorkerDependency(const std::vector<int> added_ids,
+ const std::vector<int> removed_ids) {
+ g_worker_dependency_updates.push_back(std::make_pair(added_ids, removed_ids));
+}
+
+} // namespace
+
+class SharedWorkerServiceImplTest : public testing::Test {
+ protected:
+ SharedWorkerServiceImplTest()
+ : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
+ browser_context_(new TestBrowserContext()),
+ partition_(
+ new WorkerStoragePartition(browser_context_->GetRequestContext(),
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL)) {
+ SharedWorkerServiceImpl::GetInstance()
+ ->ChangeUpdateWorkerDependencyFuncForTesting(
+ MockUpdateWorkerDependency);
+ }
+
+ virtual void SetUp() {}
+ virtual void TearDown() {
kinuko 2014/03/10 04:25:43 OVERRIDE
horo 2014/03/10 11:48:31 Done.
+ g_worker_dependency_updates.clear();
+ SharedWorkerServiceImpl::GetInstance()->ResetForTesting();
+ }
+
+ TestBrowserThreadBundle browser_thread_bundle_;
+ scoped_ptr<TestBrowserContext> browser_context_;
+ scoped_ptr<WorkerStoragePartition> partition_;
+ DISALLOW_COPY_AND_ASSIGN(SharedWorkerServiceImplTest);
+};
+
+TEST_F(SharedWorkerServiceImplTest, SimpleTest) {
kinuko 2014/03/10 04:25:43 Can you add some more comments in the test code bo
horo 2014/03/10 11:48:31 Done.
+ scoped_ptr<MockRenderer> renderer1(new MockRenderer(
+ 100, 200, browser_context_->GetResourceContext(), *partition_.get()));
+
+ int msg_port_route1_1, msg_port_id1_1;
+ int msg_port_route1_2, msg_port_id1_2;
+ CreateMessagePortPair(renderer1.get(),
+ &msg_port_route1_1,
+ &msg_port_id1_1,
+ &msg_port_route1_2,
+ &msg_port_id1_2);
+ EXPECT_EQ(101, msg_port_route1_1);
+ EXPECT_EQ(102, msg_port_route1_2);
+
+ int connector_route_id1;
+ PostCreateWorker(renderer1.get(),
+ "http://example.com/w.js",
+ "name",
+ 300,
+ 400,
+ &connector_route_id1);
+ EXPECT_EQ(103, connector_route_id1);
+ EXPECT_EQ(2, renderer1->QueuedMessageCount());
+ int worker_route_id = 104;
+ CheckWorkerProcessMsgCreateWorker(renderer1->PopMessage(),
+ "http://example.com/w.js",
+ "name",
+ blink::WebContentSecurityPolicyTypeReport,
+ worker_route_id);
+ CheckViewMsgWorkerCreated(renderer1->PopMessage(), connector_route_id1);
+
+ EXPECT_TRUE(
+ renderer1->Post(new MessagePortHostMsg_QueueMessages(msg_port_id1_1)));
+ EXPECT_EQ(1, renderer1->QueuedMessageCount());
+ CheckMessagePortMsgMessagesQueued(renderer1->PopMessage(), msg_port_route1_1);
+
+ const std::vector<int> empty_ids;
+ EXPECT_TRUE(renderer1->Post(new MessagePortHostMsg_PostMessage(
+ msg_port_id1_2, base::ASCIIToUTF16("test"), empty_ids)));
+ EXPECT_EQ(0, renderer1->QueuedMessageCount());
+
+ int new_msg_port_route1 = 105;
+ EXPECT_TRUE(renderer1->Post(new ViewHostMsg_ForwardToWorker(WorkerMsg_Connect(
+ connector_route_id1, msg_port_id1_1, MSG_ROUTING_NONE))));
+ EXPECT_EQ(1, renderer1->QueuedMessageCount());
+ CheckWorkerMsgConnect(renderer1->PopMessage(),
+ worker_route_id,
+ msg_port_id1_1,
+ new_msg_port_route1);
+
+ std::vector<QueuedMessage> queued_messages;
+ EXPECT_TRUE(renderer1->Post(new MessagePortHostMsg_SendQueuedMessages(
+ msg_port_id1_1, queued_messages)));
+ EXPECT_EQ(1, renderer1->QueuedMessageCount());
+ CheckMessagePortMsgMessage(
+ renderer1->PopMessage(), new_msg_port_route1, "test");
+
+ EXPECT_TRUE(
+ renderer1->Post(new WorkerHostMsg_WorkerScriptLoaded(worker_route_id)));
+ EXPECT_EQ(0, renderer1->QueuedMessageCount());
+
+ EXPECT_TRUE(renderer1->Post(
+ new WorkerHostMsg_WorkerConnected(msg_port_id1_1, worker_route_id)));
+ EXPECT_EQ(1, renderer1->QueuedMessageCount());
+ CheckViewMsgWorkerConnected(renderer1->PopMessage(), connector_route_id1);
+
+ EXPECT_TRUE(renderer1->Post(new MessagePortHostMsg_PostMessage(
+ msg_port_id1_1, base::ASCIIToUTF16("test2"), empty_ids)));
+ EXPECT_EQ(1, renderer1->QueuedMessageCount());
+ CheckMessagePortMsgMessage(
+ renderer1->PopMessage(), msg_port_route1_2, "test2");
+
+ scoped_ptr<MockRenderer> renderer2(new MockRenderer(
+ 500, 600, browser_context_->GetResourceContext(), *partition_.get()));
+
+ int msg_port_route2_1, msg_port_id2_1;
+ int msg_port_route2_2, msg_port_id2_2;
+ CreateMessagePortPair(renderer2.get(),
+ &msg_port_route2_1,
+ &msg_port_id2_1,
+ &msg_port_route2_2,
+ &msg_port_id2_2);
+ EXPECT_EQ(501, msg_port_route2_1);
+ EXPECT_EQ(502, msg_port_route2_2);
+
+ EXPECT_EQ(0U, g_worker_dependency_updates.size());
+
+ int connector_route_id2;
+ PostCreateWorker(renderer2.get(),
+ "http://example.com/w.js",
+ "name",
+ 700,
+ 800,
+ &connector_route_id2);
+ EXPECT_EQ(503, connector_route_id2);
+ EXPECT_EQ(1, renderer2->QueuedMessageCount());
+ CheckViewMsgWorkerCreated(renderer2->PopMessage(), connector_route_id2);
+
+ EXPECT_EQ(1U, g_worker_dependency_updates.size());
+ EXPECT_EQ(1U, g_worker_dependency_updates[0].first.size());
+ EXPECT_EQ(200, g_worker_dependency_updates[0].first[0]);
+ EXPECT_EQ(0U, g_worker_dependency_updates[0].second.size());
+
+ EXPECT_TRUE(
+ renderer2->Post(new MessagePortHostMsg_QueueMessages(msg_port_id2_1)));
+ EXPECT_EQ(1, renderer2->QueuedMessageCount());
+ CheckMessagePortMsgMessagesQueued(renderer2->PopMessage(), msg_port_route2_1);
+
+ int new_msg_port_route2 = 106;
+ EXPECT_TRUE(renderer2->Post(new ViewHostMsg_ForwardToWorker(WorkerMsg_Connect(
+ connector_route_id2, msg_port_id2_1, MSG_ROUTING_NONE))));
+ EXPECT_EQ(1, renderer1->QueuedMessageCount());
+ CheckWorkerMsgConnect(renderer1->PopMessage(),
+ worker_route_id,
+ msg_port_id2_1,
+ new_msg_port_route2);
+
+ EXPECT_TRUE(renderer2->Post(new MessagePortHostMsg_SendQueuedMessages(
+ msg_port_id2_1, queued_messages)));
+ EXPECT_EQ(0, renderer2->QueuedMessageCount());
+
+ EXPECT_TRUE(renderer1->Post(
+ new WorkerHostMsg_WorkerConnected(msg_port_id2_1, worker_route_id)));
+ EXPECT_EQ(1, renderer2->QueuedMessageCount());
+ CheckViewMsgWorkerConnected(renderer2->PopMessage(), connector_route_id2);
+
+ EXPECT_TRUE(renderer2->Post(new MessagePortHostMsg_PostMessage(
+ msg_port_id2_2, base::ASCIIToUTF16("test3"), empty_ids)));
+ EXPECT_EQ(1, renderer1->QueuedMessageCount());
+ CheckMessagePortMsgMessage(
+ renderer1->PopMessage(), new_msg_port_route2, "test3");
+
+ EXPECT_TRUE(renderer1->Post(new MessagePortHostMsg_PostMessage(
+ msg_port_id2_1, base::ASCIIToUTF16("test4"), empty_ids)));
+ EXPECT_EQ(1, renderer2->QueuedMessageCount());
+ CheckMessagePortMsgMessage(
+ renderer2->PopMessage(), msg_port_route2_2, "test4");
+
+ EXPECT_EQ(1U, g_worker_dependency_updates.size());
+ renderer2.reset();
+ EXPECT_EQ(2U, g_worker_dependency_updates.size());
+ EXPECT_EQ(0U, g_worker_dependency_updates[1].first.size());
+ EXPECT_EQ(1U, g_worker_dependency_updates[1].second.size());
+ EXPECT_EQ(200, g_worker_dependency_updates[1].second[0]);
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698