Use template for UnitTest

This commit is contained in:
Vinnie Falco
2013-07-13 04:48:53 -07:00
parent d684d7742c
commit a937c379f6
15 changed files with 167 additions and 141 deletions

View File

@@ -194,6 +194,9 @@ namespace beast
// Order matters, since headers don't have their own #include lines.
// Add new includes to the bottom.
#include "system/beast_PlatformDefs.h"
#include "system/beast_TargetPlatform.h"
#include "memory/beast_Uncopyable.h"
#include "maths/beast_MathsFunctions.h"
#include "memory/beast_Atomic.h"
@@ -204,6 +207,14 @@ namespace beast
#include "containers/beast_LockFreeStack.h"
#include "threads/beast_SpinDelay.h"
#include "memory/beast_StaticObject.h"
#include "text/beast_String.h"
#include "text/beast_CharacterFunctions.h"
#include "text/beast_CharPointer_ASCII.h"
#include "text/beast_CharPointer_UTF16.h"
#include "text/beast_CharPointer_UTF32.h"
#include "text/beast_CharPointer_UTF8.h"
#include "time/beast_PerformedAtExit.h"
#include "diagnostic/beast_LeakChecked.h"
#include "memory/beast_Memory.h"
@@ -280,19 +291,10 @@ namespace beast
#include "streams/beast_OutputStream.h"
#include "streams/beast_SubregionStream.h"
#include "system/beast_Functional.h"
#include "system/beast_PlatformDefs.h"
#include "system/beast_StandardHeader.h"
#include "system/beast_SystemStats.h"
#include "system/beast_TargetPlatform.h"
#include "text/beast_CharacterFunctions.h"
#include "text/beast_CharPointer_ASCII.h"
#include "text/beast_CharPointer_UTF16.h"
#include "text/beast_CharPointer_UTF32.h"
#include "text/beast_CharPointer_UTF8.h"
#include "text/beast_Identifier.h"
#include "text/beast_LocalisedStrings.h"
#include "text/beast_NewLine.h"
#include "text/beast_String.h"
#include "text/beast_StringArray.h"
#include "text/beast_StringPairArray.h"
#include "text/beast_StringPool.h"

View File

@@ -125,13 +125,13 @@ void AbstractFifo::finishedRead (int numRead) noexcept
}
//==============================================================================
//==============================================================================
#if BEAST_UNIT_TESTS
class AbstractFifoTests : public UnitTest
class AbstractFifoTests : public UnitTestType <AbstractFifoTests>
{
public:
AbstractFifoTests() : UnitTest ("Abstract Fifo") {}
AbstractFifoTests() : UnitTestType <AbstractFifoTests> ("Abstract Fifo")
{
}
class WriteThread : public Thread
{
@@ -201,7 +201,7 @@ public:
&& (size1 == 0 || (start1 >= 0 && start1 < fifo.getTotalSize()))
&& (size2 == 0 || (start2 >= 0 && start2 < fifo.getTotalSize())))
{
expect (false, "prepareToRead returned -ve values");
expect (false, "prepareToRead returned negative values");
break;
}
@@ -224,6 +224,6 @@ public:
}
};
static AbstractFifoTests fifoUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <AbstractFifoTests>;
#endif

View File

