1 // Copyright 2017 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.
4
5 #include <stdint.h>
6
7 #include <vector>
8
9 #include "base/bind.h"
10 #include "base/macros.h"
11 #include "base/run_loop.h"
12 #include "base/test/scoped_task_environment.h"
13 #include "ipc/ipc_param_traits.h"
14 #include "mojo/public/cpp/bindings/binding.h"
15 #include "mojo/public/cpp/bindings/tests/bindings_test_base.h"
16 #include "mojo/public/cpp/system/message_pipe.h"
17 #include "mojo/public/cpp/system/wait.h"
18 #include "mojo/public/interfaces/bindings/tests/test_native_types.mojom.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace mojo {
22
23 class NativeStructTest : public BindingsTestBase,
24 public test::NativeTypeTester {
25 public:
NativeStructTest()26 NativeStructTest() : binding_(this, mojo::MakeRequest(&proxy_)) {}
27 ~NativeStructTest() override = default;
28
proxy()29 test::NativeTypeTester* proxy() { return proxy_.get(); }
30
31 private:
32 // test::NativeTypeTester:
PassNativeStruct(const test::TestNativeStruct & s,const PassNativeStructCallback & callback)33 void PassNativeStruct(const test::TestNativeStruct& s,
34 const PassNativeStructCallback& callback) override {
35 callback.Run(s);
36 }
37
PassNativeStructWithAttachments(test::TestNativeStructWithAttachments s,const PassNativeStructWithAttachmentsCallback & callback)38 void PassNativeStructWithAttachments(
39 test::TestNativeStructWithAttachments s,
40 const PassNativeStructWithAttachmentsCallback& callback) override {
41 callback.Run(std::move(s));
42 }
43
44 test::NativeTypeTesterPtr proxy_;
45 Binding<test::NativeTypeTester> binding_;
46
47 DISALLOW_COPY_AND_ASSIGN(NativeStructTest);
48 };
49
TEST_P(NativeStructTest,NativeStruct)50 TEST_P(NativeStructTest, NativeStruct) {
51 test::TestNativeStruct s("hello world", 5, 42);
52 base::RunLoop loop;
53 proxy()->PassNativeStruct(
54 s, base::Bind(
55 [](test::TestNativeStruct* expected_struct, base::RunLoop* loop,
56 const test::TestNativeStruct& passed) {
57 EXPECT_EQ(expected_struct->message(), passed.message());
58 EXPECT_EQ(expected_struct->x(), passed.x());
59 EXPECT_EQ(expected_struct->y(), passed.y());
60 loop->Quit();
61 },
62 &s, &loop));
63 loop.Run();
64 }
65
TEST_P(NativeStructTest,NativeStructWithAttachments)66 TEST_P(NativeStructTest, NativeStructWithAttachments) {
67 mojo::MessagePipe pipe;
68 const std::string kTestMessage = "hey hi";
69 test::TestNativeStructWithAttachments s(kTestMessage,
70 std::move(pipe.handle0));
71 base::RunLoop loop;
72 proxy()->PassNativeStructWithAttachments(
73 std::move(s),
74 base::Bind(
75 [](const std::string& expected_message,
76 mojo::ScopedMessagePipeHandle peer_pipe, base::RunLoop* loop,
77 test::TestNativeStructWithAttachments passed) {
78 // To ensure that the received pipe handle is functioning, we write
79 // to its peer and wait for the message to be received.
80 WriteMessageRaw(peer_pipe.get(), "ping", 4, nullptr, 0,
81 MOJO_WRITE_MESSAGE_FLAG_NONE);
82 auto pipe = passed.PassPipe();
83 EXPECT_EQ(MOJO_RESULT_OK,
84 Wait(pipe.get(), MOJO_HANDLE_SIGNAL_READABLE));
85 std::vector<uint8_t> bytes;
86 EXPECT_EQ(MOJO_RESULT_OK,
87 ReadMessageRaw(pipe.get(), &bytes, nullptr,
88 MOJO_READ_MESSAGE_FLAG_NONE));
89 EXPECT_EQ("ping", std::string(bytes.begin(), bytes.end()));
90 loop->Quit();
91 },
92 kTestMessage, base::Passed(&pipe.handle1), &loop));
93 loop.Run();
94 }
95
96 INSTANTIATE_MOJO_BINDINGS_TEST_CASE_P(NativeStructTest);
97
98 } // namespace mojo
99