/* -------------------------------------------------------------------------- */ /* Copyright 2002-2011, OpenNebula Project Leads (OpenNebula.org) */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); you may */ /* not use this file except in compliance with the License. You may obtain */ /* a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ /* See the License for the specific language governing permissions and */ /* limitations under the License. */ /* -------------------------------------------------------------------------- */ #ifndef POOL_TEST_H_ #define POOL_TEST_H_ #include #include "PoolSQL.h" #include "Nebula.h" #include "OneUnitTest.h" // Use this macro in sub-classes to add all the tests defined here #define ALL_POOLTEST_CPPUNIT_TESTS() \ CPPUNIT_TEST (oid_assignment); \ CPPUNIT_TEST (get_from_cache); \ CPPUNIT_TEST (get_from_db); \ CPPUNIT_TEST (wrong_get); \ CPPUNIT_TEST (drop_and_get); \ using namespace std; /* ************************************************************************* */ /* ************************************************************************* */ class PoolTest : public OneUnitTest { protected: PoolSQL * pool; PoolObjectSQL * obj; /* * Bootstrap the DB with the neccessary tables for the test */ virtual void bootstrap(SqlDB* db) = 0; /* * Create the appropiate pool */ virtual PoolSQL* create_pool(SqlDB* db) = 0; /* * Allocate the indexth sample pool object */ virtual int allocate(int index) = 0; /* * Check if the indexth sample object is equal to this one */ virtual void check(int index, PoolObjectSQL* obj) = 0; PoolTest():pool(0){}; virtual ~PoolTest(){}; /** * Replaces all elements, padding them with 0 */ string fix_regtimes(string& xml) { return fix_time(xml, "REGTIME"); } string fix_stimes(string& xml) { return fix_time(xml, "STIME"); } string fix_time(string& xml, string elem_name) { string start = "<" + elem_name + ">"; string replacement = "0000000000"; size_t pos = 0; while( (pos = xml.find(start, pos)) != string::npos ) { if ( xml[pos+start.size()] != '0' ) { xml.replace( pos+start.size(), replacement.size(), replacement); } pos++; } return xml; } public: void setUp() { create_db(); bootstrap(db); pool = create_pool(db); }; void tearDown() { delete_db(); if ( pool != 0 ) { delete pool; } }; // ***************************************************************************** void oid_assignment() { int oid; oid = allocate(0); // first element in the pool should have oid=0 CPPUNIT_ASSERT(oid == 0); oid = allocate(1); // second element in the pool should have oid=1 CPPUNIT_ASSERT(oid == 1); } // Try to allocate two objects, and retrieve them void get_from_cache() { int oid_0, oid_1; // Allocate two objects oid_0 = allocate(0); oid_1 = allocate(1); CPPUNIT_ASSERT(oid_0 != -1); CPPUNIT_ASSERT(oid_1 != -1); // --------------------------------- // Get first object and check its integrity obj = pool->get(oid_0, false); check(0, obj); // Same for the second, but ask it to be locked obj = pool->get(oid_1, true); if(obj != 0) { obj->unlock(); } check(1, obj); }; // Try to allocate two objects, and retrieve them void get_from_db() { int oid_0, oid_1; // Allocate two objects oid_0 = allocate(0); oid_1 = allocate(1); CPPUNIT_ASSERT(oid_0 != -1); CPPUNIT_ASSERT(oid_1 != -1); // Clean the cache, forcing the pool to read the objects from the DB pool->clean(); // --------------------------------- // Get first object and check its integrity obj = pool->get(oid_0, false); check(0, obj); // Same for the second one, but ask it to be locked obj = pool->get(oid_1, true); if(obj != 0) { obj->unlock(); } check(1, obj); }; void wrong_get() { // The pool is empty // Non existing oid obj = pool->get(13, false); CPPUNIT_ASSERT( obj == 0 ); // Allocate an object allocate(0); // Ask again for a non-existing oid obj = pool->get(213, false); CPPUNIT_ASSERT( obj == 0 ); } void drop_and_get() { int oid_0, oid_1; string error_str; // Allocate two objects oid_0 = allocate(0); oid_1 = allocate(1); CPPUNIT_ASSERT(oid_0 != -1); CPPUNIT_ASSERT(oid_1 != -1); // Get the first object obj = pool->get(oid_0, true); if(obj != 0) { obj->unlock(); } CPPUNIT_ASSERT(obj != 0); obj->lock(); // Delete it pool->drop(obj, error_str); if(obj != 0) { obj->unlock(); } // It should be gone now obj = pool->get(oid_0, false); CPPUNIT_ASSERT(obj == 0); // The cache is cleaned, the object should be also gone from the DB pool->clean(); obj = pool->get(oid_0, true); CPPUNIT_ASSERT(obj == 0); // But the other object must be accessible obj = pool->get(oid_1, false); check(1, obj); }; }; // ----------------------------------------------------------------------------- #endif // POOL_TEST_H_