Initial commit
This commit is contained in:
106
ZTestSuite/Test-ZReferenceCounter.cpp
Normal file
106
ZTestSuite/Test-ZReferenceCounter.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
Test-ZReferenceCounter.cpp
|
||||
Author: James Russell <jcrussell@762studios.com>
|
||||
|
||||
Purpose: Unit Test the ZReferenceCounter class.
|
||||
*/
|
||||
|
||||
#include "ZUnitTest.hpp"
|
||||
|
||||
#include <ZUtil/ZConcurrency.hpp>
|
||||
#include <ZUtil/ZReferenceCounter.hpp>
|
||||
#include <SST/SST_Thread.h> // SST_Concurrency_YieldThread()
|
||||
|
||||
static const char* test_GainLoseReferences();
|
||||
static const char* test_Signal();
|
||||
|
||||
//List of unit tests
|
||||
ZUnitTest ZReferenceCounterUnitTests[] =
|
||||
{
|
||||
{ "ZReferenceCounter: Gain / Lose References", test_GainLoseReferences },
|
||||
{ "ZReferenceCounter: Signal", test_Signal }
|
||||
};
|
||||
|
||||
//Now declare the ZUnitTestBlock associated with this.
|
||||
DECLARE_ZTESTBLOCK(ZReferenceCounter);
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static const char* test_GainLoseReferences()
|
||||
{
|
||||
ZReferenceCounter counter;
|
||||
|
||||
//Ensure both start at zero
|
||||
TASSERT(counter.GetStrongRefCount() == 0, "Strong count set to non-zero value on default construct!");
|
||||
TASSERT(counter.GetWeakRefCount() == 0, "Weak count set to non-zero value on default construct!");
|
||||
|
||||
//Test GainStrongRef()
|
||||
counter.GainStrongRef();
|
||||
TASSERT(counter.GetStrongRefCount() == 1, "Strong count not equal to 1 after strong reference gained!");
|
||||
|
||||
//Test GainWeakRef()
|
||||
counter.GainWeakRef();
|
||||
counter.GainWeakRef();
|
||||
TASSERT(counter.GetWeakRefCount() == 2, "Weak count not equal to 2 after double increment!");
|
||||
|
||||
//Test validity of both counters after weak ref decrement
|
||||
uint32_t combinedCount = counter.LoseWeakRef();
|
||||
TASSERT(ZREFCOUNTER_EXTRACT_STRONG_REF(combinedCount) == 1, "After losing weak reference, strong count does not equal one!");
|
||||
TASSERT(ZREFCOUNTER_EXTRACT_WEAK_REF(combinedCount) == 1, "After losing weak reference, weak count does not equal one!");
|
||||
|
||||
//Test validity of both counters after strong ref decrement
|
||||
combinedCount = counter.LoseStrongRef();
|
||||
TASSERT(ZREFCOUNTER_EXTRACT_STRONG_REF(combinedCount) == 0, "After losing strong reference, strong count does not equal zero!");
|
||||
TASSERT(ZREFCOUNTER_EXTRACT_WEAK_REF(combinedCount) == 1, "After losing strong reference, weak count does not equal one!");
|
||||
|
||||
//Test validity of both counters when all references are lost
|
||||
combinedCount = counter.LoseWeakRef();
|
||||
TASSERT(ZREFCOUNTER_EXTRACT_STRONG_REF(combinedCount) == 0, "After losing second weak reference, strong count does not equal zero!");
|
||||
TASSERT(ZREFCOUNTER_EXTRACT_WEAK_REF(combinedCount) == 0, "After losing second weak reference, weak count does not equal one!");
|
||||
|
||||
return ZTEST_SUCCESS;
|
||||
}
|
||||
|
||||
/*************************************************************************/
|
||||
|
||||
static int signalDeallocate(void* _refCounter)
|
||||
{
|
||||
//This should block
|
||||
reinterpret_cast<ZReferenceCounter*>(_refCounter)->SignalDeallocateObject();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* test_Signal()
|
||||
{
|
||||
ZReferenceCounter counter;
|
||||
|
||||
counter.GainStrongRef();
|
||||
counter.GainWeakRef();
|
||||
|
||||
TASSERT(counter.GetStrongRefCount() == 1, "Strong count incorrect after GainStrongRef!");
|
||||
TASSERT(counter.GetWeakRefCount() == 1, "Weak count incorrect after GainWeakRef!");
|
||||
|
||||
TASSERT(counter.SignalInUse(), "SignalInUse returned false when it should be valid to use!");
|
||||
|
||||
TASSERT(counter.State > 0, "State not increased after SignalInUse!");
|
||||
|
||||
ZThreadContext ctxt = ZConcurrency::CreateThread(signalDeallocate, &counter);
|
||||
|
||||
//At this point, the other thread should be waiting on this one, but
|
||||
//should signal us by setting state to NULL with an atomic XOR
|
||||
while (counter.State > 0)
|
||||
SST_Concurrency_YieldThread();
|
||||
|
||||
TASSERT(counter.SignalInUse() == false, "SignalInUse returned true when it should be invalid to use!");
|
||||
|
||||
counter.SignalUnused(); //This should allow the thread to return from the SignalDeallocate method
|
||||
|
||||
ZConcurrency::WaitThread(ctxt);
|
||||
ZConcurrency::DestroyThread(ctxt);
|
||||
|
||||
TASSERT(counter.State == (-1 & ZREFCOUNTER_DEALLOC_BIT), "State variable invalid after SignalDeallocate and SignalUnused!");
|
||||
|
||||
return ZTEST_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user