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 * 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
32/**
33 * \file
34 * \ingroup core-tests
35 * \ingroup commandline
36 * \ingroup commandline-tests
37 * CommandLine test suite.
38 */
39
40/**
41 * \ingroup core-tests
42 * \defgroup commandline-tests CommandLine test suite
43 */
44
45namespace ns3
46{
47
48namespace tests
49{
50
51/**
52 * \ingroup commandline-tests
53 * A test base class that drives Command Line parsing
54 */
56{
57 public:
58 /**
59 * Constructor
60 *
61 * \param description purpose of this TestCase
62 */
63 CommandLineTestCaseBase(std::string description);
64
65 /** Destructor */
67 {
68 }
69
70 /**
71 * Exercise the CommandLine with the provided arguments
72 *
73 * \param cmd the configured CommandLine
74 * \param n the number of arguments
75 */
76 void Parse(CommandLine& cmd, int n, ...);
77
78 /** Test iteration counter to give each test a unique name. */
79 static int m_count;
80};
81
83
85 : TestCase(description)
86{
87}
88
89void
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
123/**
124 * \ingroup commandline-tests
125 * Test boolean Command Line processing
126 */
128{
129 public:
130 /** Constructor */
132
133 /** Destructor */
135 {
136 }
137
138 private:
139 /** Run the test */
140 void DoRun() override;
141};
142
144 : CommandLineTestCaseBase("boolean")
145{
146}
147
148void
150{
151 CommandLine cmd;
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");
160 false,
161 "CommandLine did not correctly set a boolean value to false, given 0");
162
163 Parse(cmd, 1, "--my-bool=1");
165 true,
166 "CommandLine did not correctly set a boolean value to true, given 1");
167
168 Parse(cmd, 1, "--my-bool");
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
193/**
194 * \ingroup commandline-tests
195 * Test \c uint8_t Command Line processing
196 */
198{
199 public:
200 /** Constructor */
202
203 /** Destructor */
205 {
206 }
207
208 private:
209 /** Run the test */
210 void DoRun() override;
211};
212
214 : CommandLineTestCaseBase("uint8_t")
215{
216}
217
218void
220{
221 CommandLine cmd;
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
232/**
233 * \ingroup commandline-tests
234 * Test int Command Line processing
235 */
237{
238 public:
239 /** Constructor */
241
242 /** Destructor */
244 {
245 }
246
247 private:
248 /** Run the test */
249 void DoRun() override;
250};
251
254{
255}
256
257void
259{
260 CommandLine cmd;
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");
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");
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
280/**
281 * \ingroup commandline-tests
282 * Test unsigned int Command Line processing
283 */
285{
286 public:
287 /** Constructor */
289
290 /** Destructor */
292 {
293 }
294
295 private:
296 /** Run the test */
297 void DoRun() override;
298};
299
301 : CommandLineTestCaseBase("unsigned-int")
302{
303}
304
305void
307{
308 CommandLine cmd;
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
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
325/**
326 * \ingroup commandline-tests
327 * Test string Command Line processing
328 */
330{
331 public:
332 /** Constructor */
334
335 /** Destructor */
337 {
338 }
339
340 private:
341 /** Run the test */
342 void DoRun() override;
343};
344
346 : CommandLineTestCaseBase("string")
347{
348}
349
350void
352{
353 CommandLine cmd;
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");
366 "XX",
367 "CommandLine did not correctly set a string value to \"XX\"");
368}
369
370/**
371 * \ingroup commandline-tests
372 * Test order of argument parsing
373 */
375{
376 public:
377 /** Constructor */
379
380 /** Destructor */
382 {
383 }
384
385 private:
386 /** Run the test */
387 void DoRun() override;
388};
389
391 : CommandLineTestCaseBase("order")
392{
393}
394
395void
397{
398 CommandLine cmd;
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
410/**
411 * \ingroup commandline-tests
412 * Test ignoring invalid arguments
413 */
415{
416 public:
417 /** Constructor */
419
420 /** Destructor */
422 {
423 }
424
425 private:
426 /** Run the test */
427 void DoRun() override;
428};
429
431 : CommandLineTestCaseBase("invalid")
432{
433}
434
435void
437{
438 CommandLine cmd;
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
450/**
451 * \ingroup commandline-tests
452 * Test non-option arguments
453 */
455{
456 public:
457 /** Constructor */
459
460 /** Destructor */
462 {
463 }
464
465 private:
466 /** Run the test */
467 void DoRun() override;
468};
469
471 : CommandLineTestCaseBase("nonoption")
472{
473}
474
475void
477{
478 CommandLine cmd;
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");
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");
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
514/**
515 * \ingroup commandline-tests
516 * Test \c char* buffer argument
517 */
519{
520 public:
521 /** Constructor */
523
524 /** Destructor */
526 {
527 }
528
529 private:
530 /** Run the test */
531 void DoRun() override;
532};
533
535 : CommandLineTestCaseBase("charstar")
536{
537}
538
539void
541{
542 // char* buffer option
543 constexpr int CHARBUF_SIZE = 10;
544 char charbuf[CHARBUF_SIZE] = "charstar";
545
546 CommandLine cmd;
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
555/**
556 * \ingroup commandline-tests
557 * The Test Suite that glues all of the Test Cases together.
558 */
560{
561 public:
562 /** Constructor */
564};
565
567 : TestSuite("command-line")
568{
578}
579
580/**
581 * \ingroup commandline-tests
582 * CommandLineTestSuite instance variable.
583 */
585
586} // namespace tests
587
588} // namespace ns3
Parse command-line arguments.
Definition: command-line.h:232
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=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:1268
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:145
Every class exported by the ns3 library is enclosed in the ns3 namespace.