/* DefsManager(Test) - checking basic behaviour of the defaults manager Copyright (C) Lumiera.org 2008, Hermann Vosseler 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/assetmanager.hpp" #include "proc/mobject/session.hpp" #include "lib/streamtype.hpp" #include using boost::format; using util::isnil; using std::string; namespace asset { namespace test { using util::cStr; using lib::Symbol; using mobject::Session; using lumiera::Query; using lumiera::query::normaliseID; using lumiera::StreamType; /** shortcut: run just a query * without creating new instances */ bool find (Query& 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 ()); CHECK (pipe2 == pipe1); pipe2 = asset::Struct::retrieve (Query ()); CHECK (pipe2 == pipe1); pipe2 = asset::Struct::retrieve (Query ("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 ()); // "the default pipe" string new_pID (str (format ("dummy_%s_%i") % pipe1->getPipeID() % std::rand() )); // make random new pipeID Query 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 query_for_pID ("pipe("+pID+")"); size_t hash; { // create new pipe and declare it to be a default PPipe pipe1 = Struct::retrieve.newInstance (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 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 asset::test