@@ -41,7 +41,7 @@ Array<UnitTest*>& UnitTest::getAllTests()
void UnitTest::initialise() {}
void UnitTest::shutdown() {}
void UnitTest::performTest (UnitTestRunner* const runner_)
void UnitTest::performTest (UnitTests* const runner_)
{
bassert (runner_ != nullptr);
runner = runner_;
@@ -70,42 +70,42 @@ void UnitTest::expect (const bool result, const String& failureMessage)
}
//==============================================================================
UnitTestRunner::UnitTestRunner()
UnitTests::UnitTests()
: currentTest (nullptr),
assertOnFailure (true),
logPasses (false)
{
}
UnitTestRunner::~UnitTestRunner()
UnitTests::~UnitTests()
{
}
void UnitTestRunner::setAssertOnFailure (bool shouldAssert) noexcept
void UnitTests::setAssertOnFailure (bool shouldAssert) noexcept
{
assertOnFailure = shouldAssert;
}
void UnitTestRunner::setPassesAreLogged (bool shouldDisplayPasses) noexcept
void UnitTests::setPassesAreLogged (bool shouldDisplayPasses) noexcept
{
logPasses = shouldDisplayPasses;
}
int UnitTestRunner::getNumResults() const noexcept
int UnitTests::getNumResults() const noexcept
{
return results.size();
}
const UnitTestRunner::TestResult* UnitTestRunner::getResult (int index) const noexcept
const UnitTests::TestResult* UnitTests::getResult (int index) const noexcept
{
return results [index];
}
void UnitTestRunner::resultsUpdated()
void UnitTests::resultsUpdated()
{
}
void UnitTestRunner::runTests (const Array<UnitTest*>& tests)
void UnitTests::runTests (const Array<UnitTest*>& tests)
{
results.clear();
resultsUpdated();
@@ -128,22 +128,22 @@ void UnitTestRunner::runTests (const Array<UnitTest*>& tests)
endTest();
}
void UnitTestRunner::runAllTests()
void UnitTests::runAllTests()
{
runTests (UnitTest::getAllTests());
}
void UnitTestRunner::logMessage (const String& message)
void UnitTests::logMessage (const String& message)
{
Logger::writeToLog (message);
}
bool UnitTestRunner::shouldAbortTests()
bool UnitTests::shouldAbortTests()
{
return false;
}
void UnitTestRunner::beginNewTest (UnitTest* const test, const String& subCategory)
void UnitTests::beginNewTest (UnitTest* const test, const String& subCategory)
{
endTest();
currentTest = test;
@@ -160,7 +160,7 @@ void UnitTestRunner::beginNewTest (UnitTest* const test, const String& subCatego
resultsUpdated();
}
void UnitTestRunner::endTest()
void UnitTests::endTest()
{
if (results.size() > 0)
{
@@ -183,7 +183,7 @@ void UnitTestRunner::endTest()
}
}
void UnitTestRunner::addPass()
void UnitTests::addPass()
{
{
const ScopedLock sl (results.getLock());
@@ -204,7 +204,7 @@ void UnitTestRunner::addPass()
resultsUpdated();
}
void UnitTestRunner::addFail (const String& failureMessage)
void UnitTests::addFail (const String& failureMessage)
{
{
const ScopedLock sl (results.getLock());

View File

@@ -26,46 +26,9 @@
#include "../text/beast_StringArray.h"
#include "../containers/beast_OwnedArray.h"
class UnitTestRunner;
class UnitTests;
//==============================================================================
/**
This is a base class for classes that perform a unit test.
To write a test using this class, your code should look something like this:
@code
class MyTest : public UnitTest
{
public:
MyTest() : UnitTest ("Foobar testing") {}
void runTest()
{
beginTest ("Part 1");
expect (myFoobar.doesSomething());
expect (myFoobar.doesSomethingElse());
beginTest ("Part 2");
expect (myOtherFoobar.doesSomething());
expect (myOtherFoobar.doesSomethingElse());
...etc..
}
};
// Creating a static instance will automatically add the instance to the array
// returned by UnitTest::getAllTests(), so the test will be included when you call
// UnitTestRunner::runAllTests()
static MyTest test;
@endcode
To run a test, use the UnitTestRunner class.
@see UnitTestRunner
/** Factored base class for unit test template.
*/
class BEAST_API UnitTest : Uncopyable
{
@@ -80,11 +43,11 @@ public:
/** Returns the name of the test. */
const String& getName() const noexcept { return name; }
/** Runs the test, using the specified UnitTestRunner.
/** Runs the test, using the specified UnitTests.
You shouldn't need to call this method directly - use
UnitTestRunner::runTests() instead.
UnitTests::runTests() instead.
*/
void performTest (UnitTestRunner* runner);
void performTest (UnitTests* runner);
/** Returns the set of all UnitTest objects that currently exist. */
static Array<UnitTest*>& getAllTests();
@@ -163,10 +126,9 @@ public:
private:
//==============================================================================
const String name;
UnitTestRunner* runner;
UnitTests* runner;
};
//==============================================================================
/**
Runs a set of unit tests.
@@ -174,20 +136,20 @@ private:
You can instantiate one of these objects and use it to invoke tests on a set of
UnitTest objects.
By using a subclass of UnitTestRunner, you can intercept logging messages and
By using a subclass of UnitTests, you can intercept logging messages and
perform custom behaviour when each test completes.
@see UnitTest
*/
class BEAST_API UnitTestRunner : Uncopyable
class BEAST_API UnitTests : Uncopyable
{
public:
//==============================================================================
/** */
UnitTestRunner();
UnitTests();
/** Destructor. */
virtual ~UnitTestRunner();
virtual ~UnitTests();
/** Runs a set of tests.
@@ -199,7 +161,7 @@ public:
/** Runs all the UnitTest objects that currently exist.
This calls runTests() for all the objects listed in UnitTest::getAllTests().
*/
void runAllTests();
void runAllTests ();
/** Sets a flag to indicate whether an assertion should be triggered if a test fails.
This is true by default.
@@ -222,11 +184,13 @@ public:
{
/** The main name of this test (i.e. the name of the UnitTest object being run). */
String unitTestName;
/** The name of the current subcategory (i.e. the name that was set when UnitTest::beginTest() was called). */
String subcategoryName;
/** The number of UnitTest::expect() calls that succeeded. */
int passes;
/** The number of UnitTest::expect() calls that failed. */
int failures;
@@ -248,34 +212,87 @@ protected:
/** Called when the list of results changes.
You can override this to perform some sort of behaviour when results are added.
*/
virtual void resultsUpdated();
virtual void resultsUpdated ();
/** Logs a message about the current test progress.
By default this just writes the message to the Logger class, but you could override
this to do something else with the data.
*/
virtual void logMessage (const String& message);
virtual void logMessage (String const& message);
/** This can be overridden to let the runner know that it should abort the tests
as soon as possible, e.g. because the thread needs to stop.
*/
virtual bool shouldAbortTests();
virtual bool shouldAbortTests ();
private:
//==============================================================================
friend class UnitTest;
UnitTest* currentTest;
String currentSubCategory;
OwnedArray <TestResult, CriticalSection> results;
bool assertOnFailure, logPasses;
void beginNewTest (UnitTest* test, const String& subCategory);
void endTest();
void addPass();
void addFail (const String& failureMessage);
UnitTest* currentTest;
String currentSubCategory;
OwnedArray <TestResult, CriticalSection> results;
bool assertOnFailure;
bool logPasses;
};
//------------------------------------------------------------------------------
#endif // BEAST_UNITTEST_BEASTHEADER
/** This is a base class for classes that perform a unit test.
To write a test using this class, your code should look something like this:
@code
class MyTest : public UnitTestType <MyTest>
{
public:
MyTest() : UnitTestType <MyTest> ("Foobar testing") { }
void runTest()
{
beginTest ("Part 1");
expect (myFoobar.doesSomething());
expect (myFoobar.doesSomethingElse());
beginTest ("Part 2");
expect (myOtherFoobar.doesSomething());
expect (myOtherFoobar.doesSomethingElse());
//...
}
};
// Explicit template instantiation is required to make the unit
// test get automatically added to the set of unit tests.
template class UnitTestType <MyTest>;
@endcode
To run one or more unit tests, use the UnitTests class.
@see UnitTests
*/
template <class Type>
class UnitTestType : public UnitTest
{
public:
explicit UnitTestType (String const& name)
: UnitTest (name)
{
}
static Type s_test;
};
template <class Type>
Type UnitTestType <Type>::s_test;
#endif

View File

@@ -921,14 +921,12 @@ MemoryMappedFile::MemoryMappedFile (const File& file, const Range<int64>& fileRa
openInternal (file, mode);
}
//==============================================================================
#if BEAST_UNIT_TESTS
class FileTests : public UnitTest
class FileTests : public UnitTestType <FileTests>
{
public:
FileTests() : UnitTest ("Files") {}
FileTests() : UnitTestType <FileTests> ("File") {}
void runTest()
{
@@ -1108,6 +1106,7 @@ public:
}
};
static FileTests fileUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <FileTests>;
#endif

View File

@@ -531,12 +531,11 @@ void JSON::writeToStream (OutputStream& output, const var& data, const bool allO
//==============================================================================
//==============================================================================
#if BEAST_UNIT_TESTS
class JSONTests : public UnitTest
class JSONTests : public UnitTestType <JSONTests>
{
public:
JSONTests() : UnitTest ("JSON") {}
JSONTests() : UnitTestType <JSONTests> ("JSON") {}
static String createRandomWideCharString (Random& r)
{
@@ -640,6 +639,6 @@ public:
}
};
static JSONTests JSONUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <JSONTests>;
#endif

View File

@@ -133,12 +133,11 @@ void Random::fillBitsRandomly (BigInteger& arrayToChange, int startBit, int numB
}
//==============================================================================
#if BEAST_UNIT_TESTS
class RandomTests : public UnitTest
class RandomTests : public UnitTestType <RandomTests>
{
public:
RandomTests() : UnitTest ("Random") {}
RandomTests() : UnitTestType <RandomTests> ("Random") {}
void runTest()
{
@@ -166,6 +165,6 @@ public:
}
};
static RandomTests randomTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <RandomTests>;
#endif

View File

@@ -87,14 +87,12 @@ int64 MemoryInputStream::getPosition()
return position;
}
//==============================================================================
#if BEAST_UNIT_TESTS
class MemoryStreamTests : public UnitTest
class MemoryStreamTests : public UnitTestType <MemoryStreamTests>
{
public:
MemoryStreamTests() : UnitTest ("MemoryInputStream & MemoryOutputStream") {}
MemoryStreamTests() : UnitTestType <MemoryStreamTests> ("MemoryStream") {}
void runTest()
{
@@ -150,6 +148,7 @@ public:
}
};
static MemoryStreamTests memoryInputStreamUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <MemoryStreamTests>;
#endif

View File

@@ -2074,12 +2074,11 @@ String String::fromUTF8 (const char* const buffer, int bufferSizeBytes)
//==============================================================================
//==============================================================================
#if BEAST_UNIT_TESTS
class StringTests : public UnitTest
class StringTests : public UnitTestType <StringTests>
{
public:
StringTests() : UnitTest ("String class") {}
StringTests() : UnitTestType <StringTests> ("String") {}
template <class CharPointerType>
struct TestUTFConversion
@@ -2403,6 +2402,6 @@ public:
}
};
static StringTests stringUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <StringTests>;
#endif

View File

@@ -173,13 +173,11 @@ String TextDiff::Change::appliedTo (const String& text) const noexcept
}
//==============================================================================
//==============================================================================
#if BEAST_UNIT_TESTS
class DiffTests : public UnitTest
class DiffTests : public UnitTestType <DiffTests>
{
public:
DiffTests() : UnitTest ("TextDiff class") {}
DiffTests() : UnitTestType <DiffTests> ("TextDiff") {}
static String createString()
{
@@ -231,6 +229,6 @@ public:
}
};
static DiffTests diffTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <DiffTests>;
#endif

View File

@@ -57,12 +57,11 @@ String ChildProcess::readAllProcessOutput()
}
//==============================================================================
#if BEAST_UNIT_TESTS
class ChildProcessTests : public UnitTest
class ChildProcessTests : public UnitTestType <ChildProcessTests>
{
public:
ChildProcessTests() : UnitTest ("ChildProcess") {}
ChildProcessTests() : UnitTestType <ChildProcessTests> ("ChildProcess") {}
void runTest()
{
@@ -83,6 +82,6 @@ public:
}
};
static ChildProcessTests childProcessUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <ChildProcessTests>;
#endif

View File

@@ -251,12 +251,11 @@ void SpinLock::enter() const noexcept
}
//==============================================================================
#if BEAST_UNIT_TESTS
class AtomicTests : public UnitTest
class AtomicTests : public UnitTestType <AtomicTests>
{
public:
AtomicTests() : UnitTest ("Atomics") {}
AtomicTests() : UnitTestType <AtomicTests> ("Atomic") {}
void runTest()
{
@@ -351,6 +350,6 @@ public:
};
};
static AtomicTests atomicUnitTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <AtomicTests>;
#endif

