A Discrete-Event Network Simulator
API
packet-metadata-test.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2006,2007 INRIA
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 #include "ns3/header.h"
20 #include "ns3/packet-metadata.h"
21 #include "ns3/packet.h"
22 #include "ns3/test.h"
23 #include "ns3/trailer.h"
24 
25 #include <cstdarg>
26 #include <iostream>
27 #include <sstream>
28 
29 using namespace ns3;
30 
31 namespace
32 {
33 
42 class HistoryHeaderBase : public Header
43 {
44  public:
49  static TypeId GetTypeId();
55  bool IsOk() const;
56 
57  protected:
61  void ReportError();
62 
63  private:
64  bool m_ok;
65 };
66 
67 TypeId
68 HistoryHeaderBase::GetTypeId()
69 {
70  static TypeId tid = TypeId("ns3::HistoryHeaderBase").SetParent<Header>();
71  return tid;
72 }
73 
74 HistoryHeaderBase::HistoryHeaderBase()
75  : m_ok(true)
76 {
77 }
78 
79 bool
81 {
82  return m_ok;
83 }
84 
85 void
87 {
88  m_ok = false;
89 }
90 
99 template <int N>
101 {
102  public:
103  HistoryHeader();
108  static TypeId GetTypeId();
109  TypeId GetInstanceTypeId() const override;
110  void Print(std::ostream& os) const override;
111  uint32_t GetSerializedSize() const override;
112  void Serialize(Buffer::Iterator start) const override;
113  uint32_t Deserialize(Buffer::Iterator start) override;
114 };
115 
116 template <int N>
119 {
120 }
121 
122 template <int N>
123 TypeId
125 {
126  std::ostringstream oss;
127  oss << "ns3::HistoryHeader<" << N << ">";
128  static TypeId tid =
129  TypeId(oss.str()).SetParent<HistoryHeaderBase>().AddConstructor<HistoryHeader<N>>();
130  return tid;
131 }
132 
133 template <int N>
134 TypeId
136 {
137  return GetTypeId();
138 }
139 
140 template <int N>
141 void
142 HistoryHeader<N>::Print(std::ostream& os) const
143 {
144  NS_ASSERT(false);
145 }
146 
147 template <int N>
148 uint32_t
150 {
151  return N;
152 }
153 
154 template <int N>
155 void
157 {
158  start.WriteU8(N, N);
159 }
160 
161 template <int N>
162 uint32_t
164 {
165  for (int i = 0; i < N; i++)
166  {
167  if (start.ReadU8() != N)
168  {
169  ReportError();
170  }
171  }
172  return N;
173 }
174 
184 {
185  public:
190  static TypeId GetTypeId();
196  bool IsOk() const;
197 
198  protected:
202  void ReportError();
203 
204  private:
205  bool m_ok;
206 };
207 
208 TypeId
210 {
211  static TypeId tid = TypeId("ns3::HistoryTrailerBase").SetParent<Trailer>();
212  return tid;
213 }
214 
216  : m_ok(true)
217 {
218 }
219 
220 bool
222 {
223  return m_ok;
224 }
225 
226 void
228 {
229  m_ok = false;
230 }
231 
240 template <int N>
242 {
243  public:
244  HistoryTrailer();
245 
250  static TypeId GetTypeId();
251  TypeId GetInstanceTypeId() const override;
252  void Print(std::ostream& os) const override;
253  uint32_t GetSerializedSize() const override;
254  void Serialize(Buffer::Iterator start) const override;
255  uint32_t Deserialize(Buffer::Iterator start) override;
256 };
257 
258 template <int N>
260 {
261 }
262 
263 template <int N>
264 TypeId
266 {
267  std::ostringstream oss;
268  oss << "ns3::HistoryTrailer<" << N << ">";
269  static TypeId tid =
270  TypeId(oss.str()).SetParent<HistoryTrailerBase>().AddConstructor<HistoryTrailer<N>>();
271  return tid;
272 }
273 
274 template <int N>
275 TypeId
277 {
278  return GetTypeId();
279 }
280 
281 template <int N>
282 void
283 HistoryTrailer<N>::Print(std::ostream& os) const
284 {
285  NS_ASSERT(false);
286 }
287 
288 template <int N>
289 uint32_t
291 {
292  return N;
293 }
294 
295 template <int N>
296 void
298 {
299  start.Prev(N);
300  start.WriteU8(N, N);
301 }
302 
303 template <int N>
304 uint32_t
306 {
307  start.Prev(N);
308  for (int i = 0; i < N; i++)
309  {
310  if (start.ReadU8() != N)
311  {
312  ReportError();
313  }
314  }
315  return N;
316 }
317 
318 } // namespace
319 
327 {
328  public:
330  ~PacketMetadataTest() override;
337  void CheckHistory(Ptr<Packet> p, uint32_t n, ...);
338  void DoRun() override;
339 
340  private:
346  Ptr<Packet> DoAddHeader(Ptr<Packet> p);
347 };
348 
350  : TestCase("Packet metadata")
351 {
352 }
353 
355 {
356 }
357 
358 void
360 {
361  std::list<int> expected;
362  va_list ap;
363  va_start(ap, n);
364  for (uint32_t j = 0; j < n; j++)
365  {
366  int v = va_arg(ap, int);
367  expected.push_back(v);
368  }
369  va_end(ap);
370 
372  std::list<int> got;
373  while (k.HasNext())
374  {
375  PacketMetadata::Item item = k.Next();
376  if (item.isFragment || item.type == PacketMetadata::Item::PAYLOAD)
377  {
378  got.push_back(item.currentSize);
379  continue;
380  }
381  if (item.type == PacketMetadata::Item::HEADER)
382  {
383  Callback<ObjectBase*> constructor = item.tid.GetConstructor();
384  auto header = dynamic_cast<HistoryHeaderBase*>(constructor());
385  if (header == nullptr)
386  {
387  goto error;
388  }
389  header->Deserialize(item.current);
390  if (!header->IsOk())
391  {
392  delete header;
393  goto error;
394  }
395  delete header;
396  }
397  else if (item.type == PacketMetadata::Item::TRAILER)
398  {
399  Callback<ObjectBase*> constructor = item.tid.GetConstructor();
400  auto trailer = dynamic_cast<HistoryTrailerBase*>(constructor());
401  if (trailer == nullptr)
402  {
403  goto error;
404  }
405  trailer->Deserialize(item.current);
406  if (!trailer->IsOk())
407  {
408  delete trailer;
409  goto error;
410  }
411  delete trailer;
412  }
413  got.push_back(item.currentSize);
414  }
415 
416  for (auto i = got.begin(), j = expected.begin(); i != got.end(); i++, j++)
417  {
418  NS_ASSERT(j != expected.end());
419  if (*j != *i)
420  {
421  goto error;
422  }
423  }
424  return;
425 error:
426  std::ostringstream failure;
427  failure << "PacketMetadata error. Got:\"";
428  for (auto i = got.begin(); i != got.end(); i++)
429  {
430  failure << *i << ", ";
431  }
432  failure << "\", expected: \"";
433  for (auto j = expected.begin(); j != expected.end(); j++)
434  {
435  failure << *j << ", ";
436  }
437  failure << "\"";
438  NS_TEST_ASSERT_MSG_EQ(false, true, failure.str());
439 }
440 
441 #define ADD_HEADER(p, n) \
442  { \
443  HistoryHeader<n> header; \
444  p->AddHeader(header); \
445  }
446 #define ADD_TRAILER(p, n) \
447  { \
448  HistoryTrailer<n> trailer; \
449  p->AddTrailer(trailer); \
450  }
451 #define REM_HEADER(p, n) \
452  { \
453  HistoryHeader<n> header; \
454  p->RemoveHeader(header); \
455  }
456 #define REM_TRAILER(p, n) \
457  { \
458  HistoryTrailer<n> trailer; \
459  p->RemoveTrailer(trailer); \
460  }
461 #define CHECK_HISTORY(p, ...) \
462  { \
463  CheckHistory(p, __VA_ARGS__); \
464  uint32_t size = p->GetSerializedSize(); \
465  uint8_t* buffer = new uint8_t[size]; \
466  p->Serialize(buffer, size); \
467  Ptr<Packet> otherPacket = Create<Packet>(buffer, size, true); \
468  delete[] buffer; \
469  CheckHistory(otherPacket, __VA_ARGS__); \
470  }
471 
474 {
475  ADD_HEADER(p, 10);
476  return p;
477 }
478 
479 void
481 {
482  PacketMetadata::Enable();
483 
484  Ptr<Packet> p = Create<Packet>(0);
485  Ptr<Packet> p1 = Create<Packet>(0);
486 
487  p = Create<Packet>(10);
488  ADD_TRAILER(p, 100);
489  CHECK_HISTORY(p, 2, 10, 100);
490 
491  p = Create<Packet>(10);
492  ADD_HEADER(p, 1);
493  ADD_HEADER(p, 2);
494  ADD_HEADER(p, 3);
495  CHECK_HISTORY(p, 4, 3, 2, 1, 10);
496  ADD_HEADER(p, 5);
497  CHECK_HISTORY(p, 5, 5, 3, 2, 1, 10);
498  ADD_HEADER(p, 6);
499  CHECK_HISTORY(p, 6, 6, 5, 3, 2, 1, 10);
500 
501  p = Create<Packet>(10);
502  ADD_HEADER(p, 1);
503  ADD_HEADER(p, 2);
504  ADD_HEADER(p, 3);
505  REM_HEADER(p, 3);
506  CHECK_HISTORY(p, 3, 2, 1, 10);
507 
508  p = Create<Packet>(10);
509  ADD_HEADER(p, 1);
510  ADD_HEADER(p, 2);
511  ADD_HEADER(p, 3);
512  REM_HEADER(p, 3);
513  REM_HEADER(p, 2);
514  CHECK_HISTORY(p, 2, 1, 10);
515 
516  p = Create<Packet>(10);
517  ADD_HEADER(p, 1);
518  ADD_HEADER(p, 2);
519  ADD_HEADER(p, 3);
520  REM_HEADER(p, 3);
521  REM_HEADER(p, 2);
522  REM_HEADER(p, 1);
523  CHECK_HISTORY(p, 1, 10);
524 
525  p = Create<Packet>(10);
526  ADD_HEADER(p, 1);
527  ADD_HEADER(p, 2);
528  ADD_HEADER(p, 3);
529  p1 = p->Copy();
530  REM_HEADER(p1, 3);
531  REM_HEADER(p1, 2);
532  REM_HEADER(p1, 1);
533  CHECK_HISTORY(p1, 1, 10);
534  CHECK_HISTORY(p, 4, 3, 2, 1, 10);
535  ADD_HEADER(p1, 1);
536  ADD_HEADER(p1, 2);
537  CHECK_HISTORY(p1, 3, 2, 1, 10);
538  CHECK_HISTORY(p, 4, 3, 2, 1, 10);
539  ADD_HEADER(p, 3);
540  CHECK_HISTORY(p, 5, 3, 3, 2, 1, 10);
541  ADD_TRAILER(p, 4);
542  CHECK_HISTORY(p, 6, 3, 3, 2, 1, 10, 4);
543  ADD_TRAILER(p, 5);
544  CHECK_HISTORY(p, 7, 3, 3, 2, 1, 10, 4, 5);
545  REM_HEADER(p, 3);
546  CHECK_HISTORY(p, 6, 3, 2, 1, 10, 4, 5);
547  REM_TRAILER(p, 5);
548  CHECK_HISTORY(p, 5, 3, 2, 1, 10, 4);
549  p1 = p->Copy();
550  REM_TRAILER(p, 4);
551  CHECK_HISTORY(p, 4, 3, 2, 1, 10);
552  CHECK_HISTORY(p1, 5, 3, 2, 1, 10, 4);
553  p1->RemoveAtStart(3);
554  CHECK_HISTORY(p1, 4, 2, 1, 10, 4);
555  p1->RemoveAtStart(1);
556  CHECK_HISTORY(p1, 4, 1, 1, 10, 4);
557  p1->RemoveAtStart(1);
558  CHECK_HISTORY(p1, 3, 1, 10, 4);
559  p1->RemoveAtEnd(4);
560  CHECK_HISTORY(p1, 2, 1, 10);
561  p1->RemoveAtStart(1);
562  CHECK_HISTORY(p1, 1, 10);
563 
564  p = Create<Packet>(10);
565  ADD_HEADER(p, 8);
566  ADD_TRAILER(p, 8);
567  ADD_TRAILER(p, 8);
568  p->RemoveAtStart(8 + 10 + 8);
569  CHECK_HISTORY(p, 1, 8);
570 
571  p = Create<Packet>(10);
572  ADD_HEADER(p, 10);
573  ADD_HEADER(p, 8);
574  ADD_TRAILER(p, 6);
575  ADD_TRAILER(p, 7);
576  ADD_TRAILER(p, 9);
577  p->RemoveAtStart(5);
578  p->RemoveAtEnd(12);
579  CHECK_HISTORY(p, 5, 3, 10, 10, 6, 4);
580 
581  p = Create<Packet>(10);
582  ADD_HEADER(p, 10);
583  ADD_TRAILER(p, 6);
584  p->RemoveAtEnd(18);
585  ADD_TRAILER(p, 5);
586  ADD_HEADER(p, 3);
587  CHECK_HISTORY(p, 3, 3, 8, 5);
588  p->RemoveAtStart(12);
589  CHECK_HISTORY(p, 1, 4);
590  p->RemoveAtEnd(2);
591  CHECK_HISTORY(p, 1, 2);
592  ADD_HEADER(p, 10);
593  CHECK_HISTORY(p, 2, 10, 2);
594  p->RemoveAtEnd(5);
595  CHECK_HISTORY(p, 1, 7);
596 
597  Ptr<Packet> p2 = Create<Packet>(0);
598  Ptr<Packet> p3 = Create<Packet>(0);
599 
600  p = Create<Packet>(40);
601  ADD_HEADER(p, 5);
602  ADD_HEADER(p, 8);
603  CHECK_HISTORY(p, 3, 8, 5, 40);
604  p1 = p->CreateFragment(0, 5);
605  p2 = p->CreateFragment(5, 5);
606  p3 = p->CreateFragment(10, 43);
607  CHECK_HISTORY(p1, 1, 5);
608  CHECK_HISTORY(p2, 2, 3, 2);
609  CHECK_HISTORY(p3, 2, 3, 40);
610  p1->AddAtEnd(p2);
611  CHECK_HISTORY(p1, 2, 8, 2);
612  CHECK_HISTORY(p2, 2, 3, 2);
613  p1->AddAtEnd(p3);
614  CHECK_HISTORY(p1, 3, 8, 5, 40);
615  CHECK_HISTORY(p2, 2, 3, 2);
616  CHECK_HISTORY(p3, 2, 3, 40);
617  p1 = p->CreateFragment(0, 5);
618  CHECK_HISTORY(p1, 1, 5);
619 
620  p3 = Create<Packet>(50);
621  ADD_HEADER(p3, 8);
622  CHECK_HISTORY(p3, 2, 8, 50);
623  CHECK_HISTORY(p1, 1, 5);
624  p1->AddAtEnd(p3);
625  CHECK_HISTORY(p1, 3, 5, 8, 50);
626  ADD_HEADER(p1, 5);
627  CHECK_HISTORY(p1, 4, 5, 5, 8, 50);
628  ADD_TRAILER(p1, 2);
629  CHECK_HISTORY(p1, 5, 5, 5, 8, 50, 2);
630  REM_HEADER(p1, 5);
631  CHECK_HISTORY(p1, 4, 5, 8, 50, 2);
632  p1->RemoveAtEnd(60);
633  CHECK_HISTORY(p1, 1, 5);
634  p1->AddAtEnd(p2);
635  CHECK_HISTORY(p1, 2, 8, 2);
636  CHECK_HISTORY(p2, 2, 3, 2);
637 
638  p3 = Create<Packet>(40);
639  ADD_HEADER(p3, 5);
640  ADD_HEADER(p3, 5);
641  CHECK_HISTORY(p3, 3, 5, 5, 40);
642  p1 = p3->CreateFragment(0, 5);
643  p2 = p3->CreateFragment(5, 5);
644  CHECK_HISTORY(p1, 1, 5);
645  CHECK_HISTORY(p2, 1, 5);
646  p1->AddAtEnd(p2);
647  CHECK_HISTORY(p1, 2, 5, 5);
648 
649  p = Create<Packet>(0);
650  CHECK_HISTORY(p, 0);
651 
652  p3 = Create<Packet>(0);
653  ADD_HEADER(p3, 5);
654  ADD_HEADER(p3, 5);
655  CHECK_HISTORY(p3, 2, 5, 5);
656  p1 = p3->CreateFragment(0, 4);
657  p2 = p3->CreateFragment(9, 1);
658  CHECK_HISTORY(p1, 1, 4);
659  CHECK_HISTORY(p2, 1, 1);
660  p1->AddAtEnd(p2);
661  CHECK_HISTORY(p1, 2, 4, 1);
662 
663  p = Create<Packet>(2000);
664  CHECK_HISTORY(p, 1, 2000);
665 
666  p = Create<Packet>();
667  ADD_TRAILER(p, 10);
668  ADD_HEADER(p, 5);
669  p1 = p->CreateFragment(0, 8);
670  p2 = p->CreateFragment(8, 7);
671  p1->AddAtEnd(p2);
672  CHECK_HISTORY(p, 2, 5, 10);
673 
674  p = Create<Packet>();
675  ADD_TRAILER(p, 10);
676  REM_TRAILER(p, 10);
677  ADD_TRAILER(p, 10);
678  CHECK_HISTORY(p, 1, 10);
679 
680  p = Create<Packet>();
681  ADD_HEADER(p, 10);
682  REM_HEADER(p, 10);
683  ADD_HEADER(p, 10);
684  CHECK_HISTORY(p, 1, 10);
685 
686  p = Create<Packet>();
687  ADD_HEADER(p, 10);
688  p = DoAddHeader(p);
689  CHECK_HISTORY(p, 2, 10, 10);
690 
691  p = Create<Packet>(10);
692  ADD_HEADER(p, 8);
693  ADD_TRAILER(p, 8);
694  ADD_TRAILER(p, 8);
695  p->RemoveAtStart(8 + 10 + 8);
696  CHECK_HISTORY(p, 1, 8);
697 
698  p = Create<Packet>(0);
699  ADD_HEADER(p, 8);
700  REM_HEADER(p, 8);
701  CHECK_HISTORY(p, 0);
702 
703  p = Create<Packet>(0);
704  ADD_TRAILER(p, 8);
705  REM_TRAILER(p, 8);
706  CHECK_HISTORY(p, 0);
707 
708  p = Create<Packet>(0);
709  ADD_HEADER(p, 8);
710  p->RemoveAtStart(8);
711  CHECK_HISTORY(p, 0);
712 
713  p = Create<Packet>(0);
714  ADD_HEADER(p, 8);
715  ADD_TRAILER(p, 8);
716  REM_TRAILER(p, 8);
717  REM_HEADER(p, 8);
718  CHECK_HISTORY(p, 0);
719 
720  p = Create<Packet>(0);
721  ADD_HEADER(p, 8);
722  ADD_TRAILER(p, 8);
723  REM_HEADER(p, 8);
724  REM_TRAILER(p, 8);
725  CHECK_HISTORY(p, 0);
726 
727  p = Create<Packet>(0);
728  ADD_HEADER(p, 8);
729  ADD_TRAILER(p, 8);
730  REM_TRAILER(p, 8);
731  p->RemoveAtStart(8);
732  CHECK_HISTORY(p, 0);
733 
734  p = Create<Packet>(0);
735  ADD_HEADER(p, 8);
736  ADD_TRAILER(p, 8);
737  REM_HEADER(p, 8);
738  p->RemoveAtEnd(8);
739  CHECK_HISTORY(p, 0);
740 
741  p = Create<Packet>(0);
742  ADD_HEADER(p, 8);
743  ADD_TRAILER(p, 8);
744  REM_TRAILER(p, 8);
745  p->RemoveAtEnd(8);
746  CHECK_HISTORY(p, 0);
747 
748  p = Create<Packet>(0);
749  ADD_HEADER(p, 8);
750  ADD_TRAILER(p, 8);
751  REM_HEADER(p, 8);
752  p->RemoveAtStart(8);
753  CHECK_HISTORY(p, 0);
754 
755  p = Create<Packet>(16383);
756  p = Create<Packet>(16384);
757 
760  p = Create<Packet>(40);
761  p2 = p->CreateFragment(5, 5);
762  p3 = p->CreateFragment(10, 30);
763  ADD_HEADER(p2, 8);
764  ADD_HEADER(p3, 8);
765  REM_HEADER(p2, 8);
766  REM_HEADER(p3, 8);
767  p2->AddAtEnd(p3);
768 
769  p = Create<Packet>(1000);
770  ADD_HEADER(p, 10);
771  ADD_TRAILER(p, 5);
772  p1 = p->Copy();
773  ADD_HEADER(p1, 20);
774  REM_HEADER(p1, 20);
775  REM_TRAILER(p1, 5);
776  NS_TEST_EXPECT_MSG_EQ(p->GetSize(), 1015, "Correct size");
777 
778  p = Create<Packet>(1510);
779  ADD_HEADER(p, 8);
780  ADD_HEADER(p, 25);
781  REM_HEADER(p, 25);
782  ADD_HEADER(p, 1);
783  p1 = p->CreateFragment(0, 1500);
784  p2 = p1->Copy();
785  ADD_HEADER(p2, 24);
786  NS_TEST_EXPECT_MSG_EQ(p->GetSize(), 1519, "Correct size");
787 
788  p = Create<Packet>(1000);
789  ADD_HEADER(p, 2);
790  ADD_TRAILER(p, 3);
791  p1 = p->Copy();
792  CHECK_HISTORY(p1, 3, 2, 1000, 3);
793  REM_HEADER(p, 2);
794  ADD_HEADER(p, 1);
795  CHECK_HISTORY(p, 3, 1, 1000, 3);
796  CHECK_HISTORY(p1, 3, 2, 1000, 3);
797 
798  p = Create<Packet>(200);
799  ADD_HEADER(p, 24);
800  p1 = p->CreateFragment(0, 100);
801  p2 = p->CreateFragment(100, 100);
802  p1->AddAtEnd(p2);
803 
804  p = Create<Packet>();
805  ADD_HEADER(p, 10);
806  p1 = Create<Packet>();
807  ADD_HEADER(p1, 11);
808  REM_HEADER(p1, 11);
809  p->AddAtEnd(p1);
810 
811  p = Create<Packet>(500);
812  CHECK_HISTORY(p, 1, 500);
813  ADD_HEADER(p, 10);
814  CHECK_HISTORY(p, 2, 10, 500);
815  REM_HEADER(p, 10);
816  CHECK_HISTORY(p, 1, 500);
817  p->RemoveAtEnd(10);
818  CHECK_HISTORY(p, 1, 490);
819 
820  p = Create<Packet>(500);
821  CHECK_HISTORY(p, 1, 500);
822  ADD_TRAILER(p, 10);
823  CHECK_HISTORY(p, 2, 500, 10);
824  REM_TRAILER(p, 10);
825  CHECK_HISTORY(p, 1, 500);
826  p->RemoveAtStart(10);
827  CHECK_HISTORY(p, 1, 490);
828 
831  p = Create<Packet>(500);
832  ADD_HEADER(p, 10);
833  ADD_HEADER(p, 20);
834  ADD_HEADER(p, 5);
835  CHECK_HISTORY(p, 4, 5, 20, 10, 500);
836  p1 = p->CreateFragment(0, 6);
837  p2 = p->CreateFragment(6, 535 - 6);
838  p1->AddAtEnd(p2);
839 
842  p = Create<Packet>(reinterpret_cast<const uint8_t*>("hello world"), 11);
843  ADD_HEADER(p, 2);
844  CHECK_HISTORY(p, 2, 2, 11);
845  p1 = p->CreateFragment(0, 5);
846  CHECK_HISTORY(p1, 2, 2, 3);
847  p2 = p->CreateFragment(5, 8);
848  CHECK_HISTORY(p2, 1, 8);
849 
850  ADD_HEADER(p1, 8 + 2 + 2 * 6);
851  ADD_TRAILER(p1, 4);
852  CHECK_HISTORY(p1, 4, 22, 2, 3, 4);
853  ADD_HEADER(p2, 8 + 2 + 2 * 6);
854  ADD_TRAILER(p2, 4);
855  CHECK_HISTORY(p2, 3, 22, 8, 4);
856 
857  REM_TRAILER(p1, 4);
858  REM_HEADER(p1, 8 + 2 + 2 * 6);
859  CHECK_HISTORY(p1, 2, 2, 3);
860  REM_TRAILER(p2, 4);
861  REM_HEADER(p2, 8 + 2 + 2 * 6);
862  CHECK_HISTORY(p2, 1, 8);
863 
864  p3 = p1->Copy();
865  CHECK_HISTORY(p3, 2, 2, 3);
866  p3->AddAtEnd(p2);
867  CHECK_HISTORY(p3, 2, 2, 11);
868 
869  CHECK_HISTORY(p, 2, 2, 11);
870  REM_HEADER(p, 2);
871  CHECK_HISTORY(p, 1, 11);
872  REM_HEADER(p3, 2);
873  CHECK_HISTORY(p3, 1, 11);
874 
875  auto buf = new uint8_t[p3->GetSize()];
876  p3->CopyData(buf, p3->GetSize());
877  std::string msg = std::string(reinterpret_cast<const char*>(buf), p3->GetSize());
878  delete[] buf;
880  std::string("hello world"),
881  "Could not find original data in received packet");
882 }
883 
891 {
892  public:
894 };
895 
897  : TestSuite("packet-metadata", UNIT)
898 {
899  AddTestCase(new PacketMetadataTest, TestCase::QUICK);
900 }
901 
Packet Metadata unit tests.
void DoRun() override
Implementation to actually run this TestCase.
Ptr< Packet > DoAddHeader(Ptr< Packet > p)
Adds an header to the packet.
void CheckHistory(Ptr< Packet > p, uint32_t n,...)
Checks the packet header and trailer history.
Packet Metadata TestSuite.
Base header-type class to check the proper header concatenation.
bool IsOk() const
Checks if the header has deserialization errors.
void ReportError()
Signal that an error has been found in deserialization.
Template header-type class to check the proper header concatenation.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
void Serialize(Buffer::Iterator start) const override
Base trailer-type class to check the proper trailer concatenation.
void ReportError()
Signal that an error has been found in deserialization.
bool IsOk() const
Checks if the header has deserialization errors.
Template trailer-type class to check the proper trailer concatenation.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
iterator in a Buffer instance
Definition: buffer.h:100
Callback template class.
Definition: callback.h:438
Protocol header serialization and deserialization.
Definition: header.h:44
virtual uint32_t Deserialize(Buffer::Iterator start)=0
Deserialize the object from a buffer iterator.
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:354
PacketMetadata::ItemIterator BeginItem() const
Returns an iterator which points to the first 'item' stored in this buffer.
Definition: packet.cc:590
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Copy the packet contents to a byte buffer.
Definition: packet.cc:400
void RemoveAtEnd(uint32_t size)
Remove size bytes from the end of the current packet.
Definition: packet.cc:376
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:384
Ptr< Packet > Copy() const
performs a COW copy of the packet.
Definition: packet.cc:131
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:238
Iterator class for metadata items.
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1256
Protocol trailer serialization and deserialization.
Definition: trailer.h:41
a unique identifier for an interface.
Definition: type-id.h:59
Callback< ObjectBase * > GetConstructor() const
Get the constructor callback.
Definition: type-id.cc:1084
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition: assert.h:66
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:144
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report if not.
Definition: test.h:251
Every class exported by the ns3 library is enclosed in the ns3 namespace.
#define ADD_HEADER(p, n)
#define CHECK_HISTORY(p,...)
#define REM_TRAILER(p, n)
static PacketMetadataTestSuite g_packetMetadataTest
Static variable for test initialization.
#define REM_HEADER(p, n)
#define ADD_TRAILER(p, n)
structure describing a packet metadata item
ItemType type
metadata type
TypeId tid
TypeId of Header or Trailer.
bool isFragment
true: this is a fragmented header, trailer, or, payload.
Buffer::Iterator current
an iterator which can be fed to Deserialize.
uint32_t currentSize
size of item.