2 * Copyright 2019 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "packet/packet_view.h"
19 #include <gtest/gtest.h>
20 #include <forward_list>
23 #include "common/address.h"
25 using bluetooth::common::Address;
26 using bluetooth::packet::PacketView;
27 using bluetooth::packet::View;
31 vector<uint8_t> count_all = {
32 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
33 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
36 vector<uint8_t> count_1 = {
42 vector<uint8_t> count_2 = {
43 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
46 vector<uint8_t> count_3 = {
47 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
55 class IteratorTest : public ::testing::Test {
57 IteratorTest() = default;
58 ~IteratorTest() = default;
61 packet = std::shared_ptr<T>(new T({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())}));
68 std::shared_ptr<T> packet;
71 using PacketViewTypes = ::testing::Types<PacketView<true>, PacketView<false>>;
72 TYPED_TEST_CASE(IteratorTest, PacketViewTypes);
74 class IteratorExtractTest : public ::testing::Test {
76 IteratorExtractTest() = default;
77 ~IteratorExtractTest() = default;
81 class PacketViewTest : public IteratorTest<T> {
83 PacketViewTest() = default;
84 ~PacketViewTest() = default;
87 using PacketViewTypes = ::testing::Types<PacketView<true>, PacketView<false>>;
88 TYPED_TEST_CASE(PacketViewTest, PacketViewTypes);
90 class PacketViewMultiViewTest : public ::testing::Test {
92 PacketViewMultiViewTest() = default;
93 ~PacketViewMultiViewTest() = default;
96 class ViewTest : public ::testing::Test {
99 ~ViewTest() = default;
102 TEST(IteratorExtractTest, extractLeTest) {
103 PacketView<true> packet({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
104 auto general_case = packet.begin();
106 ASSERT_EQ(0x00, general_case.extract<uint8_t>());
107 ASSERT_EQ(0x0201, general_case.extract<uint16_t>());
108 ASSERT_EQ(0x06050403u, general_case.extract<uint32_t>());
109 ASSERT_EQ(0x0e0d0c0b0a090807u, general_case.extract<uint64_t>());
110 ASSERT_EQ(0x0f, general_case.extract<uint8_t>());
111 Address raw({0x10, 0x11, 0x12, 0x13, 0x14, 0x15});
112 ASSERT_EQ(raw, general_case.extract<Address>());
113 ASSERT_EQ(0x16, general_case.extract<uint8_t>());
116 TEST(IteratorExtractTest, extractBeTest) {
117 PacketView<false> packet({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
118 auto general_case = packet.begin();
120 ASSERT_EQ(0x00, general_case.extract<uint8_t>());
121 ASSERT_EQ(0x0102, general_case.extract<uint16_t>());
122 ASSERT_EQ(0x03040506u, general_case.extract<uint32_t>());
123 ASSERT_EQ(0x0708090a0b0c0d0eu, general_case.extract<uint64_t>());
124 ASSERT_EQ(0x0f, general_case.extract<uint8_t>());
125 Address raw({0x15, 0x14, 0x13, 0x12, 0x11, 0x10});
126 ASSERT_EQ(raw, general_case.extract<Address>());
127 ASSERT_EQ(0x16, general_case.extract<uint8_t>());
130 TYPED_TEST(IteratorTest, extractBoundsDeathTest) {
131 auto bounds_test = this->packet->end();
133 ASSERT_DEATH(bounds_test.template extract<uint8_t>(), "");
134 ASSERT_DEATH(bounds_test.template extract<uint16_t>(), "");
135 ASSERT_DEATH(bounds_test.template extract<uint32_t>(), "");
136 ASSERT_DEATH(bounds_test.template extract<uint64_t>(), "");
139 TYPED_TEST(IteratorTest, dereferenceDeathTest) {
140 auto dereference_test = this->packet->end();
142 ASSERT_DEATH(*dereference_test, "");
143 ASSERT_EQ(0x1f, *(dereference_test - 1));
146 TYPED_TEST(IteratorTest, plusEqTest) {
147 auto plus_eq = this->packet->begin();
148 for (size_t i = 0; i < count_all.size(); i += 2) {
149 ASSERT_EQ(count_all[i], *plus_eq) << "+= test: Dereferenced iterator does not equal expected at index " << i;
154 TYPED_TEST(IteratorTest, preIncrementTest) {
155 auto plus_plus = this->packet->begin();
156 for (size_t i = 0; i < count_all.size() - 1; i++) {
157 ASSERT_EQ(count_all[i + 1], *(++plus_plus)) << "Pre-increment test: Dereferenced iterator does not equal expected "
162 TYPED_TEST(IteratorTest, postIncrementTest) {
163 auto plus_plus = this->packet->begin();
164 for (size_t i = 0; i < count_all.size(); i++) {
165 ASSERT_EQ(count_all[i], *(plus_plus++)) << "Post-increment test: Dereferenced iterator does not equal expected "
170 TYPED_TEST(IteratorTest, additionTest) {
171 auto plus = this->packet->begin();
172 for (size_t i = 0; i < count_all.size(); i++) {
173 ASSERT_EQ(count_all[i], *plus) << "+ test: Dereferenced iterator does not equal expected at index " << i;
178 TYPED_TEST(IteratorTest, minusEqTest) {
179 auto minus_eq = this->packet->end();
181 size_t index = count_all.size() - 1;
182 for (size_t i = 0; index > i; i++) {
183 ASSERT_EQ(count_all[index], *minus_eq)
184 << "-= test: Dereferenced iterator does not equal expected at index " << index;
190 TYPED_TEST(IteratorTest, preDecrementTest) {
191 auto minus_minus = this->packet->end();
192 for (size_t i = count_all.size(); i > 0; i--) {
193 ASSERT_EQ(count_all[i - 1], *(--minus_minus))
194 << "Pre-decrement test: Dereferenced iterator does not equal expected "
199 TYPED_TEST(IteratorTest, postDecrementTest) {
200 auto minus_minus = this->packet->end();
202 for (size_t i = count_all.size() - 1; i > 0; i--) {
203 ASSERT_EQ(count_all[i], *(minus_minus--)) << "Post-decrement test: Dereferenced iterator does not equal expected "
208 TYPED_TEST(IteratorTest, subtractionTest) {
209 auto minus = this->packet->end();
211 for (size_t i = count_all.size() - 1; i > 0; i--) {
212 ASSERT_EQ(count_all[i], *minus) << "- test: Dereferenced iterator does not equal expected at index " << i;
217 TYPED_TEST(IteratorTest, differenceTest) {
218 auto begin = this->packet->begin();
219 auto end = this->packet->end();
220 int difference = end - begin;
221 ASSERT_EQ(difference, static_cast<int>(count_all.size()));
222 int neg_difference = begin - end;
223 ASSERT_EQ(neg_difference, -static_cast<int>(count_all.size()));
226 TYPED_TEST(IteratorTest, equalityTest) {
227 auto begin = this->packet->begin();
228 auto end = this->packet->end();
229 auto begin_copy = this->packet->begin();
230 auto end_copy = this->packet->end();
231 ASSERT_EQ(begin_copy, begin);
232 ASSERT_EQ(end_copy, end);
235 TYPED_TEST(IteratorTest, comparisonsTest) {
236 auto begin = this->packet->begin();
237 auto end = this->packet->end();
238 auto begin_copy = this->packet->begin();
239 auto end_copy = this->packet->end();
240 ASSERT_EQ(begin_copy, begin);
241 ASSERT_EQ(end_copy, end);
242 ASSERT_NE(begin, end);
243 ASSERT_TRUE(begin < end);
244 ASSERT_FALSE(end < end);
245 ASSERT_FALSE(end < begin);
246 ASSERT_FALSE(begin > end);
247 ASSERT_FALSE(end > end);
248 ASSERT_TRUE(end > begin);
249 ASSERT_TRUE(begin <= end);
250 ASSERT_TRUE(end <= end);
251 ASSERT_FALSE(end <= begin);
252 ASSERT_FALSE(begin >= end);
253 ASSERT_TRUE(end >= end);
254 ASSERT_TRUE(end >= begin);
257 TYPED_TEST(PacketViewTest, getLengthTest) {
258 size_t length = this->packet->size();
259 ASSERT_EQ(length, count_all.size());
262 TYPED_TEST(PacketViewTest, getAtIndexTest) {
263 size_t past_end = this->packet->size();
264 ASSERT_DEATH(this->packet->at(past_end), "");
265 size_t working_index = 0x1f;
266 ASSERT_EQ(0x1f, this->packet->at(working_index));
269 TYPED_TEST(PacketViewTest, arrayOperatorTest) {
270 size_t past_end = this->packet->size();
271 ASSERT_DEATH((*(this->packet))[past_end], "");
272 size_t working_index = 0x1f;
273 ASSERT_EQ(0x1f, (*(this->packet))[working_index]);
276 TYPED_TEST(PacketViewTest, numBytesRemainingTest) {
277 auto all = this->packet->begin();
278 size_t remaining = all.NumBytesRemaining();
279 for (size_t n = remaining; n > 0; n--) {
280 ASSERT_EQ(remaining, all.NumBytesRemaining());
284 ASSERT_EQ(static_cast<size_t>(0), all.NumBytesRemaining());
285 ASSERT_DEATH(*(all++), "");
287 ASSERT_EQ(static_cast<size_t>(0), all.NumBytesRemaining());
288 ASSERT_DEATH(*(all++), "");
291 using SubviewTestParam = std::pair<size_t, size_t>;
292 class SubviewBaseTest : public ::testing::TestWithParam<SubviewTestParam> {
294 class SubPacketView : public PacketView<true> {
296 using PacketView<true>::PacketView;
297 PacketView<true> Slice(size_t header, size_t tail) {
298 return PacketView<true>::GetLittleEndianSubview(header, tail);
303 class SubviewPassTest : public SubviewBaseTest {};
305 TEST_P(SubviewPassTest, subviewTest) {
306 auto header = GetParam().first;
307 auto tail = GetParam().second;
308 SubPacketView single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
309 SubPacketView multi_view({
310 View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
311 View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
312 View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
315 auto single_slice = single_view.Slice(header, tail);
316 auto multi_slice = multi_view.Slice(header, tail);
318 ASSERT_EQ(single_slice.size(), tail - header);
319 ASSERT_EQ(single_slice.size(), multi_slice.size());
320 for (size_t i = 0; i < single_slice.size(); i++) {
321 ASSERT_EQ(single_slice[i], multi_slice[i]);
325 static const size_t boundary_1 = count_1.size();
326 static const size_t boundary_2 = count_1.size() + count_2.size();
328 INSTANTIATE_TEST_CASE_P(
329 chopomatic, SubviewPassTest,
331 // {begin, end} pairs for subsets into the PacketView
332 SubviewTestParam{0, 0}, SubviewTestParam{0, boundary_1}, SubviewTestParam{0, boundary_1 + 1},
333 SubviewTestParam{0, boundary_2}, SubviewTestParam{0, boundary_2 + 1}, SubviewTestParam{0, count_all.size()},
334 SubviewTestParam{boundary_1 - 1, boundary_1}, SubviewTestParam{boundary_1 - 1, boundary_1 + 1},
335 SubviewTestParam{boundary_1 - 1, boundary_2}, SubviewTestParam{boundary_1 - 1, boundary_2 + 1},
336 SubviewTestParam{boundary_1 - 1, count_all.size()}, SubviewTestParam{boundary_1, boundary_1},
337 SubviewTestParam{boundary_1, boundary_2}, SubviewTestParam{boundary_1, boundary_2 + 1},
338 SubviewTestParam{boundary_1, count_all.size()}, SubviewTestParam{boundary_2 - 1, boundary_2},
339 SubviewTestParam{boundary_2 - 1, boundary_2 + 1}, SubviewTestParam{boundary_2 - 1, count_all.size()},
340 SubviewTestParam{boundary_2, boundary_2}, SubviewTestParam{boundary_2, boundary_2 + 1},
341 SubviewTestParam{boundary_2, count_all.size()}, SubviewTestParam{count_all.size() - 1, count_all.size()},
342 SubviewTestParam{count_all.size(), count_all.size()}));
344 class SubviewDeathTest : public SubviewBaseTest {};
346 TEST_P(SubviewDeathTest, subviewDeathTest) {
347 auto header = GetParam().first;
348 auto tail = GetParam().second;
349 SubPacketView single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
350 SubPacketView multi_view({
351 View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
352 View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
353 View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
356 ASSERT_DEATH(auto single_slice = single_view.Slice(header, tail), "");
357 ASSERT_DEATH(auto multi_slice = multi_view.Slice(header, tail), "");
360 INSTANTIATE_TEST_CASE_P(chopomaticDeath, SubviewDeathTest,
362 // {begin, end} pairs for subsets into the PacketView
363 SubviewTestParam{1, 0}, SubviewTestParam{count_all.size(), count_all.size() - 1},
364 SubviewTestParam{count_all.size(), count_all.size() + 1}));
366 TEST(SubviewTest, simpleSubviewTest) {
367 PacketView<true> view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
368 PacketView<true> sub_1_view = view.GetLittleEndianSubview(0, view.size());
369 PacketView<true> sub_2_view = sub_1_view.GetLittleEndianSubview(0, sub_1_view.size());
370 PacketView<true> sub_3_view = sub_2_view.GetLittleEndianSubview(0, sub_2_view.size());
371 PacketView<true> sub_4_view = sub_3_view.GetLittleEndianSubview(0, sub_3_view.size());
372 ASSERT_EQ(sub_1_view.size(), view.size());
373 ASSERT_EQ(sub_2_view.size(), view.size());
374 ASSERT_EQ(sub_3_view.size(), view.size());
375 ASSERT_EQ(sub_4_view.size(), view.size());
378 TEST(SubviewTest, realSubviewTest) {
379 PacketView<true> view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
380 std::vector<PacketView<true>> sub_views{view};
381 for (size_t i = 1; i < 6; i++) {
382 size_t parent_size = sub_views[i - 1].size();
383 sub_views.push_back(sub_views[i - 1].GetLittleEndianSubview(1, parent_size - 1));
384 ASSERT_EQ(sub_views[i][0], i);
385 ASSERT_EQ(sub_views[i].size(), parent_size - 2);
389 TEST(SubviewTest, subSubviewTest) {
390 PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
391 PacketView<true> multi_view({
392 View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
393 View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
394 View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
396 ASSERT_EQ(single_view.size(), multi_view.size());
397 for (size_t i = 0; i < count_all.size() / 2; i++) {
398 PacketView<true> sub_single_view = single_view.GetLittleEndianSubview(i, count_all.size() - i);
399 PacketView<true> sub_multi_view = multi_view.GetLittleEndianSubview(i, count_all.size() - i);
400 ASSERT_EQ(count_all.size() - 2 * i, sub_single_view.size());
401 ASSERT_EQ(sub_single_view.size(), sub_multi_view.size());
402 for (size_t j = 0; j < sub_single_view.size() / 2; j++) {
403 PacketView<true> sub_sub_single_view = sub_single_view.GetLittleEndianSubview(j, sub_single_view.size() - j);
404 PacketView<true> sub_sub_multi_view = sub_multi_view.GetLittleEndianSubview(j, sub_multi_view.size() - j);
405 ASSERT_EQ(sub_single_view.size() - 2 * j, sub_sub_single_view.size());
406 ASSERT_EQ(sub_sub_single_view.size(), sub_sub_multi_view.size());
411 TEST(PacketViewMultiViewTest, sizeTest) {
412 PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
413 PacketView<true> multi_view({
414 View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
415 View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
416 View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
418 ASSERT_EQ(single_view.size(), multi_view.size());
421 TEST(PacketViewMultiViewTest, dereferenceTestLittleEndian) {
422 PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
423 PacketView<true> multi_view({
424 View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
425 View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
426 View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
428 auto single_itr = single_view.begin();
429 auto multi_itr = multi_view.begin();
430 for (size_t i = 0; i < single_view.size(); i++) {
431 ASSERT_EQ(*(single_itr++), *(multi_itr++));
433 ASSERT_DEATH(*multi_itr, "");
436 TEST(PacketViewMultiViewTest, dereferenceTestBigEndian) {
437 PacketView<false> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
438 PacketView<false> multi_view({
439 View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
440 View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
441 View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
443 auto single_itr = single_view.begin();
444 auto multi_itr = multi_view.begin();
445 for (size_t i = 0; i < single_view.size(); i++) {
446 ASSERT_EQ(*(single_itr++), *(multi_itr++));
448 ASSERT_DEATH(*multi_itr, "");
451 TEST(PacketViewMultiViewTest, arrayOperatorTest) {
452 PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
453 PacketView<true> multi_view({
454 View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
455 View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
456 View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
458 for (size_t i = 0; i < single_view.size(); i++) {
459 ASSERT_EQ(single_view[i], multi_view[i]);
461 ASSERT_DEATH(multi_view[single_view.size()], "");
464 TEST(ViewTest, arrayOperatorTest) {
465 View view_all(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
466 size_t past_end = view_all.size();
467 for (size_t i = 0; i < past_end; i++) {
468 ASSERT_EQ(view_all[i], count_all[i]);
470 ASSERT_DEATH(view_all[past_end], "");
472 size_t header_size = 2;
473 size_t tail_size = 3;
474 View view_subset(std::make_shared<const vector<uint8_t>>(count_all), header_size, count_all.size() - tail_size);
475 View view_subset2(view_all, header_size, count_all.size() - tail_size);
476 size_t subset_length = view_subset.size();
477 for (size_t i = 0; i < subset_length; i++) {
478 ASSERT_EQ(view_subset[i], count_all[header_size + i]);
479 ASSERT_EQ(view_subset[i], view_subset2[i]);
481 ASSERT_DEATH(view_subset[subset_length + 1], "");
482 ASSERT_DEATH(view_subset2[subset_length + 1], "");
485 TEST(ViewTest, earlySubSubviewTest) {
486 View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
487 View sub_1_view(view, view.size() - 3, view.size() - 1);
488 View sub_2_view(sub_1_view, 1, 2);
489 ASSERT_EQ(sub_1_view.size(), 2u);
490 ASSERT_EQ(sub_2_view.size(), 1u);
493 TEST(ViewTest, subSubviewTest) {
494 View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
495 std::vector<View> sub_views{view};
496 for (size_t i = 1; i < 6; i++) {
497 size_t parent_size = sub_views[i - 1].size();
498 sub_views.push_back({View(sub_views[i - 1], 1, parent_size - 1)});
499 ASSERT_EQ(sub_views[i][0], i);
500 ASSERT_EQ(sub_views[i].size(), parent_size - 2);
504 TEST(ViewTest, zeroSubviewTest) {
505 View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
506 View subview(view, view.size(), view.size() + 1);
507 ASSERT_EQ(subview.size(), 0u);
509 } // namespace packet
510 } // namespace bluetooth