summaryrefslogtreecommitdiff
path: root/mojo/public/cpp/bindings/tests/pickle_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'mojo/public/cpp/bindings/tests/pickle_unittest.cc')
-rw-r--r--mojo/public/cpp/bindings/tests/pickle_unittest.cc403
1 files changed, 403 insertions, 0 deletions
diff --git a/mojo/public/cpp/bindings/tests/pickle_unittest.cc b/mojo/public/cpp/bindings/tests/pickle_unittest.cc
new file mode 100644
index 0000000000..a5947ce9ed
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/pickle_unittest.cc
@@ -0,0 +1,403 @@
+// Copyright 2015 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 <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "mojo/public/cpp/bindings/tests/pickled_types_blink.h"
+#include "mojo/public/cpp/bindings/tests/pickled_types_chromium.h"
+#include "mojo/public/cpp/bindings/tests/variant_test_util.h"
+#include "mojo/public/interfaces/bindings/tests/test_native_types.mojom-blink.h"
+#include "mojo/public/interfaces/bindings/tests/test_native_types.mojom.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace test {
+namespace {
+
+template <typename T>
+void DoExpectResult(int foo, int bar, const base::Closure& callback, T actual) {
+ EXPECT_EQ(foo, actual.foo());
+ EXPECT_EQ(bar, actual.bar());
+ callback.Run();
+}
+
+template <typename T>
+base::Callback<void(T)> ExpectResult(const T& t,
+ const base::Closure& callback) {
+ return base::Bind(&DoExpectResult<T>, t.foo(), t.bar(), callback);
+}
+
+template <typename T>
+void DoFail(const std::string& reason, T) {
+ EXPECT_TRUE(false) << reason;
+}
+
+template <typename T>
+base::Callback<void(T)> Fail(const std::string& reason) {
+ return base::Bind(&DoFail<T>, reason);
+}
+
+template <typename T>
+void DoExpectEnumResult(T expected, const base::Closure& callback, T actual) {
+ EXPECT_EQ(expected, actual);
+ callback.Run();
+}
+
+template <typename T>
+base::Callback<void(T)> ExpectEnumResult(T t, const base::Closure& callback) {
+ return base::Bind(&DoExpectEnumResult<T>, t, callback);
+}
+
+template <typename T>
+void DoEnumFail(const std::string& reason, T) {
+ EXPECT_TRUE(false) << reason;
+}
+
+template <typename T>
+base::Callback<void(T)> EnumFail(const std::string& reason) {
+ return base::Bind(&DoEnumFail<T>, reason);
+}
+
+template <typename T>
+void ExpectError(InterfacePtr<T>* proxy, const base::Closure& callback) {
+ proxy->set_connection_error_handler(callback);
+}
+
+template <typename Func, typename Arg>
+void RunSimpleLambda(Func func, Arg arg) { func(std::move(arg)); }
+
+template <typename Arg, typename Func>
+base::Callback<void(Arg)> BindSimpleLambda(Func func) {
+ return base::Bind(&RunSimpleLambda<Func, Arg>, func);
+}
+
+// This implements the generated Chromium variant of PicklePasser.
+class ChromiumPicklePasserImpl : public PicklePasser {
+ public:
+ ChromiumPicklePasserImpl() {}
+
+ // mojo::test::PicklePasser:
+ void PassPickledStruct(PickledStructChromium pickle,
+ const PassPickledStructCallback& callback) override {
+ callback.Run(std::move(pickle));
+ }
+
+ void PassPickledEnum(PickledEnumChromium pickle,
+ const PassPickledEnumCallback& callback) override {
+ callback.Run(pickle);
+ }
+
+ void PassPickleContainer(
+ PickleContainerPtr container,
+ const PassPickleContainerCallback& callback) override {
+ callback.Run(std::move(container));
+ }
+
+ void PassPickles(std::vector<PickledStructChromium> pickles,
+ const PassPicklesCallback& callback) override {
+ callback.Run(std::move(pickles));
+ }
+
+ void PassPickleArrays(
+ std::vector<std::vector<PickledStructChromium>> pickle_arrays,
+ const PassPickleArraysCallback& callback) override {
+ callback.Run(std::move(pickle_arrays));
+ }
+};
+
+// This implements the generated Blink variant of PicklePasser.
+class BlinkPicklePasserImpl : public blink::PicklePasser {
+ public:
+ BlinkPicklePasserImpl() {}
+
+ // mojo::test::blink::PicklePasser:
+ void PassPickledStruct(PickledStructBlink pickle,
+ const PassPickledStructCallback& callback) override {
+ callback.Run(std::move(pickle));
+ }
+
+ void PassPickledEnum(PickledEnumBlink pickle,
+ const PassPickledEnumCallback& callback) override {
+ callback.Run(pickle);
+ }
+
+ void PassPickleContainer(
+ blink::PickleContainerPtr container,
+ const PassPickleContainerCallback& callback) override {
+ callback.Run(std::move(container));
+ }
+
+ void PassPickles(WTF::Vector<PickledStructBlink> pickles,
+ const PassPicklesCallback& callback) override {
+ callback.Run(std::move(pickles));
+ }
+
+ void PassPickleArrays(
+ WTF::Vector<WTF::Vector<PickledStructBlink>> pickle_arrays,
+ const PassPickleArraysCallback& callback) override {
+ callback.Run(std::move(pickle_arrays));
+ }
+};
+
+// A test which runs both Chromium and Blink implementations of the
+// PicklePasser service.
+class PickleTest : public testing::Test {
+ public:
+ PickleTest() {}
+
+ template <typename ProxyType = PicklePasser>
+ InterfacePtr<ProxyType> ConnectToChromiumService() {
+ InterfacePtr<ProxyType> proxy;
+ InterfaceRequest<ProxyType> request(&proxy);
+ chromium_bindings_.AddBinding(
+ &chromium_service_,
+ ConvertInterfaceRequest<PicklePasser>(std::move(request)));
+ return proxy;
+ }
+
+ template <typename ProxyType = blink::PicklePasser>
+ InterfacePtr<ProxyType> ConnectToBlinkService() {
+ InterfacePtr<ProxyType> proxy;
+ InterfaceRequest<ProxyType> request(&proxy);
+ blink_bindings_.AddBinding(
+ &blink_service_,
+ ConvertInterfaceRequest<blink::PicklePasser>(std::move(request)));
+ return proxy;
+ }
+
+ private:
+ base::MessageLoop loop_;
+ ChromiumPicklePasserImpl chromium_service_;
+ BindingSet<PicklePasser> chromium_bindings_;
+ BlinkPicklePasserImpl blink_service_;
+ BindingSet<blink::PicklePasser> blink_bindings_;
+};
+
+} // namespace
+
+TEST_F(PickleTest, ChromiumProxyToChromiumService) {
+ auto chromium_proxy = ConnectToChromiumService();
+ {
+ base::RunLoop loop;
+ chromium_proxy->PassPickledStruct(
+ PickledStructChromium(1, 2),
+ ExpectResult(PickledStructChromium(1, 2), loop.QuitClosure()));
+ loop.Run();
+ }
+ {
+ base::RunLoop loop;
+ chromium_proxy->PassPickledStruct(
+ PickledStructChromium(4, 5),
+ ExpectResult(PickledStructChromium(4, 5), loop.QuitClosure()));
+ loop.Run();
+ }
+
+ {
+ base::RunLoop loop;
+ chromium_proxy->PassPickledEnum(
+ PickledEnumChromium::VALUE_1,
+ ExpectEnumResult(PickledEnumChromium::VALUE_1, loop.QuitClosure()));
+ loop.Run();
+ }
+}
+
+TEST_F(PickleTest, ChromiumProxyToBlinkService) {
+ auto chromium_proxy = ConnectToBlinkService<PicklePasser>();
+ {
+ base::RunLoop loop;
+ chromium_proxy->PassPickledStruct(
+ PickledStructChromium(1, 2),
+ ExpectResult(PickledStructChromium(1, 2), loop.QuitClosure()));
+ loop.Run();
+ }
+ {
+ base::RunLoop loop;
+ chromium_proxy->PassPickledStruct(
+ PickledStructChromium(4, 5),
+ ExpectResult(PickledStructChromium(4, 5), loop.QuitClosure()));
+ loop.Run();
+ }
+ // The Blink service should drop our connection because the
+ // PickledStructBlink ParamTraits deserializer rejects negative values.
+ {
+ base::RunLoop loop;
+ chromium_proxy->PassPickledStruct(
+ PickledStructChromium(-1, -1),
+ Fail<PickledStructChromium>("Blink service should reject this."));
+ ExpectError(&chromium_proxy, loop.QuitClosure());
+ loop.Run();
+ }
+
+ chromium_proxy = ConnectToBlinkService<PicklePasser>();
+ {
+ base::RunLoop loop;
+ chromium_proxy->PassPickledEnum(
+ PickledEnumChromium::VALUE_0,
+ ExpectEnumResult(PickledEnumChromium::VALUE_0, loop.QuitClosure()));
+ loop.Run();
+ }
+
+ // The Blink service should drop our connection because the
+ // PickledEnumBlink ParamTraits deserializer rejects this value.
+ {
+ base::RunLoop loop;
+ chromium_proxy->PassPickledEnum(
+ PickledEnumChromium::VALUE_2,
+ EnumFail<PickledEnumChromium>("Blink service should reject this."));
+ ExpectError(&chromium_proxy, loop.QuitClosure());
+ loop.Run();
+ }
+}
+
+TEST_F(PickleTest, BlinkProxyToBlinkService) {
+ auto blink_proxy = ConnectToBlinkService();
+ {
+ base::RunLoop loop;
+ blink_proxy->PassPickledStruct(
+ PickledStructBlink(1, 1),
+ ExpectResult(PickledStructBlink(1, 1), loop.QuitClosure()));
+ loop.Run();
+ }
+
+ {
+ base::RunLoop loop;
+ blink_proxy->PassPickledEnum(
+ PickledEnumBlink::VALUE_0,
+ ExpectEnumResult(PickledEnumBlink::VALUE_0, loop.QuitClosure()));
+ loop.Run();
+ }
+}
+
+TEST_F(PickleTest, BlinkProxyToChromiumService) {
+ auto blink_proxy = ConnectToChromiumService<blink::PicklePasser>();
+ {
+ base::RunLoop loop;
+ blink_proxy->PassPickledStruct(
+ PickledStructBlink(1, 1),
+ ExpectResult(PickledStructBlink(1, 1), loop.QuitClosure()));
+ loop.Run();
+ }
+
+ {
+ base::RunLoop loop;
+ blink_proxy->PassPickledEnum(
+ PickledEnumBlink::VALUE_1,
+ ExpectEnumResult(PickledEnumBlink::VALUE_1, loop.QuitClosure()));
+ loop.Run();
+ }
+}
+
+TEST_F(PickleTest, PickleArray) {
+ auto proxy = ConnectToChromiumService();
+ auto pickles = std::vector<PickledStructChromium>(2);
+ pickles[0].set_foo(1);
+ pickles[0].set_bar(2);
+ pickles[0].set_baz(100);
+ pickles[1].set_foo(3);
+ pickles[1].set_bar(4);
+ pickles[1].set_baz(100);
+ {
+ base::RunLoop run_loop;
+ // Verify that the array of pickled structs can be serialized and
+ // deserialized intact. This ensures that the ParamTraits are actually used
+ // rather than doing a byte-for-byte copy of the element data, beacuse the
+ // |baz| field should never be serialized.
+ proxy->PassPickles(std::move(pickles),
+ BindSimpleLambda<std::vector<PickledStructChromium>>(
+ [&](std::vector<PickledStructChromium> passed) {
+ ASSERT_EQ(2u, passed.size());
+ EXPECT_EQ(1, passed[0].foo());
+ EXPECT_EQ(2, passed[0].bar());
+ EXPECT_EQ(0, passed[0].baz());
+ EXPECT_EQ(3, passed[1].foo());
+ EXPECT_EQ(4, passed[1].bar());
+ EXPECT_EQ(0, passed[1].baz());
+ run_loop.Quit();
+ }));
+ run_loop.Run();
+ }
+}
+
+TEST_F(PickleTest, PickleArrayArray) {
+ auto proxy = ConnectToChromiumService();
+ auto pickle_arrays = std::vector<std::vector<PickledStructChromium>>(2);
+ for (size_t i = 0; i < 2; ++i)
+ pickle_arrays[i] = std::vector<PickledStructChromium>(2);
+
+ pickle_arrays[0][0].set_foo(1);
+ pickle_arrays[0][0].set_bar(2);
+ pickle_arrays[0][0].set_baz(100);
+ pickle_arrays[0][1].set_foo(3);
+ pickle_arrays[0][1].set_bar(4);
+ pickle_arrays[0][1].set_baz(100);
+ pickle_arrays[1][0].set_foo(5);
+ pickle_arrays[1][0].set_bar(6);
+ pickle_arrays[1][0].set_baz(100);
+ pickle_arrays[1][1].set_foo(7);
+ pickle_arrays[1][1].set_bar(8);
+ pickle_arrays[1][1].set_baz(100);
+ {
+ base::RunLoop run_loop;
+ // Verify that the array-of-arrays serializes and deserializes properly.
+ proxy->PassPickleArrays(
+ std::move(pickle_arrays),
+ BindSimpleLambda<std::vector<std::vector<PickledStructChromium>>>(
+ [&](std::vector<std::vector<PickledStructChromium>> passed) {
+ ASSERT_EQ(2u, passed.size());
+ ASSERT_EQ(2u, passed[0].size());
+ ASSERT_EQ(2u, passed[1].size());
+ EXPECT_EQ(1, passed[0][0].foo());
+ EXPECT_EQ(2, passed[0][0].bar());
+ EXPECT_EQ(0, passed[0][0].baz());
+ EXPECT_EQ(3, passed[0][1].foo());
+ EXPECT_EQ(4, passed[0][1].bar());
+ EXPECT_EQ(0, passed[0][1].baz());
+ EXPECT_EQ(5, passed[1][0].foo());
+ EXPECT_EQ(6, passed[1][0].bar());
+ EXPECT_EQ(0, passed[1][0].baz());
+ EXPECT_EQ(7, passed[1][1].foo());
+ EXPECT_EQ(8, passed[1][1].bar());
+ EXPECT_EQ(0, passed[1][1].baz());
+ run_loop.Quit();
+ }));
+ run_loop.Run();
+ }
+}
+
+TEST_F(PickleTest, PickleContainer) {
+ auto proxy = ConnectToChromiumService();
+ PickleContainerPtr pickle_container = PickleContainer::New();
+ pickle_container->f_struct.set_foo(42);
+ pickle_container->f_struct.set_bar(43);
+ pickle_container->f_struct.set_baz(44);
+ pickle_container->f_enum = PickledEnumChromium::VALUE_1;
+ EXPECT_TRUE(pickle_container.Equals(pickle_container));
+ EXPECT_FALSE(pickle_container.Equals(PickleContainer::New()));
+ {
+ base::RunLoop run_loop;
+ proxy->PassPickleContainer(std::move(pickle_container),
+ BindSimpleLambda<PickleContainerPtr>(
+ [&](PickleContainerPtr passed) {
+ ASSERT_FALSE(passed.is_null());
+ EXPECT_EQ(42, passed->f_struct.foo());
+ EXPECT_EQ(43, passed->f_struct.bar());
+ EXPECT_EQ(0, passed->f_struct.baz());
+ EXPECT_EQ(PickledEnumChromium::VALUE_1,
+ passed->f_enum);
+ run_loop.Quit();
+ }));
+ run_loop.Run();
+ }
+}
+
+} // namespace test
+} // namespace mojo