A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
packet-test-suite.cc
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005,2006 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "ns3/packet.h"
21 #include "ns3/test.h"
22 #include <string>
23 #include <cstdarg>
24 
25 using namespace ns3;
26 
27 //-----------------------------------------------------------------------------
28 // Unit tests
29 //-----------------------------------------------------------------------------
30 namespace {
31 
32 class ATestTagBase : public Tag
33 {
34 public:
35  ATestTagBase () : m_error (false) {}
36  bool m_error;
37 };
38 
39 template <int N>
40 class ATestTag : public ATestTagBase
41 {
42 public:
43  static TypeId GetTypeId (void) {
44  std::ostringstream oss;
45  oss << "anon::ATestTag<" << N << ">";
46  static TypeId tid = TypeId (oss.str ().c_str ())
47  .SetParent<Tag> ()
49  .HideFromDocumentation ()
50  ;
51  return tid;
52  }
53  virtual TypeId GetInstanceTypeId (void) const {
54  return GetTypeId ();
55  }
56  virtual uint32_t GetSerializedSize (void) const {
57  return N;
58  }
59  virtual void Serialize (TagBuffer buf) const {
60  for (uint32_t i = 0; i < N; ++i)
61  {
62  buf.WriteU8 (N);
63  }
64  }
65  virtual void Deserialize (TagBuffer buf) {
66  for (uint32_t i = 0; i < N; ++i)
67  {
68  uint8_t v = buf.ReadU8 ();
69  if (v != N)
70  {
71  m_error = true;
72  }
73  }
74  }
75  virtual void Print (std::ostream &os) const {
76  os << N;
77  }
78  ATestTag ()
79  : ATestTagBase () {}
80 };
81 
82 class ATestHeaderBase : public Header
83 {
84 public:
85  ATestHeaderBase () : Header (), m_error (false) {}
86  bool m_error;
87 };
88 
89 template <int N>
91 {
92 public:
93  static TypeId GetTypeId (void) {
94  std::ostringstream oss;
95  oss << "anon::ATestHeader<" << N << ">";
96  static TypeId tid = TypeId (oss.str ().c_str ())
97  .SetParent<Header> ()
99  .HideFromDocumentation ()
100  ;
101  return tid;
102  }
103  virtual TypeId GetInstanceTypeId (void) const {
104  return GetTypeId ();
105  }
106  virtual uint32_t GetSerializedSize (void) const {
107  return N;
108  }
109  virtual void Serialize (Buffer::Iterator iter) const {
110  for (uint32_t i = 0; i < N; ++i)
111  {
112  iter.WriteU8 (N);
113  }
114  }
115  virtual uint32_t Deserialize (Buffer::Iterator iter) {
116  for (uint32_t i = 0; i < N; ++i)
117  {
118  uint8_t v = iter.ReadU8 ();
119  if (v != N)
120  {
121  m_error = true;
122  }
123  }
124  return N;
125  }
126  virtual void Print (std::ostream &os) const {
127  }
128  ATestHeader ()
129  : ATestHeaderBase () {}
130 
131 };
132 
133 class ATestTrailerBase : public Trailer
134 {
135 public:
136  ATestTrailerBase () : Trailer (), m_error (false) {}
137  bool m_error;
138 };
139 
140 template <int N>
142 {
143 public:
144  static TypeId GetTypeId (void) {
145  std::ostringstream oss;
146  oss << "anon::ATestTrailer<" << N << ">";
147  static TypeId tid = TypeId (oss.str ().c_str ())
148  .SetParent<Header> ()
150  .HideFromDocumentation ()
151  ;
152  return tid;
153  }
154  virtual TypeId GetInstanceTypeId (void) const {
155  return GetTypeId ();
156  }
157  virtual uint32_t GetSerializedSize (void) const {
158  return N;
159  }
160  virtual void Serialize (Buffer::Iterator iter) const {
161  iter.Prev (N);
162  for (uint32_t i = 0; i < N; ++i)
163  {
164  iter.WriteU8 (N);
165  }
166  }
167  virtual uint32_t Deserialize (Buffer::Iterator iter) {
168  iter.Prev (N);
169  for (uint32_t i = 0; i < N; ++i)
170  {
171  uint8_t v = iter.ReadU8 ();
172  if (v != N)
173  {
174  m_error = true;
175  }
176  }
177  return N;
178  }
179  virtual void Print (std::ostream &os) const {
180  }
181  ATestTrailer ()
182  : ATestTrailerBase () {}
183 
184 };
185 
186 
187 struct Expected
188 {
189  Expected (uint32_t n_, uint32_t start_, uint32_t end_)
190  : n (n_), start (start_), end (end_) {}
191 
192  uint32_t n;
193  uint32_t start;
194  uint32_t end;
195 };
196 
197 }
198 
199 // tag name, start, end
200 #define E(a,b,c) a,b,c
201 
202 #define CHECK(p, n, ...) \
203  DoCheck (p, __FILE__, __LINE__, n, __VA_ARGS__)
204 
205 class PacketTest : public TestCase
206 {
207 public:
208  PacketTest ();
209  virtual void DoRun (void);
210 private:
211  void DoCheck (Ptr<const Packet> p, const char *file, int line, uint32_t n, ...);
212 };
213 
214 
215 PacketTest::PacketTest ()
216  : TestCase ("Packet") {
217 }
218 
219 void
220 PacketTest::DoCheck (Ptr<const Packet> p, const char *file, int line, uint32_t n, ...)
221 {
222  std::vector<struct Expected> expected;
223  va_list ap;
224  va_start (ap, n);
225  for (uint32_t k = 0; k < n; ++k)
226  {
227  uint32_t N = va_arg (ap, uint32_t);
228  uint32_t start = va_arg (ap, uint32_t);
229  uint32_t end = va_arg (ap, uint32_t);
230  expected.push_back (Expected (N, start, end));
231  }
232  va_end (ap);
233 
235  uint32_t j = 0;
236  while (i.HasNext () && j < expected.size ())
237  {
238  ByteTagIterator::Item item = i.Next ();
239  struct Expected e = expected[j];
240  std::ostringstream oss;
241  oss << "anon::ATestTag<" << e.n << ">";
242  NS_TEST_EXPECT_MSG_EQ_INTERNAL (item.GetTypeId ().GetName (), oss.str (), "trivial", file, line);
243  NS_TEST_EXPECT_MSG_EQ_INTERNAL (item.GetStart (), e.start, "trivial", file, line);
244  NS_TEST_EXPECT_MSG_EQ_INTERNAL (item.GetEnd (), e.end, "trivial", file, line);
245  ATestTagBase *tag = dynamic_cast<ATestTagBase *> (item.GetTypeId ().GetConstructor () ());
246  NS_TEST_EXPECT_MSG_NE (tag, 0, "trivial");
247  item.GetTag (*tag);
248  NS_TEST_EXPECT_MSG_EQ (tag->m_error, false, "trivial");
249  delete tag;
250  j++;
251  }
252  NS_TEST_EXPECT_MSG_EQ (i.HasNext (), false, "Nothing left");
253  NS_TEST_EXPECT_MSG_EQ (j, expected.size (), "Size match");
254 }
255 
256 void
258 {
259  Ptr<Packet> pkt1 = Create<Packet> (reinterpret_cast<const uint8_t*> ("hello"), 5);
260  Ptr<Packet> pkt2 = Create<Packet> (reinterpret_cast<const uint8_t*> (" world"), 6);
261  Ptr<Packet> packet = Create<Packet> ();
262  packet->AddAtEnd (pkt1);
263  packet->AddAtEnd (pkt2);
264 
265  NS_TEST_EXPECT_MSG_EQ (packet->GetSize (), 11, "trivial");
266 
267  uint8_t *buf = new uint8_t[packet->GetSize ()];
268  packet->CopyData (buf, packet->GetSize ());
269 
270  std::string msg = std::string (reinterpret_cast<const char *>(buf),
271  packet->GetSize ());
272  delete [] buf;
273 
274  NS_TEST_EXPECT_MSG_EQ (msg, "hello world", "trivial");
275 
276 
277  Ptr<const Packet> p = Create<Packet> (1000);
278 
279  p->AddByteTag (ATestTag<1> ());
280  CHECK (p, 1, E (1, 0, 1000));
281  Ptr<const Packet> copy = p->Copy ();
282  CHECK (copy, 1, E (1, 0, 1000));
283 
284  p->AddByteTag (ATestTag<2> ());
285  CHECK (p, 2, E (1, 0, 1000), E (2, 0, 1000));
286  CHECK (copy, 1, E (1, 0, 1000));
287 
288  {
289  Packet c0 = *copy;
290  Packet c1 = *copy;
291  c0 = c1;
292  CHECK (&c0, 1, E (1, 0, 1000));
293  CHECK (&c1, 1, E (1, 0, 1000));
294  CHECK (copy, 1, E (1, 0, 1000));
295  c0.AddByteTag (ATestTag<10> ());
296  CHECK (&c0, 2, E (1, 0, 1000), E (10, 0, 1000));
297  CHECK (&c1, 1, E (1, 0, 1000));
298  CHECK (copy, 1, E (1, 0, 1000));
299  }
300 
301  Ptr<Packet> frag0 = p->CreateFragment (0, 10);
302  Ptr<Packet> frag1 = p->CreateFragment (10, 90);
303  Ptr<const Packet> frag2 = p->CreateFragment (100, 900);
304  frag0->AddByteTag (ATestTag<3> ());
305  CHECK (frag0, 3, E (1, 0, 10), E (2, 0, 10), E (3, 0, 10));
306  frag1->AddByteTag (ATestTag<4> ());
307  CHECK (frag1, 3, E (1, 0, 90), E (2, 0, 90), E (4, 0, 90));
308  frag2->AddByteTag (ATestTag<5> ());
309  CHECK (frag2, 3, E (1, 0, 900), E (2, 0, 900), E (5, 0, 900));
310 
311  frag1->AddAtEnd (frag2);
312  CHECK (frag1, 6, E (1, 0, 90), E (2, 0, 90), E (4, 0, 90), E (1, 90, 990), E (2, 90, 990), E (5, 90, 990));
313 
314  CHECK (frag0, 3, E (1, 0, 10), E (2, 0, 10), E (3, 0, 10));
315  frag0->AddAtEnd (frag1);
316  CHECK (frag0, 9,
317  E (1, 0, 10), E (2, 0, 10), E (3, 0, 10),
318  E (1, 10, 100), E (2, 10, 100), E (4, 10, 100),
319  E (1, 100, 1000), E (2, 100, 1000), E (5, 100, 1000));
320 
321 
322  // force caching a buffer of the right size.
323  frag0 = Create<Packet> (1000);
324  frag0->AddHeader (ATestHeader<10> ());
325  frag0 = 0;
326 
327  p = Create<Packet> (1000);
328  p->AddByteTag (ATestTag<20> ());
329  CHECK (p, 1, E (20, 0, 1000));
330  frag0 = p->CreateFragment (10, 90);
331  CHECK (p, 1, E (20, 0, 1000));
332  CHECK (frag0, 1, E (20, 0, 90));
333  p = 0;
334  frag0->AddHeader (ATestHeader<10> ());
335  CHECK (frag0, 1, E (20, 10, 100));
336 
337  {
338  Ptr<Packet> tmp = Create<Packet> (100);
339  tmp->AddByteTag (ATestTag<20> ());
340  CHECK (tmp, 1, E (20, 0, 100));
341  tmp->AddHeader (ATestHeader<10> ());
342  CHECK (tmp, 1, E (20, 10, 110));
343  ATestHeader<10> h;
344  tmp->RemoveHeader (h);
345  CHECK (tmp, 1, E (20, 0, 100));
346  tmp->AddHeader (ATestHeader<10> ());
347  CHECK (tmp, 1, E (20, 10, 110));
348 
349  tmp = Create<Packet> (100);
350  tmp->AddByteTag (ATestTag<20> ());
351  CHECK (tmp, 1, E (20, 0, 100));
352  tmp->AddTrailer (ATestTrailer<10> ());
353  CHECK (tmp, 1, E (20, 0, 100));
354  ATestTrailer<10> t;
355  tmp->RemoveTrailer (t);
356  CHECK (tmp, 1, E (20, 0, 100));
357  tmp->AddTrailer (ATestTrailer<10> ());
358  CHECK (tmp, 1, E (20, 0, 100));
359 
360  }
361 
362  {
363  Ptr<Packet> tmp = Create<Packet> (0);
364  tmp->AddHeader (ATestHeader<156> ());
365  tmp->AddByteTag (ATestTag<20> ());
366  CHECK (tmp, 1, E (20, 0, 156));
367  tmp->RemoveAtStart (120);
368  CHECK (tmp, 1, E (20, 0, 36));
369  Ptr<Packet> a = Create<Packet> (0);
370  a->AddAtEnd (tmp);
371  CHECK (a, 1, E (20, 0, 36));
372  }
373 
374  {
375  Ptr<Packet> tmp = Create<Packet> (0);
376  tmp->AddByteTag (ATestTag<20> ());
377  CHECK (tmp, 0, E (20, 0, 0));
378  }
379  {
380  Ptr<Packet> tmp = Create<Packet> (1000);
381  tmp->AddByteTag (ATestTag<20> ());
382  CHECK (tmp, 1, E (20, 0, 1000));
383  tmp->RemoveAtStart (1000);
384  CHECK (tmp, 0, E (0,0,0));
385  Ptr<Packet> a = Create<Packet> (10);
386  a->AddByteTag (ATestTag<10> ());
387  CHECK (a, 1, E (10, 0, 10));
388  tmp->AddAtEnd (a);
389  CHECK (tmp, 1, E (10, 0, 10));
390  }
391 
392  {
393  Packet p;
394  ATestTag<10> a;
395  p.AddPacketTag (a);
396  NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (a), true, "trivial");
397  ATestTag<11> b;
398  p.AddPacketTag (b);
399  NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (b), true, "trivial");
400  NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (a), true, "trivial");
401  Packet copy = p;
402  NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (b), true, "trivial");
403  NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (a), true, "trivial");
404  ATestTag<12> c;
405  NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (c), false, "trivial");
406  copy.AddPacketTag (c);
407  NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (c), true, "trivial");
408  NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (b), true, "trivial");
409  NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (a), true, "trivial");
410  NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (c), false, "trivial");
411  copy.RemovePacketTag (b);
412  NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (b), false, "trivial");
413  NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (b), true, "trivial");
414  p.RemovePacketTag (a);
415  NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (a), false, "trivial");
416  NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (a), true, "trivial");
417  NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (c), false, "trivial");
418  NS_TEST_EXPECT_MSG_EQ (copy.PeekPacketTag (c), true, "trivial");
419  p.RemoveAllPacketTags ();
420  NS_TEST_EXPECT_MSG_EQ (p.PeekPacketTag (b), false, "trivial");
421  }
422 
423  {
424  // bug 572
425  Ptr<Packet> tmp = Create<Packet> (1000);
426  tmp->AddByteTag (ATestTag<20> ());
427  CHECK (tmp, 1, E (20, 0, 1000));
428  tmp->AddHeader (ATestHeader<2> ());
429  CHECK (tmp, 1, E (20, 2, 1002));
430  tmp->RemoveAtStart (1);
431  CHECK (tmp, 1, E (20, 1, 1001));
432 #if 0
433  tmp->PeekData ();
434  CHECK (tmp, 1, E (20, 1, 1001));
435 #endif
436  }
437 }
438 //-----------------------------------------------------------------------------
440 {
441 public:
442  PacketTestSuite ();
443 };
444 
445 PacketTestSuite::PacketTestSuite ()
446  : TestSuite ("packet", UNIT)
447 {
448  AddTestCase (new PacketTest, TestCase::QUICK);
449 }
450 
451 static PacketTestSuite g_packetTestSuite;
bool HasNext(void) const
Definition: packet.cc:69
Protocol header serialization and deserialization.
Definition: header.h:42
uint32_t RemoveHeader(Header &header)
Definition: packet.cc:285
virtual void DoRun(void)
Implementation to actually run this test case.
TypeId AddConstructor(void)
Definition: type-id.h:388
virtual void Serialize(Buffer::Iterator iter) const
virtual uint32_t Deserialize(Buffer::Iterator iter)
A suite of tests to run.
Definition: test.h:962
void AddPacketTag(const Tag &tag) const
Definition: packet.cc:868
uint32_t GetSize(void) const
Definition: packet.h:620
encapsulates test code
Definition: test.h:834
network packets
Definition: packet.h:203
virtual void Print(std::ostream &os) const
TAG_BUFFER_INLINE uint8_t ReadU8(void)
Definition: tag-buffer.h:179
iterator in a Buffer instance
Definition: buffer.h:98
Callback< ObjectBase * > GetConstructor(void) const
Definition: type-id.cc:576
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Definition: packet.cc:243
void AddAtEnd(Ptr< const Packet > packet)
Definition: packet.cc:334
uint8_t const * PeekData(void) const NS_DEPRECATED
Definition: packet.cc:385
bool PeekPacketTag(Tag &tag) const
Definition: packet.cc:881
void RemoveAllPacketTags(void)
Definition: packet.cc:888
void RemoveAtStart(uint32_t size)
Definition: packet.cc:370
void Prev(void)
Definition: buffer.h:672
ByteTagIterator GetByteTagIterator(void) const
Definition: packet.cc:843
Item Next(void)
Definition: packet.cc:74
uint32_t GetEnd(void) const
Definition: packet.cc:45
Ptr< Packet > Copy(void) const
Definition: packet.cc:131
Protocol trailer serialization and deserialization.
Definition: trailer.h:40
tag a set of bytes in a packet
Definition: tag.h:36
void AddTrailer(const Trailer &trailer)
Definition: packet.cc:301
Iterator over the set of tags in a packet.
Definition: packet.h:50
uint32_t RemoveTrailer(Trailer &trailer)
Definition: packet.cc:317
std::string GetName(void) const
Definition: type-id.cc:518
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition: tag-buffer.h:156
TypeId GetTypeId(void) const
Definition: packet.cc:34
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual test case to this test suite.
Definition: test.cc:172
void GetTag(Tag &tag) const
Definition: packet.cc:51
read and write tag data
Definition: tag-buffer.h:51
uint32_t GetStart(void) const
Definition: packet.cc:39
void WriteU8(uint8_t data)
Definition: buffer.h:690
bool RemovePacketTag(Tag &tag)
Definition: packet.cc:874
virtual uint32_t Deserialize(Buffer::Iterator iter)
uint8_t ReadU8(void)
Definition: buffer.h:819
uint32_t CopyData(uint8_t *buffer, uint32_t size) const
Definition: packet.cc:398
virtual void Serialize(Buffer::Iterator iter) const
a unique identifier for an interface.
Definition: type-id.h:44
void AddHeader(const Header &header)
Definition: packet.cc:270
void AddByteTag(const Tag &tag) const
Definition: packet.cc:833