1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-27 10:50:10 +03:00

feature #192: Initial tests for the PoolSQL class

This commit is contained in:
Carlos Martin and Ruben S. Montero 2010-03-12 23:16:32 +01:00 committed by Ruben S. Montero
parent 83bf1a6cbb
commit 237d2c5607
4 changed files with 511 additions and 0 deletions

68
src/pool/test/SConstruct Normal file
View File

@ -0,0 +1,68 @@
# --------------------------------------------------------------------------
# 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.
# --------------------------------------------------------------------------
import os
import sys
import shutil
sys.path.append("../../../share/scons")
from lex_bison import *
# This is the absolute path where the project is located
cwd="../../../"
# Environment that will be applied to each scons child
main_env=Environment()
main_env['ENV']['PATH']=os.environ['PATH']
# Add builders for flex and bison
add_lex(main_env)
add_bison(main_env)
# Include dirs
main_env.Append(CPPPATH=[
cwd + '/include',
'/usr/include/cppunit/',
])
# Library dirs
main_env.Append(LIBPATH=[
cwd + '/src/common',
cwd + '/src/pool',
cwd + '/src/pool/test',
])
main_env.Append(LIBS=[
'nebula_pool',
'nebula_common',
'cppunit',
'dl',
'pthread',
'sqlite3',
'test_object'
])
# Compile flags
main_env.Append(CPPFLAGS=[
"-g",
"-Wall"
])
# Linking flags
main_env.Append(LDFLAGS=["-g "])
main_env.StaticLibrary('test_object', ['TestPoolSQL.cc', 'TestPoolSQL.h'])
main_env.Program('pool.cc')
#

View File

@ -0,0 +1,159 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <openssl/evp.h>
#include <iomanip>
#include "TestPoolSQL.h"
/* ************************************************************************** */
/* Database Access Functions */
/* ************************************************************************** */
const char * TestObjectSQL::table = "test_pool";
const char * TestObjectSQL::db_names = "(oid,number,text)";
const char * TestObjectSQL::db_bootstrap = "CREATE TABLE test_pool ("
"oid INTEGER, number INTEGER, text TEXT, PRIMARY KEY(oid))";
/* -------------------------------------------------------------------------- */
int TestObjectSQL::unmarshall(int num, char **names, char ** values)
{
if ((!values[OID]) ||
(!values[NUMBER]) ||
(!values[TEXT]) ||
(num != LIMIT ))
{
return -1;
}
oid = atoi(values[OID]);
number = atoi(values[NUMBER]);
text = values[TEXT];
return 0;
}
/* -------------------------------------------------------------------------- */
extern "C" int user_select_cb (
void * _user,
int num,
char ** values,
char ** names)
{
TestObjectSQL * user;
user = static_cast<TestObjectSQL *>(_user);
if (user == 0)
{
return -1;
}
return user->unmarshall(num,names,values);
};
/* -------------------------------------------------------------------------- */
int TestObjectSQL::select(SqliteDB *db)
{
ostringstream oss;
int rc;
int boid;
oss << "SELECT * FROM " << table << " WHERE oid = " << oid;
boid = oid;
oid = -1;
rc = db->exec(oss, user_select_cb, (void *) this);
if ((rc != 0) || (oid != boid ))
{
return -1;
}
return 0;
}
/* -------------------------------------------------------------------------- */
int TestObjectSQL::insert(SqliteDB *db)
{
return update(db);
}
/* -------------------------------------------------------------------------- */
int TestObjectSQL::update(SqliteDB *db)
{
ostringstream oss;
int rc;
char * sql_number;
char * sql_text;
sql_number = sqlite3_mprintf("%d",number);
sql_text = sqlite3_mprintf("%q",text.c_str());
if ( sql_text == 0 )
{
sqlite3_free(sql_number);
return -1;
}
oss << "INSERT OR REPLACE INTO " << table << " "<< db_names <<" VALUES ("
<< oid << ","
<< sql_number << ","
<< "'" << sql_text << "')";
rc = db->exec(oss);
sqlite3_free(sql_number);
sqlite3_free(sql_text);
return rc;
}
/* -------------------------------------------------------------------------- */
int TestObjectSQL::drop(SqliteDB * db)
{
ostringstream oss;
int rc;
oss << "DELETE FROM " << table << " WHERE oid=" << oid;
rc = db->exec(oss);
if ( rc == 0 )
{
set_valid(false);
}
return rc;
}

102
src/pool/test/TestPoolSQL.h Normal file
View File

