A Discrete-Event Network Simulator
API
command-line-test-suite.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008 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  * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18  */
19 #include "ns3/command-line.h"
20 #include "ns3/config.h"
21 #include "ns3/global-value.h"
22 #include "ns3/log.h"
23 #include "ns3/string.h"
24 #include "ns3/system-path.h"
25 #include "ns3/test.h"
26 #include "ns3/type-id.h"
27 
28 #include <cstdarg>
29 #include <cstdlib>
30 #include <sstream>
31 
45 namespace ns3
46 {
47 
48 namespace tests
49 {
50 
56 {
57  public:
63  CommandLineTestCaseBase(std::string description);
64 
67  {
68  }
69 
76  void Parse(CommandLine& cmd, int n, ...);
77 
79  static int m_count;
80 };
81 
83 
85  : TestCase(description)
86 {
87 }
88 
89 void
91 {
92  std::stringstream ss;
93  ss << GetParent()->GetName() << "-testcase-" << m_count << "-" << GetName();
94  ++m_count;
95 
96  int argc = n + 1; // test name will go in argv[0], other n to follow
97  char** argv = new char*[argc + 1]; // extra entry for final null
98  argv[argc] = nullptr;
99 
100  argv[0] = new char[strlen(ss.str().c_str()) + 1];
101  strcpy(argv[0], ss.str().c_str());
102 
103  va_list ap;
104  va_start(ap, n);
105  for (int i = 1; i < argc; ++i)
106  {
107  char* arg = va_arg(ap, char*);
108  argv[i] = new char[strlen(arg) + 1];
109  strcpy(argv[i], arg);
110  }
111  va_end(ap);
112 
113  cmd.Parse(argc, argv);
114 
115  // Clean up all the new's
116  for (int i = 0; i < argc; ++i)
117  {
118  delete[] argv[i];
119  }
120  delete[] argv;
121 }
122 
128 {
129  public:
132 
135  {
136  }
137 
138  private:
140  void DoRun() override;
141 };
142 
144  : CommandLineTestCaseBase("boolean")
145 {
146 }
147 
148 void
150 {
152  bool myBool = true;
153  bool myDefaultFalseBool = false;
154 
155  cmd.AddValue("my-bool", "help", myBool);
156  cmd.AddValue("my-false-bool", "help", myDefaultFalseBool);
157 
158  Parse(cmd, 1, "--my-bool=0");
159  NS_TEST_ASSERT_MSG_EQ(myBool,
160  false,
161  "CommandLine did not correctly set a boolean value to false, given 0");
162 
163  Parse(cmd, 1, "--my-bool=1");
164  NS_TEST_ASSERT_MSG_EQ(myBool,
165  true,
166  "CommandLine did not correctly set a boolean value to true, given 1");
167 
168  Parse(cmd, 1, "--my-bool");
169  NS_TEST_ASSERT_MSG_EQ(myBool,
170  false,
171  "CommandLine did not correctly toggle a default true boolean value to "
172  "false, given no argument");
173 
174  Parse(cmd, 1, "--my-false-bool");
175  NS_TEST_ASSERT_MSG_EQ(myDefaultFalseBool,
176  true,
177  "CommandLine did not correctly toggle a default false boolean value to "
178  "true, given no argument");
179 
180  Parse(cmd, 1, "--my-bool=t");
182  myBool,
183  true,
184  "CommandLine did not correctly set a boolean value to true, given 't' argument");
185 
186  Parse(cmd, 1, "--my-bool=true");
188  myBool,
189  true,
190  "CommandLine did not correctly set a boolean value to true, given \"true\" argument");
191 }
192 
198 {
199  public:
202 
205  {
206  }
207 
208  private:
210  void DoRun() override;
211 };
212 
214  : CommandLineTestCaseBase("uint8_t")
215 {
216 }
217 
218 void
220 {
222  uint8_t myUint8 = 10;
223 
224  cmd.AddValue("my-uint8", "help", myUint8);
225 
226  Parse(cmd, 1, "--my-uint8=1");
227  NS_TEST_ASSERT_MSG_EQ(myUint8,
228  1,
229  "CommandLine did not correctly set a uint8_t value to 1, given 1");
230 }
231 
237 {
238  public:
241 
244  {
245  }
246 
247  private:
249  void DoRun() override;
250 };
251 
253  : CommandLineTestCaseBase("int")
254 {
255 }
256 
257 void
259 {
261  bool myBool = true;
262  int32_t myInt32 = 10;
263 
264  cmd.AddValue("my-bool", "help", myBool);
265  cmd.AddValue("my-int32", "help", myInt32);
266 
267  Parse(cmd, 2, "--my-bool=0", "--my-int32=-3");
268  NS_TEST_ASSERT_MSG_EQ(myBool,
269  false,
270  "CommandLine did not correctly set a boolean value to false");
271  NS_TEST_ASSERT_MSG_EQ(myInt32, -3, "CommandLine did not correctly set an integer value to -3");
272 
273  Parse(cmd, 2, "--my-bool=1", "--my-int32=+2");
274  NS_TEST_ASSERT_MSG_EQ(myBool,
275  true,
276  "CommandLine did not correctly set a boolean value to true");
277  NS_TEST_ASSERT_MSG_EQ(myInt32, +2, "CommandLine did not correctly set an integer value to +2");
278 }
279 
285 {
286  public:
289 
292  {
293  }
294 
295  private:
297  void DoRun() override;
298 };
299 
301  : CommandLineTestCaseBase("unsigned-int")
302 {
303 }
304 
305 void
307 {
309  bool myBool = true;
310  uint32_t myUint32 = 10;
311 
312  cmd.AddValue("my-bool", "help", myBool);
313  cmd.AddValue("my-uint32", "help", myUint32);
314 
315  Parse(cmd, 2, "--my-bool=0", "--my-uint32=9");
316 
317  NS_TEST_ASSERT_MSG_EQ(myBool,
318  false,
319  "CommandLine did not correctly set a boolean value to false");
320  NS_TEST_ASSERT_MSG_EQ(myUint32,
321  9,
322  "CommandLine did not correctly set an unsigned integer value to 9");
323 }
324 
330 {
331  public:
334 
337  {
338  }
339 
340  private:
342  void DoRun() override;
343 };
344 
346  : CommandLineTestCaseBase("string")
347 {
348 }
349 
350 void
352 {
354  uint32_t myUint32 = 10;
355  std::string myStr = "MyStr";
356 
357  cmd.AddValue("my-uint32", "help", myUint32);
358  cmd.AddValue("my-str", "help", myStr);
359 
360  Parse(cmd, 2, "--my-uint32=9", "--my-str=XX");
361 
362  NS_TEST_ASSERT_MSG_EQ(myUint32,
363  9,
364  "CommandLine did not correctly set an unsigned integer value to 9");
365  NS_TEST_ASSERT_MSG_EQ(myStr,
366  "XX",
367  "CommandLine did not correctly set a string value to \"XX\"");
368 }
369 
375 {
376  public:
379 
382  {
383  }
384 
385  private:
387  void DoRun() override;
388 };
389 
391  : CommandLineTestCaseBase("order")
392 {
393 }
394 
395 void
397 {
399  uint32_t myUint32 = 0;
400 
401  cmd.AddValue("my-uint32", "help", myUint32);
402 
403  Parse(cmd, 2, "--my-uint32=1", "--my-uint32=2");
404 
405  NS_TEST_ASSERT_MSG_EQ(myUint32,
406  2,
407  "CommandLine did not correctly set an unsigned integer value to 2");
408 }
409 
415 {
416  public:
419 
422  {
423  }
424 
425  private:
427  void DoRun() override;
428 };
429 
431  : CommandLineTestCaseBase("invalid")
432 {
433 }
434 
435 void
437 {
439  uint32_t myUint32 = 0;
440 
441  cmd.AddValue("my-uint32", "help", myUint32);
442 
443  Parse(cmd, 2, "quack", "--my-uint32=5");
444 
445  NS_TEST_ASSERT_MSG_EQ(myUint32,
446  5,
447  "CommandLine did not correctly set an unsigned integer value to 5");
448 }
449 
455 {
456  public:
459 
462  {
463  }
464 
465  private:
467  void DoRun() override;
468 };
469 
471  : CommandLineTestCaseBase("nonoption")
472 {
473 }
474 
475 void
477 {
479  bool myBool = false;
480  int32_t myInt = 1;
481  std::string myStr = "MyStr";
482 
483  cmd.AddNonOption("my-bool", "help", myBool);
484  cmd.AddNonOption("my-int", "help", myInt);
485  cmd.AddNonOption("my-str", "help", myStr);
486 
487  Parse(cmd, 2, "true", "5");
488 
489  NS_TEST_ASSERT_MSG_EQ(myBool, true, "CommandLine did not correctly set a boolean non-option");
490  NS_TEST_ASSERT_MSG_EQ(myInt,
491  5,
492  "CommandLine did not correctly set an integer non-option value to 5");
493  NS_TEST_ASSERT_MSG_EQ(myStr, "MyStr", "CommandLine did not leave a non-option unmodified.");
494 
495  Parse(cmd, 5, "false", "6", "newValue", "extraVal1", "extraVal2");
496 
497  NS_TEST_ASSERT_MSG_EQ(myBool, false, "CommandLine did not correctly set a boolean non-option");
498  NS_TEST_ASSERT_MSG_EQ(myInt,
499  6,
500  "CommandLine did not correctly set an integer non-option value to 5");
501  NS_TEST_ASSERT_MSG_EQ(myStr, "newValue", "CommandLine did not leave a non-option unmodified.");
502 
503  NS_TEST_ASSERT_MSG_EQ(cmd.GetNExtraNonOptions(),
504  2,
505  "CommandLine did not parse the correct number of extra non-options.");
506  NS_TEST_ASSERT_MSG_EQ(cmd.GetExtraNonOption(0),
507  "extraVal1",
508  "CommandLine did not correctly get one extra non-option");
509  NS_TEST_ASSERT_MSG_EQ(cmd.GetExtraNonOption(1),
510  "extraVal2",
511  "CommandLine did not correctly get two extra non-option");
512 }
513 
519 {
520  public:
523 
526  {
527  }
528 
529  private:
531  void DoRun() override;
532 };
533 
535  : CommandLineTestCaseBase("charstar")
536 {
537 }
538 
539 void
541 {
542  // char* buffer option
543  constexpr int CHARBUF_SIZE = 10;
544  char charbuf[CHARBUF_SIZE] = "charstar";
545 
547  cmd.AddValue("charbuf", "a char* buffer", charbuf, CHARBUF_SIZE);
548  Parse(cmd, 1, "--charbuf=deadbeef");
549 
550  std::string value{charbuf};
551 
552  NS_TEST_ASSERT_MSG_EQ(value, "deadbeef", "CommandLine did not correctly set a char* buffer");
553 }
554 
560 {
561  public:
564 };
565 
567  : TestSuite("command-line")
568 {
578 }
579 
585 
586 } // namespace tests
587 
588 } // namespace ns3
Parse command-line arguments.
Definition: command-line.h:232
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
TestCase * GetParent() const
Get the parent of this TestCase.
Definition: test.cc:380
std::string GetName() const
Definition: test.cc:373
A suite of tests to run.
Definition: test.h:1256
Test boolean Command Line processing.
Test int Command Line processing.
Test string Command Line processing.
A test base class that drives Command Line parsing.
CommandLineTestCaseBase(std::string description)
Constructor.
void Parse(CommandLine &cmd, int n,...)
Exercise the CommandLine with the provided arguments.
static int m_count
Test iteration counter to give each test a unique name.
The Test Suite that glues all of the Test Cases together.
Test uint8_t Command Line processing.
Test unsigned int Command Line processing.
static CommandLineTestSuite g_commandLineTestSuite
CommandLineTestSuite instance variable.
#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
Every class exported by the ns3 library is enclosed in the ns3 namespace.
cmd
Definition: second.py:40