1 /* 2 * Copyright 2019 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 "packet/fragmenting_inserter.h" 18 19 #include <gtest/gtest.h> 20 #include <memory> 21 22 #include "os/log.h" 23 24 using bluetooth::packet::FragmentingInserter; 25 using std::vector; 26 27 namespace bluetooth { 28 namespace packet { 29 30 TEST(FragmentingInserterTest, addMoreBits) { 31 std::vector<uint8_t> result = {0b00011101 /* 3 2 1 */, 0b00010101 /* 5 4 */, 0b11100011 /* 7 6 */, 0b10000000 /* 8 */, 32 0b10100000 /* filled with 1010 */}; 33 std::vector<std::unique_ptr<RawBuilder>> fragments; 34 35 FragmentingInserter it(result.size(), std::back_insert_iterator(fragments)); 36 37 for (size_t i = 0; i < 9; i++) { 38 it.insert_bits(static_cast<uint8_t>(i), i); 39 } 40 it.insert_bits(static_cast<uint8_t>(0b1010), 4); 41 42 it.finalize(); 43 44 ASSERT_EQ(1, fragments.size()); 45 46 std::vector<uint8_t> bytes; 47 BitInserter bit_inserter(bytes); 48 fragments[0]->Serialize(bit_inserter); 49 50 ASSERT_EQ(result.size(), bytes.size()); 51 for (size_t i = 0; i < bytes.size(); i++) { 52 ASSERT_EQ(result[i], bytes[i]); 53 } 54 } 55 56 TEST(FragmentingInserterTest, observerTest) { 57 std::vector<uint8_t> result = {0b00011101 /* 3 2 1 */, 0b00010101 /* 5 4 */, 0b11100011 /* 7 6 */, 0b10000000 /* 8 */, 58 0b10100000 /* filled with 1010 */}; 59 std::vector<std::unique_ptr<RawBuilder>> fragments; 60 61 FragmentingInserter it(result.size() + 1, std::back_insert_iterator(fragments)); 62 63 std::vector<uint8_t> copy; 64 65 uint64_t checksum = 0x0123456789abcdef; 66 it.RegisterObserver(ByteObserver([©](uint8_t byte) { copy.push_back(byte); }, [checksum]() { return checksum; })); 67 68 for (size_t i = 0; i < 9; i++) { 69 it.insert_bits(static_cast<uint8_t>(i), i); 70 } 71 it.insert_bits(static_cast<uint8_t>(0b1010), 4); 72 it.finalize(); 73 74 ASSERT_EQ(1, fragments.size()); 75 76 std::vector<uint8_t> bytes; 77 BitInserter bit_inserter(bytes); 78 fragments[0]->Serialize(bit_inserter); 79 80 ASSERT_EQ(result.size(), bytes.size()); 81 for (size_t i = 0; i < bytes.size(); i++) { 82 ASSERT_EQ(result[i], bytes[i]); 83 } 84 85 ASSERT_EQ(result.size(), copy.size()); 86 for (size_t i = 0; i < copy.size(); i++) { 87 ASSERT_EQ(result[i], copy[i]); 88 } 89 90 ByteObserver observer = it.UnregisterObserver(); 91 ASSERT_EQ(checksum, observer.GetValue()); 92 } 93 94 TEST(FragmentingInserterTest, testMtuBoundaries) { 95 constexpr size_t kPacketSize = 1024; 96 auto counts = RawBuilder(); 97 for (size_t i = 0; i < kPacketSize; i++) { 98 counts.AddOctets1(static_cast<uint8_t>(i)); 99 } 100 101 std::vector<std::unique_ptr<RawBuilder>> fragments_mtu_is_kPacketSize; 102 FragmentingInserter it(kPacketSize, std::back_insert_iterator(fragments_mtu_is_kPacketSize)); 103 counts.Serialize(it); 104 it.finalize(); 105 ASSERT_EQ(1, fragments_mtu_is_kPacketSize.size()); 106 ASSERT_EQ(kPacketSize, fragments_mtu_is_kPacketSize[0]->size()); 107 108 std::vector<std::unique_ptr<RawBuilder>> fragments_mtu_is_less; 109 FragmentingInserter it_less(kPacketSize - 1, std::back_insert_iterator(fragments_mtu_is_less)); 110 counts.Serialize(it_less); 111 it_less.finalize(); 112 ASSERT_EQ(2, fragments_mtu_is_less.size()); 113 ASSERT_EQ(kPacketSize - 1, fragments_mtu_is_less[0]->size()); 114 ASSERT_EQ(1, fragments_mtu_is_less[1]->size()); 115 116 std::vector<std::unique_ptr<RawBuilder>> fragments_mtu_is_more; 117 FragmentingInserter it_more(kPacketSize + 1, std::back_insert_iterator(fragments_mtu_is_more)); 118 counts.Serialize(it_more); 119 it_more.finalize(); 120 ASSERT_EQ(1, fragments_mtu_is_more.size()); 121 ASSERT_EQ(kPacketSize, fragments_mtu_is_more[0]->size()); 122 } 123 124 constexpr size_t kPacketSize = 128; 125 class FragmentingTest : public ::testing::TestWithParam<size_t> { 126 public: 127 void StartUp() { 128 counts_.reserve(kPacketSize); 129 for (size_t i = 0; i < kPacketSize; i++) { 130 counts_.push_back(static_cast<uint8_t>(i)); 131 } 132 } 133 void ShutDown() { 134 counts_.clear(); 135 } 136 std::vector<uint8_t> counts_; 137 }; 138 139 TEST_P(FragmentingTest, mtuFragmentTest) { 140 size_t mtu = GetParam(); 141 std::vector<std::unique_ptr<RawBuilder>> fragments; 142 FragmentingInserter it(mtu, std::back_insert_iterator(fragments)); 143 144 RawBuilder original_packet(counts_); 145 ASSERT_EQ(counts_.size(), original_packet.size()); 146 147 original_packet.Serialize(it); 148 it.finalize(); 149 150 size_t expected_fragments = counts_.size() / mtu; 151 if (counts_.size() % mtu != 0) { 152 expected_fragments++; 153 } 154 ASSERT_EQ(expected_fragments, fragments.size()); 155 156 std::vector<std::vector<uint8_t>> serialized_fragments; 157 for (size_t f = 0; f < fragments.size(); f++) { 158 serialized_fragments.emplace_back(mtu); 159 BitInserter bit_inserter(serialized_fragments[f]); 160 fragments[f]->Serialize(bit_inserter); 161 if (f + 1 == fragments.size() && (counts_.size() % mtu != 0)) { 162 ASSERT_EQ(serialized_fragments[f].size(), counts_.size() % mtu); 163 } else { 164 ASSERT_EQ(serialized_fragments[f].size(), mtu); 165 } 166 for (size_t b = 0; b < serialized_fragments[f].size(); b++) { 167 EXPECT_EQ(counts_[f * mtu + b], serialized_fragments[f][b]); 168 } 169 } 170 } 171 172 INSTANTIATE_TEST_CASE_P(chopomatic, FragmentingTest, ::testing::Range<size_t>(1, kPacketSize + 1)); 173 174 } // namespace packet 175 } // namespace bluetooth 176