mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-25 06:03:36 +03:00
360 lines
9.1 KiB
C++
360 lines
9.1 KiB
C++
/* -------------------------------------------------------------------------- */
|
|
/* Copyright 2002-2010, 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 <string>
|
|
#include <iostream>
|
|
#include <stdlib.h>
|
|
#include <getopt.h>
|
|
|
|
#include <TestFixture.h>
|
|
#include <TestAssert.h>
|
|
#include <TestSuite.h>
|
|
#include <TestCaller.h>
|
|
#include <ui/text/TestRunner.h>
|
|
#include <cppunit/extensions/HelperMacros.h>
|
|
#include <unistd.h>
|
|
|
|
#include "SqlDB.h"
|
|
#include "SqliteDB.h"
|
|
#include "MySqlDB.h"
|
|
#include "PoolSQL.h"
|
|
#include "Nebula.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 CppUnit::TestFixture
|
|
{
|
|
private:
|
|
// Global flag to use either Sqlite or MySQL
|
|
static bool mysql;
|
|
|
|
protected:
|
|
PoolSQL * pool;
|
|
SqlDB * db;
|
|
|
|
PoolObjectSQL* obj;
|
|
|
|
/*
|
|
* The name of the database to execute the test on
|
|
*/
|
|
virtual string database_name() = 0;
|
|
|
|
/*
|
|
* 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;
|
|
|
|
public:
|
|
|
|
void setUp()
|
|
{
|
|
string db_name = "test.db";
|
|
unlink("test.db");
|
|
|
|
|
|
if (mysql)
|
|
{
|
|
db = new MySqlDB("localhost","oneadmin","onepass",NULL);
|
|
|
|
ostringstream oss1;
|
|
oss1 << "DROP DATABASE IF EXISTS " << database_name();
|
|
db->exec(oss1);
|
|
|
|
ostringstream oss;
|
|
oss << "CREATE DATABASE " << database_name();
|
|
db->exec(oss);
|
|
|
|
ostringstream oss2;
|
|
oss2 << "use " << database_name();
|
|
db->exec(oss2);
|
|
}
|
|
else
|
|
db = new SqliteDB(db_name);
|
|
|
|
|
|
bootstrap(db);
|
|
|
|
pool = create_pool(db);
|
|
};
|
|
|
|
void tearDown()
|
|
{
|
|
if (mysql)
|
|
{
|
|
ostringstream oss;
|
|
oss << "DROP DATABASE IF EXISTS " << database_name();
|
|
db->exec(oss);
|
|
}
|
|
else
|
|
remove ("test.db");
|
|
|
|
delete db;
|
|
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, true);
|
|
CPPUNIT_ASSERT( obj == 0 );
|
|
|
|
// Allocate an object
|
|
allocate(0);
|
|
|
|
// Ask again for a non-existing oid
|
|
obj = pool->get(213, true);
|
|
CPPUNIT_ASSERT( obj == 0 );
|
|
}
|
|
|
|
void drop_and_get()
|
|
{
|
|
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 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);
|
|
|
|
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);
|
|
};
|
|
|
|
|
|
// *****************************************************************************
|
|
|
|
|
|
static void show_options ()
|
|
{
|
|
cout << "Options:\n";
|
|
cout << " -h --help Show this help\n"
|
|
" -s --sqlite Run Sqlite tests (default)\n"
|
|
" -m --mysql Run MySQL tests\n"
|
|
" -l --log Keep the log file, test.log\n";
|
|
}
|
|
|
|
|
|
/*
|
|
* Not a true main, but a static method that can be called from the
|
|
* child classes' true main.
|
|
* Options:
|
|
* s: run sqlite tests
|
|
* m: run mysql tests
|
|
*/
|
|
static int main(int argc, char ** argv, CPPUNIT_NS::TestSuite* suite)
|
|
{
|
|
|
|
// Option flags
|
|
bool sqlite_flag = true;
|
|
bool log_flag = false;
|
|
|
|
// Long options
|
|
const struct option long_opt[] =
|
|
{
|
|
{ "sqlite", 0, NULL, 's'},
|
|
{ "mysql", 0, NULL, 'm'},
|
|
{ "log", 0, NULL, 'l'},
|
|
{ "help", 0, NULL, 'h'}
|
|
};
|
|
|
|
int c;
|
|
while ((c = getopt_long (argc, argv, "smlh", long_opt, NULL)) != -1)
|
|
switch (c)
|
|
{
|
|
case 'm':
|
|
sqlite_flag = false;
|
|
break;
|
|
case 'l':
|
|
log_flag = true;
|
|
break;
|
|
case 'h':
|
|
show_options();
|
|
return 0;
|
|
}
|
|
|
|
|
|
// When a DB query fails, it tries to log the error.
|
|
// We need to set the log file, otherwise it will end in a dead-lock
|
|
NebulaLog::init_log_system(NebulaLog::FILE, Log::DEBUG, "test.log");
|
|
NebulaLog::log("Test", Log::INFO, "Test started");
|
|
|
|
CppUnit::TextUi::TestRunner runner;
|
|
runner.addTest( suite );
|
|
|
|
if (sqlite_flag)
|
|
{
|
|
PoolTest::mysql = false;
|
|
NebulaLog::log("Test", Log::INFO, "Running Sqlite tests...");
|
|
cout << "\nRunning Sqlite tests...\n";
|
|
}
|
|
else
|
|
{
|
|
PoolTest::mysql = true;
|
|
NebulaLog::log("Test", Log::INFO, "Running MySQL tests...");
|
|
cout << "\nRunning MySQL tests...\n";
|
|
}
|
|
|
|
runner.run();
|
|
|
|
if (!log_flag)
|
|
remove("test.log");
|
|
|
|
NebulaLog::finalize_log_system();
|
|
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
bool PoolTest::mysql;
|
|
|
|
#endif // POOL_TEST_H_
|