A Discrete-Event Network Simulator
API
buffer-test.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 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@cutebugs.net>
19  */
20 
21 #include "ns3/buffer.h"
22 #include "ns3/random-variable-stream.h"
23 #include "ns3/double.h"
24 #include "ns3/test.h"
25 
26 using namespace ns3;
27 
28 //-----------------------------------------------------------------------------
29 // Unit tests
30 //-----------------------------------------------------------------------------
31 class BufferTest : public TestCase {
32 private:
33  void EnsureWrittenBytes (Buffer b, uint32_t n, uint8_t array[], const char *file, int line);
34 public:
35  virtual void DoRun (void);
36  BufferTest ();
37 };
38 
39 
41  : TestCase ("Buffer") {
42 }
43 
44 void
45 BufferTest::EnsureWrittenBytes (Buffer b, uint32_t n, uint8_t array[], const char *file, int line)
46 {
47  bool success = true;
48  uint8_t *expected = array;
49  uint8_t const*got;
50  got = b.PeekData ();
51  for (uint32_t j = 0; j < n; j++)
52  {
53  if (got[j] != expected[j])
54  {
55  success = false;
56  }
57  }
58  if (!success)
59  {
60  std::ostringstream failure;
61  failure << "Buffer -- ";
62  failure << "expected: n=";
63  failure << n << ", ";
64  failure.setf (std::ios::hex, std::ios::basefield);
65  for (uint32_t j = 0; j < n; j++)
66  {
67  failure << (uint16_t)expected[j] << " ";
68  }
69  failure.setf (std::ios::dec, std::ios::basefield);
70  failure << "got: ";
71  failure.setf (std::ios::hex, std::ios::basefield);
72  for (uint32_t j = 0; j < n; j++)
73  {
74  failure << (uint16_t)got[j] << " ";
75  }
76  failure << std::endl;
77  NS_TEST_ASSERT_MSG_EQ_INTERNAL (true, false, failure.str (), file, line);
78  }
79 }
80 
84 #define ENSURE_WRITTEN_BYTES(buffer, n, ...) \
85  { \
86  uint8_t bytes[] = { __VA_ARGS__}; \
87  EnsureWrittenBytes (buffer, n, bytes, __FILE__, __LINE__); \
88  }
89 
90 void
92 {
93  Buffer buffer;
95  buffer.AddAtStart (6);
96  i = buffer.Begin ();
97  i.WriteU8 (0x66);
98  ENSURE_WRITTEN_BYTES (buffer, 1, 0x66);
99  i = buffer.Begin ();
100  i.WriteU8 (0x67);
101  ENSURE_WRITTEN_BYTES (buffer, 1, 0x67);
102  i.WriteHtonU16 (0x6568);
103  i = buffer.Begin ();
104  ENSURE_WRITTEN_BYTES (buffer, 3, 0x67, 0x65, 0x68);
105  i.WriteHtonU16 (0x6369);
106  ENSURE_WRITTEN_BYTES (buffer, 3, 0x63, 0x69, 0x68);
107  i.WriteHtonU32 (0xdeadbeaf);
108  ENSURE_WRITTEN_BYTES (buffer, 6, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf);
109  buffer.AddAtStart (2);
110  i = buffer.Begin ();
111  i.WriteU16 (0);
112  ENSURE_WRITTEN_BYTES (buffer, 8, 0, 0, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf);
113  buffer.AddAtEnd (2);
114  i = buffer.Begin ();
115  i.Next (8);
116  i.WriteU16 (0);
117  ENSURE_WRITTEN_BYTES (buffer, 10, 0, 0, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
118  buffer.RemoveAtStart (3);
119  i = buffer.Begin ();
120  ENSURE_WRITTEN_BYTES (buffer, 7, 0x69, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
121  buffer.RemoveAtEnd (4);
122  i = buffer.Begin ();
123  ENSURE_WRITTEN_BYTES (buffer, 3, 0x69, 0xde, 0xad);
124  buffer.AddAtStart (1);
125  i = buffer.Begin ();
126  i.WriteU8 (0xff);
127  ENSURE_WRITTEN_BYTES (buffer, 4, 0xff, 0x69, 0xde, 0xad);
128  buffer.AddAtEnd (1);
129  i = buffer.Begin ();
130  i.Next (4);
131  i.WriteU8 (0xff);
132  i.Prev (2);
133  uint16_t saved = i.ReadU16 ();
134  i.Prev (2);
135  i.WriteHtonU16 (0xff00);
136  i.Prev (2);
137  NS_TEST_ASSERT_MSG_EQ (i.ReadNtohU16 (), 0xff00, "Could not read expected value");
138  i.Prev (2);
139  i.WriteU16 (saved);
140  ENSURE_WRITTEN_BYTES (buffer, 5, 0xff, 0x69, 0xde, 0xad, 0xff);
141  Buffer o = buffer;
142  ENSURE_WRITTEN_BYTES (o, 5, 0xff, 0x69, 0xde, 0xad, 0xff);
143  o.AddAtStart (1);
144  i = o.Begin ();
145  i.WriteU8 (0xfe);
146  ENSURE_WRITTEN_BYTES (o, 6, 0xfe, 0xff, 0x69, 0xde, 0xad, 0xff);
147  buffer.AddAtStart (2);
148  i = buffer.Begin ();
149  i.WriteU8 (0xfd);
150  i.WriteU8 (0xfd);
151  ENSURE_WRITTEN_BYTES (o, 6, 0xfe, 0xff, 0x69, 0xde, 0xad, 0xff);
152  ENSURE_WRITTEN_BYTES (buffer, 7, 0xfd, 0xfd, 0xff, 0x69, 0xde, 0xad, 0xff);
153 
154  // test 64-bit read/write
155  Buffer buff64;
156  buff64.AddAtStart (8);
157  i = buff64.Begin ();
158  i.WriteU64 (0x0123456789ABCDEFllu);
159  i = buff64.Begin ();
160  NS_TEST_ASSERT_MSG_EQ (i.ReadU64 (), 0x0123456789abcdefllu, "Could not read expected value");
161  i = buff64.Begin ();
162  i.WriteHtolsbU64 (0x0123456789ABCDEFllu);
163  ENSURE_WRITTEN_BYTES (buff64, 8, 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01);
164  i = buff64.Begin ();
165  NS_TEST_ASSERT_MSG_EQ (i.ReadLsbtohU64 (), 0x0123456789abcdefllu, "Could not read expected value");
166  i = buff64.Begin ();
167  i.WriteHtonU64 (0x0123456789ABCDEFllu);
168  ENSURE_WRITTEN_BYTES (buff64, 8, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef);
169  i = buff64.Begin ();
170  NS_TEST_ASSERT_MSG_EQ (i.ReadNtohU64 (), 0x0123456789abcdefllu, "could not read expected value");
171 
172  // test self-assignment
173  {
174  Buffer a = o;
175  a = a;
176  }
177 
178  // test Remove start.
179  buffer = Buffer (5);
180  ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0);
181  buffer.RemoveAtStart (1);
182  ENSURE_WRITTEN_BYTES (buffer, 4, 0, 0, 0, 0);
183  buffer.AddAtStart (1);
184  buffer.Begin ().WriteU8 (0xff);
185  ENSURE_WRITTEN_BYTES (buffer, 5, 0xff, 0, 0, 0, 0);
186  buffer.RemoveAtStart (3);
187  ENSURE_WRITTEN_BYTES (buffer, 2, 0, 0);
188  buffer.AddAtStart (4);
189  buffer.Begin ().WriteHtonU32 (0xdeadbeaf);
190  ENSURE_WRITTEN_BYTES (buffer, 6, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
191  buffer.RemoveAtStart (2);
192  ENSURE_WRITTEN_BYTES (buffer, 4, 0xbe, 0xaf, 0, 0);
193  buffer.AddAtEnd (4);
194  i = buffer.Begin ();
195  i.Next (4);
196  i.WriteHtonU32 (0xdeadbeaf);
197  ENSURE_WRITTEN_BYTES (buffer, 8, 0xbe, 0xaf, 0, 0, 0xde, 0xad, 0xbe, 0xaf);
198  buffer.RemoveAtStart (5);
199  ENSURE_WRITTEN_BYTES (buffer, 3, 0xad, 0xbe, 0xaf);
200  // test Remove end
201  buffer = Buffer (5);
202  ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0);
203  buffer.RemoveAtEnd (1);
204  ENSURE_WRITTEN_BYTES (buffer, 4, 0, 0, 0, 0);
205  buffer.AddAtEnd (2);
206  i = buffer.Begin ();
207  i.Next (4);
208  i.WriteU8 (0xab);
209  i.WriteU8 (0xac);
210  ENSURE_WRITTEN_BYTES (buffer, 6, 0, 0, 0, 0, 0xab, 0xac);
211  buffer.RemoveAtEnd (1);
212  ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0xab);
213  buffer.RemoveAtEnd (3);
214  ENSURE_WRITTEN_BYTES (buffer, 2, 0, 0);
215  buffer.AddAtEnd (6);
216  i = buffer.Begin ();
217  i.Next (2);
218  i.WriteU8 (0xac);
219  i.WriteU8 (0xad);
220  i.WriteU8 (0xae);
221  i.WriteU8 (0xaf);
222  i.WriteU8 (0xba);
223  i.WriteU8 (0xbb);
224  ENSURE_WRITTEN_BYTES (buffer, 8, 0, 0, 0xac, 0xad, 0xae, 0xaf, 0xba, 0xbb);
225  buffer.AddAtStart (3);
226  i = buffer.Begin ();
227  i.WriteU8 (0x30);
228  i.WriteU8 (0x31);
229  i.WriteU8 (0x32);
230  ENSURE_WRITTEN_BYTES (buffer, 11, 0x30, 0x31, 0x32, 0, 0, 0xac, 0xad, 0xae, 0xaf, 0xba, 0xbb);
231  buffer.RemoveAtEnd (9);
232  ENSURE_WRITTEN_BYTES (buffer, 2, 0x30, 0x31);
233  buffer = Buffer (3);
234  buffer.AddAtEnd (2);
235  i = buffer.Begin ();
236  i.Next (3);
237  i.WriteHtonU16 (0xabcd);
238  buffer.AddAtStart (1);
239  buffer.Begin ().WriteU8 (0x21);
240  ENSURE_WRITTEN_BYTES (buffer, 6, 0x21, 0, 0, 0, 0xab, 0xcd);
241  buffer.RemoveAtEnd (8);
242  NS_TEST_ASSERT_MSG_EQ (buffer.GetSize (), 0, "Buffer size not zero");
243 
244  buffer = Buffer (6);
245  buffer.AddAtStart (9);
246  buffer.AddAtEnd (3);
247  i = buffer.End ();
248  i.Prev (1);
249  i.WriteU8 (1, 1);
250 
251  buffer = Buffer (6);
252  buffer.AddAtStart (3);
253  buffer.RemoveAtEnd (8);
254  buffer.AddAtEnd (4);
255  i = buffer.End ();
256  i.Prev (4);
257  i.WriteU8 (1, 4);
258 
259  buffer = Buffer (1);
260  buffer.AddAtEnd (100);
261  i = buffer.End ();
262  i.Prev (100);
263  i.WriteU8 (1, 100);
264 
267  {
268  const uint32_t actualSize = 72602;
269  const uint32_t chunkSize = 67624;
270  Ptr<UniformRandomVariable> bytesRng = CreateObject<UniformRandomVariable> ();
271  bytesRng->SetAttribute ("Min", DoubleValue (0));
272  bytesRng->SetAttribute ("Max", DoubleValue (256));
273 
274  Buffer inputBuffer;
275  Buffer outputBuffer;
276 
277  inputBuffer.AddAtEnd (actualSize);
278  {
279  Buffer::Iterator iter = inputBuffer.Begin ();
280  for (uint32_t i = 0; i < actualSize; i++)
281  iter.WriteU8 (static_cast<uint8_t> (bytesRng->GetValue ()));
282  }
283 
284  outputBuffer.AddAtEnd (chunkSize);
285  Buffer::Iterator iter = outputBuffer.End ();
286  iter.Prev (chunkSize);
287  iter.Write (inputBuffer.PeekData (), chunkSize);
288 
289  NS_TEST_EXPECT_MSG_EQ (memcmp (inputBuffer.PeekData (), outputBuffer.PeekData (), chunkSize), 0, "memcp works");
290  }
291 
292  buffer = Buffer (5);
293  buffer.AddAtEnd (2);
294  i = buffer.End ();
295  i.Prev (2);
296  i.WriteU8 (0);
297  i.WriteU8 (0x66);
298  ENSURE_WRITTEN_BYTES (buffer, 7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66);
299  Buffer frag0 = buffer.CreateFragment (0, 2);
300  ENSURE_WRITTEN_BYTES (frag0, 2, 0x00, 0x00);
301  Buffer frag1 = buffer.CreateFragment (2, 5);
302  ENSURE_WRITTEN_BYTES (frag1, 5, 0x00, 0x00, 0x00, 0x00, 0x66);
303  frag0.AddAtEnd (frag1);
304  ENSURE_WRITTEN_BYTES (buffer, 7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66);
305  ENSURE_WRITTEN_BYTES (frag0, 7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66);
306 
307  buffer = Buffer (5);
308  buffer.AddAtStart (2);
309  i = buffer.Begin ();
310  i.WriteU8 (0x1);
311  i.WriteU8 (0x2);
312  buffer.AddAtEnd (2);
313  i = buffer.End ();
314  i.Prev (2);
315  i.WriteU8 (0x3);
316  i.WriteU8 (0x4);
317  ENSURE_WRITTEN_BYTES (buffer, 9, 0x1, 0x2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3, 0x4);
318  Buffer other;
319  other.AddAtStart (9);
320  i = other.Begin ();
321  i.Write (buffer.Begin (), buffer.End ());
322  ENSURE_WRITTEN_BYTES (other, 9, 0x1, 0x2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3, 0x4);
323 
325  std::string ct ("This is the next content of the buffer.");
326  buffer = Buffer ();
327  buffer.AddAtStart (ct.size ());
328  i = buffer.Begin ();
329  i.Write ((const uint8_t*)ct.c_str (), ct.size ());
330  uint32_t sizeBuffer = buffer.GetSize ();
331  NS_TEST_ASSERT_MSG_EQ (sizeBuffer, ct.size(), "Buffer bad size");
332  uint8_t const* evilBuffer = buffer.PeekData ();
333  NS_TEST_ASSERT_MSG_NE( evilBuffer, 0, "Buffer PeekData failed");
334  uint8_t *cBuf = (uint8_t*) malloc ( sizeBuffer );
335  uint32_t copyLen = buffer.CopyData (cBuf, sizeBuffer);
336  NS_TEST_ASSERT_MSG_EQ (copyLen, sizeBuffer, "CopyData return bad size");
337  for (uint8_t i=0; i < sizeBuffer ; i++ )
338  {
339  NS_TEST_ASSERT_MSG_EQ ( cBuf [i], *(((const uint8_t*)ct.c_str ()) + i), "Bad buffer copied data");
340  NS_TEST_ASSERT_MSG_EQ ( evilBuffer [i], cBuf [i] , "Bad buffer peeked");
341  }
342  free (cBuf);
343 
345  buffer = Buffer (1);
346  buffer.AddAtEnd (2);
347  i = buffer.Begin ();
348  i.Next (1);
349  i.WriteU8 (0x77);
350  i.WriteU8 (0x66);
351  ENSURE_WRITTEN_BYTES (buffer, 3, 0x00, 0x77, 0x66);
352  i = buffer.Begin ();
353  i.ReadU8 ();
354  uint16_t val1 = i.ReadNtohU16 ();
355  i = buffer.Begin ();
356  i.ReadU8 ();
357  uint16_t val2 = 0;
358  val2 |= i.ReadU8 ();
359  val2 <<= 8;
360  val2 |= i.ReadU8 ();
361  NS_TEST_ASSERT_MSG_EQ (val1, val2, "Bad ReadNtohU16()");
362 }
363 //-----------------------------------------------------------------------------
365 {
366 public:
367  BufferTestSuite ();
368 };
369 
371  : TestSuite ("buffer", UNIT)
372 {
373  AddTestCase (new BufferTest, TestCase::QUICK);
374 }
375 
uint16_t ReadU16(void)
Definition: buffer.h:1028
void WriteHtonU64(uint64_t data)
Definition: buffer.cc:940
void AddAtStart(uint32_t start)
Definition: buffer.cc:309
#define ENSURE_WRITTEN_BYTES(buffer, n,...)
Definition: buffer-test.cc:84
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:486
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:441
A suite of tests to run.
Definition: test.h:1333
automatically resized byte buffer
Definition: buffer.h:92
#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:278
encapsulates test code
Definition: test.h:1147
void EnsureWrittenBytes(Buffer b, uint32_t n, uint8_t array[], const char *file, int line)
Definition: buffer-test.cc:45
#define NS_TEST_ASSERT_MSG_EQ_INTERNAL(actual, limit, msg, file, line)
Test that an actual and expected (limit) value are equal and report and abort if not.
Definition: test.h:113
iterator in a Buffer instance
Definition: buffer.h:98
void AddTestCase(TestCase *testCase, enum TestDuration duration)
Add an individual child TestCase to this test suite.
Definition: test.cc:298
void Prev(void)
go backward by one byte
Definition: buffer.h:850
#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:161
void WriteU16(uint16_t data)
Definition: buffer.cc:870
void WriteHtonU16(uint16_t data)
Definition: buffer.h:904
Buffer::Iterator End(void) const
Definition: buffer.h:1074
uint8_t const * PeekData(void) const
Definition: buffer.cc:705
void Next(void)
go forward by one byte
Definition: buffer.h:844
void WriteU64(uint64_t data)
Definition: buffer.cc:890
Buffer::Iterator Begin(void) const
Definition: buffer.h:1068
void AddAtEnd(uint32_t end)
Definition: buffer.cc:354
Every class exported by the ns3 library is enclosed in the ns3 namespace.
double GetValue(double min, double max)
Get the next random value, as a double in the specified range .
virtual void DoRun(void)
Implementation to actually run this TestCase.
Definition: buffer-test.cc:91
uint64_t ReadU64(void)
Definition: buffer.cc:989
void WriteHtonU32(uint32_t data)
Definition: buffer.h:923
uint32_t GetSize(void) const
Definition: buffer.h:1062
Buffer CreateFragment(uint32_t start, uint32_t length) const
Definition: buffer.cc:522
void WriteU8(uint8_t data)
Definition: buffer.h:868
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not...
Definition: test.h:617
void WriteHtolsbU64(uint64_t data)
Definition: buffer.cc:926
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:953
uint16_t ReadNtohU16(void)
Definition: buffer.h:945
This class can be used to hold variables of floating point type such as 'double' or 'float'...
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Set a single attribute, raising fatal errors if unsuccessful.
Definition: object-base.cc:191
static BufferTestSuite g_bufferTestSuite
Definition: buffer-test.cc:376