1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-15 23:24:09 +03:00

Bug #721: Add tests for cache when objects are gotten by name

This commit is contained in:
Carlos Martín 2011-07-27 18:20:29 +02:00
parent 033b96dfa9
commit dcf4ce4a5e
3 changed files with 191 additions and 104 deletions

View File

@ -27,123 +27,85 @@
#include "TestPoolSQL.h"
/* ************************************************************************** */
/* Database Access Functions */
/* Database Access Functions */
/* ************************************************************************** */
const char * TestObjectSQL::table = "test_pool";
const char * TestObjectSQL::db_names = "(oid,number,name)";
const char * TestObjectSQL::db_names = "oid,name,body,uid,number";
const char * TestObjectSQL::db_bootstrap = "CREATE TABLE test_pool ("
"oid INTEGER, number INTEGER, name TEXT, PRIMARY KEY(oid))";
/* -------------------------------------------------------------------------- */
int TestObjectSQL::unmarshall(void * nil, int num, char **values, char **names)
{
if ((!values[OID]) ||
(!values[NUMBER]) ||
(!values[TEXT]) ||
(num != LIMIT ))
{
return -1;
}
oid = atoi(values[OID]);
number = atoi(values[NUMBER]);
text = values[TEXT];
return 0;
}
/* -------------------------------------------------------------------------- */
int TestObjectSQL::select(SqlDB *db)
{
ostringstream oss;
int rc;
int boid;
set_callback(
static_cast<Callbackable::Callback>(&TestObjectSQL::unmarshall),0);
oss << "SELECT * FROM " << table << " WHERE oid = " << oid;
boid = oid;
oid = -1;
rc = db->exec(oss, this);
unset_callback();
if ((rc != 0) || (oid != boid ))
{
return -1;
}
return 0;
}
"oid INTEGER PRIMARY KEY, name VARCHAR(256), body TEXT, uid INTEGER, "
"number INTEGER)";
/* -------------------------------------------------------------------------- */
int TestObjectSQL::insert(SqlDB *db, string& str)
{
ostringstream oss;
int rc;
char * sql_text;
sql_text = db->escape_str(text.c_str());
oss << "INSERT INTO " << table << " "<< db_names <<" VALUES ("
<< oid << ","
<< number << ","
<< "'" << sql_text << "')";
rc = db->exec(oss);
db->free_str(sql_text);
return rc;
return insert_replace(db, false);
}
/* -------------------------------------------------------------------------- */
int TestObjectSQL::update(SqlDB *db)
{
ostringstream oss;
int rc;
char * sql_text;
sql_text = db->escape_str(text.c_str());
oss << "REPLACE INTO " << table << " "<< db_names <<" VALUES ("
<< oid << ","
<< number << ","
<< "'" << sql_text << "')";
rc = db->exec(oss);
db->free_str(sql_text);
return rc;
return insert_replace(db, true);
}
/* -------------------------------------------------------------------------- */
int TestObjectSQL::drop(SqlDB * db)
int TestObjectSQL::insert_replace(SqlDB *db, bool replace)
{
ostringstream oss;
int rc;
ostringstream oss;
oss << "DELETE FROM " << table << " WHERE oid=" << oid;
int rc;
string xml_body;
char * sql_name;
char * sql_xml;
// Update the User
sql_name = db->escape_str(name.c_str());
if ( sql_name == 0 )
{
goto error_name;
}
sql_xml = db->escape_str(to_xml(xml_body).c_str());
if ( sql_xml == 0 )
{
goto error_body;
}
// Construct the SQL statement to Insert or Replace
if(replace)
{
oss << "REPLACE";
}
else
{
oss << "INSERT";
}
oss << " INTO " << table << " ("<< db_names <<") VALUES ("
<< oid << ","
<< "'" << sql_name << "',"
<< "'" << sql_xml << "',"
<< uid << ","
<< number << ")";
rc = db->exec(oss);
if ( rc == 0 )
{
set_valid(false);
}
db->free_str(sql_name);
db->free_str(sql_xml);
return rc;
error_body:
db->free_str(sql_name);
error_name:
return -1;
}

View File

