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

feature #192: New tests for the user pool

This commit is contained in:
Ruben S. Montero 2010-04-22 23:29:14 +02:00
parent 238644743d
commit 37d9bb74da
2 changed files with 142 additions and 192 deletions

View File

@ -1,18 +1,18 @@
# --------------------------------------------------------------------------
# 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,
# --------------------------------------------------------------------------
# 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.
# --------------------------------------------------------------------------
# See the License for the specific language governing permissions and
# limitations under the License.
# --------------------------------------------------------------------------
import os
import sys
@ -34,6 +34,7 @@ add_bison(main_env)
# Include dirs
main_env.Append(CPPPATH=[
cwd + '/include',
cwd + '/include/test',
'/usr/include/cppunit/',
])
@ -55,6 +56,7 @@ main_env.Append(LIBS=[
'dl',
'pthread',
'sqlite3',
'mysqlclient',
'crypto'
])
@ -66,6 +68,9 @@ main_env.Append(CPPFLAGS=[
# Linking flags
main_env.Append(LDFLAGS=["-g "])
main_env.Program('UserPoolTest.cc')
# MYSQL
main_env.Append(LIBPATH=["/usr/lib/mysql"])
main_env.Append(CPPPATH=["/usr/include/mysql"])

View File

@ -18,76 +18,87 @@
#include <iostream>
#include <stdlib.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 "UserPool.h"
#include "SqliteDB.h"
#include "PoolTest.h"
using namespace std;
/* ************************************************************************* */
/* ************************************************************************* */
class UserPoolTest : public CppUnit::TestFixture
const string usernames[] = { "A user", "B user", "C user", "D user", "E user" };
const string passwords[] = { "A pass", "B pass", "C pass", "D pass", "E pass" };
class UserPoolTest : public PoolTest
{
CPPUNIT_TEST_SUITE (UserPoolTest);
CPPUNIT_TEST (sha1_digest);
CPPUNIT_TEST (initial_user);
CPPUNIT_TEST (authenticate);
// Not all tests from PoolTest can be used. Because
// of the initial user added to the DB, the oid_assignment would fail.
CPPUNIT_TEST (get_from_cache);
CPPUNIT_TEST (get_from_db);
CPPUNIT_TEST (wrong_get);
CPPUNIT_TEST (drop_and_get);
CPPUNIT_TEST (sha1_digest);
CPPUNIT_TEST (split_secret);
CPPUNIT_TEST (initial_user);
CPPUNIT_TEST (authenticate);
CPPUNIT_TEST (get_using_name);
CPPUNIT_TEST (wrong_get_name);
CPPUNIT_TEST (update);
CPPUNIT_TEST (dump);
CPPUNIT_TEST_SUITE_END ();
private:
UserPool * pool;
SqlDB * db;
protected:
User* user;
string database_name()
{
return "user_pool_test";
};
void bootstrap(SqlDB* db)
{
UserPool::bootstrap(db);
};
PoolSQL* create_pool(SqlDB* db)
{
return new UserPool(db);
};
int allocate(int index)
{
int oid;
((UserPool*)pool)->allocate(&oid, usernames[index], passwords[index], true);
return oid;
};
void check(int index, PoolObjectSQL* obj)
{
CPPUNIT_ASSERT( obj != 0 );
string name = ((User*)obj)->get_username();
CPPUNIT_ASSERT( name == usernames[index] );
CPPUNIT_ASSERT( ((User*)obj)->get_password() == passwords[index] );
};
public:
UserPoolTest(){};
~UserPoolTest(){};
void setUp()
UserPoolTest()
{
string db_name = "test.db";
unlink("test.db");
db = new SqliteDB(db_name);
UserPool::bootstrap(db);
// The UserPool constructor checks if the DB contains at least
// one user, and adds one automatically from the ONE_AUTH file.
// So the ONE_AUTH environment is forced to point to a test one_auth
// file.
ostringstream oss;
oss << getenv("PWD") << "/one_auth";
setenv("ONE_AUTH", oss.str().c_str(), 1);
pool = new UserPool(db);
};
void tearDown()
{
delete db;
delete pool;
remove ("test.db");
};
~UserPoolTest(){};
/* ********************************************************************* */
/* ********************************************************************* */
@ -100,6 +111,18 @@ public:
CPPUNIT_ASSERT( sha1 == User::sha1_digest(st) );
}
void split_secret()
{
string secret = "left_part-user.N AME:pass--word..SECRET?";
string left = "";
string right = "";
User::split_secret(secret, left, right);
CPPUNIT_ASSERT( left == "left_part-user.N AME" );
CPPUNIT_ASSERT( right == "pass--word..SECRET?" );
}
void initial_user()
{
// When creating a new pool, the constructor will check if the DB
@ -112,7 +135,7 @@ public:
// one_auth file at set-up, so the pool should contain the user
// one_user_test:password
user = pool->get(0, false);
User* user = (User*) pool->get(0, false);
CPPUNIT_ASSERT(user != 0);
CPPUNIT_ASSERT( user->get_uid() == 0 );
@ -122,164 +145,89 @@ public:
void authenticate()
{
UserPool* user_pool = (UserPool*) pool;
// There is an initial user, created with the one_auth file:
// one_user_test:password
string session =
"one_user_test:5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8";
int oid = pool->authenticate( session );
string session="one_user_test:5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8";
int oid = user_pool->authenticate( session );
CPPUNIT_ASSERT( oid == 0 );
session = "one_user_test:wrong_password";
oid = pool->authenticate( session );
oid = user_pool->authenticate( session );
CPPUNIT_ASSERT( oid == -1 );
session =
"unknown_user:5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8";
oid = pool->authenticate( session );
session = "unknown_user:5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8";
oid = user_pool->authenticate( session );
CPPUNIT_ASSERT( oid == -1 );
}
// Try to allocate two objects, and retrieve them
void get_from_cache()
void get_using_name()
{
string username_1 = "A user";
string username_2 = "B user";
string pass_1 = "A pass";
string pass_2 = "B pass";
int oid_1, oid_2;
pool->allocate(&oid_1, username_1, pass_1, true);
// first element in the pool should have oid=1 (the 0th one is created
// by the UserPool constructor)
CPPUNIT_ASSERT(oid_1 == 1);
pool->allocate(&oid_2, username_2, pass_2, true);
// second element in the pool should have oid=2
CPPUNIT_ASSERT(oid_2 == 2);
int oid_0, oid_1;
// Allocate two objects
oid_0 = allocate(0);
oid_1 = allocate(1);
// ---------------------------------
user = pool->get(oid_1, false);
CPPUNIT_ASSERT(user != 0);
// Get first object and check its integrity
obj = pool->get(oid_0, false);
CPPUNIT_ASSERT( obj != 0 );
check(0, obj);
CPPUNIT_ASSERT( user->get_uid() == 1 );
CPPUNIT_ASSERT( user->get_username() == username_1 );
CPPUNIT_ASSERT( user->get_password() == pass_1 );
// Get using its name
obj = ((UserPool*)pool)->get(usernames[1], true);
check(1, obj);
obj->unlock();
// ---------------------------------
user = pool->get(oid_2, true);
CPPUNIT_ASSERT(user != 0);
CPPUNIT_ASSERT( user->get_uid() == 2 );
CPPUNIT_ASSERT( user->get_username() == username_2 );
CPPUNIT_ASSERT( user->get_password() == pass_2 );
user->unlock();
};
// Try to allocate two objects, and retrieve them
void get_from_db()
{
string username_1 = "A user";
string username_2 = "B user";
string pass_1 = "A pass";
string pass_2 = "B pass";
int oid_1, oid_2;
pool->allocate(&oid_1, username_1, pass_1, true);
pool->allocate(&oid_2, username_2, pass_2, true);
string str;
// Get the xml representation of the two users
string xml_1 = pool->get(oid_1, false)->to_xml(str);
string xml_2 = pool->get(oid_2, false)->to_xml(str);
// Clean the users from the cache, forcing the pool to read them from
// the DB when we retrieve them
// Clean the cache, forcing the pool to read the objects from the DB
pool->clean();
// ---------------------------------
user = pool->get(oid_1, false);
CPPUNIT_ASSERT(user != 0);
// Get first object and check its integrity
obj = pool->get(oid_0, false);
check(0, obj);
// The user objects constructed from the data in the DB should be the
// same as the previous ones
CPPUNIT_ASSERT(user->to_xml(str) == xml_1);
CPPUNIT_ASSERT(user->get_uid() == oid_1);
CPPUNIT_ASSERT(user->get_username() == username_1);
CPPUNIT_ASSERT(user->get_password() == pass_1);
// ---------------------------------
user = pool->get(oid_2, true);
CPPUNIT_ASSERT(user != 0);
CPPUNIT_ASSERT(user->to_xml(str) == xml_2);
CPPUNIT_ASSERT(user->get_uid() == oid_2);
CPPUNIT_ASSERT(user->get_username() == username_2);
CPPUNIT_ASSERT(user->get_password() == pass_2);
user->unlock();
// Get using its name
obj = ((UserPool*)pool)->get(usernames[1], true);
check(1, obj);
obj->unlock();
};
void drop_and_get()
void wrong_get_name()
{
string username_1 = "A user";
string username_2 = "B user";
// The pool is empty
// Non existing name
obj = ((UserPool*)pool)->get("Wrong name", true);
CPPUNIT_ASSERT( obj == 0 );
string pass_1 = "A pass";
string pass_2 = "B pass";
// Allocate an object
allocate(0);
int oid_1, oid_2;
pool->allocate(&oid_1, username_1, pass_1, true);
pool->allocate(&oid_2, username_2, pass_2, true);
// Get the first user (A)
user = pool->get(oid_1,true);
CPPUNIT_ASSERT(user != 0);
// Delete it
pool->drop(user);
user->unlock();
// It should be gone now
user = pool->get(oid_1,true);
CPPUNIT_ASSERT(user == 0);
// The cache is cleaned, the user should be also gone from the DB
pool->clean();
user = pool->get(oid_1,true);
CPPUNIT_ASSERT(user == 0);
// But the other user must be accessible
user = pool->get(oid_2,false);
CPPUNIT_ASSERT(user != 0);
};
// Ask again for a non-existing name
obj = ((UserPool*)pool)->get("Non existing name", true);
CPPUNIT_ASSERT( obj == 0 );
}
void update()
{
string username_1 = "A user";
string pass_1 = "A pass";
int oid_1, oid_2;
int oid;
User* user;
// Allocate some users, to popullate the DB
pool->allocate(&oid_2, "someone", pass_1, true);
pool->allocate(&oid_2, "some_user", pass_1, true);
allocate(0);
allocate(1);
// The user we are interested in
pool->allocate(&oid_1, username_1, pass_1, true);
oid = allocate(2);
// Some more users...
pool->allocate(&oid_2, "not_used", pass_1, true);
pool->allocate(&oid_2, "no_name", pass_1, true);
allocate(3);
allocate(4);
user = pool->get(oid_1, true);
user = ((UserPool*)pool)->get(oid, true);
// User object should be cached. Let's update its status
user->disable();
@ -293,21 +241,21 @@ public:
int rc;
ostringstream oss;
oss << "oid = " << oid_1;
oss << "oid = " << oid;
rc = pool->search(results,"user_pool", oss.str());
CPPUNIT_ASSERT(rc == 0);
CPPUNIT_ASSERT(results.size() == 1);
CPPUNIT_ASSERT(results.at(0) == oid_1);
CPPUNIT_ASSERT(results.at(0) == oid);
user = pool->get(oid_1,false);
user = ((UserPool*)pool)->get(oid,false);
CPPUNIT_ASSERT( user->isEnabled() == false );
//Now force access to DB
pool->clean();
user = pool->get(oid_1,false);
user = ((UserPool*)pool)->get(oid,false);
CPPUNIT_ASSERT( user->isEnabled() == false );
};
@ -327,29 +275,29 @@ public:
"</USER_POOL>";
string names[] = {"a", "a name", "a_name", "another name", "user"};
string pass[] = {"p", "pass", "password", "secret", "1234"};
string d_names[] = {"a", "a name", "a_name", "another name", "user"};
string d_pass[] = {"p", "pass", "password", "secret", "1234"};
int oid;
for(int i=0; i<5; i++)
{
pool->allocate(&oid, names[i], pass[i], true);
((UserPool*)pool)->allocate(&oid, d_names[i], d_pass[i], true);
}
ostringstream oss;
pool->dump(oss, "");
((UserPool*)pool)->dump(oss, "");
CPPUNIT_ASSERT( oss.str() == xml_result );
// Allocate and delete a new user
pool->allocate(&oid, "new name", "new pass", true);
user = pool->get(oid, true);
((UserPool*)pool)->allocate(&oid, "new name", "new pass", true);
User* user = ((UserPool*)pool)->get(oid, true);
pool->drop(user);
user->unlock();
ostringstream new_oss;
pool->dump(new_oss, "");
((UserPool*)pool)->dump(new_oss, "");
CPPUNIT_ASSERT( new_oss.str() == xml_result );
}
@ -361,8 +309,5 @@ public:
int main(int argc, char ** argv)
{
CppUnit::TextUi::TestRunner runner;
runner.addTest( UserPoolTest::suite() );
runner.run();
return 0;
return PoolTest::main(argc, argv, UserPoolTest::suite());
}