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/packet_view.h"
18 
19 #include <gtest/gtest.h>
20 #include <forward_list>
21 #include <memory>
22 
23 #include "hci/address.h"
24 
25 using bluetooth::hci::Address;
26 using bluetooth::packet::PacketView;
27 using bluetooth::packet::View;
28 using std::vector;
29 
30 namespace {
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,
34 };
35 
36 vector<uint8_t> count_1 = {
37     0x00,
38     0x01,
39     0x02,
40 };
41 
42 vector<uint8_t> count_2 = {
43     0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
44 };
45 
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,
48 };
49 }  // namespace
50 
51 namespace bluetooth {
52 namespace packet {
53 
54 template <typename T>
55 class IteratorTest : public ::testing::Test {
56  public:
57   IteratorTest() = default;
58   ~IteratorTest() = default;
59 
60   void SetUp() {
61     packet = std::shared_ptr<T>(new T({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())}));
62   }
63 
64   void TearDown() {
65     packet.reset();
66   }
67 
68   std::shared_ptr<T> packet;
69 };
70 
71 using PacketViewTypes = ::testing::Types<PacketView<true>, PacketView<false>>;
72 TYPED_TEST_CASE(IteratorTest, PacketViewTypes);
73 
74 class IteratorExtractTest : public ::testing::Test {
75  public:
76   IteratorExtractTest() = default;
77   ~IteratorExtractTest() = default;
78 };
79 
80 template <typename T>
81 class PacketViewTest : public IteratorTest<T> {
82  public:
83   PacketViewTest() = default;
84   ~PacketViewTest() = default;
85 };
86 
87 using PacketViewTypes = ::testing::Types<PacketView<true>, PacketView<false>>;
88 TYPED_TEST_CASE(PacketViewTest, PacketViewTypes);
89 
90 class PacketViewMultiViewTest : public ::testing::Test {
91  public:
92   PacketViewMultiViewTest() = default;
93   ~PacketViewMultiViewTest() = default;
94 
95   const PacketView<true> single_view =
96       PacketView<true>({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
97   const PacketView<true> multi_view = PacketView<true>({
98       View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
99       View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
100       View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
101   });
102 };
103 
104 class PacketViewMultiViewAppendTest : public ::testing::Test {
105  public:
106   PacketViewMultiViewAppendTest() = default;
107   ~PacketViewMultiViewAppendTest() = default;
108 
109   class AppendedPacketView : public PacketView<true> {
110    public:
111     AppendedPacketView(PacketView<true> first, std::forward_list<PacketView<true>> to_append)
112         : PacketView<true>(first) {
113       for (const auto& packet_view : to_append) {
114         Append(packet_view);
115       }
116     }
117   };
118   const PacketView<true> single_view =
119       PacketView<true>({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
120   const PacketView<true> multi_view = AppendedPacketView(
121       PacketView<true>({View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size())}),
122       {PacketView<true>({View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size())}),
123        PacketView<true>({View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size())})});
124 };
125 
126 class ViewTest : public ::testing::Test {
127  public:
128   ViewTest() = default;
129   ~ViewTest() = default;
130 };
131 
132 TEST(IteratorExtractTest, extractLeTest) {
133   PacketView<true> packet({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
134   auto general_case = packet.begin();
135 
136   ASSERT_EQ(0x00, general_case.extract<uint8_t>());
137   ASSERT_EQ(0x0201, general_case.extract<uint16_t>());
138   ASSERT_EQ(0x06050403u, general_case.extract<uint32_t>());
139   ASSERT_EQ(0x0e0d0c0b0a090807u, general_case.extract<uint64_t>());
140   ASSERT_EQ(0x0f, general_case.extract<uint8_t>());
141   Address raw({0x10, 0x11, 0x12, 0x13, 0x14, 0x15});
142   ASSERT_EQ(raw, general_case.extract<Address>());
143   ASSERT_EQ(0x16, general_case.extract<uint8_t>());
144 }
145 
146 TEST(IteratorExtractTest, extractBeTest) {
147   PacketView<false> packet({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
148   auto general_case = packet.begin();
149 
150   ASSERT_EQ(0x00, general_case.extract<uint8_t>());
151   ASSERT_EQ(0x0102, general_case.extract<uint16_t>());
152   ASSERT_EQ(0x03040506u, general_case.extract<uint32_t>());
153   ASSERT_EQ(0x0708090a0b0c0d0eu, general_case.extract<uint64_t>());
154   ASSERT_EQ(0x0f, general_case.extract<uint8_t>());
155   Address raw({0x15, 0x14, 0x13, 0x12, 0x11, 0x10});
156   ASSERT_EQ(raw, general_case.extract<Address>());
157   ASSERT_EQ(0x16, general_case.extract<uint8_t>());
158 }
159 
160 TYPED_TEST(IteratorTest, extractBoundsDeathTest) {
161   auto bounds_test = this->packet->end();
162 
163   ASSERT_DEATH(bounds_test.template extract<uint8_t>(), "");
164   ASSERT_DEATH(bounds_test.template extract<uint16_t>(), "");
165   ASSERT_DEATH(bounds_test.template extract<uint32_t>(), "");
166   ASSERT_DEATH(bounds_test.template extract<uint64_t>(), "");
167 }
168 
169 TYPED_TEST(IteratorTest, dereferenceDeathTest) {
170   auto dereference_test = this->packet->end();
171 
172   ASSERT_DEATH(*dereference_test, "");
173   ASSERT_EQ(0x1f, *(dereference_test - 1));
174 }
175 
176 TYPED_TEST(IteratorTest, plusEqTest) {
177   auto plus_eq = this->packet->begin();
178   for (size_t i = 0; i < count_all.size(); i += 2) {
179     ASSERT_EQ(count_all[i], *plus_eq) << "+= test: Dereferenced iterator does not equal expected at index " << i;
180     plus_eq += 2;
181   }
182 }
183 
184 TYPED_TEST(IteratorTest, preIncrementTest) {
185   auto plus_plus = this->packet->begin();
186   for (size_t i = 0; i < count_all.size() - 1; i++) {
187     ASSERT_EQ(count_all[i + 1], *(++plus_plus)) << "Pre-increment test: Dereferenced iterator does not equal expected "
188                                                 << "at index " << i;
189   }
190 }
191 
192 TYPED_TEST(IteratorTest, postIncrementTest) {
193   auto plus_plus = this->packet->begin();
194   for (size_t i = 0; i < count_all.size(); i++) {
195     ASSERT_EQ(count_all[i], *(plus_plus++)) << "Post-increment test: Dereferenced iterator does not equal expected "
196                                             << "at index " << i;
197   }
198 }
199 
200 TYPED_TEST(IteratorTest, additionTest) {
201   auto plus = this->packet->begin();
202   for (size_t i = 0; i < count_all.size(); i++) {
203     ASSERT_EQ(count_all[i], *plus) << "+ test: Dereferenced iterator does not equal expected at index " << i;
204     plus = plus + 1;
205   }
206 }
207 
208 TYPED_TEST(IteratorTest, minusEqTest) {
209   auto minus_eq = this->packet->end();
210   minus_eq -= 1;
211   size_t index = count_all.size() - 1;
212   for (size_t i = 0; index > i; i++) {
213     ASSERT_EQ(count_all[index], *minus_eq)
214         << "-= test: Dereferenced iterator does not equal expected at index " << index;
215     index -= i;
216     minus_eq -= i;
217   }
218 }
219 
220 TYPED_TEST(IteratorTest, preDecrementTest) {
221   auto minus_minus = this->packet->end();
222   for (size_t i = count_all.size(); i > 0; i--) {
223     ASSERT_EQ(count_all[i - 1], *(--minus_minus))
224         << "Pre-decrement test: Dereferenced iterator does not equal expected "
225         << "at index " << i;
226   }
227 }
228 
229 TYPED_TEST(IteratorTest, postDecrementTest) {
230   auto minus_minus = this->packet->end();
231   minus_minus--;
232   for (size_t i = count_all.size() - 1; i > 0; i--) {
233     ASSERT_EQ(count_all[i], *(minus_minus--)) << "Post-decrement test: Dereferenced iterator does not equal expected "
234                                               << "at index " << i;
235   }
236 }
237 
238 TYPED_TEST(IteratorTest, subtractionTest) {
239   auto minus = this->packet->end();
240   minus = minus - 1;
241   for (size_t i = count_all.size() - 1; i > 0; i--) {
242     ASSERT_EQ(count_all[i], *minus) << "- test: Dereferenced iterator does not equal expected at index " << i;
243     minus = minus - 1;
244   }
245 }
246 
247 TYPED_TEST(IteratorTest, differenceTest) {
248   auto begin = this->packet->begin();
249   auto end = this->packet->end();
250   int difference = end - begin;
251   ASSERT_EQ(difference, static_cast<int>(count_all.size()));
252   int neg_difference = begin - end;
253   ASSERT_EQ(neg_difference, -static_cast<int>(count_all.size()));
254 }
255 
256 TYPED_TEST(IteratorTest, equalityTest) {
257   auto begin = this->packet->begin();
258   auto end = this->packet->end();
259   auto begin_copy = this->packet->begin();
260   auto end_copy = this->packet->end();
261   ASSERT_EQ(begin_copy, begin);
262   ASSERT_EQ(end_copy, end);
263 }
264 
265 TYPED_TEST(IteratorTest, comparisonsTest) {
266   auto begin = this->packet->begin();
267   auto end = this->packet->end();
268   auto begin_copy = this->packet->begin();
269   auto end_copy = this->packet->end();
270   ASSERT_EQ(begin_copy, begin);
271   ASSERT_EQ(end_copy, end);
272   ASSERT_NE(begin, end);
273   ASSERT_TRUE(begin < end);
274   ASSERT_FALSE(end < end);
275   ASSERT_FALSE(end < begin);
276   ASSERT_FALSE(begin > end);
277   ASSERT_FALSE(end > end);
278   ASSERT_TRUE(end > begin);
279   ASSERT_TRUE(begin <= end);
280   ASSERT_TRUE(end <= end);
281   ASSERT_FALSE(end <= begin);
282   ASSERT_FALSE(begin >= end);
283   ASSERT_TRUE(end >= end);
284   ASSERT_TRUE(end >= begin);
285 }
286 
287 TYPED_TEST(PacketViewTest, getLengthTest) {
288   size_t length = this->packet->size();
289   ASSERT_EQ(length, count_all.size());
290 }
291 
292 TYPED_TEST(PacketViewTest, getAtIndexTest) {
293   size_t past_end = this->packet->size();
294   ASSERT_DEATH(this->packet->at(past_end), "");
295   size_t working_index = 0x1f;
296   ASSERT_EQ(0x1f, this->packet->at(working_index));
297 }
298 
299 TYPED_TEST(PacketViewTest, arrayOperatorTest) {
300   size_t past_end = this->packet->size();
301   ASSERT_DEATH((*(this->packet))[past_end], "");
302   size_t working_index = 0x1f;
303   ASSERT_EQ(0x1f, (*(this->packet))[working_index]);
304 }
305 
306 TYPED_TEST(IteratorTest, numBytesRemainingTest) {
307   auto all = this->packet->begin();
308   size_t remaining = all.NumBytesRemaining();
309   for (size_t n = remaining; n > 0; n--) {
310     ASSERT_EQ(remaining, all.NumBytesRemaining());
311     all++;
312     remaining--;
313   }
314   ASSERT_EQ(static_cast<size_t>(0), all.NumBytesRemaining());
315   ASSERT_DEATH(*(all++), "");
316   all++;
317   ASSERT_EQ(static_cast<size_t>(0), all.NumBytesRemaining());
318   ASSERT_DEATH(*(all++), "");
319 }
320 
321 TYPED_TEST(IteratorTest, subrangeTest) {
322   auto empty = this->packet->begin().Subrange(0, 0);
323   ASSERT_EQ(static_cast<size_t>(0), empty.NumBytesRemaining());
324   ASSERT_DEATH(*empty, "");
325 
326   empty = this->packet->begin().Subrange(this->packet->size(), 1);
327   ASSERT_EQ(static_cast<size_t>(0), empty.NumBytesRemaining());
328   ASSERT_DEATH(*empty, "");
329 
330   auto all = this->packet->begin();
331   auto fullrange = all.Subrange(0, all.NumBytesRemaining());
332   ASSERT_EQ(all.NumBytesRemaining(), fullrange.NumBytesRemaining());
333   ASSERT_EQ(*(all + 1), 1);
334 
335   fullrange = all.Subrange(0, all.NumBytesRemaining() + 1);
336   ASSERT_EQ(all.NumBytesRemaining(), fullrange.NumBytesRemaining());
337   ASSERT_EQ(*(all + 1), 1);
338 
339   fullrange = all.Subrange(0, all.NumBytesRemaining() + 10);
340   ASSERT_EQ(all.NumBytesRemaining(), fullrange.NumBytesRemaining());
341   ASSERT_EQ(*(all + 1), 1);
342 
343   auto subrange = all.Subrange(0, 1);
344   ASSERT_EQ(1, subrange.NumBytesRemaining());
345   ASSERT_EQ(*(subrange), 0);
346 
347   subrange = this->packet->begin().Subrange(0, 4);
348   ASSERT_EQ(4, subrange.NumBytesRemaining());
349   ASSERT_EQ(*(subrange + 1), 1);
350 
351   subrange = all.Subrange(0, 3);
352   ASSERT_EQ(3, subrange.NumBytesRemaining());
353   ASSERT_EQ(*(subrange + 1), 1);
354 
355   subrange = all.Subrange(0, all.NumBytesRemaining() - 1);
356   ASSERT_EQ(all.NumBytesRemaining() - 1, subrange.NumBytesRemaining());
357   ASSERT_EQ(*(subrange + 1), 1);
358 
359   subrange = all.Subrange(0, all.NumBytesRemaining() - 2);
360   ASSERT_EQ(all.NumBytesRemaining() - 2, subrange.NumBytesRemaining());
361   ASSERT_EQ(*(subrange + 1), 1);
362 
363   subrange = all.Subrange(1, all.NumBytesRemaining());
364   ASSERT_EQ(all.NumBytesRemaining() - 1, subrange.NumBytesRemaining());
365   ASSERT_EQ(*subrange, 1);
366 
367   subrange = all.Subrange(2, all.NumBytesRemaining());
368   ASSERT_EQ(all.NumBytesRemaining() - 2, subrange.NumBytesRemaining());
369   ASSERT_EQ(*subrange, 2);
370 
371   subrange = all.Subrange(1, all.NumBytesRemaining() - 1);
372   ASSERT_EQ(all.NumBytesRemaining() - 1, subrange.NumBytesRemaining());
373   ASSERT_EQ(*subrange, 1);
374 
375   subrange = all.Subrange(2, all.NumBytesRemaining() - 2);
376   ASSERT_EQ(all.NumBytesRemaining() - 2, subrange.NumBytesRemaining());
377   ASSERT_EQ(*subrange, 2);
378 
379   subrange = all.Subrange(1, 1);
380   ASSERT_EQ(1, subrange.NumBytesRemaining());
381   ASSERT_EQ(*(subrange), 1);
382 
383   subrange = all.Subrange(1, 2);
384   ASSERT_EQ(2, subrange.NumBytesRemaining());
385   ASSERT_EQ(*(subrange), 1);
386 
387   subrange = all.Subrange(2, 1);
388   ASSERT_EQ(1, subrange.NumBytesRemaining());
389   ASSERT_EQ(*(subrange), 2);
390 
391   subrange = this->packet->begin().Subrange(this->packet->size() - 1, 2);
392   ASSERT_EQ(static_cast<size_t>(1), subrange.NumBytesRemaining());
393   ASSERT_EQ(*(subrange), this->packet->size() - 1);
394 }
395 
396 using SubviewTestParam = std::pair<size_t, size_t>;
397 class SubviewBaseTest : public ::testing::TestWithParam<SubviewTestParam> {
398  public:
399   class SubPacketView : public PacketView<true> {
400    public:
401     using PacketView<true>::PacketView;
402     PacketView<true> Slice(size_t header, size_t tail) {
403       return PacketView<true>::GetLittleEndianSubview(header, tail);
404     }
405   };
406 };
407 
408 class SubviewPassTest : public SubviewBaseTest {};
409 
410 TEST_P(SubviewPassTest, subviewTest) {
411   auto header = GetParam().first;
412   auto tail = GetParam().second;
413   SubPacketView single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
414   SubPacketView multi_view({
415       View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
416       View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
417       View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
418   });
419 
420   auto single_slice = single_view.Slice(header, tail);
421   auto multi_slice = multi_view.Slice(header, tail);
422 
423   ASSERT_EQ(single_slice.size(), tail - header);
424   ASSERT_EQ(single_slice.size(), multi_slice.size());
425   for (size_t i = 0; i < single_slice.size(); i++) {
426     ASSERT_EQ(single_slice[i], multi_slice[i]);
427   }
428 }
429 
430 static const size_t boundary_1 = count_1.size();
431 static const size_t boundary_2 = count_1.size() + count_2.size();
432 
433 INSTANTIATE_TEST_CASE_P(
434     chopomatic, SubviewPassTest,
435     ::testing::Values(
436         // {begin, end} pairs for subsets into the PacketView
437         SubviewTestParam{0, 0}, SubviewTestParam{0, boundary_1}, SubviewTestParam{0, boundary_1 + 1},
438         SubviewTestParam{0, boundary_2}, SubviewTestParam{0, boundary_2 + 1}, SubviewTestParam{0, count_all.size()},
439         SubviewTestParam{boundary_1 - 1, boundary_1}, SubviewTestParam{boundary_1 - 1, boundary_1 + 1},
440         SubviewTestParam{boundary_1 - 1, boundary_2}, SubviewTestParam{boundary_1 - 1, boundary_2 + 1},
441         SubviewTestParam{boundary_1 - 1, count_all.size()}, SubviewTestParam{boundary_1, boundary_1},
442         SubviewTestParam{boundary_1, boundary_2}, SubviewTestParam{boundary_1, boundary_2 + 1},
443         SubviewTestParam{boundary_1, count_all.size()}, SubviewTestParam{boundary_2 - 1, boundary_2},
444         SubviewTestParam{boundary_2 - 1, boundary_2 + 1}, SubviewTestParam{boundary_2 - 1, count_all.size()},
445         SubviewTestParam{boundary_2, boundary_2}, SubviewTestParam{boundary_2, boundary_2 + 1},
446         SubviewTestParam{boundary_2, count_all.size()}, SubviewTestParam{count_all.size() - 1, count_all.size()},
447         SubviewTestParam{count_all.size(), count_all.size()}));
448 
449 class SubviewDeathTest : public SubviewBaseTest {};
450 
451 TEST_P(SubviewDeathTest, subviewDeathTest) {
452   auto header = GetParam().first;
453   auto tail = GetParam().second;
454   SubPacketView single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
455   SubPacketView multi_view({
456       View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
457       View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
458       View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
459   });
460 
461   ASSERT_DEATH(auto single_slice = single_view.Slice(header, tail), "");
462   ASSERT_DEATH(auto multi_slice = multi_view.Slice(header, tail), "");
463 }
464 
465 INSTANTIATE_TEST_CASE_P(chopomaticDeath, SubviewDeathTest,
466                         ::testing::Values(
467                             // {begin, end} pairs for subsets into the PacketView
468                             SubviewTestParam{1, 0}, SubviewTestParam{count_all.size(), count_all.size() - 1},
469                             SubviewTestParam{count_all.size(), count_all.size() + 1}));
470 
471 TEST(SubviewTest, simpleSubviewTest) {
472   PacketView<true> view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
473   PacketView<true> sub_1_view = view.GetLittleEndianSubview(0, view.size());
474   PacketView<true> sub_2_view = sub_1_view.GetLittleEndianSubview(0, sub_1_view.size());
475   PacketView<true> sub_3_view = sub_2_view.GetLittleEndianSubview(0, sub_2_view.size());
476   PacketView<true> sub_4_view = sub_3_view.GetLittleEndianSubview(0, sub_3_view.size());
477   ASSERT_EQ(sub_1_view.size(), view.size());
478   ASSERT_EQ(sub_2_view.size(), view.size());
479   ASSERT_EQ(sub_3_view.size(), view.size());
480   ASSERT_EQ(sub_4_view.size(), view.size());
481 }
482 
483 TEST(SubviewTest, realSubviewTest) {
484   PacketView<true> view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
485   std::vector<PacketView<true>> sub_views{view};
486   for (size_t i = 1; i < 6; i++) {
487     size_t parent_size = sub_views[i - 1].size();
488     sub_views.push_back(sub_views[i - 1].GetLittleEndianSubview(1, parent_size - 1));
489     ASSERT_EQ(sub_views[i][0], i);
490     ASSERT_EQ(sub_views[i].size(), parent_size - 2);
491   }
492 }
493 
494 TEST(SubviewTest, subSubviewTest) {
495   PacketView<true> single_view({View(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size())});
496   PacketView<true> multi_view({
497       View(std::make_shared<const vector<uint8_t>>(count_1), 0, count_1.size()),
498       View(std::make_shared<const vector<uint8_t>>(count_2), 0, count_2.size()),
499       View(std::make_shared<const vector<uint8_t>>(count_3), 0, count_3.size()),
500   });
501   ASSERT_EQ(single_view.size(), multi_view.size());
502   for (size_t i = 0; i < count_all.size() / 2; i++) {
503     PacketView<true> sub_single_view = single_view.GetLittleEndianSubview(i, count_all.size() - i);
504     PacketView<true> sub_multi_view = multi_view.GetLittleEndianSubview(i, count_all.size() - i);
505     ASSERT_EQ(count_all.size() - 2 * i, sub_single_view.size());
506     ASSERT_EQ(sub_single_view.size(), sub_multi_view.size());
507     for (size_t j = 0; j < sub_single_view.size() / 2; j++) {
508       PacketView<true> sub_sub_single_view = sub_single_view.GetLittleEndianSubview(j, sub_single_view.size() - j);
509       PacketView<true> sub_sub_multi_view = sub_multi_view.GetLittleEndianSubview(j, sub_multi_view.size() - j);
510       ASSERT_EQ(sub_single_view.size() - 2 * j, sub_sub_single_view.size());
511       ASSERT_EQ(sub_sub_single_view.size(), sub_sub_multi_view.size());
512     }
513   }
514 }
515 
516 TEST_F(PacketViewMultiViewTest, sizeTest) {
517   ASSERT_EQ(single_view.size(), multi_view.size());
518 }
519 
520 TEST_F(PacketViewMultiViewTest, dereferenceTestLittleEndian) {
521   auto single_itr = single_view.begin();
522   auto multi_itr = multi_view.begin();
523   for (size_t i = 0; i < single_view.size(); i++) {
524     ASSERT_EQ(*(single_itr++), *(multi_itr++));
525   }
526   ASSERT_DEATH(*multi_itr, "");
527 }
528 
529 TEST_F(PacketViewMultiViewTest, dereferenceTestBigEndian) {
530   auto single_itr = single_view.begin();
531   auto multi_itr = multi_view.begin();
532   for (size_t i = 0; i < single_view.size(); i++) {
533     ASSERT_EQ(*(single_itr++), *(multi_itr++));
534   }
535   ASSERT_DEATH(*multi_itr, "");
536 }
537 
538 TEST_F(PacketViewMultiViewTest, arrayOperatorTest) {
539   for (size_t i = 0; i < single_view.size(); i++) {
540     ASSERT_EQ(single_view[i], multi_view[i]);
541   }
542   ASSERT_DEATH(multi_view[single_view.size()], "");
543 }
544 
545 TEST_F(PacketViewMultiViewAppendTest, sizeTestAppend) {
546   ASSERT_EQ(single_view.size(), multi_view.size());
547 }
548 
549 TEST_F(PacketViewMultiViewAppendTest, dereferenceTestLittleEndianAppend) {
550   auto single_itr = single_view.begin();
551   auto multi_itr = multi_view.begin();
552   for (size_t i = 0; i < single_view.size(); i++) {
553     ASSERT_EQ(*(single_itr++), *(multi_itr++));
554   }
555   ASSERT_DEATH(*multi_itr, "");
556 }
557 
558 TEST_F(PacketViewMultiViewAppendTest, dereferenceTestBigEndianAppend) {
559   auto single_itr = single_view.begin();
560   auto multi_itr = multi_view.begin();
561   for (size_t i = 0; i < single_view.size(); i++) {
562     ASSERT_EQ(*(single_itr++), *(multi_itr++));
563   }
564   ASSERT_DEATH(*multi_itr, "");
565 }
566 
567 TEST_F(PacketViewMultiViewAppendTest, arrayOperatorTestAppend) {
568   for (size_t i = 0; i < single_view.size(); i++) {
569     ASSERT_EQ(single_view[i], multi_view[i]);
570   }
571   ASSERT_DEATH(multi_view[single_view.size()], "");
572 }
573 
574 TEST(ViewTest, arrayOperatorTest) {
575   View view_all(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
576   size_t past_end = view_all.size();
577   for (size_t i = 0; i < past_end; i++) {
578     ASSERT_EQ(view_all[i], count_all[i]);
579   }
580   ASSERT_DEATH(view_all[past_end], "");
581 
582   size_t header_size = 2;
583   size_t tail_size = 3;
584   View view_subset(std::make_shared<const vector<uint8_t>>(count_all), header_size, count_all.size() - tail_size);
585   View view_subset2(view_all, header_size, count_all.size() - tail_size);
586   size_t subset_length = view_subset.size();
587   for (size_t i = 0; i < subset_length; i++) {
588     ASSERT_EQ(view_subset[i], count_all[header_size + i]);
589     ASSERT_EQ(view_subset[i], view_subset2[i]);
590   }
591   ASSERT_DEATH(view_subset[subset_length + 1], "");
592   ASSERT_DEATH(view_subset2[subset_length + 1], "");
593 }
594 
595 TEST(ViewTest, earlySubSubviewTest) {
596   View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
597   View sub_1_view(view, view.size() - 3, view.size() - 1);
598   View sub_2_view(sub_1_view, 1, 2);
599   ASSERT_EQ(sub_1_view.size(), 2u);
600   ASSERT_EQ(sub_2_view.size(), 1u);
601 }
602 
603 TEST(ViewTest, subSubviewTest) {
604   View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
605   std::vector<View> sub_views{view};
606   for (size_t i = 1; i < 6; i++) {
607     size_t parent_size = sub_views[i - 1].size();
608     sub_views.push_back({View(sub_views[i - 1], 1, parent_size - 1)});
609     ASSERT_EQ(sub_views[i][0], i);
610     ASSERT_EQ(sub_views[i].size(), parent_size - 2);
611   }
612 }
613 
614 TEST(ViewTest, zeroSubviewTest) {
615   View view(std::make_shared<const vector<uint8_t>>(count_all), 0, count_all.size());
616   View subview(view, view.size(), view.size() + 1);
617   ASSERT_EQ(subview.size(), 0u);
618 }
619 }  // namespace packet
620 }  // namespace bluetooth
621