View File

@@ -157,12 +157,11 @@ bool GZIPCompressorOutputStream::setPosition (int64 /*newPosition*/)
}
//==============================================================================
#if BEAST_UNIT_TESTS
class GZIPTests : public UnitTest
class GZIPTests : public UnitTestType <GZIPTests>
{
public:
GZIPTests() : UnitTest ("GZIP") {}
GZIPTests() : UnitTestType <GZIPTests> ("GZIP") {}
void runTest()
{
@@ -206,6 +205,6 @@ public:
}
};
static GZIPTests gzipTests;
#if BEAST_UNIT_TESTS
template class UnitTestType <GZIPTests>;
#endif

View File

@@ -2,6 +2,8 @@
RIPPLE TODO
--------------------------------------------------------------------------------
- Examples for different backend key/value config settings
- Unit Test attention
- NodeStore backend unit test
@@ -313,6 +315,21 @@ What we want from the unique node list:
ChosenValidators
--------------------------------------------------------------------------------
David:
I've cut 2 of the 6 active client-facing servers to hyper. Since then, we've
had 5 spinouts on 3 servers, none of them on the 2 I've cut over. But they
are also the most recently restarted servers, so it's not a 100% fair test.
Maybe OC should have a URL that you can query to get the latest list of URI's
for OC-approved organzations that publish lists of validators. The server and
client can ship with that master trust URL and also the list of URI's at the
time it's released, in case for some reason it can't pull from OC. That would
make the default installation safe even against major changes in the
organizations that publish validator lists.
The difference is that if an organization that provides lists of validators
goes rogue, administrators don't have to act.
TODO:
Write up from end-user perspective on the deployment and administration
of this feature, on the wiki. "DRAFT" or "PROPOSE" to mark it as provisional.

View File

@@ -119,7 +119,7 @@ void printHelp (const po::options_description& desc)
*/
static void runBeastUnitTests ()
{
UnitTestRunner tr;
UnitTests tr;
tr.setAssertOnFailure (false);
tr.setPassesAreLogged (false);
@@ -129,7 +129,7 @@ static void runBeastUnitTests ()
// Report
for (int i = 0; i < tr.getNumResults (); ++i)
{
UnitTestRunner::TestResult const& r (*tr.getResult (i));
UnitTests::TestResult const& r (*tr.getResult (i));
for (int j = 0; j < r.messages.size (); ++i)
Log::out () << r.messages [j].toStdString ();