Skip to content

Commit

Permalink
Reland "[cast_bindings] Tests for MessagePort abstraction."
Browse files Browse the repository at this point in the history
This is a reland of 02cc2ed

Original change's description:
> [cast_bindings] Tests for MessagePort abstraction.
>
> Test coverage for public MessagePort interface and its interactions with
> MessagePort::Receiver. Includes conversion to and from the underlying
> platform type of MessagePortCast or MessagePortFuchsia.
>
> Bug: 1135377
> Test: //components/cast/message_port:message_port_test added
> Change-Id: I5e51aa5e08eb1e3e8957963b033497a94fe0bdac
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2515208
> Commit-Queue: Shawn Quereshi <shawnq@google.com>
> Reviewed-by: Kevin Marshall <kmarshall@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#824126}

Bug: 1135377
Change-Id: Ifb49217d8d10a0e2903f132661c138978fb97b71
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2521890
Commit-Queue: Kevin Marshall <kmarshall@chromium.org>
Reviewed-by: Kevin Marshall <kmarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824645}
  • Loading branch information
saqneo authored and Commit Bot committed Nov 5, 2020
1 parent bd979bb commit 95e7230
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 5 deletions.
4 changes: 4 additions & 0 deletions components/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ test("components_unittests") {
"//components/webcrypto:unit_tests",
]

if (!is_win) { # !iOS and !Windows
deps += [ "//components/cast:unit_tests" ]
}

