WIP: change management of test/mock PlacementIndex

now lifecycle of this mock index is managed automatically
from within the session services. This allows to get
rid of the smart-ptr creating factory. As a consequence,
PlacementIndex now resides directly within SessionImpl.
This commit is contained in:
Fischlurch 2009-12-11 02:49:12 +01:00
parent 54d0b30358
commit fd782eb139
9 changed files with 121 additions and 118 deletions

View file

@ -37,7 +37,7 @@
#include "proc/mobject/session/session-impl.hpp"
#include "proc/mobject/session/scope.hpp"
#include "lib/typed-allocation-manager.hpp"
#include "proc/mobject/mobject.hpp" ///////////////////////TODO necessary?
//#include "proc/mobject/mobject.hpp" ///////////////////////TODO necessary?
#include "lib/util.hpp"

View file

@ -51,12 +51,10 @@
//#include "proc/asset/pipe.hpp"
#include "lib/util.hpp"
#include "lib/error.hpp"
#include "lib/factory.hpp"
#include "lib/itertools.hpp"
#include "proc/mobject/placement.hpp"
#include "proc/mobject/placement-ref.hpp"
#include <tr1/memory>
#include <tr1/unordered_map>
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
@ -74,13 +72,9 @@ namespace session {
LUMIERA_ERROR_DECLARE (NONEMPTY_SCOPE); ///< Placement scope (still) contains other elements
using lib::factory::RefcountFac;
using std::tr1::shared_ptr;
using boost::scoped_ptr;
class PlacementIndex;
typedef shared_ptr<PlacementIndex> PPIdx;
/**
* Structured compound of Placement instances
@ -134,6 +128,8 @@ namespace session {
bool contains (PlacementMO const&) const;
bool contains (ID) const;
bool isValid() const;
@ -144,18 +140,13 @@ namespace session {
bool remove (ID);
typedef RefcountFac<PlacementIndex> Factory;
static Factory create;
~PlacementIndex();
PlacementIndex() ;
~PlacementIndex() ;
void clear();
protected:
PlacementIndex() ;
friend class lib::factory::Factory<PlacementIndex, lib::factory::Wrapper<PlacementIndex, shared_ptr<PlacementIndex> > >;
};

View file

@ -82,7 +82,7 @@ namespace session {
vector<EDL> edls;
PFix fixture;
shared_ptr<PlacementIndex> pIdx_;
PlacementIndex pIdx_;
scoped_ptr<DefsManager> defaultsManager_; ///////////TODO: later, this will be the real defaults manager. Currently this is just never initialised (11/09)
@ -103,10 +103,10 @@ namespace session {
void clear ();
friend class SessManagerImpl;
PPIdx const&
PlacementIndex&
getPlacementIndex()
{
ENSURE (pIdx_);
ENSURE (pIdx_.isValid());
return pIdx_;
}
@ -166,23 +166,23 @@ namespace session {
struct ServiceAccessPoint<SessionServiceMockIndex, IMPL>
: IMPL
{
PPIdx const&
PlacementIndex&
getPlacementIndex()
{
if (mockIndex_)
return mockIndex_;
if (mockIndex_ && mockIndex_->isValid())
return *mockIndex_;
else
return IMPL::getPlacementIndex();
}
void
reset_PlacementIndex (PPIdx const& alternativeIndex)
reset_PlacementIndex (PlacementIndex* alternativeIndex =0)
{
mockIndex_ = alternativeIndex;
}
private:
PPIdx mockIndex_;
PlacementIndex* mockIndex_;
};

View file

@ -24,10 +24,16 @@
/** @file session-service-mock-index.hpp
** Implementation level session API: PlacementIndex mock for tests.
** Allows (temporarily) to replace the real Placement index within
** the session by a mock instance handed in through this API. Unit
** tests may use this \em backdoor to set up a specially prepared
** index to verify the behaviour of Placement and Scope resolution
** operations.
** the session by a mock instance installed and provided through
** this API. Unit tests may use this \em backdoor to set up a
** specially prepared index to verify the behaviour of Placement
** and Scope resolution operations.
**
** The test/mock instance of the placement index obtained by this API
** is \em not wired with the session. Rather it is managed by smart-ptr.
** When the last smart-ptr instance goes out of scope, the test index
** instance will be shut down and removed, thereby uncovering the
** original PlacementIndex living within the session.
**
** @see session-impl.hpp implementation of the service
** @see session-services.cpp implementation of access
@ -39,8 +45,8 @@
#define MOBJECT_SESSION_SESSION_SERVICE_MOCK_INDEX_H
#include "proc/mobject/session/placement-index.hpp"
//#include "proc/mobject/session.hpp"
//#include "lib/meta/generator.hpp"
#include <tr1/memory>
@ -48,22 +54,22 @@
namespace mobject {
namespace session {
// using lumiera::typelist::InstantiateChained;
// using lumiera::typelist::InheritFrom;
// using lumiera::typelist::NullType;
typedef std::tr1::shared_ptr<PlacementIndex> PPIdx;
/** there is an implicit PlacementIndex available on a global level,
* by default implemented within the current session. This Service
* to re-define this implicit index temporarily, e.g. for unit tests.
* @param alternativeIndex alternative Index instance to install.
* when \c NIL, then restore access to the PlacementIndex
* instance always available within the SessionImpl
* temporarily overlays a newly created mock instance, e.g. for tests.
* @return smart-ptr managing a newly created mock index instance.
* Any implicit access to the session's placement index will
* be redirected to that instance. When the smart-ptr reaches
* use-count zero, access to the original PlacementIndex
* will be restored.
*/
class SessionServiceMockIndex
{
public:
static void reset_PlacementIndex (PPIdx const& alternativeIndex =PPIdx());
static PPIdx install ();
};

View file

@ -61,11 +61,30 @@ namespace session {
}
namespace { // deleter function to clean up test/mock PlacementIndex
void
remove_testIndex (PlacementIndex* testIdx)
{
REQUIRE (testIdx);
SessionImplAPI::current->reset_PlacementIndex(); // restore default Index from Session
testIdx->clear();
ASSERT (0 == testIdx->size());
delete testIdx;
}
}
/** Re-define the implicit PlacementIndex temporarily, e.g. for unit tests. */
void
SessionServiceMockIndex::reset_PlacementIndex (PPIdx const& alternativeIndex)
PPIdx
SessionServiceMockIndex:: install ()
{
return SessionImplAPI::current->reset_PlacementIndex (alternativeIndex);
PPIdx mockIndex (new PlacementIndex(), &remove_testIndex); // manage instance lifecycle
ENSURE (mockIndex);
ENSURE (mockIndex->isValid());
ENSURE (1 == mockIndex.use_count());
SessionImplAPI::current->reset_PlacementIndex (*mockIndex);
return mockIndex;
}

View file

@ -49,6 +49,7 @@ namespace test {
using session::Clip;
using session::SessionServiceMockIndex;
/***************************************************************************
@ -89,10 +90,8 @@ namespace test {
#if false //////////////////////////////////////////////////////////////////////////////////////////////////////////TICKET 384 !!!!!!!!!
// Prepare an (test)Index
typedef shared_ptr<PlacementIndex> PIdx;
PIdx index (PlacementIndex::create());
PPIdx index = SessionServiceMockIndex::install();
PMO& root = index->getRoot();
SessionServiceMockIndex::reset_PlacementIndex (index);
// Add the Clips to "session"
index->insert (pClip1, root);
@ -128,10 +127,12 @@ namespace test {
index->remove (pClip1);
index->remove (pClip2);
ASSERT (0 == index->size());
ASSERT (1 == index.use_count());
ASSERT (2 == pClip1.use_count());
ASSERT (2 == pClip2.use_count());
index.reset();
#endif ////////////////////////////////////////////////////////////////////////////////////////TODO lots of things unimplemented.....!!!!!
SessionServiceMockIndex::reset_PlacementIndex();
}

View file

@ -68,10 +68,8 @@ namespace test {
p2.chain(Time(2)); // define start time of Placement-2 to be at t=2
// Prepare an (test)Index backing the PlacementRefs
typedef shared_ptr<PlacementIndex> PIdx;
PIdx index (PlacementIndex::create());
PPIdx index = SessionServiceMockIndex::install();
PMO& root = index->getRoot();
SessionServiceMockIndex::reset_PlacementIndex(index);
index->insert (p1, root);
index->insert (p2, root);
@ -180,7 +178,8 @@ namespace test {
//consistency check; then reset PlacementRef index to default
ASSERT (0 == index->size());
SessionServiceMockIndex::reset_PlacementIndex();
ASSERT (1 == index.use_count());
index.reset();
}
};

View file

@ -50,6 +50,7 @@ namespace test {
using asset::VIDEO;
using session::test::TestClip;
typedef PlacementIndex& Idx;
/***************************************************************************
@ -66,7 +67,7 @@ namespace test {
virtual void
run (Arg)
{
PPIdx index (PlacementIndex::create());
PlacementIndex index;
ASSERT (index);
checkSimpleInsertRemove (index);
@ -80,100 +81,100 @@ namespace test {
////////////////////////////TODO
index->clear();
index.clear();
has_size (0, index);
}
void
has_size(uint siz, PPIdx index)
has_size(uint siz, Idx index)
{
ASSERT (siz == index->size());
ASSERT (siz == index.size());
}
void
checkSimpleInsertRemove (PPIdx index)
checkSimpleInsertRemove (Idx index)
{
PMO clip = TestClip::create();
PMO& root = index->getRoot();
PMO& root = index.getRoot();
ASSERT (0 == index->size());
ASSERT (!index->contains (clip));
ASSERT (0 == index.size());
ASSERT (!index.contains (clip));
index->insert (clip, root);
ASSERT (1 == index->size());
ASSERT ( index->contains (clip));
index.insert (clip, root);
ASSERT (1 == index.size());
ASSERT ( index.contains (clip));
index->remove(clip);
ASSERT (0 == index->size());
ASSERT (!index->contains (clip));
ASSERT ( index->contains (root));
index.remove(clip);
ASSERT (0 == index.size());
ASSERT (!index.contains (clip));
ASSERT ( index.contains (root));
}
void
checkSimpleAccess (PPIdx index)
checkSimpleAccess (Idx index)
{
PMO testObj = TestClip::create();
PMO& root = index->getRoot();
PMO::ID elmID = index->insert (testObj, root);
PMO& root = index.getRoot();
PMO::ID elmID = index.insert (testObj, root);
PMO& elm = index->find(elmID);
PMO& elm = index.find(elmID);
ASSERT (elmID == elm.getID());
ASSERT (!isSameObject (elm,testObj)); // note: placements are registered as copy
ASSERT (elm == testObj); // they are semantically equivalent
ASSERT (elmID != testObj.getID()); // but have a distinct identity
PMO::ID elmID2 = index->insert(testObj, root);
PMO::ID elmID2 = index.insert(testObj, root);
ASSERT (elmID != elmID); // ...and each insert creates a new instance
ASSERT (testObj == index->find(elmID2));
ASSERT (!isSameObject (elm, index->find(elmID2)));
ASSERT ( isSameObject (elm, index->find(elmID )));
ASSERT (testObj == index.find(elmID2));
ASSERT (!isSameObject (elm, index.find(elmID2)));
ASSERT ( isSameObject (elm, index.find(elmID )));
// can also re-access objects by previous ref
ASSERT ( isSameObject (elm, index->find(elm)));
ASSERT ( isSameObject (elm, index.find(elm)));
}
void
checkScopeHandling (PPIdx index)
checkScopeHandling (Idx index)
{
PMO testObj = TestClip::create();
PMO& root = index->getRoot();
PMO& root = index.getRoot();
typedef PMO::ID ID;
ID e1 = index->insert (testObj, root);
ID e11 = index->insert (testObj, e1);
ID e12 = index->insert (testObj, e1);
ID e13 = index->insert (testObj, e1);
ID e131 = index->insert (testObj, e13);
ID e132 = index->insert (testObj, e13);
ID e133 = index->insert (testObj, e13);
ID e1331 = index->insert (testObj, e133);
ID e1 = index.insert (testObj, root);
ID e11 = index.insert (testObj, e1);
ID e12 = index.insert (testObj, e1);
ID e13 = index.insert (testObj, e1);
ID e131 = index.insert (testObj, e13);
ID e132 = index.insert (testObj, e13);
ID e133 = index.insert (testObj, e13);
ID e1331 = index.insert (testObj, e133);
ASSERT (root == index->getScope(e1));
ASSERT (e1 == index->getScope(e11).getID());
ASSERT (e1 == index->getScope(e12).getID());
ASSERT (e1 == index->getScope(e13).getID());
ASSERT (e13 == index->getScope(e131).getID());
ASSERT (e13 == index->getScope(e132).getID());
ASSERT (e13 == index->getScope(e133).getID());
ASSERT (e133 == index->getScope(e1331).getID());
ASSERT (root == index.getScope(e1));
ASSERT (e1 == index.getScope(e11).getID());
ASSERT (e1 == index.getScope(e12).getID());
ASSERT (e1 == index.getScope(e13).getID());
ASSERT (e13 == index.getScope(e131).getID());
ASSERT (e13 == index.getScope(e132).getID());
ASSERT (e13 == index.getScope(e133).getID());
ASSERT (e133 == index.getScope(e1331).getID());
ASSERT (e1 != e13);
ASSERT (e13 != e133);
ASSERT (index->getScope(e11) == index->getScope(index->find(e11)));
ASSERT (index->getScope(e131) == index->getScope(index->find(e131)));
ASSERT (index.getScope(e11) == index.getScope(index.find(e11)));
ASSERT (index.getScope(e131) == index.getScope(index.find(e131)));
VERIFY_ERROR(NONEMPTY_SCOPE, index->remove(e13) ); // can't remove a scope-constituting element
VERIFY_ERROR(NONEMPTY_SCOPE, index->remove(e133) );
VERIFY_ERROR(NONEMPTY_SCOPE, index.remove(e13) ); // can't remove a scope-constituting element
VERIFY_ERROR(NONEMPTY_SCOPE, index.remove(e133) );
ASSERT (index->contains(e1331));
ASSERT (index->remove(e1331));
ASSERT (!index->contains(e1331));
ASSERT (!index->remove(e1331));
ASSERT (index.contains(e1331));
ASSERT (index.remove(e1331));
ASSERT (!index.contains(e1331));
ASSERT (!index.remove(e1331));
ASSERT (index->remove(e133)); // but can remove an scope, after emptying it
ASSERT (!index->contains(e133));
ASSERT (index.remove(e133)); // but can remove an scope, after emptying it
ASSERT (!index.contains(e133));
}
};

View file

@ -32,23 +32,9 @@ namespace session {
namespace test {
namespace { // deleter function to clean up Test fixture
void
remove_testIndex (PlacementIndex* testIdx)
{
REQUIRE (testIdx);
testIdx->clear();
ASSERT (0 == testIdx->size());
SessionServiceMockIndex::reset_PlacementIndex(); // restore default Index from Session
delete testIdx;
}
}
/** @note when this object goes out of scope, the activation of this
* test PlacementIndex will be cleared automatically, and the
* default Index within the session will be re-activated.
/** @note this dummy index isn't actively connected to the session;
* the unit tests rely on this dummy index containing
* a specific tree structure of test-dummy MObjects.
*/
PPIdx
build_testScopes()
@ -64,8 +50,8 @@ namespace test {
PDum ps3(*new TestSubMO1);
// Prepare an (test)Index backing the PlacementRefs
PPIdx index (PlacementIndex::create().get(), &remove_testIndex); // taking ownership
SessionServiceMockIndex::reset_PlacementIndex(index);
PPIdx index (SessionServiceMockIndex::install());
PMO& root = index->getRoot();
typedef PMO::ID ID;