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

Unified Diff: remoting/protocol/data_channel_manager_unittest.cc

Issue 2907073003: [Chromoting] Add DataChannelManager to manage optional incoming data channels (Closed)
Patch Set: Resolve review comments Created 3 years, 6 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: remoting/protocol/data_channel_manager_unittest.cc
diff --git a/remoting/protocol/data_channel_manager_unittest.cc b/remoting/protocol/data_channel_manager_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..196bbe5b300d8217586723d5fe9484e51e44391d
--- /dev/null
+++ b/remoting/protocol/data_channel_manager_unittest.cc
@@ -0,0 +1,274 @@
+// Copyright 2017 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 "remoting/protocol/data_channel_manager.h"
+
+#include <map>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "remoting/base/compound_buffer.h"
+#include "remoting/proto/test.pb.h"
+#include "remoting/protocol/data_channel_handler.h"
+#include "remoting/protocol/fake_message_pipe.h"
+#include "remoting/protocol/fake_message_pipe_wrapper.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace remoting {
+namespace protocol {
+
+namespace {
+
+class FakeDataChannelHandler final : public DataChannelHandler {
+ public:
+ FakeDataChannelHandler(const std::string& name,
+ std::unique_ptr<MessagePipe> pipe,
+ const std::string& expected_data)
+ : DataChannelHandler(name, std::move(pipe)),
+ expected_data_(expected_data) {
+ handlers_[name] = this;
+ }
+
+ int received_message_count() const { return received_message_count_; }
+
+ static FakeDataChannelHandler* Find(const std::string& name);
+
+ static int instance_count() { return handlers_.size(); }
+
+ // DataChannelHandler implementation.
+ void OnIncomingMessage(std::unique_ptr<CompoundBuffer> message) override;
+
+ // Public functions for test cases.
+ void Close() { DataChannelHandler::Close(); }
+
+ bool closing() const { return DataChannelHandler::closing(); }
+
+ bool Send(google::protobuf::MessageLite* message,
+ const base::Closure& done);
+
+ protected:
+ ~FakeDataChannelHandler() override {
+ EXPECT_EQ(handlers_.erase(pipe_name()), 1U);
+ }
+
+ private:
+ static std::map<std::string, FakeDataChannelHandler*> handlers_;
+
+ const std::string expected_data_;
+ int received_message_count_ = 0;
+};
+
+void FakeDataChannelHandler::OnIncomingMessage(
+ std::unique_ptr<CompoundBuffer> message) {
+ ASSERT_TRUE(message != nullptr);
+ std::string content;
+ content.resize(expected_data_.size());
+ message->CopyTo(&(content[0]), content.size());
+ ASSERT_EQ(content, expected_data_);
+ received_message_count_++;
+}
+
+// static
+FakeDataChannelHandler* FakeDataChannelHandler::Find(const std::string& name) {
+ auto it = handlers_.find(name);
+ if (it == handlers_.end()) {
+ return nullptr;
+ }
+ return it->second;
+}
+
+bool FakeDataChannelHandler::Send(google::protobuf::MessageLite* message,
+ const base::Closure& done) {
+ return DataChannelHandler::Send(message, done);
+}
+
+// static
+std::map<std::string, FakeDataChannelHandler*>
+FakeDataChannelHandler::handlers_;
+
+void TestDataChannelManagerFullMatch(bool asynchronous) {
+ base::MessageLoop message_loop;
+ DataChannelManager manager;
+ ASSERT_TRUE(manager.RegisterCreateHandlerCallback("FullMatch", base::Bind(
+ [](const std::string& expected_data,
+ const std::string& name,
+ std::unique_ptr<MessagePipe> pipe) -> void {
+ new FakeDataChannelHandler(name, std::move(pipe), expected_data);
+ },
+ "FullMatchContent")));
+ ASSERT_TRUE(manager.RegisterCreateHandlerCallback("AnotherFullMatch", base::Bind(
+ [](const std::string& expected_data,
+ const std::string& name,
+ std::unique_ptr<MessagePipe> pipe) -> void {
+ new FakeDataChannelHandler(name, std::move(pipe), expected_data);
+ },
+ "AnotherFullMatchContent")));
+
+ FakeMessagePipe pipe1(asynchronous);
+ FakeMessagePipe pipe2(asynchronous);
+ ASSERT_TRUE(manager.OnIncomingDataChannel("FullMatch", pipe1.Wrap()));
+ ASSERT_TRUE(manager.OnIncomingDataChannel("AnotherFullMatch", pipe2.Wrap()));
+ base::RunLoop().RunUntilIdle();
+
+ FakeDataChannelHandler* handler1 = FakeDataChannelHandler::Find("FullMatch");
+ FakeDataChannelHandler* handler2 =
+ FakeDataChannelHandler::Find("AnotherFullMatch");
+ ASSERT_TRUE(handler1 != nullptr);
+ ASSERT_TRUE(handler2 != nullptr);
+
+ pipe1.OpenPipe();
+ base::RunLoop().RunUntilIdle();
+ {
+ DataChannelManagerTestProto message;
+ int sent = 0;
+ base::Closure sent_callback = base::Bind([](int* sent) {
+ (*sent)++;
+ },
+ base::Unretained(&sent));
+ ASSERT_TRUE(handler1->Send(&message, sent_callback));
+ ASSERT_FALSE(handler2->Send(&message, sent_callback));
+
+ base::RunLoop().RunUntilIdle();
+ ASSERT_EQ(sent, 1);
+ }
+
+ pipe2.OpenPipe();
+ base::RunLoop().RunUntilIdle();
+ {
+ DataChannelManagerTestProto message;
+ int sent = 0;
+ base::Closure sent_callback = base::Bind([](int* sent) {
+ (*sent)++;
+ },
+ base::Unretained(&sent));
+ ASSERT_TRUE(handler1->Send(&message, sent_callback));
+ ASSERT_TRUE(handler2->Send(&message, sent_callback));
+
+ base::RunLoop().RunUntilIdle();
+ ASSERT_EQ(sent, 2);
+ }
+
+ {
+ std::string content;
+ auto message = base::MakeUnique<CompoundBuffer>();
+ content = "FullMatchContent";
+ message->AppendCopyOf(&(content[0]), content.size());
+ pipe1.Receive(std::move(message));
+
+ message = base::MakeUnique<CompoundBuffer>();
+ content = "AnotherFullMatchContent";
+ message->AppendCopyOf(&(content[0]), content.size());
+ pipe2.Receive(std::move(message));
+
+ base::RunLoop().RunUntilIdle();
+ ASSERT_EQ(handler1->received_message_count(), 1);
+ ASSERT_EQ(handler2->received_message_count(), 1);
+ }
+
+ pipe2.ClosePipe();
+ if (!asynchronous) {
+ ASSERT_TRUE(handler2->closing());
+ }
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(FakeDataChannelHandler::Find("AnotherFullMatch") == nullptr);
+
+ handler1->Close();
+ ASSERT_TRUE(handler1->closing());
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(FakeDataChannelHandler::Find("FullMatch") == nullptr);
+
+ ASSERT_EQ(FakeDataChannelHandler::instance_count(), 0);
+}
+
+void TestDataChannelManagerMultipleRegistrations(bool asynchronous) {
+ base::MessageLoop message_loop;
+ DataChannelManager manager;
+ ASSERT_TRUE(manager.RegisterCreateHandlerCallback("FullMatch", base::Bind(
+ [](const std::string& expected_data,
+ const std::string& name,
+ std::unique_ptr<MessagePipe> pipe) -> void {
+ new FakeDataChannelHandler(name, std::move(pipe), expected_data);
+ },
+ "FullMatchContent")));
+ ASSERT_TRUE(manager.RegisterCreateHandlerCallback("Prefix-", base::Bind(
+ [](const std::string& expected_data,
+ const std::string& name,
+ std::unique_ptr<MessagePipe> pipe) -> void {
+ new FakeDataChannelHandler(name, std::move(pipe), expected_data);
+ },
+ "PrefixMatchContent")));
+
+ FakeMessagePipe pipe1(asynchronous);
+ FakeMessagePipe pipe2(asynchronous);
+ FakeMessagePipe pipe3(asynchronous);
+ FakeMessagePipe pipe4(asynchronous);
+ ASSERT_TRUE(manager.OnIncomingDataChannel("Prefix-1", pipe1.Wrap()));
+ ASSERT_TRUE(manager.OnIncomingDataChannel("Prefix-2", pipe2.Wrap()));
+ ASSERT_FALSE(manager.OnIncomingDataChannel(
+ "PrefixShouldNotMatch", pipe3.Wrap()));
+ ASSERT_TRUE(manager.OnIncomingDataChannel("FullMatch", pipe4.Wrap()));
+ base::RunLoop().RunUntilIdle();
+
+ FakeDataChannelHandler* handler1 = FakeDataChannelHandler::Find("Prefix-1");
+ FakeDataChannelHandler* handler2 = FakeDataChannelHandler::Find("Prefix-2");
+ FakeDataChannelHandler* handler3 =
+ FakeDataChannelHandler::Find("PrefixShouldNotMatch");
+ FakeDataChannelHandler* handler4 = FakeDataChannelHandler::Find("FullMatch");
+ ASSERT_TRUE(handler1 != nullptr);
+ ASSERT_TRUE(handler2 != nullptr);
+ ASSERT_TRUE(handler3 == nullptr);
+ ASSERT_TRUE(handler4 != nullptr);
+
+ handler1->Close();
+ handler2->Close();
+ handler4->Close();
+ base::RunLoop().RunUntilIdle();
+}
+
+} // namespace
+
+TEST(DataChannelManagerTest, FullMatchWithSynchronousPipe) {
+ TestDataChannelManagerFullMatch(false);
+}
+
+TEST(DataChannelManagerTest, FullMatchWithAsynchronousPipe) {
+ TestDataChannelManagerFullMatch(true);
+}
+
+TEST(DataChannelManagerTest, MultipleRegistrationsWithSynchronousPipe) {
+ TestDataChannelManagerMultipleRegistrations(false);
+}
+
+TEST(DataChannelManagerTest, MultipleRegistrationsWithAsynchronousPipe) {
+ TestDataChannelManagerMultipleRegistrations(true);
+}
+
+#if DCHECK_IS_ON()
+TEST(DataChannelManagerTest, MultipleMatchesIsNotAllowed) {
+ DataChannelManager manager;
+ ASSERT_TRUE(manager.RegisterCreateHandlerCallback("Pipe", base::Bind(
+ [](const std::string& expected_data,
+ const std::string& name,
+ std::unique_ptr<MessagePipe> pipe) -> void {
+ new FakeDataChannelHandler(name, std::move(pipe), expected_data);
+ },
+ "")));
+ ASSERT_TRUE(manager.RegisterCreateHandlerCallback("Pipe-", base::Bind(
+ [](const std::string& expected_data,
+ const std::string& name,
+ std::unique_ptr<MessagePipe> pipe) -> void {
+ new FakeDataChannelHandler(name, std::move(pipe), expected_data);
+ },
+ "")));
+ FakeMessagePipe pipe(false);
+ ASSERT_DEATH_IF_SUPPORTED(
+ manager.OnIncomingDataChannel("Pipe-1", pipe.Wrap()), "!matched");
+}
+#endif
+
+} // namespace protocol
+} // namespace remoting

Powered by Google App Engine
This is Rietveld 408576698