1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "types.h"
18
19 #include <gtest/gtest.h>
20
21 #include <memory>
22 #include <type_traits>
23 #include <utility>
24
25 #include "adb.h"
26 #include "apacket_reader.h"
27 #include "fdevent/fdevent_test.h"
28
create_block(const std::string & string)29 static IOVector::block_type create_block(const std::string& string) {
30 return IOVector::block_type(string.begin(), string.end());
31 }
32
create_block(char value,size_t len)33 static IOVector::block_type create_block(char value, size_t len) {
34 auto block = IOVector::block_type();
35 block.resize(len);
36
37 static_assert(std::is_standard_layout<decltype(block)>());
38 memset(&(block)[0], value, len);
39
40 return block;
41 }
42
43 template <typename T>
copy_block(const T & block)44 static IOVector::block_type copy_block(const T& block) {
45 auto copy = IOVector::block_type();
46 copy.assign(block.begin(), block.end());
47 return copy;
48 }
49
TEST(IOVector,empty)50 TEST(IOVector, empty) {
51 // Empty IOVector.
52 IOVector bc;
53 CHECK_EQ(0ULL, bc.coalesce().size());
54 }
55
TEST(IOVector,move_constructor)56 TEST(IOVector, move_constructor) {
57 IOVector x;
58 size_t xsize = x.coalesce().size();
59 IOVector y(std::move(x));
60 CHECK_EQ(xsize, y.coalesce().size());
61 }
62
TEST(IOVector,single_block)63 TEST(IOVector, single_block) {
64 // A single block.
65 auto block = create_block('x', 100);
66 IOVector bc;
67 bc.append(copy_block(block));
68 ASSERT_EQ(100ULL, bc.size());
69 auto coalesced = bc.coalesce();
70 ASSERT_EQ(block, coalesced);
71 }
72
TEST(IOVector,single_block_split)73 TEST(IOVector, single_block_split) {
74 // One block split.
75 IOVector bc;
76 bc.append(create_block("foobar"));
77 IOVector foo = bc.take_front(3);
78 ASSERT_EQ(3ULL, foo.size());
79 ASSERT_EQ(3ULL, bc.size());
80 ASSERT_EQ(create_block("foo"), foo.coalesce());
81 ASSERT_EQ(create_block("bar"), bc.coalesce());
82 }
83
TEST(IOVector,aligned_split)84 TEST(IOVector, aligned_split) {
85 IOVector bc;
86 bc.append(create_block("foo"));
87 bc.append(create_block("bar"));
88 bc.append(create_block("baz"));
89 ASSERT_EQ(9ULL, bc.size());
90
91 IOVector foo = bc.take_front(3);
92 ASSERT_EQ(3ULL, foo.size());
93 ASSERT_EQ(create_block("foo"), foo.coalesce());
94
95 IOVector bar = bc.take_front(3);
96 ASSERT_EQ(3ULL, bar.size());
97 ASSERT_EQ(create_block("bar"), bar.coalesce());
98
99 IOVector baz = bc.take_front(3);
100 ASSERT_EQ(3ULL, baz.size());
101 ASSERT_EQ(create_block("baz"), baz.coalesce());
102
103 ASSERT_EQ(0ULL, bc.size());
104 }
105
TEST(IOVector,misaligned_split)106 TEST(IOVector, misaligned_split) {
107 IOVector bc;
108 bc.append(create_block("foo"));
109 bc.append(create_block("bar"));
110 bc.append(create_block("baz"));
111 bc.append(create_block("qux"));
112 bc.append(create_block("quux"));
113
114 // Aligned left, misaligned right, across multiple blocks.
115 IOVector foob = bc.take_front(4);
116 ASSERT_EQ(4ULL, foob.size());
117 ASSERT_EQ(create_block("foob"), foob.coalesce());
118
119 // Misaligned left, misaligned right, in one block.
120 IOVector a = bc.take_front(1);
121 ASSERT_EQ(1ULL, a.size());
122 ASSERT_EQ(create_block("a"), a.coalesce());
123
124 // Misaligned left, misaligned right, across two blocks.
125 IOVector rba = bc.take_front(3);
126 ASSERT_EQ(3ULL, rba.size());
127 ASSERT_EQ(create_block("rba"), rba.coalesce());
128
129 // Misaligned left, misaligned right, across three blocks.
130 IOVector zquxquu = bc.take_front(7);
131 ASSERT_EQ(7ULL, zquxquu.size());
132 ASSERT_EQ(create_block("zquxquu"), zquxquu.coalesce());
133
134 ASSERT_EQ(1ULL, bc.size());
135 ASSERT_EQ(create_block("x"), bc.coalesce());
136 }
137
TEST(IOVector,drop_front)138 TEST(IOVector, drop_front) {
139 IOVector vec;
140
141 vec.append(create_block('x', 2));
142 vec.append(create_block('y', 1000));
143 ASSERT_EQ(2U, vec.front_size());
144 ASSERT_EQ(1002U, vec.size());
145
146 vec.drop_front(1);
147 ASSERT_EQ(1U, vec.front_size());
148 ASSERT_EQ(1001U, vec.size());
149
150 vec.drop_front(1);
151 ASSERT_EQ(1000U, vec.front_size());
152 ASSERT_EQ(1000U, vec.size());
153 }
154
TEST(IOVector,take_front)155 TEST(IOVector, take_front) {
156 IOVector vec;
157 ASSERT_TRUE(vec.take_front(0).empty());
158
159 vec.append(create_block('x', 2));
160 ASSERT_EQ(2ULL, vec.size());
161
162 ASSERT_EQ(1ULL, vec.take_front(1).size());
163 ASSERT_EQ(1ULL, vec.size());
164
165 ASSERT_EQ(1ULL, vec.take_front(1).size());
166 ASSERT_EQ(0ULL, vec.size());
167 }
168
TEST(IOVector,trim_front)169 TEST(IOVector, trim_front) {
170 IOVector vec;
171 vec.append(create_block('x', 2));
172
173 ASSERT_EQ(1ULL, vec.take_front(1).size());
174 ASSERT_EQ(1ULL, vec.size());
175 vec.trim_front();
176 ASSERT_EQ(1ULL, vec.size());
177 }
178
179 class weak_ptr_test : public FdeventTest {};
180
181 struct Destructor : public enable_weak_from_this<Destructor> {
DestructorDestructor182 Destructor(bool* destroyed) : destroyed_(destroyed) {}
~DestructorDestructor183 ~Destructor() { *destroyed_ = true; }
184
185 bool* destroyed_;
186 };
187
TEST_F(weak_ptr_test,smoke)188 TEST_F(weak_ptr_test, smoke) {
189 PrepareThread();
190
191 Destructor* destructor = nullptr;
192 bool destroyed = false;
193 std::optional<weak_ptr<Destructor>> p;
194
195 fdevent_run_on_looper([&p, &destructor, &destroyed]() {
196 destructor = new Destructor(&destroyed);
197 p = destructor->weak();
198 ASSERT_TRUE(p->get());
199
200 p->reset();
201 ASSERT_FALSE(p->get());
202
203 p->reset(destructor);
204 ASSERT_TRUE(p->get());
205 });
206 WaitForFdeventLoop();
207 ASSERT_TRUE(destructor);
208 ASSERT_FALSE(destroyed);
209
210 destructor->schedule_deletion();
211 WaitForFdeventLoop();
212
213 ASSERT_TRUE(destroyed);
214 fdevent_run_on_looper([&p]() {
215 ASSERT_FALSE(p->get());
216 p.reset();
217 });
218
219 TerminateThread();
220 }
221
ASSERT_APACKET_EQ(const apacket & expected,const std::unique_ptr<apacket> & result)222 void ASSERT_APACKET_EQ(const apacket& expected, const std::unique_ptr<apacket>& result) {
223 ASSERT_EQ(expected.msg.data_length, result->msg.data_length);
224 ASSERT_EQ(expected.msg.command, result->msg.command);
225 ASSERT_EQ(expected.msg.arg0, result->msg.arg0);
226 ASSERT_EQ(expected.msg.arg1, result->msg.arg1);
227 ASSERT_EQ(expected.msg.data_check, result->msg.data_check);
228 ASSERT_EQ(expected.msg.magic, result->msg.magic);
229 ASSERT_EQ(size_t(0), expected.payload.position());
230 ASSERT_EQ(size_t(0), result->payload.position());
231
232 ASSERT_EQ(expected.payload.remaining(), result->payload.remaining());
233 ASSERT_EQ(0, memcmp(expected.payload.data(), result->payload.data(),
234 expected.payload.remaining()));
235 }
236
ASSERT_APACKETS_EQ(const std::vector<apacket> & expected,const std::vector<std::unique_ptr<apacket>> & result)237 void ASSERT_APACKETS_EQ(const std::vector<apacket>& expected,
238 const std::vector<std::unique_ptr<apacket>>& result) {
239 ASSERT_EQ(expected.size(), result.size());
240 for (size_t i = 0; i < expected.size(); i++) {
241 ASSERT_APACKET_EQ(expected[i], result[i]);
242 }
243 }
block_from_header(amessage & header)244 static Block block_from_header(amessage& header) {
245 Block b{sizeof(amessage)};
246 memcpy(b.data(), reinterpret_cast<char*>(&header), sizeof(amessage));
247 return b;
248 }
249
make_packet(uint32_t cmd,const std::string payload="")250 static apacket make_packet(uint32_t cmd, const std::string payload = "") {
251 apacket p;
252 p.msg.command = cmd;
253 p.msg.data_length = payload.size();
254 p.payload.resize(payload.size());
255 memcpy(p.payload.data(), payload.data(), payload.size());
256 return p;
257 }
258
packets_to_blocks(const std::vector<apacket> & packets)259 static std::vector<Block> packets_to_blocks(const std::vector<apacket>& packets) {
260 std::vector<Block> blocks;
261 for (auto& p : packets) {
262 // Create the header
263 Block header{sizeof(amessage)};
264 memcpy(header.data(), reinterpret_cast<const char*>(&p.msg), sizeof(amessage));
265 blocks.emplace_back(std::move(header));
266
267 // Create the payload
268 if (p.msg.data_length != 0) {
269 Block payload{p.msg.data_length};
270 memcpy(payload.data(), p.payload.data(), p.msg.data_length);
271 blocks.push_back(std::move(payload));
272 }
273 }
274 return blocks;
275 }
276
TEST(APacketReader,initial_state)277 TEST(APacketReader, initial_state) {
278 APacketReader reader;
279 auto packets = reader.get_packets();
280 ASSERT_EQ(packets.size(), (size_t)0);
281 }
282
runAndVerifyAPacketTest(std::vector<Block> & traffic,const std::vector<apacket> & expected)283 void runAndVerifyAPacketTest(std::vector<Block>& traffic, const std::vector<apacket>& expected) {
284 adb_trace_enable(USB);
285 // Feed the blocks to the reader (on the receiver end)
286 APacketReader reader;
287 for (auto& b : traffic) {
288 auto res = reader.add_bytes(std::move(b));
289 ASSERT_EQ(res, APacketReader::AddResult::OK);
290 }
291
292 // Make sure the input and the output match
293 ASSERT_APACKETS_EQ(expected, reader.get_packets());
294 }
295
TEST(APacketReader,one_packet_two_blocks)296 TEST(APacketReader, one_packet_two_blocks) {
297 std::vector<apacket> input;
298 input.emplace_back(make_packet(A_OKAY, "12345"));
299
300 auto blocks = packets_to_blocks(input);
301 ASSERT_EQ(size_t(2), blocks.size());
302
303 runAndVerifyAPacketTest(blocks, input);
304 }
305
TEST(APacketReader,one_packet_empty_blocks)306 TEST(APacketReader, one_packet_empty_blocks) {
307 std::vector<apacket> input;
308 input.emplace_back(make_packet(A_OKAY, "12345"));
309
310 auto blocks = packets_to_blocks(input);
311 blocks.emplace(blocks.begin(), Block{0});
312 blocks.emplace_back(Block{0});
313 ASSERT_EQ(size_t(4), blocks.size());
314
315 runAndVerifyAPacketTest(blocks, input);
316 }
317
TEST(APacketReader,no_payload)318 TEST(APacketReader, no_payload) {
319 std::vector<apacket> input;
320 input.emplace_back(make_packet(A_OKAY));
321
322 auto blocks = packets_to_blocks(input);
323 // Make sure we have a single block with the header in it.
324 ASSERT_EQ(size_t(1), blocks.size());
325 ASSERT_EQ(sizeof(amessage), blocks[0].size());
326
327 runAndVerifyAPacketTest(blocks, input);
328 }
329
TEST(APacketReader,several_no_payload)330 TEST(APacketReader, several_no_payload) {
331 std::vector<apacket> input;
332 input.emplace_back(make_packet(A_OKAY));
333 input.emplace_back(make_packet(A_WRTE));
334 input.emplace_back(make_packet(A_CLSE));
335 input.emplace_back(make_packet(A_CNXN));
336
337 auto blocks = packets_to_blocks(input);
338 // Make sure we have a single block with the header in it.
339 ASSERT_EQ(size_t(4), blocks.size());
340 for (const auto& block : blocks) {
341 ASSERT_EQ(sizeof(amessage), block.size());
342 }
343
344 runAndVerifyAPacketTest(blocks, input);
345 }
346
TEST(APacketReader,payload_overflow)347 TEST(APacketReader, payload_overflow) {
348 std::vector<apacket> input;
349 std::string payload = "0";
350 input.emplace_back(make_packet(A_OKAY, payload));
351
352 // Create a header block but a payload block with too much payload
353 std::vector<Block> blocks;
354 blocks.emplace_back(block_from_header(input[0].msg));
355 blocks.emplace_back(payload + "0");
356
357 runAndVerifyAPacketTest(blocks, input);
358 }
359
TEST(APacketReader,several_packets)360 TEST(APacketReader, several_packets) {
361 std::vector<apacket> input;
362 for (int i = 0; i < 10; i++) {
363 input.emplace_back(make_packet(i, std::string(i, (char)i)));
364 }
365
366 auto blocks = packets_to_blocks(input);
367 ASSERT_EQ(size_t(19), blocks.size()); // Not 20, because first one has no payload!
368
369 runAndVerifyAPacketTest(blocks, input);
370 }
371
TEST(APacketReader,split_header)372 TEST(APacketReader, split_header) {
373 std::string payload = "0123456789";
374 std::vector<apacket> input;
375 input.emplace_back(make_packet(A_OKAY, payload));
376
377 // We do some surgery here to split the header into two Blocks
378 std::vector<Block> blocks;
379 // First half of header
380 Block header1(sizeof(amessage) / 2);
381 memcpy(header1.data(), (char*)&input[0].msg, sizeof(amessage) / 2);
382 blocks.emplace_back(std::move(header1));
383
384 // Second half of header
385 Block header2(sizeof(amessage) / 2);
386 memcpy(header2.data(), ((char*)&input[0].msg) + sizeof(amessage) / 2, sizeof(amessage) / 2);
387 blocks.emplace_back(std::move(header2));
388
389 // Payload is not split
390 blocks.emplace_back(Block{payload});
391
392 runAndVerifyAPacketTest(blocks, input);
393 }
394
TEST(APacketReader,payload_and_next_header_merged)395 TEST(APacketReader, payload_and_next_header_merged) {
396 std::vector<apacket> input;
397 input.emplace_back(make_packet(A_OKAY, "12345"));
398 std::string second_payload = "67890";
399 input.emplace_back(make_packet(A_CLSE, second_payload));
400
401 // We do some surgery here to merge the payload of first packet with header of second packet
402 std::vector<Block> blocks;
403 blocks.emplace_back(block_from_header(input[0].msg));
404 Block mergedBlock{input[0].payload.size() + sizeof(amessage)};
405 memcpy(mergedBlock.data(), input[0].payload.data(), input[0].msg.data_length);
406 memcpy(mergedBlock.data() + input[0].msg.data_length, block_from_header(input[1].msg).data(),
407 sizeof(amessage));
408 blocks.emplace_back(std::move(mergedBlock));
409 blocks.emplace_back(Block{second_payload});
410
411 ASSERT_EQ(size_t(3), blocks.size());
412 runAndVerifyAPacketTest(blocks, input);
413 }
414
mergeBlocks(std::vector<Block> & blocks)415 static Block mergeBlocks(std::vector<Block>& blocks) {
416 size_t total_size = 0;
417 for (Block& b : blocks) {
418 total_size += b.size();
419 }
420 Block block{total_size};
421 size_t rover = 0;
422 for (Block& b : blocks) {
423 memcpy(block.data() + rover, b.data(), b.size());
424 rover += b.size();
425 }
426 return block;
427 }
428
TEST(APacketReader,one_packet_one_block)429 TEST(APacketReader, one_packet_one_block) {
430 std::vector<apacket> input;
431 input.emplace_back(make_packet(A_OKAY, "12345"));
432
433 std::vector<Block> blocks_clean = packets_to_blocks(input);
434 std::vector<Block> blocks;
435 blocks.emplace_back(mergeBlocks(blocks_clean));
436
437 runAndVerifyAPacketTest(blocks, input);
438 }
439
TEST(APacketReader,two_packets_one_block)440 TEST(APacketReader, two_packets_one_block) {
441 std::vector<apacket> input;
442 input.emplace_back(make_packet(A_OKAY, "12345"));
443 input.emplace_back(make_packet(A_WRTE, "67890"));
444
445 std::vector<Block> blocks_clean = packets_to_blocks(input);
446 std::vector<Block> blocks;
447 blocks.emplace_back(mergeBlocks(blocks_clean));
448 ASSERT_EQ(size_t(1), blocks.size());
449
450 runAndVerifyAPacketTest(blocks, input);
451 }
452
TEST(APacketReader,bad_big_payload_header)453 TEST(APacketReader, bad_big_payload_header) {
454 std::vector<apacket> input;
455 input.emplace_back(make_packet(A_OKAY, std::string(MAX_PAYLOAD + 1, 'a')));
456 std::vector<Block> blocks = packets_to_blocks(input);
457
458 APacketReader reader;
459 auto res = reader.add_bytes(std::move(blocks[0]));
460 ASSERT_EQ(res, APacketReader::AddResult::ERROR);
461 }
462
splitBlock(Block src_block,size_t chop_size)463 std::vector<Block> splitBlock(Block src_block, size_t chop_size) {
464 std::vector<Block> blocks;
465 while (src_block.remaining()) {
466 Block block{std::min(chop_size, src_block.remaining())};
467 block.fillFrom(src_block);
468 block.rewind();
469 blocks.emplace_back(std::move(block));
470 }
471 return blocks;
472 }
473
474 // Collapse all packets into a single block. Chop it into chop_size Blocks.
475 // And feed that to the packet reader.
chainSaw(int chop_size)476 void chainSaw(int chop_size) {
477 std::vector<apacket> packets;
478 packets.emplace_back(make_packet(A_CNXN));
479 packets.emplace_back(make_packet(A_OKAY, "12345"));
480 packets.emplace_back(make_packet(A_WRTE, "6890"));
481 packets.emplace_back(make_packet(A_CNXN));
482 packets.emplace_back(make_packet(A_AUTH, "abc"));
483 packets.emplace_back(make_packet(A_WRTE));
484 ASSERT_EQ(size_t(6), packets.size());
485
486 auto all_blocks = packets_to_blocks(packets);
487 ASSERT_EQ(size_t(9), all_blocks.size());
488
489 auto single_block = mergeBlocks(all_blocks);
490 auto single_block_size = single_block.remaining();
491 auto blocks = splitBlock(std::move(single_block), chop_size);
492 auto expected_num_blocks =
493 single_block_size / chop_size + (single_block_size % chop_size == 0 ? 0 : 1);
494 ASSERT_EQ(expected_num_blocks, blocks.size());
495
496 runAndVerifyAPacketTest(blocks, packets);
497 }
498
TEST(APacketReader,chainsaw)499 TEST(APacketReader, chainsaw) {
500 // Try to send packets, chopping in various pieces sizes
501 for (int i = 1; i < 256; i++) {
502 chainSaw(i);
503 }
504 }