if (!is_fuchsia) { # !iOS and !Fuchsia
deps += [
"//components/crash/content/browser:unit_tests",
Expand Down
5 changes: 5 additions & 0 deletions components/cast/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@
source_set("export") {
sources = [ "cast_component_export.h" ]
}

source_set("unit_tests") {
testonly = true
deps = [ "//components/cast/message_port:message_port_unittest" ]
}
16 changes: 14 additions & 2 deletions components/cast/message_port/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
# found in the LICENSE file.

import("//build/config/features.gni")
import("//testing/test.gni")

source_set("message_port") {
if (is_fuchsia) {
public_deps = [ ":message_port_fuchsia" ]
} else if (is_chromecast) {
} else {
public_deps = [ ":message_port_cast" ]
}
}
Expand Down Expand Up @@ -58,14 +59,25 @@ source_set("message_port_cast") {
]
}

source_set("message_port_unittest") {
testonly = true
sources = [ "message_port_unittest.cc" ]
deps = [
":message_port",
":test_message_port_receiver",
"//base/test:test_support",
"//testing/gtest",
]
}

source_set("test_message_port_receiver") {
testonly = true
sources = [
"test_message_port_receiver.cc",
"test_message_port_receiver.h",
]
deps = [
":message_port",
":public",
"//base",
]
}
2 changes: 1 addition & 1 deletion components/cast/message_port/DEPS
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
include_rules = [
"+third_party/blink/public/common/messaging",
"+fuchsia",
"+third_party/blink/public/common/messaging",
]
1 change: 0 additions & 1 deletion components/cast/message_port/message_port_cast.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ blink::WebMessagePort MessagePortCast::TakePort() {
return std::move(port_);
}

// cast_api_bindings::MessagePortCast implementation
bool MessagePortCast::PostMessage(base::StringPiece message) {
return PostMessageWithTransferables(message, {});
}
Expand Down
176 changes: 176 additions & 0 deletions components/cast/message_port/message_port_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
// Copyright 2020 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 "components/cast/message_port/message_port.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "components/cast/message_port/test_message_port_receiver.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_FUCHSIA)
#include "components/cast/message_port/message_port_fuchsia.h"
#include "fuchsia/fidl/chromium/cast/cpp/fidl.h"
#else
#include "components/cast/message_port/message_port_cast.h" // nogncheck
#include "third_party/blink/public/common/messaging/web_message_port.h" // nogncheck
#endif // defined(OS_FUCHSIA)

#ifdef PostMessage
#undef PostMessage
#endif

namespace cast_api_bindings {

class MessagePortTest : public ::testing::Test {
public:
MessagePortTest()
: task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {
MessagePort::CreatePair(&client_, &server_);
}

~MessagePortTest() override = default;

void SetDefaultReceivers() {
client_->SetReceiver(&client_receiver_);
server_->SetReceiver(&server_receiver_);
}

// Posts multiple |messages| from |sender| to |receiver| and validates their
// arrival order
void PostMessages(const std::vector<std::string>& messages,
MessagePort* sender,
TestMessagePortReceiver* receiver) {
for (const auto& message : messages) {
sender->PostMessage(message);
}

EXPECT_TRUE(receiver->RunUntilMessageCountEqual(messages.size()));
for (size_t i = 0; i < messages.size(); i++) {
EXPECT_EQ(receiver->buffer()[i].first, messages[i]);
}
}

// Posts a |port| from |sender| to |receiver| and validates its arrival.
// Returns the transferred |port|.
std::unique_ptr<MessagePort> PostMessageWithTransferables(
std::unique_ptr<MessagePort> port,
MessagePort* sender,
TestMessagePortReceiver* receiver) {
std::vector<std::unique_ptr<MessagePort>> ports;
ports.emplace_back(std::move(port));
sender->PostMessageWithTransferables("", std::move(ports));
EXPECT_TRUE(receiver->RunUntilMessageCountEqual(1));
EXPECT_EQ(receiver->buffer()[0].second.size(), (size_t)1);
return std::move(receiver->buffer()[0].second[0]);
}

void TestPostMessage() {
SetDefaultReceivers();
PostMessages({"from client"}, client_.get(), &server_receiver_);
PostMessages({"from server"}, server_.get(), &client_receiver_);
}

protected:
std::unique_ptr<MessagePort> client_;
std::unique_ptr<MessagePort> server_;
TestMessagePortReceiver client_receiver_;
TestMessagePortReceiver server_receiver_;

private:
const base::test::TaskEnvironment task_environment_;
};

TEST_F(MessagePortTest, Close) {
SetDefaultReceivers();
ASSERT_TRUE(client_->CanPostMessage());
ASSERT_TRUE(server_->CanPostMessage());

server_->Close();
client_receiver_.RunUntilDisconnected();
ASSERT_FALSE(client_->CanPostMessage());
ASSERT_FALSE(server_->CanPostMessage());
}

TEST_F(MessagePortTest, OnError) {
server_receiver_.SetOnMessageResult(false);
SetDefaultReceivers();
client_->PostMessage("");

#if defined(OS_FUCHSIA)
// blink::WebMessagePort reports failure when PostMessage returns false, but
// fuchsia::web::MessagePort will not report the error until the port closes
server_receiver_.RunUntilMessageCountEqual(1);
server_.reset();
#endif

client_receiver_.RunUntilDisconnected();
}

TEST_F(MessagePortTest, PostMessage) {
TestPostMessage();
}

TEST_F(MessagePortTest, PostMessageMultiple) {
SetDefaultReceivers();
PostMessages({"c1", "c2", "c3"}, client_.get(), &server_receiver_);
PostMessages({"s1", "s2", "s3"}, server_.get(), &client_receiver_);
}

TEST_F(MessagePortTest, PostMessageWithTransferables) {
std::unique_ptr<MessagePort> port0;
std::unique_ptr<MessagePort> port1;
TestMessagePortReceiver port0_receiver;
TestMessagePortReceiver port1_receiver;
MessagePort::CreatePair(&port0, &port1);

// If the ports are represented by multiple types as in the case of
// MessagePortFuchsia, make sure both are transferrable
SetDefaultReceivers();
port0 = PostMessageWithTransferables(std::move(port0), client_.get(),
&server_receiver_);
port1 = PostMessageWithTransferables(std::move(port1), server_.get(),
&client_receiver_);

// Make sure the ports are still usable
port0->SetReceiver(&port0_receiver);
port1->SetReceiver(&port1_receiver);
PostMessages({"from port0"}, port0.get(), &port1_receiver);
PostMessages({"from port1"}, port1.get(), &port0_receiver);
}

TEST_F(MessagePortTest, WrapPlatformPort) {
// Initialize ports from the platform type instead of agnostic CreatePair
#if defined(OS_FUCHSIA)
fidl::InterfaceHandle<fuchsia::web::MessagePort> port0;
fidl::InterfaceRequest<fuchsia::web::MessagePort> port1 = port0.NewRequest();
client_ = MessagePortFuchsia::Create(std::move(port0));
server_ = MessagePortFuchsia::Create(std::move(port1));
#else
auto pair = blink::WebMessagePort::CreatePair();
client_ = MessagePortCast::Create(std::move(pair.first));
server_ = MessagePortCast::Create(std::move(pair.second));
#endif // defined(OS_FUCHSIA)

TestPostMessage();
}

TEST_F(MessagePortTest, UnwrapPlatformPortCast) {
// Test unwrapping via TakePort (rewrapped for test methods)
#if defined(OS_FUCHSIA)
client_ = MessagePortFuchsia::Create(
MessagePortFuchsia::FromMessagePort(client_.get())->TakeClientHandle());
server_ = MessagePortFuchsia::Create(
MessagePortFuchsia::FromMessagePort(server_.get())->TakeServiceRequest());
#else
client_ = MessagePortCast::Create(
MessagePortCast::FromMessagePort(client_.get())->TakePort());
server_ = MessagePortCast::Create(
MessagePortCast::FromMessagePort(server_.get())->TakePort());
#endif // defined(OS_FUCHSIA)

TestPostMessage();
}

} // namespace cast_api_bindings
6 changes: 5 additions & 1 deletion components/cast/message_port/test_message_port_receiver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ TestMessagePortReceiver::TestMessagePortReceiver() = default;

TestMessagePortReceiver::~TestMessagePortReceiver() = default;

void TestMessagePortReceiver::SetOnMessageResult(bool result) {
on_message_result_ = result;
}

bool TestMessagePortReceiver::RunUntilMessageCountEqual(size_t message_count) {
base::RunLoop run_loop;
on_receive_satisfied_ = run_loop.QuitClosure();
Expand All @@ -34,7 +38,7 @@ bool TestMessagePortReceiver::OnMessage(
DCHECK(on_receive_satisfied_);
std::move(on_receive_satisfied_).Run();
}
return true;
return on_message_result_;
}

void TestMessagePortReceiver::OnPipeError() {
Expand Down
4 changes: 4 additions & 0 deletions components/cast/message_port/test_message_port_receiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class TestMessagePortReceiver
// Spins a RunLoop until the associated MessagePort is disconnected.
void RunUntilDisconnected();

// Sets the return value of OnMessage
void SetOnMessageResult(bool result);

std::vector<
std::pair<std::string, std::vector<std::unique_ptr<MessagePort>>>>&
buffer() {
Expand All @@ -46,6 +49,7 @@ class TestMessagePortReceiver
size_t message_count_target_ = 0;
base::OnceClosure on_receive_satisfied_;
base::OnceClosure on_disconnect_;
bool on_message_result_ = true;
};

} // namespace cast_api_bindings
Expand Down

0 comments on commit 95e7230

Please sign in to comment.