• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/core/ext/transport/binder/wire_format/wire_writer.h"
16 
17 #include <string>
18 #include <utility>
19 
20 #include <gtest/gtest.h>
21 
22 #include "absl/memory/memory.h"
23 
24 #include <grpcpp/impl/grpc_library.h>
25 
26 #include "test/core/transport/binder/mock_objects.h"
27 #include "test/core/util/test_config.h"
28 
29 namespace grpc_binder {
30 
31 using ::testing::Return;
32 
33 MATCHER_P(StrEqInt8Ptr, target, "") {
34   return std::string(reinterpret_cast<const char*>(arg), target.size()) ==
35          target;
36 }
37 
TEST(WireWriterTest,RpcCall)38 TEST(WireWriterTest, RpcCall) {
39   grpc::internal::GrpcLibrary init_lib;
40   // Required because wire writer uses combiner internally.
41   grpc_core::ExecCtx exec_ctx;
42   auto mock_binder = std::make_unique<MockBinder>();
43   MockBinder& mock_binder_ref = *mock_binder;
44   MockWritableParcel mock_writable_parcel;
45   ON_CALL(mock_binder_ref, GetWritableParcel)
46       .WillByDefault(Return(&mock_writable_parcel));
47   WireWriterImpl wire_writer(std::move(mock_binder));
48 
49   auto ExpectWriteByteArray = [&](const std::string& target) {
50     // length
51     EXPECT_CALL(mock_writable_parcel, WriteInt32(target.size()));
52     if (!target.empty()) {
53       // content
54       EXPECT_CALL(mock_writable_parcel,
55                   WriteByteArray(StrEqInt8Ptr(target), target.size()));
56     }
57   };
58 
59   ::testing::InSequence sequence;
60   int sequence_number = 0;
61 
62   {
63     // flag
64     EXPECT_CALL(mock_writable_parcel, WriteInt32(0));
65     // sequence number
66     EXPECT_CALL(mock_writable_parcel, WriteInt32(sequence_number));
67 
68     EXPECT_CALL(mock_binder_ref, Transact(BinderTransportTxCode(kFirstCallId)));
69 
70     auto tx = std::make_unique<Transaction>(kFirstCallId, /*is_client=*/true);
71     EXPECT_TRUE(wire_writer.RpcCall(std::move(tx)).ok());
72     sequence_number++;
73     grpc_core::ExecCtx::Get()->Flush();
74   }
75   {
76     // flag
77     EXPECT_CALL(mock_writable_parcel, WriteInt32(kFlagPrefix));
78     // sequence number. This is another stream so the sequence number starts
79     // with 0.
80     EXPECT_CALL(mock_writable_parcel, WriteInt32(0));
81 
82     EXPECT_CALL(mock_writable_parcel,
83                 WriteString(absl::string_view("/example/method/ref")));
84 
85     const std::vector<std::pair<std::string, std::string>> kMetadata = {
86         {"", ""},
87         {"", "value"},
88         {"key", ""},
89         {"key", "value"},
90         {"another-key", "another-value"},
91     };
92 
93     // Number of metadata
94     EXPECT_CALL(mock_writable_parcel, WriteInt32(kMetadata.size()));
95 
96     for (const auto& md : kMetadata) {
97       ExpectWriteByteArray(md.first);
98       ExpectWriteByteArray(md.second);
99     }
100 
101     EXPECT_CALL(mock_binder_ref,
102                 Transact(BinderTransportTxCode(kFirstCallId + 1)));
103 
104     auto tx =
105         std::make_unique<Transaction>(kFirstCallId + 1, /*is_client=*/true);
106     tx->SetPrefix(kMetadata);
107     tx->SetMethodRef("/example/method/ref");
108     EXPECT_TRUE(wire_writer.RpcCall(std::move(tx)).ok());
109     grpc_core::ExecCtx::Get()->Flush();
110   }
111   {
112     // flag
113     EXPECT_CALL(mock_writable_parcel, WriteInt32(kFlagMessageData));
114     // sequence number
115     EXPECT_CALL(mock_writable_parcel, WriteInt32(sequence_number));
116 
117     ExpectWriteByteArray("data");
118     EXPECT_CALL(mock_binder_ref, Transact(BinderTransportTxCode(kFirstCallId)));
119 
120     auto tx = std::make_unique<Transaction>(kFirstCallId, /*is_client=*/true);
121     tx->SetData("data");
122     EXPECT_TRUE(wire_writer.RpcCall(std::move(tx)).ok());
123     sequence_number++;
124     grpc_core::ExecCtx::Get()->Flush();
125   }
126   {
127     // flag
128     EXPECT_CALL(mock_writable_parcel, WriteInt32(kFlagSuffix));
129     // sequence number
130     EXPECT_CALL(mock_writable_parcel, WriteInt32(sequence_number));
131 
132     EXPECT_CALL(mock_binder_ref, Transact(BinderTransportTxCode(kFirstCallId)));
133 
134     auto tx = std::make_unique<Transaction>(kFirstCallId, /*is_client=*/true);
135     tx->SetSuffix({});
136     EXPECT_TRUE(wire_writer.RpcCall(std::move(tx)).ok());
137     sequence_number++;
138     grpc_core::ExecCtx::Get()->Flush();
139   }
140   {
141     // flag
142     EXPECT_CALL(mock_writable_parcel,
143                 WriteInt32(kFlagPrefix | kFlagMessageData | kFlagSuffix));
144     // sequence number
145     EXPECT_CALL(mock_writable_parcel, WriteInt32(sequence_number));
146 
147     EXPECT_CALL(mock_writable_parcel,
148                 WriteString(absl::string_view("/example/method/ref")));
149 
150     const std::vector<std::pair<std::string, std::string>> kMetadata = {
151         {"", ""},
152         {"", "value"},
153         {"key", ""},
154         {"key", "value"},
155         {"another-key", "another-value"},
156     };
157 
158     // Number of metadata
159     EXPECT_CALL(mock_writable_parcel, WriteInt32(kMetadata.size()));
160 
161     for (const auto& md : kMetadata) {
162       ExpectWriteByteArray(md.first);
163       ExpectWriteByteArray(md.second);
164     }
165 
166     // Empty message data
167     ExpectWriteByteArray("");
168 
169     EXPECT_CALL(mock_binder_ref, Transact(BinderTransportTxCode(kFirstCallId)));
170 
171     auto tx = std::make_unique<Transaction>(kFirstCallId, /*is_client=*/true);
172     // TODO(waynetu): Implement a helper function that automatically creates
173     // EXPECT_CALL based on the tx object.
174     tx->SetPrefix(kMetadata);
175     tx->SetMethodRef("/example/method/ref");
176     tx->SetData("");
177     tx->SetSuffix({});
178     EXPECT_TRUE(wire_writer.RpcCall(std::move(tx)).ok());
179     sequence_number++;
180     grpc_core::ExecCtx::Get()->Flush();
181   }
182 
183   // Really large message
184   {
185     EXPECT_CALL(mock_writable_parcel,
186                 WriteInt32(kFlagMessageData | kFlagMessageDataIsPartial));
187     EXPECT_CALL(mock_writable_parcel, WriteInt32(0));
188     ExpectWriteByteArray(std::string(WireWriterImpl::kBlockSize, 'a'));
189     EXPECT_CALL(mock_writable_parcel, GetDataSize)
190         .WillOnce(Return(WireWriterImpl::kBlockSize));
191     EXPECT_CALL(mock_binder_ref,
192                 Transact(BinderTransportTxCode(kFirstCallId + 2)));
193 
194     EXPECT_CALL(mock_writable_parcel,
195                 WriteInt32(kFlagMessageData | kFlagMessageDataIsPartial));
196     EXPECT_CALL(mock_writable_parcel, WriteInt32(1));
197     ExpectWriteByteArray(std::string(WireWriterImpl::kBlockSize, 'a'));
198     EXPECT_CALL(mock_writable_parcel, GetDataSize)
199         .WillOnce(Return(WireWriterImpl::kBlockSize));
200     EXPECT_CALL(mock_binder_ref,
201                 Transact(BinderTransportTxCode(kFirstCallId + 2)));
202 
203     EXPECT_CALL(mock_writable_parcel, WriteInt32(kFlagMessageData));
204     EXPECT_CALL(mock_writable_parcel, WriteInt32(2));
205     ExpectWriteByteArray("a");
206     EXPECT_CALL(mock_writable_parcel, GetDataSize).WillOnce(Return(1));
207     EXPECT_CALL(mock_binder_ref,
208                 Transact(BinderTransportTxCode(kFirstCallId + 2)));
209 
210     // Use a new stream.
211     auto tx =
212         std::make_unique<Transaction>(kFirstCallId + 2, /*is_client=*/true);
213     tx->SetData(std::string(2 * WireWriterImpl::kBlockSize + 1, 'a'));
214     EXPECT_TRUE(wire_writer.RpcCall(std::move(tx)).ok());
215     grpc_core::ExecCtx::Get()->Flush();
216   }
217   // Really large message with metadata
218   {
219     EXPECT_CALL(
220         mock_writable_parcel,
221         WriteInt32(kFlagPrefix | kFlagMessageData | kFlagMessageDataIsPartial));
222     EXPECT_CALL(mock_writable_parcel, WriteInt32(0));
223     EXPECT_CALL(mock_writable_parcel, WriteString(absl::string_view("123")));
224     EXPECT_CALL(mock_writable_parcel, WriteInt32(0));
225     ExpectWriteByteArray(std::string(WireWriterImpl::kBlockSize, 'a'));
226     EXPECT_CALL(mock_writable_parcel, GetDataSize)
227         .WillOnce(Return(WireWriterImpl::kBlockSize));
228     EXPECT_CALL(mock_binder_ref,
229                 Transact(BinderTransportTxCode(kFirstCallId + 3)));
230 
231     EXPECT_CALL(mock_writable_parcel,
232                 WriteInt32(kFlagMessageData | kFlagMessageDataIsPartial));
233     EXPECT_CALL(mock_writable_parcel, WriteInt32(1));
234     ExpectWriteByteArray(std::string(WireWriterImpl::kBlockSize, 'a'));
235     EXPECT_CALL(mock_writable_parcel, GetDataSize)
236         .WillOnce(Return(WireWriterImpl::kBlockSize));
237     EXPECT_CALL(mock_binder_ref,
238                 Transact(BinderTransportTxCode(kFirstCallId + 3)));
239 
240     EXPECT_CALL(mock_writable_parcel,
241                 WriteInt32(kFlagMessageData | kFlagSuffix));
242     EXPECT_CALL(mock_writable_parcel, WriteInt32(2));
243     ExpectWriteByteArray("a");
244     EXPECT_CALL(mock_writable_parcel, GetDataSize).WillOnce(Return(1));
245     EXPECT_CALL(mock_binder_ref,
246                 Transact(BinderTransportTxCode(kFirstCallId + 3)));
247 
248     // Use a new stream.
249     auto tx =
250         std::make_unique<Transaction>(kFirstCallId + 3, /*is_client=*/true);
251     tx->SetPrefix({});
252     tx->SetMethodRef("123");
253     tx->SetData(std::string(2 * WireWriterImpl::kBlockSize + 1, 'a'));
254     tx->SetSuffix({});
255     EXPECT_TRUE(wire_writer.RpcCall(std::move(tx)).ok());
256     grpc_core::ExecCtx::Get()->Flush();
257   }
258   grpc_core::ExecCtx::Get()->Flush();
259 }
260 
261 }  // namespace grpc_binder
262 
main(int argc,char ** argv)263 int main(int argc, char** argv) {
264   ::testing::InitGoogleTest(&argc, argv);
265   grpc::testing::TestEnvironment env(&argc, argv);
266   return RUN_ALL_TESTS();
267 }
268