A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
command-line-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8#include "ns3/command-line.h"
9#include "ns3/config.h"
10#include "ns3/global-value.h"
11#include "ns3/log.h"
12#include "ns3/string.h"
13#include "ns3/system-path.h"
14#include "ns3/test.h"
15#include "ns3/type-id.h"
16
17#include <cstdarg>
18#include <sstream>
19
20/**
21 * @file
22 * @ingroup core-tests
23 * @ingroup commandline
24 * @ingroup commandline-tests
25 * CommandLine test suite.
26 */
27
28/**
29 * @ingroup core-tests
30 * @defgroup commandline-tests CommandLine test suite
31 */
32
33namespace ns3
34{
35
36namespace tests
37{
38
39/**
40 * @ingroup commandline-tests
41 * A test base class that drives Command Line parsing
42 */
44{
45 public:
46 /**
47 * Constructor
48 *
49 * @param description purpose of this TestCase
50 */
51 CommandLineTestCaseBase(std::string description);
52
53 /** Destructor */
55 {
56 }
57
58 /**
59 * Exercise the CommandLine with the provided arguments
60 *
61 * @param cmd the configured CommandLine
62 * @param n the number of arguments
63 */
64 void Parse(CommandLine& cmd, int n, ...);
65
66 /** Test iteration counter to give each test a unique name. */
67 static int m_count;
68};
69
71
73 : TestCase(description)
74{
75}
76
77void
79{
80 std::stringstream ss;
81 ss << GetParent()->GetName() << "-testcase-" << m_count << "-" << GetName();
82 ++m_count;
83
84 int argc = n + 1; // test name will go in argv[0], other n to follow
85 char** argv = new char*[argc + 1]; // extra entry for final null
86 argv[argc] = nullptr;
87
88 argv[0] = new char[strlen(ss.str().c_str()) + 1];
89 strcpy(argv[0], ss.str().c_str());
90
91 va_list ap;
92 va_start(ap, n);
93 for (int i = 1; i < argc; ++i)
94 {
95 char* arg = va_arg(ap, char*);
96 argv[i] = new char[strlen(arg) + 1];
97 strcpy(argv[i], arg);
98 }
99 va_end(ap);
100
101 cmd.Parse(argc, argv);
102
103 // Clean up all the new's
104 for (int i = 0; i < argc; ++i)
105 {
106 delete[] argv[i];
107 }
108 delete[] argv;
109}
110
111/**
112 * @ingroup commandline-tests
113 * Test boolean Command Line processing
114 */
116{
117 public:
118 /** Constructor */
120
121 /** Destructor */
123 {
124 }
125
126 private:
127 /** Run the test */
128 void DoRun() override;
129};
130
135
136void
138{
139 CommandLine cmd;
140 bool myBool = true;
141 bool myDefaultFalseBool = false;
142
143 cmd.AddValue("my-bool", "help", myBool);
144 cmd.AddValue("my-false-bool", "help", myDefaultFalseBool);
145
146 Parse(cmd, 1, "--my-bool=0");
148 false,
149 "CommandLine did not correctly set a boolean value to false, given 0");
150
151 Parse(cmd, 1, "--my-bool=1");
153 true,
154 "CommandLine did not correctly set a boolean value to true, given 1");
155
156 Parse(cmd, 1, "--my-bool");
158 false,
159 "CommandLine did not correctly toggle a default true boolean value to "
160 "false, given no argument");
161
162 Parse(cmd, 1, "--my-false-bool");
163 NS_TEST_ASSERT_MSG_EQ(myDefaultFalseBool,
164 true,
165 "CommandLine did not correctly toggle a default false boolean value to "
166 "true, given no argument");
167
168 Parse(cmd, 1, "--my-bool=t");
170 myBool,
171 true,
172 "CommandLine did not correctly set a boolean value to true, given 't' argument");
173
174 Parse(cmd, 1, "--my-bool=true");
176 myBool,
177 true,
178 "CommandLine did not correctly set a boolean value to true, given \"true\" argument");
179}
180
181/**
182 * @ingroup commandline-tests
183 * Test \c uint8_t Command Line processing
184 */
186{
187 public:
188 /** Constructor */
190
191 /** Destructor */
193 {
194 }
195
196 private:
197 /** Run the test */
198 void DoRun() override;
199};
200
205
206void
208{
209 CommandLine cmd;
210 uint8_t myUint8 = 10;
211
212 cmd.AddValue("my-uint8", "help", myUint8);
213
214 Parse(cmd, 1, "--my-uint8=1");
215 NS_TEST_ASSERT_MSG_EQ(myUint8,
216 1,
217 "CommandLine did not correctly set a uint8_t value to 1, given 1");
218}
219
220/**
221 * @ingroup commandline-tests
222 * Test int Command Line processing
223 */
225{
226 public:
227 /** Constructor */
229
230 /** Destructor */
232 {
233 }
234
235 private:
236 /** Run the test */
237 void DoRun() override;
238};
239
244
245void
247{
248 CommandLine cmd;
249 bool myBool = true;
250 int32_t myInt32 = 10;
251
252 cmd.AddValue("my-bool", "help", myBool);
253 cmd.AddValue("my-int32", "help", myInt32);
254
255 Parse(cmd, 2, "--my-bool=0", "--my-int32=-3");
257 false,
258 "CommandLine did not correctly set a boolean value to false");
259 NS_TEST_ASSERT_MSG_EQ(myInt32, -3, "CommandLine did not correctly set an integer value to -3");
260
261 Parse(cmd, 2, "--my-bool=1", "--my-int32=+2");
263 true,
264 "CommandLine did not correctly set a boolean value to true");
265 NS_TEST_ASSERT_MSG_EQ(myInt32, +2, "CommandLine did not correctly set an integer value to +2");
266}
267
268/**
269 * @ingroup commandline-tests
270 * Test unsigned int Command Line processing
271 */
273{
274 public:
275 /** Constructor */
277
278 /** Destructor */
280 {
281 }
282
283 private:
284 /** Run the test */
285 void DoRun() override;
286};
287
292
293void
295{
296 CommandLine cmd;
297 bool myBool = true;
298 uint32_t myUint32 = 10;
299
300 cmd.AddValue("my-bool", "help", myBool);
301 cmd.AddValue("my-uint32", "help", myUint32);
302
303 Parse(cmd, 2, "--my-bool=0", "--my-uint32=9");
304
306 false,
307 "CommandLine did not correctly set a boolean value to false");
308 NS_TEST_ASSERT_MSG_EQ(myUint32,
309 9,
310 "CommandLine did not correctly set an unsigned integer value to 9");
311}
312
313/**
314 * @ingroup commandline-tests
315 * Test string Command Line processing
316 */
318{
319 public:
320 /** Constructor */
322
323 /** Destructor */
325 {
326 }
327
328 private:
329 /** Run the test */
330 void DoRun() override;
331};
332
337
338void
340{
341 CommandLine cmd;
342 uint32_t myUint32 = 10;
343 std::string myStr = "MyStr";
344
345 cmd.AddValue("my-uint32", "help", myUint32);
346 cmd.AddValue("my-str", "help", myStr);
347
348 Parse(cmd, 2, "--my-uint32=9", "--my-str=XX");
349
350 NS_TEST_ASSERT_MSG_EQ(myUint32,
351 9,
352 "CommandLine did not correctly set an unsigned integer value to 9");
354 "XX",
355 "CommandLine did not correctly set a string value to \"XX\"");
356}
357
358/**
359 * @ingroup commandline-tests
360 * Test order of argument parsing
361 */
363{
364 public:
365 /** Constructor */
367
368 /** Destructor */
370 {
371 }
372
373 private:
374 /** Run the test */
375 void DoRun() override;
376};
377
382
383void
385{
386 CommandLine cmd;
387 uint32_t myUint32 = 0;
388
389 cmd.AddValue("my-uint32", "help", myUint32);
390
391 Parse(cmd, 2, "--my-uint32=1", "--my-uint32=2");
392
393 NS_TEST_ASSERT_MSG_EQ(myUint32,
394 2,
395 "CommandLine did not correctly set an unsigned integer value to 2");
396}
397
398/**
399 * @ingroup commandline-tests
400 * Test ignoring invalid arguments
401 */
403{
404 public:
405 /** Constructor */
407
408 /** Destructor */
410 {
411 }
412
413 private:
414 /** Run the test */
415 void DoRun() override;
416};
417
422
423void
425{
426 CommandLine cmd;
427 uint32_t myUint32 = 0;
428
429 cmd.AddValue("my-uint32", "help", myUint32);
430
431 Parse(cmd, 2, "quack", "--my-uint32=5");
432
433 NS_TEST_ASSERT_MSG_EQ(myUint32,
434 5,
435 "CommandLine did not correctly set an unsigned integer value to 5");
436}
437
438/**
439 * @ingroup commandline-tests
440 * Test non-option arguments
441 */
443{
444 public:
445 /** Constructor */
447
448 /** Destructor */
450 {
451 }
452
453 private:
454 /** Run the test */
455 void DoRun() override;
456};
457
462
463void
465{
466 CommandLine cmd;
467 bool myBool = false;
468 int32_t myInt = 1;
469 std::string myStr = "MyStr";
470
471 cmd.AddNonOption("my-bool", "help", myBool);
472 cmd.AddNonOption("my-int", "help", myInt);
473 cmd.AddNonOption("my-str", "help", myStr);
474
475 Parse(cmd, 2, "true", "5");
476
477 NS_TEST_ASSERT_MSG_EQ(myBool, true, "CommandLine did not correctly set a boolean non-option");
479 5,
480 "CommandLine did not correctly set an integer non-option value to 5");
481 NS_TEST_ASSERT_MSG_EQ(myStr, "MyStr", "CommandLine did not leave a non-option unmodified.");
482
483 Parse(cmd, 5, "false", "6", "newValue", "extraVal1", "extraVal2");
484
485 NS_TEST_ASSERT_MSG_EQ(myBool, false, "CommandLine did not correctly set a boolean non-option");
487 6,
488 "CommandLine did not correctly set an integer non-option value to 5");
489 NS_TEST_ASSERT_MSG_EQ(myStr, "newValue", "CommandLine did not leave a non-option unmodified.");
490
491 NS_TEST_ASSERT_MSG_EQ(cmd.GetNExtraNonOptions(),
492 2,
493 "CommandLine did not parse the correct number of extra non-options.");
494 NS_TEST_ASSERT_MSG_EQ(cmd.GetExtraNonOption(0),
495 "extraVal1",
496 "CommandLine did not correctly get one extra non-option");
497 NS_TEST_ASSERT_MSG_EQ(cmd.GetExtraNonOption(1),
498 "extraVal2",
499 "CommandLine did not correctly get two extra non-option");
500}
501
502/**
503 * @ingroup commandline-tests
504 * Test \c char* buffer argument
505 */
507{
508 public:
509 /** Constructor */
511
512 /** Destructor */
514 {
515 }
516
517 private:
518 /** Run the test */
519 void DoRun() override;
520};
521
526
527void
529{
530 // char* buffer option
531 constexpr int CHARBUF_SIZE = 10;
532 char charbuf[CHARBUF_SIZE] = "charstar";
533
534 CommandLine cmd;
535 cmd.AddValue("charbuf", "a char* buffer", charbuf, CHARBUF_SIZE);
536 Parse(cmd, 1, "--charbuf=deadbeef");
537
538 std::string value{charbuf};
539
540 NS_TEST_ASSERT_MSG_EQ(value, "deadbeef", "CommandLine did not correctly set a char* buffer");
541}
542
543/**
544 * @ingroup commandline-tests
545 * The Test Suite that glues all of the Test Cases together.
546 */
548{
549 public:
550 /** Constructor */
552};
553
567
568/**
569 * @ingroup commandline-tests
570 * CommandLineTestSuite instance variable.
571 */
573
574} // namespace tests
575
576} // namespace ns3
Parse command-line arguments.
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:296
TestCase * GetParent() const
Get the parent of this TestCase.
Definition test.cc:378
TestCase(const TestCase &)=delete
Caller graph was not generated because of its size.
std::string GetName() const
Definition test.cc:371
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:494
Test boolean Command Line processing.
Test int Command Line processing.
Test string Command Line processing.
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:133
Namespace for test files, TestCases and TestSuites.
Every class exported by the ns3 library is enclosed in the ns3 namespace.