blob: 6179959b0b718033c04f3e1cdb25a9d722f14709 [file] [log] [blame]
Myles Watsona37f63e2019-10-29 16:31:14 -07001/*
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
24using bluetooth::packet::FragmentingInserter;
25using std::vector;
26
27namespace bluetooth {
28namespace packet {
29
30TEST(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
56TEST(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([&copy](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
94constexpr size_t kPacketSize = 128;
95class FragmentingTest : public ::testing::TestWithParam<size_t> {
96 public:
97 void StartUp() {
98 counts_.reserve(kPacketSize);
99 for (size_t i = 0; i < kPacketSize; i++) {
100 counts_.push_back(static_cast<uint8_t>(i));
101 }
102 }
103 void ShutDown() {
104 counts_.clear();
105 }
106 std::vector<uint8_t> counts_;
107};
108
109TEST_P(FragmentingTest, mtuFragmentTest) {
110 size_t mtu = GetParam();
111 std::vector<std::unique_ptr<RawBuilder>> fragments;
112 FragmentingInserter it(mtu, std::back_insert_iterator(fragments));
113
114 RawBuilder original_packet(counts_);
115 ASSERT_EQ(counts_.size(), original_packet.size());
116
117 original_packet.Serialize(it);
118 it.finalize();
119
120 size_t expected_fragments = counts_.size() / mtu;
121 if (counts_.size() % mtu != 0) {
122 expected_fragments++;
123 }
124 ASSERT_EQ(expected_fragments, fragments.size());
125
126 std::vector<std::vector<uint8_t>> serialized_fragments;
127 for (size_t f = 0; f < fragments.size(); f++) {
128 serialized_fragments.emplace_back(mtu);
129 BitInserter bit_inserter(serialized_fragments[f]);
130 fragments[f]->Serialize(bit_inserter);
131 if (f + 1 == fragments.size() && (counts_.size() % mtu != 0)) {
132 ASSERT_EQ(serialized_fragments[f].size(), counts_.size() % mtu);
133 } else {
134 ASSERT_EQ(serialized_fragments[f].size(), mtu);
135 }
136 for (size_t b = 0; b < serialized_fragments[f].size(); b++) {
137 EXPECT_EQ(counts_[f * mtu + b], serialized_fragments[f][b]);
138 }
139 }
140}
141
142INSTANTIATE_TEST_CASE_P(chopomatic, FragmentingTest, ::testing::Range<size_t>(1, kPacketSize + 1));
143
144} // namespace packet
145} // namespace bluetooth