@ -30,7 +30,7 @@ class TestObjectSQL : public PoolObjectSQL
{
public:
//OBJECT ATTRIBUTES
TestObjectSQL(int n=-1, string t="default"):PoolObjectSQL(-1,"",0,0,"","",0),number(n),text(t){};
TestObjectSQL(int n=-1, string t="default"):PoolObjectSQL(-1,t,0,0,"","",table),number(n),text(t){};
~TestObjectSQL(){};
@ -41,22 +41,16 @@ public:
// OBJECTSQL INTERFACE
int unmarshall(void * nil, int num, char **names, char ** values);
int select(SqlDB *db);
int insert(SqlDB *db, string& err);
int update(SqlDB *db);
int drop(SqlDB *db);
int insert_replace(SqlDB *db, bool replace);
// DATABASE IMPLEMENTATION
enum ColNames
int drop(SqlDB *db)
{
OID = 0,
NUMBER = 1,
TEXT = 2,
LIMIT = 3
};
return PoolObjectSQL::drop(db);
}
static const char * db_names;
@ -74,11 +68,47 @@ public:
string& to_xml(string& xml) const
{
ostringstream oss;
oss << "<TEST>"
<< "<ID>" << oid << "</ID>"
<< "<UID>" << uid << "</UID>"
<< "<GID>" << gid << "</GID>"
<< "<UNAME>" << uname << "</UNAME>"
<< "<GNAME>" << gname << "</GNAME>"
<< "<NAME>" << name << "</NAME>"
<< "<NUMBER>" << number << "</NUMBER>"
<< "<TEXT>" << text << "</TEXT>"
<< "</TEST>";
xml = oss.str();
return xml;
};
int from_xml(const string &xml_str)
{
int rc = 0;
// Initialize the internal XML object
update_from_str(xml_str);
// Get class base attributes
rc += xpath(oid, "/TEST/ID", -1);
rc += xpath(uid, "/TEST/UID", -1);
rc += xpath(gid, "/TEST/GID", -1);
rc += xpath(uname, "/TEST/UNAME", "not_found");
rc += xpath(gname, "/TEST/GNAME", "not_found");
rc += xpath(name, "/TEST/NAME", "not_found");
rc += xpath(number, "/TEST/NUMBER", -1);
rc += xpath(text, "/TEST/TEXT", "not_found");
if ( rc != 0 )
{
return -1;
}
return 0;
};
};
@ -95,7 +125,15 @@ public:
int oid,
bool lock)
{
return static_cast<TestObjectSQL *>(PoolSQL::get(oid,lock));;
return static_cast<TestObjectSQL *>(PoolSQL::get(oid,lock));
}
TestObjectSQL * get(
const string& name,
int ouid,
bool olock)
{
return static_cast<TestObjectSQL *>(PoolSQL::get(name, ouid, olock));
}
int dump(std::ostringstream&, const std::string&){return -1;};

View File

@ -34,6 +34,7 @@ class PoolTest : public OneUnitTest
CPPUNIT_TEST (wrong_get);
CPPUNIT_TEST (search);
CPPUNIT_TEST (cache_test);
CPPUNIT_TEST (cache_name_test);
CPPUNIT_TEST_SUITE_END ();
private:
@ -63,8 +64,8 @@ public:
void tearDown()
{
delete_db();
delete pool;
delete_db();
};
/* ********************************************************************* */
@ -196,6 +197,92 @@ public:
obj_lock->unlock();
}
};
void cache_name_test()
{
TestObjectSQL *obj;
TestObjectSQL *obj_lock;
ostringstream oss;
string err_str;
//pin object in the cache, it can't be removed -
//Should be set to MAX_POOL -1
for (int i=0 ; i < 14999 ; i++)
{
oss.str("");
oss << "obj_" << i;
create_allocate(i, oss.str());
obj_lock = pool->get(oss.str(), 0, true);
CPPUNIT_ASSERT(obj_lock != 0);
}
for (int i=14999 ; i < 15200 ; i++) //Works with just 1 cache line
{
oss.str("");
oss << "obj_" << i;
create_allocate(i, oss.str());
}
for (int i=14999; i < 15200 ; i++)
{
oss.str("");
oss << "obj_" << i;
obj = pool->get(oss.str(), 0, true);
CPPUNIT_ASSERT(obj != 0);
CPPUNIT_ASSERT(obj->number == i);
CPPUNIT_ASSERT(obj->get_name() == obj->text);
CPPUNIT_ASSERT(obj->get_name() == oss.str());
obj->unlock();
}
// Delete some of the locked objects, and create new with the same name
for (int i=10 ; i < 21 ; i++)
{
oss.str("");
oss << "obj_" << i;
obj_lock = pool->get(oss.str(), 0, false);
CPPUNIT_ASSERT(obj_lock != 0);
pool->drop(obj_lock, err_str);
obj_lock->unlock();
create_allocate(i, oss.str());
}
// Try to get the new objects
for (int i=10 ; i < 21 ; i++)
{
oss.str("");
oss << "obj_" << i;
obj = pool->get(oss.str(), 0, true);
CPPUNIT_ASSERT(obj != 0);
CPPUNIT_ASSERT(obj->number == i);
CPPUNIT_ASSERT(obj->get_oid() >= 15200);
CPPUNIT_ASSERT(obj->get_name() == oss.str());
obj->unlock();
}
for (int i=0 ; i < 14999 ; i++)
{
obj_lock = pool->get(i, false);
if ( obj_lock != 0 )
{
obj_lock->unlock();
}
}
};
};
/* ************************************************************************* */