@ -0,0 +1,102 @@
/* -------------------------------------------------------------------------- */
/* 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 TESTSQL_H_
#define TESTSQL_H_
#include <string>
#include "PoolSQL.h"
using namespace std;
extern "C" int user_select_cb (void * _host,
int num,
char ** values,
char ** names);
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
// THE OBJECT
class TestObjectSQL : public PoolObjectSQL
{
public:
//OBJECT ATTRIBUTES
TestObjectSQL(int n=-1, string t="default"):number(n),text(t){};
~TestObjectSQL(){};
int number;
string text;
// OBJECTSQL INTERFACE
int unmarshall(int num, char **names, char ** values);
int select(SqliteDB *db);
int insert(SqliteDB *db);
int update(SqliteDB *db);
int drop(SqliteDB *db);
// DATABASE IMPLEMENTATION
enum ColNames
{
OID = 0,
NUMBER = 1,
TEXT = 2,
LIMIT = 3
};
static const char * db_names;
static const char * db_bootstrap;
static const char * table;
static void bootstrap(SqliteDB * db)
{
db->exec(TestObjectSQL::db_bootstrap);
};
};
// THE POOL
class TestPool : public PoolSQL
{
public:
TestPool(SqliteDB *db):PoolSQL(db,"test_pool"){};
~TestPool(){};
TestObjectSQL * get(
int oid,
bool lock)
{
return static_cast<TestObjectSQL *>(PoolSQL::get(oid,lock));;
}
private:
TestObjectSQL * create()
{
return new TestObjectSQL;
};
};
#endif

182
src/pool/test/pool.cc Normal file
View File

@ -0,0 +1,182 @@
/* -------------------------------------------------------------------------- */
/* 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. */
/* -------------------------------------------------------------------------- */
#include <string>
#include <iostream>
#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 "PoolSQL.h"
#include "TestPoolSQL.h"
using namespace std;
/* ************************************************************************* */
/* ************************************************************************* */
class PoolTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE (PoolTest);
CPPUNIT_TEST (allocate_get);
CPPUNIT_TEST (wrong_get);
CPPUNIT_TEST (search);
CPPUNIT_TEST_SUITE_END ();
private:
TestPool * pool;
SqliteDB * db;
int create_allocate(int n, string st)
{
TestObjectSQL *obj = new TestObjectSQL(n,st);
return pool->allocate(obj);
};
public:
PoolTest(){};
~PoolTest(){};
void setUp()
{
string db_name = "test.db";
unlink("test.db");
db = new SqliteDB(db_name);
TestObjectSQL::bootstrap(db);
pool = new TestPool(db);
};
void tearDown()
{
delete db;
delete pool;
};
/* ********************************************************************* */
/* ********************************************************************* */
// Try to allocate two objects, and retrieve them
void allocate_get()
{
int n1 = 3;
int n2 = 7;
string st1 = "text number one";
string st2 = "another text";
TestObjectSQL *obj;
int oid;
oid = create_allocate(n1,st1);
// first element in the pool should have oid=0
CPPUNIT_ASSERT(oid == 0);
oid = create_allocate(n2,st2);
// second element in the pool should have oid=1
CPPUNIT_ASSERT(oid == 1);
// ---------------------------------
obj = pool->get(0, false);
CPPUNIT_ASSERT(obj != 0);
CPPUNIT_ASSERT(obj->number == n1);
CPPUNIT_ASSERT(obj->text == st1);
// ---------------------------------
obj = pool->get(1, true);
CPPUNIT_ASSERT(obj != 0);
CPPUNIT_ASSERT(obj->number == n2);
CPPUNIT_ASSERT(obj->text == st2);
obj->unlock();
};
void wrong_get()
{
int n1 = 2;
string st1 = "object 2";
TestObjectSQL *obj;
int oid;
oid = create_allocate(n1,st1);
obj = pool->get(oid,true);
CPPUNIT_ASSERT(obj != 0);
obj->drop(db);
obj->unlock();
obj = pool->get(oid,true);
CPPUNIT_ASSERT(obj == 0);
pool->clean();
obj = pool->get(oid,true);
CPPUNIT_ASSERT(obj == 0);
};
void search()
{
int nA = 13;
int nB = 17;
string stA = "String value for number 13";
string stB = "String value for number 17";
int oidA = create_allocate(nA, stA);
int oidB = create_allocate(nB, stB);
vector<int> results;
const char * table = "test_pool";
string where = "text = '" + stB + "'";
int ret;
ret = pool->search(results, table, where);
CPPUNIT_ASSERT(ret == 0);
CPPUNIT_ASSERT(results.size() == 1);
CPPUNIT_ASSERT(results.at(0) == oidB);
results.erase(results.begin(), results.end());
where = "number < 18";
ret = pool->search(results, table, where);
CPPUNIT_ASSERT(ret == 0);
CPPUNIT_ASSERT(results.size() == 2);
CPPUNIT_ASSERT(results.at(0) == oidA);
CPPUNIT_ASSERT(results.at(1) == oidB);
};
};
/* ************************************************************************* */
/* ************************************************************************* */
/* ************************************************************************* */
int main(int argc, char ** argv)
{
CppUnit::TextUi::TestRunner runner;
runner.addTest( PoolTest::suite() );
runner.run();
return 0;
}