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 }