1365 lines
61 KiB
C++
1365 lines
61 KiB
C++
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
|
/*
|
|
* Copyright (c) 2009 University of Washington
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation;
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#ifndef NS3_TEST_H
|
|
#define NS3_TEST_H
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <list>
|
|
#include <limits>
|
|
#include <stdint.h>
|
|
|
|
#include "ns3/system-wall-clock-ms.h"
|
|
|
|
extern bool gBreakOnFailure;
|
|
|
|
//
|
|
// Note on below macros:
|
|
//
|
|
// When multiple statements are used in a macro, they should be bound together
|
|
// in a loop syntactically, so the macro can appear safely inside if clauses
|
|
// or other places that expect a single statement or a statement block. The
|
|
// "strange" do while construct is a generally expected best practice for
|
|
// defining a robust macro.
|
|
//
|
|
|
|
/**
|
|
* \brief Convenience macro to extract the source directory of the current
|
|
* source file.
|
|
*
|
|
* \see TestCase::GetSourceDir
|
|
*/
|
|
#define NS_TEST_SOURCEDIR \
|
|
TestCase::GetSourceDir (__FILE__)
|
|
|
|
// ===========================================================================
|
|
// Test for equality (generic version)
|
|
// ===========================================================================
|
|
|
|
/**
|
|
* \internal
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_EQ_INTERNAL(actual, limit, msg, file, line) \
|
|
do { \
|
|
if (!((actual) == (limit))) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit; \
|
|
ReportTestFailure (std::string (#actual) + " (actual) == " + std::string (#limit) + " (limit)", \
|
|
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
if (!ContinueOnFailure ()) \
|
|
{ \
|
|
return; \
|
|
} \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that an actual and expected (limit) value are equal and report
|
|
* and abort if not.
|
|
*
|
|
* Check to see if the expected (limit) value is equal to the actual value found
|
|
* in a test case. If the two values are equal nothing happens, but if the
|
|
* comparison fails, an error is reported in a consistent way and the execution
|
|
* of the current test case is aborted.
|
|
*
|
|
* The message is interpreted as a stream, for example:
|
|
*
|
|
* \code
|
|
* NS_TEST_ASSERT_MSG_EQ (result, true,
|
|
* "cannot open file " << filename << " in test");
|
|
* \endcode
|
|
*
|
|
* is legal.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the expected value of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*
|
|
* \warning Do not use this macro if you are comparing floating point numbers
|
|
* (float or double) as it is unlikely to do what you expect. Use
|
|
* NS_TEST_ASSERT_MSG_EQ_TOL instead.
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg) \
|
|
NS_TEST_ASSERT_MSG_EQ_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
|
|
|
|
/**
|
|
* \internal
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL_INTERNAL(actual, limit, msg, file, line) \
|
|
do { \
|
|
if (!((actual) == (limit))) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit; \
|
|
ReportTestFailure (std::string (#actual) + " (actual) == " + std::string (#limit) + " (limit)", \
|
|
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
if (!ContinueOnFailure ()) \
|
|
{ \
|
|
return true; \
|
|
} \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that an actual and expected (limit) value are equal and report
|
|
* and abort if not.
|
|
*
|
|
* Check to see if the expected (limit) value is equal to the actual value found
|
|
* in a test case. If the two values are equal nothing happens, but if the
|
|
* comparison fails, an error is reported in a consistent way and the execution
|
|
* of the current test case is aborted.
|
|
*
|
|
* The message is interpreted as a stream, for example:
|
|
*
|
|
* \code
|
|
* NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL (result, true,
|
|
* "cannot open file " << filename << " in test");
|
|
* \endcode
|
|
*
|
|
* is legal.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the expected value of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*
|
|
* \warning Do not use this macro if you are comparing floating point numbers
|
|
* (float or double) as it is unlikely to do what you expect. Use
|
|
* NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL_TOL instead.
|
|
*
|
|
* This function returns a boolean value.
|
|
*
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL(actual, limit, msg) \
|
|
NS_TEST_ASSERT_MSG_EQ_RETURNS_BOOL_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
|
|
|
|
/**
|
|
* \internal
|
|
*
|
|
* Required to avoid use of return statement which allows use in methods
|
|
* (esp. callbacks) returning void.
|
|
*/
|
|
#define NS_TEST_EXPECT_MSG_EQ_INTERNAL(actual, limit, msg, file, line) \
|
|
do { \
|
|
if (!((actual) == (limit))) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit; \
|
|
ReportTestFailure (std::string (#actual) + " (actual) == " + std::string (#limit) + " (limit)", \
|
|
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that an actual and expected (limit) value are equal and report
|
|
* if not.
|
|
*
|
|
* Check to see if the expected (lmit) value is equal to the actual value found
|
|
* in a test case. If the two values are equal nothing happens, but if the
|
|
* comparison fails, an error is reported in a consistent way. EXPECT* macros
|
|
* do not return if an error is detected.
|
|
*
|
|
* The message is interpreted as a stream, for example:
|
|
*
|
|
* \code
|
|
* NS_TEST_EXPECT_MSG_EQUAL (result, true,
|
|
* "cannot open file " << filename << " in test");
|
|
* \endcode
|
|
*
|
|
* is legal.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the expected value of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*
|
|
* \warning Do not use this macro if you are comparing floating point numbers
|
|
* (float or double) as it is unlikely to do what you expect. Use
|
|
* NS_TEST_EXPECT_MSG_EQ_TOL instead.
|
|
*/
|
|
#define NS_TEST_EXPECT_MSG_EQ(actual, limit, msg) \
|
|
NS_TEST_EXPECT_MSG_EQ_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
|
|
|
|
// ===========================================================================
|
|
// Test for equality with a provided tolerance (use for floating point
|
|
// comparisons -- both float and double)
|
|
// ===========================================================================
|
|
|
|
/**
|
|
* \internal
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_EQ_TOL_INTERNAL(actual, limit, tol, msg, file, line) \
|
|
do { \
|
|
if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit << " +- " << tol; \
|
|
std::ostringstream condStream; \
|
|
condStream << #actual << " (actual) < " << #limit << " (limit) + " << #tol << " (tol) && " << \
|
|
#actual << " (actual) > " << #limit << " (limit) - " << #tol << " (tol)"; \
|
|
ReportTestFailure (condStream.str (), actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
if (!ContinueOnFailure ()) \
|
|
{ \
|
|
return; \
|
|
} \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that actual and expected (limit) values are equal to plus or minus
|
|
* some tolerance and report and abort if not.
|
|
*
|
|
* Check to see if the expected (limit) value is equal to the actual value found
|
|
* in a test case to some tolerance. This is not the same thing as asking if
|
|
* two floating point are equal to within some epsilon, but is useful for that
|
|
* case. This assertion is geared toward more of a measurement problem. Consider
|
|
* measuring a physical rod of some kind that you have ordered. You need to
|
|
* determine if it is "good." You won't measure the rod to an arbitrary precision
|
|
* of sixteen significant figures, you will measure the rod to determine if its
|
|
* length is within the tolerances you provided. For example, 12.00 inches plus
|
|
* or minus .005 inch may be just fine.
|
|
*
|
|
* In ns-3, you might want to measure a signal to noise ratio and check to see
|
|
* if the answer is what you expect. If you naively measure (double)1128.93 and
|
|
* compare this number with a constant 1128.93 you are almost certainly going to
|
|
* have your test fail because of floating point rounding errors. We provide a
|
|
* floating point comparison function ns3::TestDoubleIsEqual() but you will
|
|
* probably quickly find that is not what you want either. It may turn out to
|
|
* be the case that when you measured an snr that printed as 1128.93, what was
|
|
* actually measured was something more like 1128.9287653857625442 for example.
|
|
* Given that the double epsilon is on the order of 0.0000000000000009, you would
|
|
* need to provide sixteen significant figures of expected value for this kind of
|
|
* test to pass even with a typical test for floating point "approximate equality."
|
|
* That is clearly not required or desired. You really want to be able to provide
|
|
* 1128.93 along with a tolerance just like you provided 12 inches +- 0.005 inch
|
|
* above.
|
|
*
|
|
* This assertion is designed for real measurements by taking into account
|
|
* measurement tolerances. By doing so it also automatically compensates for
|
|
* floating point rounding errors. If you really want to check floating point
|
|
* equality down to the numeric_limits<double>::epsilon () range, consider using
|
|
* ns3::TestDoubleIsEqual().
|
|
*
|
|
* The message is interpreted as a stream, for example:
|
|
*
|
|
* \code
|
|
* NS_TEST_ASSERT_MSG_EQ_TOL (snr, 1128.93, 0.005, "wrong snr (" << snr << ") in test");
|
|
* \endcode
|
|
*
|
|
* is legal.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the expected value of the test.
|
|
* \param tol Tolerance of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg) \
|
|
NS_TEST_ASSERT_MSG_EQ_TOL_INTERNAL (actual, limit, tol, msg, __FILE__, __LINE__)
|
|
|
|
/**
|
|
* \internal
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL_INTERNAL(actual, limit, tol, msg, file, line) \
|
|
do { \
|
|
if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit << " +- " << tol; \
|
|
std::ostringstream condStream; \
|
|
condStream << #actual << " (actual) < " << #limit << " (limit) + " << #tol << " (tol) && " << \
|
|
#actual << " (actual) > " << #limit << " (limit) - " << #tol << " (tol)"; \
|
|
ReportTestFailure (condStream.str (), actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
if (!ContinueOnFailure ()) \
|
|
{ \
|
|
return true; \
|
|
} \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that actual and expected (limit) values are equal to plus or minus
|
|
* some tolerance and report and abort if not.
|
|
*
|
|
* Check to see if the expected (limit) value is equal to the actual value found
|
|
* in a test case to some tolerance. This is not the same thing as asking if
|
|
* two floating point are equal to within some epsilon, but is useful for that
|
|
* case. This assertion is geared toward more of a measurement problem. Consider
|
|
* measuring a physical rod of some kind that you have ordered. You need to
|
|
* determine if it is "good." You won't measure the rod to an arbitrary precision
|
|
* of sixteen significant figures, you will measure the rod to determine if its
|
|
* length is within the tolerances you provided. For example, 12.00 inches plus
|
|
* or minus .005 inch may be just fine.
|
|
*
|
|
* In ns-3, you might want to measure a signal to noise ratio and check to see
|
|
* if the answer is what you expect. If you naively measure (double)1128.93 and
|
|
* compare this number with a constant 1128.93 you are almost certainly going to
|
|
* have your test fail because of floating point rounding errors. We provide a
|
|
* floating point comparison function ns3::TestDoubleIsEqual() but you will
|
|
* probably quickly find that is not what you want either. It may turn out to
|
|
* be the case that when you measured an snr that printed as 1128.93, what was
|
|
* actually measured was something more like 1128.9287653857625442 for example.
|
|
* Given that the double epsilon is on the order of 0.0000000000000009, you would
|
|
* need to provide sixteen significant figures of expected value for this kind of
|
|
* test to pass even with a typical test for floating point "approximate equality."
|
|
* That is clearly not required or desired. You really want to be able to provide
|
|
* 1128.93 along with a tolerance just like you provided 12 inches +- 0.005 inch
|
|
* above.
|
|
*
|
|
* This assertion is designed for real measurements by taking into account
|
|
* measurement tolerances. By doing so it also automatically compensates for
|
|
* floating point rounding errors. If you really want to check floating point
|
|
* equality down to the numeric_limits<double>::epsilon () range, consider using
|
|
* ns3::TestDoubleIsEqual().
|
|
*
|
|
* The message is interpreted as a stream, for example:
|
|
*
|
|
* \code
|
|
* NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL (snr, 1128.93, 0.005, "wrong snr (" << snr << ") in test");
|
|
* \endcode
|
|
*
|
|
* is legal.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the expected value of the test.
|
|
* \param tol Tolerance of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*
|
|
* This function returns a boolean value.
|
|
*
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL(actual, limit, tol, msg) \
|
|
NS_TEST_ASSERT_MSG_EQ_TOL_RETURNS_BOOL_INTERNAL (actual, limit, tol, msg, __FILE__, __LINE__)
|
|
|
|
/**
|
|
* \internal
|
|
*
|
|
* Required to avoid use of return statement which allows use in methods
|
|
* (esp. callbacks) returning void.
|
|
*/
|
|
#define NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL(actual, limit, tol, msg, file, line) \
|
|
do { \
|
|
if ((actual) > (limit) + (tol) || (actual) < (limit) - (tol)) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit << " +- " << tol; \
|
|
std::ostringstream condStream; \
|
|
condStream << #actual << " (actual) < " << #limit << " (limit) + " << #tol << " (tol) && " << \
|
|
#actual << " (actual) > " << #limit << " (limit) - " << #tol << " (tol)"; \
|
|
ReportTestFailure (condStream.str (), actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that actual and expected (limit) values are equal to plus or minus
|
|
* some tolerance and report if not.
|
|
*
|
|
* Check to see if the expected (limit) value is equal to the actual value found
|
|
* in a test case to some tolerance. This is not the same thing as asking if
|
|
* two floating point are equal to within some epsilon, but is useful for that
|
|
* case. This assertion is geared toward more of a measurement problem. Consider
|
|
* measuring a physical rod of some kind that you have ordered. You need to
|
|
* determine if it is "good." You won't measure the rod to an arbitrary precision
|
|
* of sixteen significant figures, you will measure the rod to determine if its
|
|
* length is within the tolerances you provided. For example, 12.00 inches plus
|
|
* or minus .005 inch may be just fine.
|
|
*
|
|
* In ns-3, you might want to measure a signal to noise ratio and check to see
|
|
* if the answer is what you expect. If you naively measure (double)1128.93 and
|
|
* compare this number with a constant 1128.93 you are almost certainly going to
|
|
* have your test fail because of floating point rounding errors. We provide a
|
|
* floating point comparison function ns3::TestDoubleIsEqual() but you will
|
|
* probably quickly find that is not what you want either. It may turn out to
|
|
* be the case that when you measured an snr that printed as 1128.93, what was
|
|
* actually measured was something more like 1128.9287653857625442 for example.
|
|
* Given that the double epsilon is on the order of 0.0000000000000009, you would
|
|
* need to provide sixteen significant figures of expected value for this kind of
|
|
* test to pass even with a typical test for floating point "approximate equality."
|
|
* That is clearly not required or desired. You really want to be able to provide
|
|
* 1128.93 along with a tolerance just like you provided 12 inches +- 0.005 inch
|
|
* above.
|
|
*
|
|
* This assertion is designed for real measurements by taking into account
|
|
* measurement tolerances. By doing so it also automatically compensates for
|
|
* floating point rounding errors. If you really want to check floating point
|
|
* equality down to the numeric_limits<double>::epsilon () range, consider using
|
|
* ns3::TestDoubleIsEqual().
|
|
*
|
|
* The message is interpreted as a stream, for example:
|
|
*
|
|
* \code
|
|
* NS_TEST_EXPECT_MSG_EQ_TOL (snr, 1128.93, 0.005, "wrong snr (" << snr << ") in test");
|
|
* \endcode
|
|
*
|
|
* is legal.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the expected value of the test.
|
|
* \param tol Tolerance of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*/
|
|
#define NS_TEST_EXPECT_MSG_EQ_TOL(actual, limit, tol, msg) \
|
|
NS_TEST_EXPECT_MSG_EQ_TOL_INTERNAL (actual, limit, tol, msg, __FILE__, __LINE__)
|
|
|
|
// ===========================================================================
|
|
// Test for inequality
|
|
// ===========================================================================
|
|
|
|
/**
|
|
* \internal
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_NE_INTERNAL(actual, limit, msg, file, line) \
|
|
do { \
|
|
if (!((actual) != (limit))) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit; \
|
|
ReportTestFailure (std::string (#actual) + " (actual) != " + std::string (#limit) + " (limit)", \
|
|
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
if (!ContinueOnFailure ()) \
|
|
{ \
|
|
return; \
|
|
} \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that an actual and expected (limit) value are equal and report
|
|
* and abort if not.
|
|
*
|
|
* Check to see if the expected (limit) value is not equal to the actual value
|
|
* found in a test case. If the two values are equal nothing happens, but if
|
|
* the comparison fails, an error is reported in a consistent way and the
|
|
* execution of the current test case is aborted.
|
|
*
|
|
* The message is interpreted as a stream, for example:
|
|
*
|
|
* \code
|
|
* NS_TEST_ASSERT_MSG_NE (result, false,
|
|
* "cannot open file " << filename << " in test");
|
|
* \endcode
|
|
*
|
|
* is legal.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the expected value of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*
|
|
* \warning Do not use this macro if you are comparing floating point numbers
|
|
* (float or double). Use NS_TEST_ASSERT_MSG_FLNE instead.
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg) \
|
|
NS_TEST_ASSERT_MSG_NE_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
|
|
|
|
/**
|
|
* \internal
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL_INTERNAL(actual, limit, msg, file, line) \
|
|
do { \
|
|
if (!((actual) != (limit))) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit; \
|
|
ReportTestFailure (std::string (#actual) + " (actual) != " + std::string (#limit) + " (limit)", \
|
|
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
if (!ContinueOnFailure ()) \
|
|
{ \
|
|
return true; \
|
|
} \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that an actual and expected (limit) value are equal and report
|
|
* and abort if not.
|
|
*
|
|
* Check to see if the expected (limit) value is not equal to the actual value
|
|
* found in a test case. If the two values are equal nothing happens, but if
|
|
* the comparison fails, an error is reported in a consistent way and the
|
|
* execution of the current test case is aborted.
|
|
*
|
|
* The message is interpreted as a stream, for example:
|
|
*
|
|
* \code
|
|
* NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL (result, false,
|
|
* "cannot open file " << filename << " in test");
|
|
* \endcode
|
|
*
|
|
* is legal.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the expected value of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*
|
|
* \warning Do not use this macro if you are comparing floating point numbers
|
|
* (float or double). Use NS_TEST_ASSERT_MSG_FLNE instead.
|
|
*
|
|
* This function returns a boolean value.
|
|
*
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL(actual, limit, msg) \
|
|
NS_TEST_ASSERT_MSG_NE_RETURNS_BOOL_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
|
|
|
|
/**
|
|
* \internal
|
|
*
|
|
* Required to avoid use of return statement which allows use in methods
|
|
* (callbacks) returning void.
|
|
*/
|
|
#define NS_TEST_EXPECT_MSG_NE_INTERNAL(actual, limit, msg, file, line) \
|
|
do { \
|
|
if (!((actual) != (limit))) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit; \
|
|
ReportTestFailure (std::string (#actual) + " (actual) != " + std::string (#limit) + " (limit)", \
|
|
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that an actual and expected (limit) value are equal and report
|
|
* if not.
|
|
*
|
|
* Check to see if the expected (limit) value is equal to the actual value
|
|
* found in a test case. If the two values are equal nothing happens, but if
|
|
* the comparison fails, an error is reported in a consistent way. EXPECT*
|
|
* macros do not return if an error is detected.
|
|
*
|
|
* The message is interpreted as a stream, for example:
|
|
*
|
|
* \code
|
|
* NS_TEST_EXPECT_MSG_EQUAL (result, true,
|
|
* "cannot open file " << filename << " in test");
|
|
* \endcode
|
|
*
|
|
* is legal.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the expected value of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*
|
|
* \warning Do not use this macro if you are comparing floating point numbers
|
|
* (float or double). Use NS_TEST_EXPECT_MSG_FLNE instead.
|
|
*/
|
|
#define NS_TEST_EXPECT_MSG_NE(actual, limit, msg) \
|
|
NS_TEST_EXPECT_MSG_NE_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
|
|
|
|
// ===========================================================================
|
|
// Test for less than relation
|
|
// ===========================================================================
|
|
|
|
/**
|
|
* \internal
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_LT_INTERNAL(actual, limit, msg, file, line) \
|
|
do { \
|
|
if (!((actual) < (limit))) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit; \
|
|
ReportTestFailure (std::string (#actual) + " (actual) < " + std::string (#limit) + " (limit)", \
|
|
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
if (!ContinueOnFailure ()) \
|
|
{ \
|
|
return; \
|
|
} \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that an actual value is less than a limit and report and abort
|
|
* if not.
|
|
*
|
|
* Check to see if the actual value found in a test case is less than the
|
|
* limit value. If the actual value is lesser nothing happens, but if the
|
|
* check fails, an error is reported in a consistent way and the execution
|
|
* of the current test case is aborted.
|
|
*
|
|
* The message is interpreted as a stream.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the limit value of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_LT(actual, limit, msg) \
|
|
NS_TEST_ASSERT_MSG_LT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
|
|
|
|
/**
|
|
* \internal
|
|
*
|
|
* Required to avoid use of return statement which allows use in methods
|
|
* (callbacks) returning void.
|
|
*/
|
|
#define NS_TEST_EXPECT_MSG_LT_INTERNAL(actual, limit, msg, file, line) \
|
|
do { \
|
|
if (!((actual) < (limit))) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit; \
|
|
ReportTestFailure (std::string (#actual) + " (actual) < " + std::string (#limit) + " (limit)", \
|
|
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that an actual value is less than a limit and report if not.
|
|
*
|
|
* Check to see if the actual value found in a test case is less than the
|
|
* limit value. If the actual value is lesser nothing happens, but if the
|
|
* check fails, an error is reported in a consistent way. EXPECT* macros do
|
|
* not return if an error is detected.
|
|
*
|
|
* The message is interpreted as a stream.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the limit value of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*/
|
|
#define NS_TEST_EXPECT_MSG_LT(actual, limit, msg) \
|
|
NS_TEST_EXPECT_MSG_LT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
|
|
|
|
// ===========================================================================
|
|
// Test for greater than relation
|
|
// ===========================================================================
|
|
|
|
/**
|
|
* \internal
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_GT_INTERNAL(actual, limit, msg, file, line) \
|
|
do { \
|
|
if (!((actual) > (limit))) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit; \
|
|
ReportTestFailure (std::string (#actual) + " (actual) > " + std::string (#limit) + " (limit)", \
|
|
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
if (!ContinueOnFailure ()) \
|
|
{ \
|
|
return; \
|
|
} \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that an actual value is greater than a limit and report and abort
|
|
* if not.
|
|
*
|
|
* Check to see if the actual value found in a test case is greater than the
|
|
* limit value. If the actual value is greater nothing happens, but if the
|
|
* check fails, an error is reported in a consistent way and the execution
|
|
* of the current test case is aborted.
|
|
*
|
|
* The message is interpreted as a stream.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the limit value of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*/
|
|
#define NS_TEST_ASSERT_MSG_GT(actual, limit, msg) \
|
|
NS_TEST_ASSERT_MSG_GT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
|
|
|
|
/**
|
|
* \internal
|
|
*
|
|
* Required to avoid use of return statement which allows use in methods
|
|
* (callbacks) returning void.
|
|
*/
|
|
#define NS_TEST_EXPECT_MSG_GT_INTERNAL(actual, limit, msg, file, line) \
|
|
do { \
|
|
if (!((actual) > (limit))) \
|
|
{ \
|
|
if (gBreakOnFailure) {*(int *)0 = 0;} \
|
|
std::ostringstream msgStream; \
|
|
msgStream << msg; \
|
|
std::ostringstream actualStream; \
|
|
actualStream << actual; \
|
|
std::ostringstream limitStream; \
|
|
limitStream << limit; \
|
|
ReporTesttFailure (std::string (#actual) + " (actual) > " + std::string (#limit) + " (limit)", \
|
|
actualStream.str (), limitStream.str (), msgStream.str (), file, line); \
|
|
} \
|
|
} while (false)
|
|
|
|
/**
|
|
* \brief Test that an actual value is greater than a limit and report if not.
|
|
*
|
|
* Check to see if the actual value found in a test case is greater than the
|
|
* limit value. If the actual value is greater nothing happens, but if the
|
|
* check fails, an error is reported in a consistent way. EXPECT* macros do
|
|
* not return if an error is detected.
|
|
*
|
|
* The message is interpreted as a stream.
|
|
*
|
|
* \param actual Expression for the actual value found during the test.
|
|
* \param limit Expression for the limit value of the test.
|
|
* \param msg Message that is output if the test does not pass.
|
|
*/
|
|
#define NS_TEST_EXPECT_MSG_GT(actual, limit, msg) \
|
|
NS_TEST_EXPECT_MSG_GT_INTERNAL (actual, limit, msg, __FILE__, __LINE__)
|
|
|
|
namespace ns3 {
|
|
|
|
/**
|
|
* \brief Compare two double precision floating point numbers and declare them
|
|
* equal if they are within some epsilon of each other.
|
|
*
|
|
* Approximate comparison of floating point numbers near equality is trickier
|
|
* than one may expect and is well-discussed in the literature. Basic
|
|
* strategies revolve around a suggestion by Knuth to compare the floating
|
|
* point numbers as binary integers, supplying a maximum difference between
|
|
* them . This max difference is specified in Units in the Last Place (ulps)
|
|
* or a floating point epsilon.
|
|
*
|
|
* This routine is based on the GNU Scientific Library function gsl_fcmp.
|
|
*
|
|
* \param a The first of double precision floating point numbers to compare
|
|
* \param b The second of double precision floating point numbers to compare
|
|
* \param epsilon The second of double precision floating point numberss to compare
|
|
* \returns Returns true if the doubles are equal to a precision defined by epsilon
|
|
*/
|
|
bool TestDoubleIsEqual (const double a, const double b, const double epsilon = std::numeric_limits<double>::epsilon ());
|
|
|
|
/**
|
|
* \brief A single test case.
|
|
*/
|
|
class TestCase
|
|
{
|
|
public:
|
|
TestCase (std::string name);
|
|
virtual ~TestCase ();
|
|
|
|
/**
|
|
* \brief Run this test case.
|
|
*/
|
|
void Run (void);
|
|
|
|
/**
|
|
* \brief Set the verbosity of this test case.
|
|
* \param verbose Whether or not to turn on any output the
|
|
* test case may provide.
|
|
*/
|
|
void SetVerbose (bool verbose);
|
|
|
|
/**
|
|
* \brief Tell the test case whether or not to continue testing if an error is
|
|
* detected.
|
|
*
|
|
* Typically, test cases depend on some number of individual tests. Often,
|
|
* these tests build on functionality that has been previously verified. In
|
|
* this case, subsequent test failures may simply be alternate manifestations
|
|
* of previously detected errors. Some developers may only be interested in
|
|
* seeing the first failure. Other developers may want to see all the
|
|
* information they can get, and want to see all failures. This is a matter
|
|
* of individual preference, so we allow this behavior to be configured.
|
|
*
|
|
* \param continueOnFailure If true, run tests after a failure has been
|
|
* detected, otherwise stop on the first error.
|
|
*/
|
|
void SetContinueOnFailure (bool continueOnFailure);
|
|
|
|
/**
|
|
* \brief Set the name of this test case.
|
|
*/
|
|
void SetName (std::string name);
|
|
|
|
/**
|
|
* \brief Get the name of this test case.
|
|
*/
|
|
std::string GetName (void);
|
|
|
|
/**
|
|
* \brief Set the base directory of the ns-3 distribution.
|
|
*/
|
|
void SetBaseDir (std::string dir);
|
|
|
|
/**
|
|
* \brief Get the base directory of the ns-3 distribution.
|
|
*/
|
|
std::string GetBaseDir (void);
|
|
|
|
/**
|
|
* \brief Set the temporary file directory (where to write temporary files).
|
|
*/
|
|
void SetTempDir (std::string dir);
|
|
|
|
/**
|
|
* \brief Get the temporary file directory .
|
|
*/
|
|
std::string GetTempDir (void);
|
|
|
|
/**
|
|
* \brief Get the source directory of the current source file.
|
|
*
|
|
* One of the basic models of the test environment is that dedicated test-
|
|
* and response vectors live in the same directory as the source file. So it
|
|
* is a common operation to figure out what directory a given source file lives
|
|
* in.
|
|
*
|
|
* __FILE__ provides almost all of what we need, but in the gnu toolchain it
|
|
* comes out as something like "../src/core/pcap-file-test-suite.cc".
|
|
*
|
|
* We really don't want to have any dependency on the directory out of which a
|
|
* test is run, so we ask that any test-runner give us the base directory of the
|
|
* distribution, which is set via TestCase::SetBaseDir(). That string will look
|
|
* something like "/home/user/repos/ns-3-allinone/ns-3-dev".
|
|
*
|
|
* This function stitches the two pieces together and removes the file name to
|
|
* return something like "/home/user/repos/ns-3-allinone/ns-3-dev/src/core/".
|
|
*
|
|
* \param file The current source file name relative to the base directory.
|
|
* \returns The current source directory.
|
|
*
|
|
* \warning Always call this function as GetSourceDir (__FILE__) or use the
|
|
* convenience macro NS_TEST_SOURCEDIR.
|
|
*/
|
|
std::string GetSourceDir (std::string file);
|
|
|
|
/**
|
|
* \brief Set the stream to which status and result messages will be written.
|
|
*
|
|
* We really don't want to have to pass an ofstream around to every function
|
|
* and we especially don't want to have to make our clients plumb an ofstream
|
|
* around so we need to save it. Since file streams are not designed to be
|
|
* copied or assigned (what does it mean to have duplicate streams to a file)
|
|
* we have to stash a pointer to the stream.
|
|
*
|
|
* \param ofs output file stream
|
|
*/
|
|
void SetStream (std::ofstream *ofs);
|
|
|
|
/**
|
|
* \brief Get the stream to which status and result messages will be written.
|
|
*/
|
|
std::ofstream *GetStream (void);
|
|
|
|
/**
|
|
* \brief Manually update the error status of this test case.
|
|
*
|
|
* This does a logical OR of the error argument with the current error status.
|
|
* If the argument is false, it does nothing. If the argument is true, it
|
|
* sets the error status to "an error has occurred."
|
|
*
|
|
* \param error The status to use to update the test case error status
|
|
*/
|
|
void UpdateErrorStatus (bool error);
|
|
|
|
/**
|
|
* \brief Manually set the error status of this test case.
|
|
*
|
|
* This sets the current error status to the argument provided. Can be used
|
|
* to reset any previous errors if the argument is false.
|
|
*
|
|
* \param error The status to use to set the test case error status
|
|
*/
|
|
void SetErrorStatus (bool error);
|
|
|
|
/**
|
|
* \brief Get the error status of this test case.
|
|
*/
|
|
bool GetErrorStatus (void);
|
|
|
|
/**
|
|
* \brief Should test cases continue running in the presence of errors?
|
|
* \returns True if the test case should continue, false otherwise.
|
|
*/
|
|
bool ContinueOnFailure (void);
|
|
|
|
/**
|
|
* \brief Issue a test report than the test suite has started running.
|
|
*/
|
|
void ReportStart (void);
|
|
|
|
/**
|
|
* \brief Issue a test report than the test case has declared success.
|
|
*/
|
|
void ReportCaseSuccess (void);
|
|
|
|
/**
|
|
* \brief Issue a test report than the test case has declared failure.
|
|
*/
|
|
void ReportCaseFailure (void);
|
|
|
|
/**
|
|
* \brief Issue a test report than the test case has found an error and
|
|
* report the details.
|
|
*/
|
|
void ReportTestFailure (std::string cond, std::string actual, std::string limit, std::string message,
|
|
std::string file, int32_t line);
|
|
|
|
/**
|
|
* \brief Issue a test report than the test case has completed its run.
|
|
*/
|
|
void ReportEnd (void);
|
|
|
|
protected:
|
|
/**
|
|
* \internal
|
|
* \brief Implementation of reporting method for the start of the test case.
|
|
*/
|
|
virtual void DoReportStart (void);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation of reporting method for success of the test case.
|
|
*/
|
|
virtual void DoReportCaseSuccess (void);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation of reporting method for failure of the test case.
|
|
*/
|
|
virtual void DoReportCaseFailure (void);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation of reporting method for failure of the test case.
|
|
*/
|
|
virtual void DoReportTestFailure (std::string cond, std::string actual, std::string limit, std::string message,
|
|
std::string file, int32_t line);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation of reporting method for the end of the test case.
|
|
*/
|
|
virtual void DoReportEnd (void);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation to do any local setup required for this test case.
|
|
*/
|
|
virtual void DoSetup (void);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation to actually run this test case.
|
|
*/
|
|
virtual void DoRun (void) = 0;
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation to do any local setup required for this test case.
|
|
*/
|
|
virtual void DoTeardown (void);
|
|
|
|
private:
|
|
TestCase (TestCase& tc);
|
|
TestCase& operator= (TestCase& tc);
|
|
|
|
SystemWallClockMs m_msClock;
|
|
std::string m_name;
|
|
bool m_verbose;
|
|
bool m_continueOnFailure;
|
|
bool m_detailsReported;
|
|
std::string m_basedir;
|
|
std::string m_tempdir;
|
|
std::ofstream *m_ofs;
|
|
bool m_error;
|
|
};
|
|
|
|
/**
|
|
* \brief A suite of tests to run.
|
|
*/
|
|
class TestSuite
|
|
{
|
|
public:
|
|
/**
|
|
* \enum TestType
|
|
* \brief Type of test.
|
|
*/
|
|
enum TestType {
|
|
BVT = 1, /**< This test suite implements a Build Verification Test */
|
|
UNIT, /**< This test suite implements a Unit Test */
|
|
SYSTEM, /**< This test suite implements a System Test */
|
|
EXAMPLE, /**< This test suite implements an Example Test */
|
|
PERFORMANCE /**< This test suite implements a Performance Test */
|
|
};
|
|
|
|
/**
|
|
* \brief Constuct a new test suite.
|
|
*
|
|
* \param name The name of the test suite.
|
|
* \param type The TestType of the test suite (defaults to UNIT test).
|
|
*/
|
|
TestSuite (std::string name, TestType type = UNIT);
|
|
|
|
/**
|
|
* \brief Destroy a test suite.
|
|
*/
|
|
virtual ~TestSuite ();
|
|
|
|
/**
|
|
* \brief Run this test suite.
|
|
*
|
|
* \returns Boolean sense of "an error has occurred."
|
|
*/
|
|
bool Run (void);
|
|
|
|
/**
|
|
* \brief Add an individual test case to this test suite.
|
|
*
|
|
* \param testCase Pointer to the test case object to be added.
|
|
* \returns Integer assigned as identifer of the provided test case.
|
|
*/
|
|
uint32_t AddTestCase (TestCase *testCase);
|
|
|
|
/**
|
|
* \brief Get the number of test cases that have been added to this test suite.
|
|
*
|
|
* \returns Number of test cases in the suite.
|
|
*/
|
|
uint32_t GetNTestCases (void);
|
|
|
|
/**
|
|
* \brief Get the test case at index i.
|
|
*/
|
|
TestCase *GetTestCase (uint32_t i);
|
|
|
|
/**
|
|
* \brief get the kind of test this test suite implements
|
|
*
|
|
* \returns the TestType of the suite.
|
|
*/
|
|
TestType GetTestType (void);
|
|
|
|
/**
|
|
* \brief Set the verbosity of this test suite.
|
|
* \param verbose Whether or not to turn on any output the
|
|
* test case may provide.
|
|
*/
|
|
void SetVerbose (bool verbose);
|
|
|
|
/**
|
|
* \brief Tell the test suite and its test cases whether or not to continue
|
|
* testing if an error is detected.
|
|
*
|
|
* Typically, test suites depend on some number of test cases, which in turn
|
|
* depend on some number of individual tests. Often, these tests build on
|
|
* functionality that has been previously verified. In this case, subsequent
|
|
* test failures may simply be alternate manifestations of previously detected
|
|
* errors. Some developers may only be interested in seeing the first failure.
|
|
* Other developers may want to see all the information they can get, and want
|
|
* to see all failures. This is a matter of individual preference, so we allow
|
|
* this behavior to be configured.
|
|
*
|
|
* \param continueOnFailure If true, continue running test cases after a
|
|
* failure has been detected, otherwise stop on the
|
|
* first error.
|
|
*/
|
|
void SetContinueOnFailure (bool continueOnFailure);
|
|
|
|
/**
|
|
* \brief Set the name of this test suite.
|
|
*/
|
|
void SetName (std::string name);
|
|
|
|
/**
|
|
* \brief Get the name of this test suite.
|
|
*/
|
|
std::string GetName (void);
|
|
|
|
/**
|
|
* \brief Set the base directory of the ns-3 distribution.
|
|
*/
|
|
void SetBaseDir (std::string basedir);
|
|
|
|
/**
|
|
* \brief Get the base directory of the ns-3 distribution.
|
|
*/
|
|
std::string GetBaseDir (void);
|
|
|
|
/**
|
|
* \brief Set the temporary file directory (where to write temporary files).
|
|
*/
|
|
void SetTempDir (std::string dir);
|
|
|
|
/**
|
|
* \brief Get the temporary file directory.
|
|
*/
|
|
std::string GetTempDir (void);
|
|
|
|
/**
|
|
* \brief Set the stream to which status and result messages will be written.
|
|
*
|
|
* We really don't want to have to pass an ofstream around to every function
|
|
* and we especially don't want to have to make our clients plumb an ofstream
|
|
* around so we need to save it. Since file streams are not designed to be
|
|
* copied or assigned (what does it mean to have duplicate streams to a file)
|
|
* we have to stash a pointer to the stream.
|
|
* \param ofs output file stream
|
|
*/
|
|
void SetStream (std::ofstream *ofs);
|
|
|
|
/**
|
|
* \brief Manually update the error status of this test suite.
|
|
*
|
|
* This does a logical OR of the error argument with the current error status.
|
|
* If the argument is false, it does nothing. If the argument is true, it
|
|
* sets the error status to "an error has occurred."
|
|
*
|
|
* \param error The status to use to update the test suite error status
|
|
*/
|
|
void UpdateErrorStatus (bool error);
|
|
|
|
/**
|
|
* \brief Manually set the error status of this test suite.
|
|
*
|
|
* This sets the current error status to the argument provided. Can be used
|
|
* to reset any previous errors if the argument is false.
|
|
*
|
|
* \param error The status to use to set the test suite error status
|
|
*/
|
|
void SetErrorStatus (bool error);
|
|
|
|
/**
|
|
* \brief Get the error status of this test suite.
|
|
*/
|
|
bool GetErrorStatus (void);
|
|
|
|
/**
|
|
* \brief Should test suite continue running cases in the presence of errors?
|
|
* \returns True if the test suite should continue, false otherwise.
|
|
*/
|
|
bool ContinueOnFailure (void);
|
|
|
|
/**
|
|
* \brief Issue a test report than the test suite has started running.
|
|
*/
|
|
void ReportStart (void);
|
|
|
|
/**
|
|
* \brief Issue a test report than the test suite has declared success.
|
|
*/
|
|
void ReportSuccess (void);
|
|
|
|
/**
|
|
* \brief Issue a test report than the test suite has found an error.
|
|
*/
|
|
void ReportFailure (void);
|
|
|
|
/**
|
|
* \brief Issue a test report than the test suite has completed its run.
|
|
*/
|
|
void ReportEnd (void);
|
|
|
|
protected:
|
|
/**
|
|
* \internal
|
|
* \brief Implementation of reporting method for the start of the test suite.
|
|
*/
|
|
virtual void DoReportStart (void);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation of reporting method for success of the test suite.
|
|
*/
|
|
virtual void DoReportSuccess (void);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation of reporting method for failure of the test suite.
|
|
*/
|
|
virtual void DoReportFailure (void);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation of reporting method for the end of the test suite.
|
|
*/
|
|
virtual void DoReportEnd (void);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation to do any local setup required for this test suite.
|
|
*/
|
|
virtual void DoSetup (void);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation to actually run this test suite.
|
|
*/
|
|
virtual void DoRun (void);
|
|
|
|
/**
|
|
* \internal
|
|
* \brief Implementation to do any local setup required for this test suite.
|
|
*/
|
|
virtual void DoTeardown (void);
|
|
|
|
private:
|
|
TestSuite (TestSuite& ts);
|
|
TestSuite& operator= (TestSuite& ts);
|
|
|
|
SystemWallClockMs m_msClock;
|
|
std::string m_name;
|
|
bool m_verbose;
|
|
bool m_continueOnFailure;
|
|
std::string m_basedir;
|
|
std::string m_tempdir;
|
|
std::ofstream *m_ofs;
|
|
bool m_error;
|
|
TestType m_type;
|
|
|
|
typedef std::vector<TestCase *> TestCaseVector_t;
|
|
TestCaseVector_t m_tests;
|
|
};
|
|
|
|
/**
|
|
* \brief A runner to execute tests.
|
|
*/
|
|
class TestRunner
|
|
{
|
|
public:
|
|
static uint32_t AddTestSuite (TestSuite *testSuite);
|
|
static uint32_t GetNTestSuites (void);
|
|
static TestSuite *GetTestSuite (uint32_t n);
|
|
};
|
|
|
|
/**
|
|
* \brief A simple way to store test vectors (for stimulus or from responses)
|
|
*/
|
|
template <typename T>
|
|
class TestVectors
|
|
{
|
|
public:
|
|
TestVectors ();
|
|
virtual ~TestVectors ();
|
|
|
|
void Reserve (uint32_t reserve);
|
|
|
|
uint32_t Add (T vector);
|
|
|
|
uint32_t GetN (void) const;
|
|
T Get (uint32_t i) const;
|
|
|
|
private:
|
|
TestVectors (const TestVectors& tv);
|
|
TestVectors& operator= (const TestVectors& tv);
|
|
bool operator== (const TestVectors& tv) const;
|
|
|
|
typedef std::vector<T> TestVector_t;
|
|
TestVector_t m_vectors;
|
|
};
|
|
|
|
template <typename T>
|
|
TestVectors<T>::TestVectors ()
|
|
: m_vectors ()
|
|
{
|
|
}
|
|
|
|
template <typename T>
|
|
void
|
|
TestVectors<T>::Reserve (uint32_t reserve)
|
|
{
|
|
m_vectors.reserve (reserve);
|
|
}
|
|
|
|
template <typename T>
|
|
TestVectors<T>::~TestVectors ()
|
|
{
|
|
}
|
|
|
|
template <typename T>
|
|
uint32_t
|
|
TestVectors<T>::Add (T vector)
|
|
{
|
|
uint32_t index = m_vectors.size ();
|
|
m_vectors.push_back (vector);
|
|
return index;
|
|
}
|
|
|
|
template <typename T>
|
|
uint32_t
|
|
TestVectors<T>::GetN (void) const
|
|
{
|
|
return m_vectors.size ();
|
|
}
|
|
|
|
template <typename T>
|
|
T
|
|
TestVectors<T>::Get (uint32_t i) const
|
|
{
|
|
NS_ABORT_MSG_UNLESS (m_vectors.size () > i, "TestVectors::Get(): Bad index");
|
|
return m_vectors[i];
|
|
}
|
|
|
|
} // namespace ns3
|
|
|
|
#endif /* NS3_TEST_H */
|