A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
buffer-test.cc
Go to the documentation of this file.
1 #include "ns3/buffer.h"
2 #include "ns3/random-variable-stream.h"
3 #include "ns3/double.h"
4 #include "ns3/test.h"
5 
6 using namespace ns3;
7 
8 //-----------------------------------------------------------------------------
9 // Unit tests
10 //-----------------------------------------------------------------------------
11 class BufferTest : public TestCase {
12 private:
13  void EnsureWrittenBytes (Buffer b, uint32_t n, uint8_t array[], const char *file, int line);
14 public:
15  virtual void DoRun (void);
16  BufferTest ();
17 };
18 
19 
21  : TestCase ("Buffer") {
22 }
23 
24 void
25 BufferTest::EnsureWrittenBytes (Buffer b, uint32_t n, uint8_t array[], const char *file, int line)
26 {
27  bool success = true;
28  uint8_t *expected = array;
29  uint8_t const*got;
30  got = b.PeekData ();
31  for (uint32_t j = 0; j < n; j++)
32  {
33  if (got[j] != expected[j])
34  {
35  success = false;
36  }
37  }
38  if (!success)
39  {
40  std::ostringstream failure;
41  failure << "Buffer -- ";
42  failure << "expected: n=";
43  failure << n << ", ";
44  failure.setf (std::ios::hex, std::ios::basefield);
45  for (uint32_t j = 0; j < n; j++)
46  {
47  failure << (uint16_t)expected[j] << " ";
48  }
49  failure.setf (std::ios::dec, std::ios::basefield);
50  failure << "got: ";
51  failure.setf (std::ios::hex, std::ios::basefield);
52  for (uint32_t j = 0; j < n; j++)
53  {
54  failure << (uint16_t)got[j] << " ";
55  }
56  failure << std::endl;
57  NS_TEST_ASSERT_MSG_EQ_INTERNAL (true, false, failure.str (), file, line);
58  }
59 }
60 
64 #define ENSURE_WRITTEN_BYTES(buffer, n, ...) \
65  { \
66  uint8_t bytes[] = { __VA_ARGS__}; \
67  EnsureWrittenBytes (buffer, n, bytes, __FILE__, __LINE__); \
68  }
69 
70 void
72 {
73  Buffer buffer;
75  buffer.AddAtStart (6);
76  i = buffer.Begin ();
77  i.WriteU8 (0x66);
78  ENSURE_WRITTEN_BYTES (buffer, 1, 0x66);
79  i = buffer.Begin ();
80  i.WriteU8 (0x67);
81  ENSURE_WRITTEN_BYTES (buffer, 1, 0x67);
82  i.WriteHtonU16 (0x6568);
83  i = buffer.Begin ();
84  ENSURE_WRITTEN_BYTES (buffer, 3, 0x67, 0x65, 0x68);
85  i.WriteHtonU16 (0x6369);
86  ENSURE_WRITTEN_BYTES (buffer, 3, 0x63, 0x69, 0x68);
87  i.WriteHtonU32 (0xdeadbeaf);
88  ENSURE_WRITTEN_BYTES (buffer, 6, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf);
89  buffer.AddAtStart (2);
90  i = buffer.Begin ();
91  i.WriteU16 (0);
92  ENSURE_WRITTEN_BYTES (buffer, 8, 0, 0, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf);
93  buffer.AddAtEnd (2);
94  i = buffer.Begin ();
95  i.Next (8);
96  i.WriteU16 (0);
97  ENSURE_WRITTEN_BYTES (buffer, 10, 0, 0, 0x63, 0x69, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
98  buffer.RemoveAtStart (3);
99  i = buffer.Begin ();
100  ENSURE_WRITTEN_BYTES (buffer, 7, 0x69, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
101  buffer.RemoveAtEnd (4);
102  i = buffer.Begin ();
103  ENSURE_WRITTEN_BYTES (buffer, 3, 0x69, 0xde, 0xad);
104  buffer.AddAtStart (1);
105  i = buffer.Begin ();
106  i.WriteU8 (0xff);
107  ENSURE_WRITTEN_BYTES (buffer, 4, 0xff, 0x69, 0xde, 0xad);
108  buffer.AddAtEnd (1);
109  i = buffer.Begin ();
110  i.Next (4);
111  i.WriteU8 (0xff);
112  i.Prev (2);
113  uint16_t saved = i.ReadU16 ();
114  i.Prev (2);
115  i.WriteHtonU16 (0xff00);
116  i.Prev (2);
117  NS_TEST_ASSERT_MSG_EQ (i.ReadNtohU16 (), 0xff00, "Could not read expected value");
118  i.Prev (2);
119  i.WriteU16 (saved);
120  ENSURE_WRITTEN_BYTES (buffer, 5, 0xff, 0x69, 0xde, 0xad, 0xff);
121  Buffer o = buffer;
122  ENSURE_WRITTEN_BYTES (o, 5, 0xff, 0x69, 0xde, 0xad, 0xff);
123  o.AddAtStart (1);
124  i = o.Begin ();
125  i.WriteU8 (0xfe);
126  ENSURE_WRITTEN_BYTES (o, 6, 0xfe, 0xff, 0x69, 0xde, 0xad, 0xff);
127  buffer.AddAtStart (2);
128  i = buffer.Begin ();
129  i.WriteU8 (0xfd);
130  i.WriteU8 (0xfd);
131  ENSURE_WRITTEN_BYTES (o, 6, 0xfe, 0xff, 0x69, 0xde, 0xad, 0xff);
132  ENSURE_WRITTEN_BYTES (buffer, 7, 0xfd, 0xfd, 0xff, 0x69, 0xde, 0xad, 0xff);
133 
134  // test 64-bit read/write
135  Buffer buff64;
136  buff64.AddAtStart (8);
137  i = buff64.Begin ();
138  i.WriteU64 (0x0123456789ABCDEFllu);
139  ENSURE_WRITTEN_BYTES (buff64, 8, 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01);
140  i = buff64.Begin ();
141  NS_TEST_ASSERT_MSG_EQ (i.ReadLsbtohU64 (), 0x0123456789abcdefllu, "Could not read expected value");
142  i = buff64.Begin ();
143  i.WriteHtolsbU64 (0x0123456789ABCDEFllu);
144  ENSURE_WRITTEN_BYTES (buff64, 8, 0xef, 0xcd, 0xab, 0x89, 0x67, 0x45, 0x23, 0x01);
145  i = buff64.Begin ();
146  NS_TEST_ASSERT_MSG_EQ (i.ReadLsbtohU64 (), 0x0123456789abcdefllu, "Could not read expected value");
147  i = buff64.Begin ();
148  i.WriteHtonU64 (0x0123456789ABCDEFllu);
149  ENSURE_WRITTEN_BYTES (buff64, 8, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef);
150  i = buff64.Begin ();
151  NS_TEST_ASSERT_MSG_EQ (i.ReadNtohU64 (), 0x0123456789abcdefllu, "could not read expected value");
152 
153  // test self-assignment
154  {
155  Buffer a = o;
156  a = a;
157  }
158 
159  // test Remove start.
160  buffer = Buffer (5);
161  ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0);
162  buffer.RemoveAtStart (1);
163  ENSURE_WRITTEN_BYTES (buffer, 4, 0, 0, 0, 0);
164  buffer.AddAtStart (1);
165  buffer.Begin ().WriteU8 (0xff);
166  ENSURE_WRITTEN_BYTES (buffer, 5, 0xff, 0, 0, 0, 0);
167  buffer.RemoveAtStart (3);
168  ENSURE_WRITTEN_BYTES (buffer, 2, 0, 0);
169  buffer.AddAtStart (4);
170  buffer.Begin ().WriteHtonU32 (0xdeadbeaf);
171  ENSURE_WRITTEN_BYTES (buffer, 6, 0xde, 0xad, 0xbe, 0xaf, 0, 0);
172  buffer.RemoveAtStart (2);
173  ENSURE_WRITTEN_BYTES (buffer, 4, 0xbe, 0xaf, 0, 0);
174  buffer.AddAtEnd (4);
175  i = buffer.Begin ();
176  i.Next (4);
177  i.WriteHtonU32 (0xdeadbeaf);
178  ENSURE_WRITTEN_BYTES (buffer, 8, 0xbe, 0xaf, 0, 0, 0xde, 0xad, 0xbe, 0xaf);
179  buffer.RemoveAtStart (5);
180  ENSURE_WRITTEN_BYTES (buffer, 3, 0xad, 0xbe, 0xaf);
181  // test Remove end
182  buffer = Buffer (5);
183  ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0);
184  buffer.RemoveAtEnd (1);
185  ENSURE_WRITTEN_BYTES (buffer, 4, 0, 0, 0, 0);
186  buffer.AddAtEnd (2);
187  i = buffer.Begin ();
188  i.Next (4);
189  i.WriteU8 (0xab);
190  i.WriteU8 (0xac);
191  ENSURE_WRITTEN_BYTES (buffer, 6, 0, 0, 0, 0, 0xab, 0xac);
192  buffer.RemoveAtEnd (1);
193  ENSURE_WRITTEN_BYTES (buffer, 5, 0, 0, 0, 0, 0xab);
194  buffer.RemoveAtEnd (3);
195  ENSURE_WRITTEN_BYTES (buffer, 2, 0, 0);
196  buffer.AddAtEnd (6);
197  i = buffer.Begin ();
198  i.Next (2);
199  i.WriteU8 (0xac);
200  i.WriteU8 (0xad);
201  i.WriteU8 (0xae);
202  i.WriteU8 (0xaf);
203  i.WriteU8 (0xba);
204  i.WriteU8 (0xbb);
205  ENSURE_WRITTEN_BYTES (buffer, 8, 0, 0, 0xac, 0xad, 0xae, 0xaf, 0xba, 0xbb);
206  buffer.AddAtStart (3);
207  i = buffer.Begin ();
208  i.WriteU8 (0x30);
209  i.WriteU8 (0x31);
210  i.WriteU8 (0x32);
211  ENSURE_WRITTEN_BYTES (buffer, 11, 0x30, 0x31, 0x32, 0, 0, 0xac, 0xad, 0xae, 0xaf, 0xba, 0xbb);
212  buffer.RemoveAtEnd (9);
213  ENSURE_WRITTEN_BYTES (buffer, 2, 0x30, 0x31);
214  buffer = Buffer (3);
215  buffer.AddAtEnd (2);
216  i = buffer.Begin ();
217  i.Next (3);
218  i.WriteHtonU16 (0xabcd);
219  buffer.AddAtStart (1);
220  buffer.Begin ().WriteU8 (0x21);
221  ENSURE_WRITTEN_BYTES (buffer, 6, 0x21, 0, 0, 0, 0xab, 0xcd);
222  buffer.RemoveAtEnd (8);
223  NS_TEST_ASSERT_MSG_EQ (buffer.GetSize (), 0, "Buffer size not zero");
224 
225  buffer = Buffer (6);
226  buffer.AddAtStart (9);
227  buffer.AddAtEnd (3);
228  i = buffer.End ();
229  i.Prev (1);
230  i.WriteU8 (1, 1);
231 
232  buffer = Buffer (6);
233  buffer.AddAtStart (3);
234  buffer.RemoveAtEnd (8);
235  buffer.AddAtEnd (4);
236  i = buffer.End ();
237  i.Prev (4);
238  i.WriteU8 (1, 4);
239 
240  buffer = Buffer (1);
241  buffer.AddAtEnd (100);
242  i = buffer.End ();
243  i.Prev (100);
244  i.WriteU8 (1, 100);
245 
248  {
249  const uint32_t actualSize = 72602;
250  const uint32_t chunkSize = 67624;
251  Ptr<UniformRandomVariable> bytesRng = CreateObject<UniformRandomVariable> ();
252  bytesRng->SetAttribute ("Min", DoubleValue (0));
253  bytesRng->SetAttribute ("Max", DoubleValue (256));
254 
255  Buffer inputBuffer;
256  Buffer outputBuffer;
257 
258  inputBuffer.AddAtEnd (actualSize);
259  {
260  Buffer::Iterator iter = inputBuffer.Begin ();
261  for (uint32_t i = 0; i < actualSize; i++)
262  iter.WriteU8 (static_cast<uint8_t> (bytesRng->GetValue ()));
263  }
264 
265  outputBuffer.AddAtEnd (chunkSize);
266  Buffer::Iterator iter = outputBuffer.End ();
267  iter.Prev (chunkSize);
268  iter.Write (inputBuffer.PeekData (), chunkSize);
269 
270  NS_TEST_EXPECT_MSG_EQ (memcmp (inputBuffer.PeekData (), outputBuffer.PeekData (), chunkSize), 0, "memcp works");
271  }
272 
273  buffer = Buffer (5);
274  buffer.AddAtEnd (2);
275  i = buffer.End ();
276  i.Prev (2);
277  i.WriteU8 (0);
278  i.WriteU8 (0x66);
279  ENSURE_WRITTEN_BYTES (buffer, 7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66);
280  Buffer frag0 = buffer.CreateFragment (0, 2);
281  ENSURE_WRITTEN_BYTES (frag0, 2, 0x00, 0x00);
282  Buffer frag1 = buffer.CreateFragment (2, 5);
283  ENSURE_WRITTEN_BYTES (frag1, 5, 0x00, 0x00, 0x00, 0x00, 0x66);
284  frag0.AddAtEnd (frag1);
285  ENSURE_WRITTEN_BYTES (buffer, 7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66);
286  ENSURE_WRITTEN_BYTES (frag0, 7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66);
287 
288  buffer = Buffer (5);
289  buffer.AddAtStart (2);
290  i = buffer.Begin ();
291  i.WriteU8 (0x1);
292  i.WriteU8 (0x2);
293  buffer.AddAtEnd (2);
294  i = buffer.End ();
295  i.Prev (2);
296  i.WriteU8 (0x3);
297  i.WriteU8 (0x4);
298  ENSURE_WRITTEN_BYTES (buffer, 9, 0x1, 0x2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3, 0x4);
299  Buffer other;
300  other.AddAtStart (9);
301  i = other.Begin ();
302  i.Write (buffer.Begin (), buffer.End ());
303  ENSURE_WRITTEN_BYTES (other, 9, 0x1, 0x2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3, 0x4);
304 
306  std::string ct ("This is the next content of the buffer.");
307  buffer = Buffer ();
308  buffer.AddAtStart (ct.size ());
309  i = buffer.Begin ();
310  i.Write ((const uint8_t*)ct.c_str (), ct.size ());
311  uint32_t sizeBuffer = buffer.GetSize ();
312  NS_TEST_ASSERT_MSG_EQ (sizeBuffer, ct.size(), "Buffer bad size");
313  uint8_t const* evilBuffer = buffer.PeekData ();
314  NS_TEST_ASSERT_MSG_NE( evilBuffer, 0, "Buffer PeekData failed");
315  uint8_t *cBuf = (uint8_t*) malloc ( sizeBuffer );
316  uint32_t copyLen = buffer.CopyData (cBuf, sizeBuffer);
317  NS_TEST_ASSERT_MSG_EQ (copyLen, sizeBuffer, "CopyData return bad size");
318  for (uint8_t i=0; i < sizeBuffer ; i++ )
319  {
320  NS_TEST_ASSERT_MSG_EQ ( cBuf [i], *(((const uint8_t*)ct.c_str ()) + i), "Bad buffer copied data");
321  NS_TEST_ASSERT_MSG_EQ ( evilBuffer [i], cBuf [i] , "Bad buffer peeked");
322  }
323  free (cBuf);
324 }
325 //-----------------------------------------------------------------------------
327 {
328 public:
329  BufferTestSuite ();
330 };
331 
333  : TestSuite ("buffer", UNIT)
334 {
335  AddTestCase (new BufferTest, TestCase::QUICK);
336 }
337 
uint16_t ReadU16(void)
Definition: buffer.h:845
void WriteHtonU64(uint64_t data)
Definition: buffer.cc:965
#define ENSURE_WRITTEN_BYTES(buffer, n,...)
Definition: buffer-test.cc:64
#define NS_TEST_ASSERT_MSG_EQ_INTERNAL(actual, limit, msg, file, line)
Definition: test.h:92
void RemoveAtEnd(uint32_t end)
Definition: buffer.cc:497
void RemoveAtStart(uint32_t start)
Definition: buffer.cc:452
A suite of tests to run.
Definition: test.h:1025
automatically resized byte buffer
Definition: buffer.h:92
#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:539
encapsulates test code
Definition: test.h:849
void EnsureWrittenBytes(Buffer b, uint32_t n, uint8_t array[], const char *file, int line)
Definition: buffer-test.cc:25
iterator in a Buffer instance
Definition: buffer.h:98
void Prev(void)
go backward by one byte
Definition: buffer.h:672
#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:244
void WriteU16(uint16_t data)
Definition: buffer.cc:895
void WriteHtonU16(uint16_t data)
Definition: buffer.h:726
Buffer::Iterator End(void) const
Definition: buffer.h:881
uint8_t const * PeekData(void) const
Definition: buffer.cc:729
void Next(void)
go forward by one byte
Definition: buffer.h:666
void WriteU64(uint64_t data)
Definition: buffer.cc:915
Buffer::Iterator Begin(void) const
Definition: buffer.h:875
double GetValue(double min, double max)
Returns a random double from the uniform distribution with the specified range.
virtual void DoRun(void)
Implementation to actually run this TestCase.
Definition: buffer-test.cc:71
void AddTestCase(TestCase *testCase) NS_DEPRECATED
Add an individual child TestCase case to this TestCase.
Definition: test.cc:173
void WriteHtonU32(uint32_t data)
Definition: buffer.h:745
uint32_t GetSize(void) const
Definition: buffer.h:869
Buffer CreateFragment(uint32_t start, uint32_t length) const
Definition: buffer.cc:533
bool AddAtEnd(uint32_t end)
Definition: buffer.cc:356
void WriteU8(uint8_t data)
Definition: buffer.h:690
void WriteHtolsbU64(uint64_t data)
Definition: buffer.cc:951
void Write(uint8_t const *buffer, uint32_t size)
Definition: buffer.cc:978
bool AddAtStart(uint32_t start)
Definition: buffer.cc:305
uint64_t ReadLsbtohU64(void)
Definition: buffer.cc:1118
uint16_t ReadNtohU16(void)
Definition: buffer.h:767
Hold a floating point type.
Definition: double.h:41
void SetAttribute(std::string name, const AttributeValue &value)
Definition: object-base.cc:161
static BufferTestSuite g_bufferTestSuite
Definition: buffer-test.cc:338
#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:137