A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
example-as-test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 Lawrence Livermore National Laboratory
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Peter D. Barnes, Jr. <pdbarnes@llnl.gov>
7 */
8
9#include "example-as-test.h"
10
11#include "ascii-test.h"
13#include "fatal-error.h"
14#include "log.h"
15
16#include <cstdlib> // itoa(), system ()
17#include <sstream>
18#include <string>
19
20/**
21 * @file
22 * @ingroup testing
23 * Implementation of classes ns3::ExampleAsTestSuite and ns3::ExampleTestCase.
24 */
25
26namespace ns3
27{
28
29NS_LOG_COMPONENT_DEFINE("ExampleAsTestCase");
30
31// Running tests as examples currently requires Python.
32
34 const std::string program,
35 const std::string dataDir,
36 const std::string args /* = "" */,
37 const bool shouldNotErr /* = true */)
38 : TestCase(name),
39 m_program(program),
40 m_dataDir(dataDir),
41 m_args(args),
42 m_shouldNotErr(shouldNotErr)
43{
44 NS_LOG_FUNCTION(this << name << program << dataDir << args);
45}
46
51
52std::string
54{
56 std::string command("%s ");
57 command += m_args;
58 return command;
59}
60
61std::string
63{
65 std::string command("");
66 return command;
67}
68
69void
71{
73 // Set up the output file names
75 std::string refFile = CreateDataDirFilename(GetName() + ".reflog");
76 std::string testFile = CreateTempDirFilename(GetName() + ".reflog");
77 std::string post = GetPostProcessingCommand();
78
79 if (!m_shouldNotErr)
80 {
81 // Strip any system- or compiler-dependent messages
82 // resulting from invoking NS_FATAL..., which in turn
83 // calls std::terminate
84 post += " | sed '1,/" + std::string(NS_FATAL_MSG) + "/!d' ";
85 }
86
87 std::stringstream ss;
88
89 ss << "python3 ./ns3 run " << m_program << " --no-build --command-template=\""
90 << GetCommandTemplate() << "\"";
91
92 if (post.empty())
93 {
94 // redirect to testfile, then std::clog, std::cerr to std::cout
95 ss << " > " << testFile << " 2>&1";
96 }
97 else
98 {
99 ss << " 2>&1 " << post << " > " << testFile;
100 }
101
102 int status = std::system(ss.str().c_str());
103
104 std::cout << "\n"
105 << GetName() << ":\n"
106 << " command: " << ss.str() << "\n"
107 << " status: " << status << "\n"
108 << " refFile: " << refFile << "\n"
109 << " testFile: " << testFile << "\n"
110 << " testFile contents:" << std::endl;
111
112 std::ifstream logF(testFile);
113 std::string line;
114 while (getline(logF, line))
115 {
116 std::cout << "--- " << line << "\n";
117 }
118 logF.close();
119
120 if (m_shouldNotErr)
121 {
122 // Make sure the example didn't outright crash
123 NS_TEST_ASSERT_MSG_EQ(status, 0, "example " + m_program + " exited abnormally");
124 }
125
126 // If we're just introspecting the command-line
127 // we've run the example and we're done
128 auto [found, intro] = EnvironmentVariable::Get("NS_COMMANDLINE_INTROSPECTION");
129 if (found)
130 {
131 return;
132 }
133
134 // Compare the testFile to the reference file
135 NS_ASCII_TEST_EXPECT_EQ(testFile, refFile);
136}
137
139 const std::string program,
140 const std::string dataDir,
141 const std::string args /* = "" */,
142 const Duration duration /* =QUICK */,
143 const bool shouldNotErr /* = true */)
144 : TestSuite(name, Type::EXAMPLE)
145{
146 NS_LOG_FUNCTION(this << name << program << dataDir << args << duration << shouldNotErr);
147 AddTestCase(new ExampleAsTestCase(name, program, dataDir, args, shouldNotErr), duration);
148}
149
150} // namespace ns3
#define NS_ASCII_TEST_EXPECT_EQ(gotFilename, expectedFilename)
Test that a pair of new/reference ascii files are equal.
Definition ascii-test.h:28
static KeyFoundType Get(const std::string &envvar, const std::string &key="", const std::string &delim=";")
Get the value corresponding to a key from an environment variable.
Execute an example program as a test, by comparing the output to a reference file.
virtual std::string GetCommandTemplate() const
Customization point for more complicated patterns to invoke the example program.
bool m_shouldNotErr
Whether error return status is a test failure.
virtual std::string GetPostProcessingCommand() const
Customization point for tests requiring post-processing of stdout.
void DoRun() override
Implementation to actually run this TestCase.
ExampleAsTestCase(const std::string name, const std::string program, const std::string dataDir, const std::string args="", const bool shouldNotErr=true)
Constructor.
std::string m_args
Any additional arguments to the program.
std::string m_dataDir
The source directory for the test.
std::string m_program
The program to run.
~ExampleAsTestCase() override
Destructor.
ExampleAsTestSuite(const std::string name, const std::string program, const std::string dataDir, const std::string args="", const Duration duration=Duration::QUICK, const bool shouldNotErr=true)
Constructor.
std::string CreateDataDirFilename(std::string filename)
Construct the full path to a file in the data directory.
Definition test.cc:417
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:296
Duration
How long the test takes to execute.
Definition test.h:1056
std::string CreateTempDirFilename(std::string filename)
Construct the full path to a file in a temporary directory.
Definition test.cc:436
void SetDataDir(std::string directory)
Set the data directory where reference trace files can be found.
Definition test.cc:476
TestCase(const TestCase &)=delete
Caller graph was not generated because of its size.
std::string GetName() const
Definition test.cc:371
Type
Type of test.
Definition test.h:1271
TestSuite(std::string name, Type type=Type::UNIT)
Construct a new test suite.
Definition test.cc:494
Class Environment declaration.
Enable examples to be run as meaningful tests.
NS_FATAL_x macro definitions.
constexpr std::string_view NS_FATAL_MSG
Output string marking imminent invocation of std::terminate.
Definition fatal-error.h:73
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#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
Debug message logging.
Every class exported by the ns3 library is enclosed in the ns3 namespace.