LUMIERA.clone/tests/components/proc/mobject/session/defs-manager-test.cpp

204 lines
6.5 KiB
C++

/*
DefsManager(Test) - checking basic behaviour of the defaults manager
Copyright (C) Lumiera.org
2008, Hermann Vosseler <Ichthyostega@web.de>
This program 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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
#include "pre_a.hpp"
#include "lib/test/run.hpp"
#include "lib/symbol.hpp"
#include "lib/query.hpp"
#include "lib/util.hpp"
#include "proc/asset.hpp"
#include "proc/asset/pipe.hpp"
#include "proc/asset/struct.hpp"
#include "proc/assetmanager.hpp"
#include "proc/mobject/session.hpp"
#include "lib/streamtype.hpp"
#include <boost/format.hpp>
using boost::format;
using util::isnil;
using std::string;
namespace mobject {
namespace session {
namespace test {
using util::cStr;
using lib::Symbol;
using asset::ID;
using asset::Asset;
using asset::AssetManager;
using asset::Pipe;
using asset::PPipe;
using asset::Struct;
using lumiera::Query;
using lumiera::query::normaliseID;
using lumiera::StreamType;
/** shortcut: run just a query
* without creating new instances
*/
bool
find (Query<Pipe>& q)
{
return Session::current->defaults.search (q);
}
/***********************************************************************
* @test basic behaviour of the defaults manager ("the big picture")
* - retrieving a "default" object repeatedly
* - retrieving a more constrained "default" object
* - failure registers a new "default"
* - instance management
*
* Using pipe assets as an example. The defaults manager shouldn't
* interfere with memory management (it holds weak refs).
*/
class DefsManager_test : public Test
{
virtual void
run (Arg arg)
{
string pipeID = isnil(arg)? "Black Hole" : arg[1];
string streamID = 2>arg.size()? "teststream" : arg[2];
normaliseID (pipeID);
normaliseID (streamID);
retrieveSimpleDefault (pipeID);
retrieveConstrainedDefault (pipeID, streamID);
failureCreatesNewDefault();
verifyRemoval();
}
void
retrieveSimpleDefault (string)
{
PPipe pipe1 = Pipe::query (""); // "the default pipe"
PPipe pipe2;
// several variants to query for "the default pipe"
pipe2 = Pipe::query ("");
CHECK (pipe2 == pipe1);
pipe2 = Pipe::query ("default(X)");
CHECK (pipe2 == pipe1);
pipe2 = Session::current->defaults(Query<Pipe> ());
CHECK (pipe2 == pipe1);
pipe2 = asset::Struct::retrieve (Query<Pipe> ());
CHECK (pipe2 == pipe1);
pipe2 = asset::Struct::retrieve (Query<Pipe> ("default(P)"));
CHECK (pipe2 == pipe1);
}
void
retrieveConstrainedDefault (string pID, string sID)
{
PPipe pipe1 = Pipe::query (""); // "the default pipe"
CHECK ( pipe1->getStreamID() != StreamType::ID(sID),
"stream-ID \"%s\" not suitable for test, because "
"the default-pipe \"%s\" happens to have the same "
"stream-ID. We need it to be different",
sID.c_str(), pID.c_str()
);
string query_for_sID ("stream("+sID+")");
PPipe pipe2 = Pipe::query (query_for_sID);
CHECK (pipe2->getStreamID() == StreamType::ID(sID));
CHECK (pipe2 != pipe1);
CHECK (pipe2 == Pipe::query (query_for_sID)); // reproducible
}
void
failureCreatesNewDefault()
{
PPipe pipe1 = Session::current->defaults(Query<Pipe> ()); // "the default pipe"
string new_pID (str (format ("dummy_%s_%i")
% pipe1->getPipeID()
% std::rand()
)); // make random new pipeID
Query<Pipe> query_for_new ("pipe("+new_pID+")");
CHECK (!find (query_for_new)); // check it doesn't exist
PPipe pipe2 = Session::current->defaults (query_for_new); // triggers creation
CHECK ( find (query_for_new)); // check it exists now
CHECK (pipe1 != pipe2);
CHECK (pipe2 == Session::current->defaults (query_for_new));
}
/** verify the defaults manager holds only weak refs,
* so if an object goes out of scope, any defaults entries
* are purged silently
*/
void
verifyRemoval()
{
Symbol pID ("some_pipe");
Query<Pipe> query_for_pID ("pipe("+pID+")");
size_t hash;
{
// create new pipe and declare it to be a default
PPipe pipe1 = Struct::retrieve.newInstance<Pipe> (pID);
Session::current->defaults.define(pipe1);
CHECK (2 == pipe1.use_count()); // the pipe1 smart-ptr and the AssetManager
hash = pipe1->getID();
}
// pipe1 out of scope....
// AssetManager now should hold the only ref
ID<Asset> assetID (hash);
AssetManager& aMang (AssetManager::instance());
CHECK ( aMang.known (assetID));
aMang.remove (assetID);
CHECK (!aMang.known (assetID));
CHECK (!find(query_for_pID)); // bare default-query should fail...
PPipe pipe2 = Session::current->defaults (query_for_pID); // triggers re-creation
CHECK ( find(query_for_pID)); // should succeed again
}
};
/** Register this test class... */
LAUNCHER (DefsManager_test, "function session");
}}} // namespace mobject::session::test