2007-08-13 09:55:32 +02:00
|
|
|
|
/*
|
|
|
|
|
|
Suite - helper class for running collections of tests
|
2010-12-17 23:28:49 +01:00
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
Copyright (C)
|
|
|
|
|
|
2008, Hermann Vosseler <Ichthyostega@web.de>
|
2010-12-17 23:28:49 +01:00
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
**Lumiera** is free software; you can redistribute it and/or modify it
|
|
|
|
|
|
under the terms of the GNU General Public License as published by the
|
|
|
|
|
|
Free Software Foundation; either version 2 of the License, or (at your
|
|
|
|
|
|
option) any later version. See the file COPYING for further details.
|
2010-12-17 23:28:49 +01:00
|
|
|
|
|
Copyright: clarify and simplify the file headers
* Lumiera source code always was copyrighted by individual contributors
* there is no entity "Lumiera.org" which holds any copyrights
* Lumiera source code is provided under the GPL Version 2+
== Explanations ==
Lumiera as a whole is distributed under Copyleft, GNU General Public License Version 2 or above.
For this to become legally effective, the ''File COPYING in the root directory is sufficient.''
The licensing header in each file is not strictly necessary, yet considered good practice;
attaching a licence notice increases the likeliness that this information is retained
in case someone extracts individual code files. However, it is not by the presence of some
text, that legally binding licensing terms become effective; rather the fact matters that a
given piece of code was provably copyrighted and published under a license. Even reformatting
the code, renaming some variables or deleting parts of the code will not alter this legal
situation, but rather creates a derivative work, which is likewise covered by the GPL!
The most relevant information in the file header is the notice regarding the
time of the first individual copyright claim. By virtue of this initial copyright,
the first author is entitled to choose the terms of licensing. All further
modifications are permitted and covered by the License. The specific wording
or format of the copyright header is not legally relevant, as long as the
intention to publish under the GPL remains clear. The extended wording was
based on a recommendation by the FSF. It can be shortened, because the full terms
of the license are provided alongside the distribution, in the file COPYING.
2024-11-17 23:42:55 +01:00
|
|
|
|
* *****************************************************************/
|
2007-08-13 09:55:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
2016-11-03 18:22:31 +01:00
|
|
|
|
/** @file suite.cpp
|
2016-11-07 15:51:41 +01:00
|
|
|
|
** Implementation of a simple test runner / test suite framework for unit testing.
|
2016-11-03 18:20:10 +01:00
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-08-26 19:14:39 +02:00
|
|
|
|
|
2024-11-10 00:40:20 +01:00
|
|
|
|
#include "lib/error.hpp"
|
2024-11-11 16:31:43 +01:00
|
|
|
|
#include "lib/symbol.hpp"
|
Library: ensure automatic re-seeding for TestFrame
This closes a ''conceptual gap.''
There was a `lib::TestFrame::reseed()` function, which should be invoked
whenever a clean / deterministinc seed is required for computations involving
`TestFrame` data.
On occasion I noticed that most actual usages of `TestFrame`, which became quite common
lately, were missing this `reseed()` call, while the enclosing test
had indeed a proper Test::seedRand() call.
So my conclusion is: if even ''I myself'' miss that fine point frequently,
it is justified to automated this setup, even while `TestFrame` is right now
the only client of such a setup-facility.
There is a twist though.
`TestFrame` is part of the ''Engine'' test coverage, i.e. it is linked
into `libtest-core.so`. While the support for random numbers and reseeding
is obviously a very basic library feature, and linked into `liblumiera.so`
**Oh well**.
So now we have ''yet another'' static registration service.
I kept everything as simple as possible, which means, we continue
to use the ''common, global random generator'' from the library,
and there is no protection against some other code using those
library functions in a non-deterministic way.
`lib/random-reseed.cpp` is just a glorified hard-wired setup, beware!
2026-02-22 21:59:43 +01:00
|
|
|
|
#include "lib/random-reseed.hpp"
|
2016-01-08 08:20:59 +01:00
|
|
|
|
#include "lib/format-cout.hpp"
|
2008-12-17 17:53:32 +01:00
|
|
|
|
#include "lib/test/suite.hpp"
|
|
|
|
|
|
#include "lib/test/run.hpp"
|
2014-08-17 08:03:21 +02:00
|
|
|
|
#include "lib/cmdline.hpp"
|
2024-11-10 00:40:20 +01:00
|
|
|
|
#include "lib/random.hpp"
|
2008-12-17 17:53:32 +01:00
|
|
|
|
#include "lib/util.hpp"
|
2007-08-17 00:36:07 +02:00
|
|
|
|
|
2009-10-02 17:26:50 +02:00
|
|
|
|
#include <boost/algorithm/string.hpp>
|
2024-11-10 16:22:46 +01:00
|
|
|
|
#include <optional>
|
2009-10-02 17:26:50 +02:00
|
|
|
|
#include <sstream>
|
2016-01-08 08:20:59 +01:00
|
|
|
|
#include <string>
|
2009-10-02 17:26:50 +02:00
|
|
|
|
#include <memory>
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <map>
|
2007-08-13 09:55:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
2009-07-19 05:47:36 +02:00
|
|
|
|
namespace test {
|
|
|
|
|
|
|
2007-08-13 09:55:32 +02:00
|
|
|
|
using std::map;
|
|
|
|
|
|
using std::vector;
|
2024-11-10 16:22:46 +01:00
|
|
|
|
using std::optional;
|
2014-04-03 22:42:48 +02:00
|
|
|
|
using std::shared_ptr;
|
2024-11-11 16:31:43 +01:00
|
|
|
|
using std::string_literals::operator ""s;
|
2007-08-23 17:52:33 +02:00
|
|
|
|
using boost::algorithm::trim;
|
2009-07-19 05:47:36 +02:00
|
|
|
|
|
2007-08-17 00:36:07 +02:00
|
|
|
|
using util::isnil;
|
2007-08-23 17:52:33 +02:00
|
|
|
|
using util::contains;
|
2024-11-11 16:31:43 +01:00
|
|
|
|
using util::toString;
|
2016-01-08 08:20:59 +01:00
|
|
|
|
using util::typeStr;
|
2024-11-10 16:22:46 +01:00
|
|
|
|
using lib::SeedNucleus;
|
2024-11-10 00:40:20 +01:00
|
|
|
|
using lib::Random;
|
2007-08-13 09:55:32 +02:00
|
|
|
|
|
|
|
|
|
|
typedef map<string, Launcher*> TestMap;
|
|
|
|
|
|
typedef shared_ptr<TestMap> PTestMap;
|
|
|
|
|
|
typedef map<string,PTestMap> GroupMap;
|
2009-07-19 05:47:36 +02:00
|
|
|
|
|
2007-08-13 09:55:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
2014-09-15 02:03:10 +02:00
|
|
|
|
namespace {
|
|
|
|
|
|
/**
|
|
|
|
|
|
* helper to collect and manage the test cases.
|
|
|
|
|
|
* Every testcase class should create a Launch instance,
|
|
|
|
|
|
* which causes a call to Suite::enrol(), so we can add a pointer
|
|
|
|
|
|
* to this Launcher into a map indexed by the provided testIDs and groupIDs.
|
|
|
|
|
|
* This enables us to build a Suite instance for any requested group
|
|
|
|
|
|
* and then instantiate and invoke individual testcases accordingly.
|
|
|
|
|
|
*/
|
|
|
|
|
|
class Registry
|
|
|
|
|
|
{
|
|
|
|
|
|
GroupMap groups_;
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
Registry() { };
|
|
|
|
|
|
|
|
|
|
|
|
PTestMap&
|
|
|
|
|
|
getGroup (string grpID)
|
|
|
|
|
|
{
|
|
|
|
|
|
return groups_[grpID];
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
add2group (Launcher* test, string testID, string groupID)
|
|
|
|
|
|
{
|
|
|
|
|
|
REQUIRE( test );
|
|
|
|
|
|
REQUIRE( !isnil(testID) );
|
|
|
|
|
|
REQUIRE( !isnil(groupID) );
|
|
|
|
|
|
|
|
|
|
|
|
PTestMap& group = getGroup(groupID);
|
|
|
|
|
|
if (!group)
|
|
|
|
|
|
group.reset( new TestMap );
|
|
|
|
|
|
(*group)[testID] = test;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2024-11-10 16:22:46 +01:00
|
|
|
|
|
|
|
|
|
|
class SuiteSeedNucleus
|
|
|
|
|
|
: public SeedNucleus
|
|
|
|
|
|
{
|
2024-11-11 16:31:43 +01:00
|
|
|
|
public:
|
|
|
|
|
|
/** optionally a fixed random seed to inject in each invoked test */
|
|
|
|
|
|
opt_uint64 fixedSeed;
|
2024-11-10 16:22:46 +01:00
|
|
|
|
|
|
|
|
|
|
uint64_t
|
|
|
|
|
|
getSeed() override
|
|
|
|
|
|
{
|
2024-11-11 16:31:43 +01:00
|
|
|
|
auto seed = fixedSeed? *fixedSeed : lib::entropyGen.u64();
|
|
|
|
|
|
auto kind = fixedSeed? "!fix" : "rand";
|
|
|
|
|
|
NOTICE (test, " ++>>> SEED(%s) <<<: %s", kind, toString(seed).c_str());
|
|
|
|
|
|
return seed;
|
2024-11-10 16:22:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* ===== global implementation state ===== */
|
|
|
|
|
|
SuiteSeedNucleus suiteSeed;
|
2014-09-15 02:03:10 +02:00
|
|
|
|
Registry testcases;
|
2007-08-26 19:14:39 +02:00
|
|
|
|
}
|
2007-08-13 09:55:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** register the given test-launcher, so it can be later accessed
|
2009-07-19 05:47:36 +02:00
|
|
|
|
* either as a member of one of the specified groups, or directly
|
2007-08-13 09:55:32 +02:00
|
|
|
|
* by its testID. Any test is automatically added to the groupID
|
|
|
|
|
|
* #ALLGROUP
|
2007-08-24 16:41:16 +02:00
|
|
|
|
* @param test the Launcher object used to run this test
|
2009-07-19 05:47:36 +02:00
|
|
|
|
* @param testID unique ID to refer to this test (will be used as std::map key)
|
2007-08-13 09:55:32 +02:00
|
|
|
|
* @param groups List of group-IDs selected by whitespace
|
|
|
|
|
|
*/
|
2024-11-11 16:31:43 +01:00
|
|
|
|
void
|
2009-07-19 05:47:36 +02:00
|
|
|
|
Suite::enrol (Launcher* test, string testID, string groups)
|
2007-08-26 19:14:39 +02:00
|
|
|
|
{
|
|
|
|
|
|
REQUIRE( test );
|
|
|
|
|
|
REQUIRE( !isnil(testID) );
|
|
|
|
|
|
|
|
|
|
|
|
std::istringstream ss(groups);
|
|
|
|
|
|
string group;
|
|
|
|
|
|
while (ss >> group )
|
|
|
|
|
|
testcases.add2group(test, testID, group);
|
|
|
|
|
|
|
2009-07-19 05:47:36 +02:00
|
|
|
|
// Magic: always add any testcase to groupID="ALL"
|
2007-08-26 19:14:39 +02:00
|
|
|
|
testcases.add2group(test,testID, ALLGROUP);
|
|
|
|
|
|
}
|
2007-08-13 09:55:32 +02:00
|
|
|
|
|
|
|
|
|
|
/** "magic" groupID containing all registered testcases */
|
|
|
|
|
|
const string Suite::ALLGROUP = "ALL";
|
|
|
|
|
|
|
2009-10-02 17:49:38 +02:00
|
|
|
|
/** exit code returned when any individual test threw */
|
|
|
|
|
|
const int Suite::EXCEPTION_THROWN = 5;
|
|
|
|
|
|
const int Suite::TEST_OK = 0;
|
|
|
|
|
|
|
2007-08-13 09:55:32 +02:00
|
|
|
|
|
|
|
|
|
|
|
2024-11-11 16:31:43 +01:00
|
|
|
|
/** create a suite comprised of all the testcases
|
|
|
|
|
|
* previously @link #enrol() registered @endlink with this this group.
|
|
|
|
|
|
* @see #run() running tests in a Suite
|
2007-08-13 09:55:32 +02:00
|
|
|
|
*/
|
2024-11-11 16:31:43 +01:00
|
|
|
|
Suite::Suite (string groupID, opt_uint64 optSeed)
|
2007-08-13 09:55:32 +02:00
|
|
|
|
: groupID_(groupID)
|
2009-10-02 17:49:38 +02:00
|
|
|
|
, exitCode_(0)
|
2007-08-26 19:14:39 +02:00
|
|
|
|
{
|
|
|
|
|
|
REQUIRE( !isnil(groupID) );
|
|
|
|
|
|
TRACE(test, "Test-Suite( groupID=%s )\n", groupID.c_str () );
|
|
|
|
|
|
|
2011-10-21 01:09:12 +02:00
|
|
|
|
// Seed random number generator
|
2018-03-22 21:43:19 +01:00
|
|
|
|
std::srand (std::time (nullptr));
|
2011-10-21 01:09:12 +02:00
|
|
|
|
|
2024-11-11 16:31:43 +01:00
|
|
|
|
suiteSeed.fixedSeed = optSeed;
|
|
|
|
|
|
|
2007-08-26 19:14:39 +02:00
|
|
|
|
if (!testcases.getGroup(groupID))
|
2009-10-02 17:26:50 +02:00
|
|
|
|
throw lumiera::error::Invalid ("empty testsuite");
|
2007-08-26 19:14:39 +02:00
|
|
|
|
}
|
2009-10-02 17:49:38 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
|
Suite::getExitCode () const
|
|
|
|
|
|
{
|
|
|
|
|
|
return exitCode_;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-11-11 16:31:43 +01:00
|
|
|
|
|
2014-05-06 00:24:45 +02:00
|
|
|
|
#define IS_VALID(test,testID) \
|
2009-07-19 05:47:36 +02:00
|
|
|
|
ASSERT ((test), "NULL testcase launcher for test '%s' found in testsuite '%s'", groupID_.c_str(),testID.c_str());
|
2007-08-23 17:52:33 +02:00
|
|
|
|
|
2007-08-13 09:55:32 +02:00
|
|
|
|
|
2009-10-02 17:26:50 +02:00
|
|
|
|
namespace { // internal helper for launching with error logging
|
|
|
|
|
|
|
2009-10-02 17:49:38 +02:00
|
|
|
|
int
|
2009-10-02 17:26:50 +02:00
|
|
|
|
invokeTestCase (Test& theTest, Arg cmdline)
|
|
|
|
|
|
{
|
2024-11-11 16:31:43 +01:00
|
|
|
|
try {
|
2016-01-08 08:20:59 +01:00
|
|
|
|
INFO (test, "++------------------- invoking TEST: %s", cStr(typeStr (theTest)));
|
2009-10-02 17:49:38 +02:00
|
|
|
|
theTest.run (cmdline);
|
|
|
|
|
|
return Suite::TEST_OK;
|
|
|
|
|
|
}
|
2009-10-02 17:26:50 +02:00
|
|
|
|
catch (lumiera::Error& failure)
|
|
|
|
|
|
{
|
|
|
|
|
|
lumiera_err errorID = lumiera_error(); // reset error flag
|
2016-01-08 08:20:59 +01:00
|
|
|
|
cerr << "*** Test Failure " << theTest << endl;
|
2009-10-02 17:26:50 +02:00
|
|
|
|
cerr << "*** : " << failure.what() << endl;
|
|
|
|
|
|
ERROR (test, "Error state %s", errorID);
|
|
|
|
|
|
WARN (progress, "Caught exception %s", failure.what());
|
2009-10-02 17:49:38 +02:00
|
|
|
|
return Suite::EXCEPTION_THROWN;
|
2009-10-02 17:26:50 +02:00
|
|
|
|
} }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-11-15 19:02:48 +01:00
|
|
|
|
|
2024-11-10 00:40:20 +01:00
|
|
|
|
void
|
|
|
|
|
|
Test::seedRand()
|
|
|
|
|
|
{
|
Library: ensure automatic re-seeding for TestFrame
This closes a ''conceptual gap.''
There was a `lib::TestFrame::reseed()` function, which should be invoked
whenever a clean / deterministinc seed is required for computations involving
`TestFrame` data.
On occasion I noticed that most actual usages of `TestFrame`, which became quite common
lately, were missing this `reseed()` call, while the enclosing test
had indeed a proper Test::seedRand() call.
So my conclusion is: if even ''I myself'' miss that fine point frequently,
it is justified to automated this setup, even while `TestFrame` is right now
the only client of such a setup-facility.
There is a twist though.
`TestFrame` is part of the ''Engine'' test coverage, i.e. it is linked
into `libtest-core.so`. While the support for random numbers and reseeding
is obviously a very basic library feature, and linked into `liblumiera.so`
**Oh well**.
So now we have ''yet another'' static registration service.
I kept everything as simple as possible, which means, we continue
to use the ''common, global random generator'' from the library,
and there is no protection against some other code using those
library functions in a non-deterministic way.
`lib/random-reseed.cpp` is just a glorified hard-wired setup, beware!
2026-02-22 21:59:43 +01:00
|
|
|
|
lib::reseed_for_test (suiteSeed);
|
2024-11-10 00:40:20 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Random
|
|
|
|
|
|
Test::makeRandGen()
|
|
|
|
|
|
{
|
2024-11-10 16:22:46 +01:00
|
|
|
|
return Random{lib::seedFromDefaultGen()};
|
2024-11-10 00:40:20 +01:00
|
|
|
|
}
|
2024-11-15 19:02:48 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uint
|
|
|
|
|
|
Test::firstVal (Arg arg, uint someNumber)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (not isnil(arg))
|
|
|
|
|
|
someNumber = boost::lexical_cast<uint> (arg[1]); // may throw
|
|
|
|
|
|
return someNumber;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string
|
|
|
|
|
|
Test::firstTok (Arg arg)
|
|
|
|
|
|
{
|
|
|
|
|
|
return isnil(arg)? util::BOTTOM_INDICATOR
|
|
|
|
|
|
: arg[1];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-10 00:40:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
2007-08-13 09:55:32 +02:00
|
|
|
|
/** run all testcases contained in this Suite.
|
2024-11-11 16:31:43 +01:00
|
|
|
|
* The first argument in the commandline, if present,
|
2007-08-23 17:52:33 +02:00
|
|
|
|
* will select one single testcase with a matching ID.
|
|
|
|
|
|
* In case of invoking a single testcase, the given cmdline
|
2009-07-19 05:47:36 +02:00
|
|
|
|
* will be forwarded to the testcase, after removing the
|
2024-11-11 16:31:43 +01:00
|
|
|
|
* testcaseID from cmdline[0]. Otherwise, every testcase
|
2007-08-23 17:52:33 +02:00
|
|
|
|
* in this suite is invoked with a empty cmdline vector.
|
2024-11-11 16:31:43 +01:00
|
|
|
|
* @param cmdline ref to the vector of commandline tokens
|
2007-08-13 09:55:32 +02:00
|
|
|
|
*/
|
2014-05-05 22:59:23 +02:00
|
|
|
|
bool
|
2007-08-23 17:52:33 +02:00
|
|
|
|
Suite::run (Arg cmdline)
|
2007-08-26 19:14:39 +02:00
|
|
|
|
{
|
|
|
|
|
|
PTestMap tests = testcases.getGroup(groupID_);
|
|
|
|
|
|
if (!tests)
|
2014-05-06 00:24:45 +02:00
|
|
|
|
throw lumiera::error::Invalid ("No tests found for test group \""+groupID_+"\"");
|
2007-08-26 19:14:39 +02:00
|
|
|
|
|
|
|
|
|
|
if (0 < cmdline.size())
|
|
|
|
|
|
{
|
|
|
|
|
|
string& testID (cmdline[0]);
|
|
|
|
|
|
trim(testID);
|
|
|
|
|
|
if ( contains (*tests, testID))
|
|
|
|
|
|
{
|
2024-11-11 16:31:43 +01:00
|
|
|
|
// first cmdline argument denotes a valid testcase registered in
|
2007-08-26 19:14:39 +02:00
|
|
|
|
// this group: invoke just this test with the remaining cmdline
|
|
|
|
|
|
Launcher* test = (*tests)[testID];
|
2014-05-06 00:24:45 +02:00
|
|
|
|
IS_VALID (test,testID);
|
|
|
|
|
|
|
|
|
|
|
|
// Special contract: in case the cmdline holds no actual arguments
|
|
|
|
|
|
// beyond the test name, then it's cleared entirely.
|
2014-09-15 02:03:10 +02:00
|
|
|
|
if (1 == cmdline.size()) cmdline.clear(); // TODO this invalidates also testID -- really need to redesign the API ////TICKET #289
|
2014-05-06 00:24:45 +02:00
|
|
|
|
|
2014-09-15 02:03:10 +02:00
|
|
|
|
exitCode_ |= invokeTestCase (*test->makeInstance(), cmdline); // TODO confusing statement, improve definition of test collection datatype Ticket #289
|
2014-05-05 22:59:23 +02:00
|
|
|
|
return true;
|
2010-07-16 15:59:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
throw lumiera::error::Invalid ("unknown test : "+testID);
|
|
|
|
|
|
}
|
2007-08-26 19:14:39 +02:00
|
|
|
|
|
|
|
|
|
|
// no test-ID was specified.
|
2009-07-19 05:47:36 +02:00
|
|
|
|
// Instantiate all tests cases and execute them.
|
2007-08-26 19:14:39 +02:00
|
|
|
|
for ( TestMap::iterator i=tests->begin(); i!=tests->end(); ++i )
|
|
|
|
|
|
{
|
2016-01-07 03:58:29 +01:00
|
|
|
|
cout << "\n ----------"<< i->first<< "----------\n";
|
2007-08-26 19:14:39 +02:00
|
|
|
|
Launcher* test = (i->second);
|
2014-05-06 00:24:45 +02:00
|
|
|
|
IS_VALID (test, i->first);
|
2014-09-15 02:03:10 +02:00
|
|
|
|
exitCode_ |= invokeTestCase (*test->makeInstance(), cmdline); // actually no cmdline arguments
|
2007-08-26 19:14:39 +02:00
|
|
|
|
}
|
2014-05-05 22:59:23 +02:00
|
|
|
|
return true;
|
2007-08-26 19:14:39 +02:00
|
|
|
|
}
|
2007-08-23 17:52:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
2009-07-19 05:47:36 +02:00
|
|
|
|
/** print to stdout an enumeration of all testcases in this suite,
|
2024-11-10 00:40:20 +01:00
|
|
|
|
* in a format suitable for use with Cehteh's ./test.sh
|
|
|
|
|
|
* @todo this function war rarely used and is kind of broken by the fact
|
|
|
|
|
|
* that Nobug-assertions terminate the program instead of throwing,
|
|
|
|
|
|
* rendering the feature to integrate output mostly useless.
|
2007-08-23 17:52:33 +02:00
|
|
|
|
*/
|
|
|
|
|
|
void
|
2024-11-10 00:40:20 +01:00
|
|
|
|
Suite::describe()
|
2007-08-26 19:14:39 +02:00
|
|
|
|
{
|
2011-02-05 23:53:37 +01:00
|
|
|
|
lib::Cmdline noCmdline("");
|
2007-08-26 19:14:39 +02:00
|
|
|
|
PTestMap tests = testcases.getGroup(groupID_);
|
|
|
|
|
|
ASSERT (tests);
|
|
|
|
|
|
|
2009-10-02 17:26:50 +02:00
|
|
|
|
cout << "TESTING \"Component Test Suite: " << groupID_ << "\" ./test-components\n\n";
|
2009-07-19 05:47:36 +02:00
|
|
|
|
|
2007-08-26 19:14:39 +02:00
|
|
|
|
for ( TestMap::iterator i=tests->begin(); i!=tests->end(); ++i )
|
|
|
|
|
|
{
|
|
|
|
|
|
string key (i->first);
|
2009-10-02 17:26:50 +02:00
|
|
|
|
cout << "\n\n";
|
|
|
|
|
|
cout << "TEST \""<<key<<"\" "<<key<<" <<END\n";
|
2007-08-26 19:14:39 +02:00
|
|
|
|
Launcher* test = (i->second);
|
2014-05-06 00:24:45 +02:00
|
|
|
|
IS_VALID (test, i->first);
|
2007-09-25 23:39:46 +02:00
|
|
|
|
try
|
|
|
|
|
|
{
|
2014-09-15 02:03:10 +02:00
|
|
|
|
test->makeInstance()->run(noCmdline); // run it to insert test generated output
|
2007-09-25 23:39:46 +02:00
|
|
|
|
}
|
2024-11-11 16:31:43 +01:00
|
|
|
|
catch (...)
|
2007-09-25 23:39:46 +02:00
|
|
|
|
{
|
2009-10-02 17:26:50 +02:00
|
|
|
|
cout << "PLANNED ============= " << lumiera_error() << "\n";
|
2007-09-25 23:39:46 +02:00
|
|
|
|
}
|
2009-10-02 17:26:50 +02:00
|
|
|
|
cout << "END\n";
|
2007-08-26 19:14:39 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2009-07-19 05:47:36 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-08-13 09:55:32 +02:00
|
|
|
|
} // namespace test
|