LUMIERA.clone/tests/core/proc/mobject/session/defs-manager-test.cpp
Ichthyostega ada5cefaaf re-arrange tests according to layer structure
the buildsystem will now pick up and link
all test cases according to the layer, e.g.
backend tests will automatically be linked
against the backend + library solely.
2013-01-07 05:43:01 +01:00

203 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 "lib/test/run.hpp"
#include "lib/symbol.hpp"
#include "lib/util.hpp"
#include "lib/query-util.hpp"
#include "common/query.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 "proc/streamtype.hpp"
#include <boost/format.hpp>
using boost::format;
using util::isnil;
using std::string;
namespace proc {
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 lib::query::normaliseID;
/** 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 proc::mobject::session::test