diff options
author | Huynh Tran <nthuynh75@gmail.com> | 2005-06-21 22:43:23 +0000 |
---|---|---|
committer | Huynh Tran <nthuynh75@gmail.com> | 2005-06-21 22:43:23 +0000 |
commit | 460a5bb2a9f57ddf9dbbd7095452c3c4fc660d65 (patch) | |
tree | ababb79e615ec1e2fcd82a4d2ddd1520c7c9179d | |
parent | 270163b535f64f2fd6baa32d8a76ecc1c5526539 (diff) | |
download | manaserv-460a5bb2a9f57ddf9dbbd7095452c3c4fc660d65.tar.gz manaserv-460a5bb2a9f57ddf9dbbd7095452c3c4fc660d65.tar.bz2 manaserv-460a5bb2a9f57ddf9dbbd7095452c3c4fc660d65.tar.xz manaserv-460a5bb2a9f57ddf9dbbd7095452c3c4fc660d65.zip |
Reorganized unit tests and initial release of the unit tests for the Storage class (to be completed).
-rw-r--r-- | src/dal/sqlitedataprovider.cpp | 4 | ||||
-rw-r--r-- | src/tests/testaccount.cpp (renamed from src/testaccount.cpp) | 1 | ||||
-rw-r--r-- | src/tests/testaccount.h (renamed from src/testaccount.h) | 2 | ||||
-rw-r--r-- | src/tests/testcipher.cpp (renamed from src/utils/testcipher.cpp) | 2 | ||||
-rw-r--r-- | src/tests/testcipher.h (renamed from src/utils/testcipher.h) | 0 | ||||
-rw-r--r-- | src/tests/testdataprovider.cpp (renamed from src/dal/testdataprovider.cpp) | 175 | ||||
-rw-r--r-- | src/tests/testdataprovider.h (renamed from src/dal/testdataprovider.h) | 44 | ||||
-rw-r--r-- | src/tests/testrecordset.cpp (renamed from src/dal/testrecordset.cpp) | 1 | ||||
-rw-r--r-- | src/tests/testrecordset.h (renamed from src/dal/testrecordset.h) | 14 | ||||
-rw-r--r-- | src/tests/testsmain.cpp (renamed from src/testsmain.cpp) | 21 | ||||
-rw-r--r-- | src/tests/teststorage.cpp | 310 | ||||
-rw-r--r-- | src/tests/teststorage.h | 132 |
12 files changed, 666 insertions, 40 deletions
diff --git a/src/dal/sqlitedataprovider.cpp b/src/dal/sqlitedataprovider.cpp index a9ed365d..00d8298c 100644 --- a/src/dal/sqlitedataprovider.cpp +++ b/src/dal/sqlitedataprovider.cpp @@ -91,6 +91,10 @@ SqLiteDataProvider::connect(const std::string& dbName, // the database after an unsuccessful call to sqlite3_open(). sqlite3_close(mDb); + // FIXME + // 21-Jun-2005: although we did invoke sqlite3_close(), there + // seems to be still a leak of 136 bytes here. + throw DbConnectionFailure(msg); } diff --git a/src/testaccount.cpp b/src/tests/testaccount.cpp index 0198ff13..a4061164 100644 --- a/src/testaccount.cpp +++ b/src/tests/testaccount.cpp @@ -65,6 +65,7 @@ AccountTest::tearDown(void) } delete mAccount; + mAccount = 0; } diff --git a/src/testaccount.h b/src/tests/testaccount.h index ee66bc9a..8806e766 100644 --- a/src/testaccount.h +++ b/src/tests/testaccount.h @@ -27,7 +27,7 @@ #include <cppunit/extensions/HelperMacros.h> -#include "account.h" +#include "../account.h" /** diff --git a/src/utils/testcipher.cpp b/src/tests/testcipher.cpp index 6d2c03d1..0c40fdf9 100644 --- a/src/utils/testcipher.cpp +++ b/src/tests/testcipher.cpp @@ -23,7 +23,7 @@ #include <string> -#include "cipher.h" +#include "../utils/cipher.h" #include "testcipher.h" diff --git a/src/utils/testcipher.h b/src/tests/testcipher.h index 7db81803..7db81803 100644 --- a/src/utils/testcipher.h +++ b/src/tests/testcipher.h diff --git a/src/dal/testdataprovider.cpp b/src/tests/testdataprovider.cpp index 08b66da8..06a2b0ee 100644 --- a/src/dal/testdataprovider.cpp +++ b/src/tests/testdataprovider.cpp @@ -21,7 +21,16 @@ */ -#include "dataproviderfactory.h" +#include <physfs.h> + +#if defined (MYSQL_SUPPORT) +#include <mysql/mysql.h> +#elif defined (POSTGRE_SUPPORT) +#include <libpq-fe.h> +#endif + +#include "../dal/dataproviderfactory.h" + #include "testdataprovider.h" @@ -29,6 +38,21 @@ CPPUNIT_TEST_SUITE_REGISTRATION(DataProviderTest); +// initialize the static variables. +std::string DataProviderTest::mDbName("tmwteststorage"); +std::string DataProviderTest::mDbUser("guest"); +std::string DataProviderTest::mDbPassword("guest"); +std::string DataProviderTest::mSqlCreateTable( + "create table employees (" + " id integer primary key, " + " name varchar(32) not null);" +); +std::string DataProviderTest::mSqlInsertRow( + "insert into employees values (1, 'john');" +); +std::string DataProviderTest::mSqlFetchRow("select * from employees;"); + + using namespace tmwserv::dal; @@ -38,6 +62,9 @@ using namespace tmwserv::dal; void DataProviderTest::setUp(void) { + // reinitialize the database before each test. + reinitDb(); + // obtain a data provider. try { mDb = DataProviderFactory::createDataProvider(); @@ -45,24 +72,6 @@ DataProviderTest::setUp(void) catch (const std::runtime_error& e) { CPPUNIT_FAIL(e.what()); } - - // init db info and account. -#ifdef SQLITE_SUPPORT - mDbName = "mydb.db"; -#else - mDbName = "mydb"; -#endif - mDbUser = "guest"; - mDbPassword = "guest"; - - // init SQL queries. - mSqlCreateTable = "create table employees ("; - mSqlCreateTable += " id int primary key, "; - mSqlCreateTable += " name varchar(32) not null);"; - - mSqlInsertRow = "insert into employees values (1, 'john');"; - - mSqlFetchRow = "select * from employees;"; } @@ -72,7 +81,13 @@ DataProviderTest::setUp(void) void DataProviderTest::tearDown(void) { + mDb->disconnect(); + delete mDb; + mDb = 0; + + // clean the database after each test. + reinitDb(); } @@ -82,7 +97,15 @@ DataProviderTest::tearDown(void) void DataProviderTest::testConnection1(void) { +#ifdef SQLITE_SUPPORT + std::string dbFile(mDbName); + dbFile += ".db"; + + mDb->connect(dbFile, mDbUser, mDbPassword); +#else mDb->connect(mDbName, mDbUser, mDbPassword); +#endif + CPPUNIT_ASSERT(mDb->isConnected()); } @@ -93,7 +116,15 @@ DataProviderTest::testConnection1(void) void DataProviderTest::testCreateTable1(void) { +#ifdef SQLITE_SUPPORT + std::string dbFile(mDbName); + dbFile += ".db"; + + mDb->connect(dbFile, mDbUser, mDbPassword); +#else mDb->connect(mDbName, mDbUser, mDbPassword); +#endif + CPPUNIT_ASSERT(mDb->isConnected()); const RecordSet& rs = mDb->execSql(mSqlCreateTable); @@ -110,11 +141,20 @@ DataProviderTest::testCreateTable1(void) void DataProviderTest::testCreateTable2(void) { +#ifdef SQLITE_SUPPORT + std::string dbFile(mDbName); + dbFile += ".db"; + + mDb->connect(dbFile, mDbUser, mDbPassword); +#else mDb->connect(mDbName, mDbUser, mDbPassword); +#endif + CPPUNIT_ASSERT(mDb->isConnected()); + mDb->execSql(mSqlCreateTable); // this should throw tmwserv::dal::DbSqlQueryExecFailure. - const RecordSet& rs = mDb->execSql(mSqlCreateTable); + mDb->execSql(mSqlCreateTable); } @@ -124,9 +164,19 @@ DataProviderTest::testCreateTable2(void) void DataProviderTest::testInsert1(void) { +#ifdef SQLITE_SUPPORT + std::string dbFile(mDbName); + dbFile += ".db"; + + mDb->connect(dbFile, mDbUser, mDbPassword); +#else mDb->connect(mDbName, mDbUser, mDbPassword); +#endif + CPPUNIT_ASSERT(mDb->isConnected()); + mDb->execSql(mSqlCreateTable); + const RecordSet& rs = mDb->execSql(mSqlInsertRow); // an insert query does not return any records // so the recordset remains empty. @@ -143,7 +193,15 @@ DataProviderTest::testInsert1(void) void DataProviderTest::testInsert2(void) { +#ifdef SQLITE_SUPPORT + std::string dbFile(mDbName); + dbFile += ".db"; + + mDb->connect(dbFile, mDbUser, mDbPassword); +#else mDb->connect(mDbName, mDbUser, mDbPassword); +#endif + CPPUNIT_ASSERT(mDb->isConnected()); // this should throw tmwserv::dal::DbSqlQueryExecFailure @@ -158,9 +216,20 @@ DataProviderTest::testInsert2(void) void DataProviderTest::testFetch1(void) { +#ifdef SQLITE_SUPPORT + std::string dbFile(mDbName); + dbFile += ".db"; + + mDb->connect(dbFile, mDbUser, mDbPassword); +#else mDb->connect(mDbName, mDbUser, mDbPassword); +#endif + CPPUNIT_ASSERT(mDb->isConnected()); + mDb->execSql(mSqlCreateTable); + mDb->execSql(mSqlInsertRow); + const RecordSet& rs = mDb->execSql(mSqlFetchRow); CPPUNIT_ASSERT(!rs.isEmpty()); @@ -180,7 +249,15 @@ DataProviderTest::testFetch1(void) void DataProviderTest::testDisconnection1(void) { +#ifdef SQLITE_SUPPORT + std::string dbFile(mDbName); + dbFile += ".db"; + + mDb->connect(dbFile, mDbUser, mDbPassword); +#else mDb->connect(mDbName, mDbUser, mDbPassword); +#endif + CPPUNIT_ASSERT(mDb->isConnected()); mDb->disconnect(); @@ -197,3 +274,61 @@ DataProviderTest::testDisconnection2(void) mDb->disconnect(); CPPUNIT_ASSERT(!mDb->isConnected()); } + + +/** + * Reinitialize the database. + */ +void +DataProviderTest::reinitDb(void) +{ + // we are not using DataProvider::execSql() to execute the SQL queries + // here as the class is the purpose of these tests. + +#if defined (MYSQL_SUPPORT) + { + // initialize the MySQL library. + MYSQL* db = mysql_init(NULL); + + if (!db) { + CPPUNIT_FAIL("unable to initialize the MySQL library: no memory"); + } + + // connect to the database. + if (!mysql_real_connect(db, + NULL, + mDbUser.c_str(), + mDbPassword.c_str(), + mDbName.c_str(), + 0, + NULL, + 0)) + { + CPPUNIT_FAIL(mysql_error(db)); + } + + // drop the table. + std::string sql("drop table employees;"); + if (mysql_query(db, sql.c_str()) != 0) { + // ignore, the table may not exist. + } + + // close the connection and free memory. + mysql_close(db); + mysql_library_end(); + db = 0; + } +#elif defined (POSTGRE_SUPPORT) + // TODO: drop tables. +#else // SQLITE_SUPPORT + std::string dbFile(mDbName); + dbFile += ".db"; + + // ensure that the database file does not exist. + if (PHYSFS_exists(dbFile.c_str())) { + if (PHYSFS_delete(dbFile.c_str()) == 0) { + CPPUNIT_FAIL(PHYSFS_getLastError()); + } + } +#endif +} diff --git a/src/dal/testdataprovider.h b/src/tests/testdataprovider.h index e677840a..1f0a082c 100644 --- a/src/dal/testdataprovider.h +++ b/src/tests/testdataprovider.h @@ -21,14 +21,26 @@ */ - #ifndef _TMWSERV_TEST_DATA_PROVIDER_H_ #define _TMWSERV_TEST_DATA_PROVIDER_H_ #include <cppunit/extensions/HelperMacros.h> -#include "dalexcept.h" +#include "../dal/dalexcept.h" +#include "../dal/dataprovider.h" + + +/** + * Requirements: + * - if using MySQL or PostgreSQL as backends, then make sure that a user + * named 'guest' with the password 'guest' has enough privileges to + * create tables and populate them in a database named 'tmwteststorage' + * prior to running the teststorage unit tests. + */ + + +using namespace tmwserv::dal; /** @@ -41,10 +53,9 @@ class DataProviderTest: public CppUnit::TestFixture // add tests to the test suite. CPPUNIT_TEST(testConnection1); CPPUNIT_TEST(testCreateTable1); - CPPUNIT_TEST_EXCEPTION(testCreateTable2, - tmwserv::dal::DbSqlQueryExecFailure); + CPPUNIT_TEST_EXCEPTION(testCreateTable2, DbSqlQueryExecFailure); CPPUNIT_TEST(testInsert1); - CPPUNIT_TEST_EXCEPTION(testInsert2, tmwserv::dal::DbSqlQueryExecFailure); + CPPUNIT_TEST_EXCEPTION(testInsert2, DbSqlQueryExecFailure); CPPUNIT_TEST(testFetch1); CPPUNIT_TEST(testDisconnection1); CPPUNIT_TEST(testDisconnection2); @@ -124,14 +135,21 @@ class DataProviderTest: public CppUnit::TestFixture private: - tmwserv::dal::DataProvider* mDb; /**< the data provider */ - std::string mDbName; /**< the database name */ - std::string mDbPath; /**< the database path */ - std::string mDbUser; /**< the database user */ - std::string mDbPassword; /**< the database password */ - std::string mSqlCreateTable; /**< SQL query to create table */ - std::string mSqlInsertRow; /**< SQL query to delete table */ - std::string mSqlFetchRow; /**< SQL query to fetch data */ + /** + * Reinitialize the database. + */ + void + reinitDb(void); + + + private: + DataProvider* mDb; /**< the data provider */ + static std::string mDbName; /**< the database name */ + static std::string mDbUser; /**< the database user */ + static std::string mDbPassword; /**< the database password */ + static std::string mSqlCreateTable; /**< SQL query to create table */ + static std::string mSqlInsertRow; /**< SQL query to delete table */ + static std::string mSqlFetchRow; /**< SQL query to fetch data */ }; diff --git a/src/dal/testrecordset.cpp b/src/tests/testrecordset.cpp index 3d8e928a..26a9e016 100644 --- a/src/dal/testrecordset.cpp +++ b/src/tests/testrecordset.cpp @@ -23,7 +23,6 @@ #include <sstream> -#include "recordset.h" #include "testrecordset.h" diff --git a/src/dal/testrecordset.h b/src/tests/testrecordset.h index 60b31137..66dc7117 100644 --- a/src/dal/testrecordset.h +++ b/src/tests/testrecordset.h @@ -27,7 +27,13 @@ #include <cppunit/extensions/HelperMacros.h> -#include "dalexcept.h" +#include <stdexcept> + +#include "../dal/dalexcept.h" +#include "../dal/recordset.h" + + +using namespace tmwserv::dal; /** @@ -54,7 +60,7 @@ class RecordSetTest: public CppUnit::TestFixture CPPUNIT_TEST(testOutputStream2); CPPUNIT_TEST(testAdd1); CPPUNIT_TEST_EXCEPTION(testAdd2, std::invalid_argument); - CPPUNIT_TEST_EXCEPTION(testAdd3, tmwserv::dal::RsColumnHeadersNotSet); + CPPUNIT_TEST_EXCEPTION(testAdd3, RsColumnHeadersNotSet); CPPUNIT_TEST_SUITE_END(); @@ -201,8 +207,8 @@ class RecordSetTest: public CppUnit::TestFixture private: - tmwserv::dal::RecordSet mEmptyRs; /**< empty recordset */ - tmwserv::dal::RecordSet mNonEmptyRs; /**< recordset with some data */ + RecordSet mEmptyRs; /**< empty recordset */ + RecordSet mNonEmptyRs; /**< recordset with some data */ }; diff --git a/src/testsmain.cpp b/src/tests/testsmain.cpp index 2f24cc48..70cdc185 100644 --- a/src/testsmain.cpp +++ b/src/tests/testsmain.cpp @@ -24,9 +24,27 @@ #include <cppunit/extensions/TestFactoryRegistry.h> #include <cppunit/ui/text/TextTestRunner.h> +#include <physfs.h> + + +/** + * Notes: + * - if the unit test application is linked to libsqlite3, there will + * be a memory leak (8 bytes) while no leaks are detected when linked + * to libmysqlclient. the leak was detected using Valgrind, an + * excellent memory debugger. + * + * TODO: check memory leak when linked to libpq (PostgreSQL). + */ + int main(int argc, char* argv[]) { + // initialize the PhysicsFS library. + PHYSFS_init(argv[0]); + PHYSFS_addToSearchPath(".", 1); + PHYSFS_setWriteDir("."); + using namespace CppUnit; // get the top level suite from the registry. @@ -39,6 +57,9 @@ int main(int argc, char* argv[]) // run the tests. bool wasSuccessful = runner.run(); + // denitialize the PhysicsFS library. + PHYSFS_deinit(); + // return error code 1 if the one of test failed. return wasSuccessful ? 0 : 1; } diff --git a/src/tests/teststorage.cpp b/src/tests/teststorage.cpp new file mode 100644 index 00000000..9757fdf3 --- /dev/null +++ b/src/tests/teststorage.cpp @@ -0,0 +1,310 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or any later version. + * + * The Mana World is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + + +#include <sstream> + +#include <physfs.h> + +#include "../utils/cipher.h" + +#include "../dalstoragesql.h" +#include "../storage.h" +#include "teststorage.h" + + +// register the fixture into the 'registry' +CPPUNIT_TEST_SUITE_REGISTRATION(StorageTest); + + +// initialization of static attributes. +std::string StorageTest::mStorageName("tmwteststorage"); +std::string StorageTest::mStorageUser("guest"); +std::string StorageTest::mStorageUserPassword("guest"); + + +using namespace tmwserv; + + +/** + * Set up fixtures. + */ +void +StorageTest::setUp(void) +{ + // reinitialize the storage before each test. + initStorage(); + + // create a storage. + Storage& myStorage = Storage::instance(mStorageName); + myStorage.setUser(mStorageUser); + myStorage.setPassword(mStorageUserPassword); + + // open the storage. + myStorage.open(); +} + + +/** + * Tear down fixtures. + */ +void +StorageTest::tearDown(void) +{ + // close the storage. + Storage& myStorage = Storage::instance(mStorageName); + myStorage.close(); + + // delete the storage. + Storage::destroy(); + + // clean the storage after each test. + cleanStorage(); +} + + +/** + * Fetch an existing account from the database. + */ +void +StorageTest::testGetAccount1(void) +{ + Storage& myStorage = Storage::instance(mStorageName); + + CPPUNIT_ASSERT(myStorage.isOpen()); + + Account* account = myStorage.getAccount("kindjal"); + + using namespace tmwserv::utils; + + std::string name("kindjal"); + std::string password(Cipher::instance().md5("kindjal")); + std::string email("kindjal@domain"); + + CPPUNIT_ASSERT(account != 0); + CPPUNIT_ASSERT_EQUAL(account->getName(), name); + CPPUNIT_ASSERT_EQUAL(account->getPassword(), password); + CPPUNIT_ASSERT_EQUAL(account->getEmail(), email); +} + + +/** + * Fetch an unexisting account from the database. + */ +void +StorageTest::testGetAccount2(void) +{ + Storage& myStorage = Storage::instance(mStorageName); + + if (!myStorage.isOpen()) { + CPPUNIT_FAIL("the storage is not opened."); + } + + Account* account = myStorage.getAccount("xxx"); + + CPPUNIT_ASSERT(account == 0); +} + + +/** + * Initialize the storage. + */ +void +StorageTest::initStorage(void) +{ +#if defined (MYSQL_SUPPORT) || defined (POSTGRE_SUPPORT) || \ + defined (SQLITE_SUPPORT) + + // we are using a database to persist the data from the storage. + + using namespace tmwserv::dal; + + // insert initial data using the data provider directly. + // we must avoid using the APIs from Storage here as it's the purpose + // of these tests. + std::auto_ptr<DataProvider> db(DataProviderFactory::createDataProvider()); + + try { +#ifdef SQLITE_SUPPORT + std::string dbFile(mStorageName); + dbFile += ".db"; + + // ensure that the file does not exist before the tests begin. + if (PHYSFS_exists(dbFile.c_str())) { + if (PHYSFS_delete(dbFile.c_str()) == 0) { + CPPUNIT_FAIL(PHYSFS_getLastError()); + } + } + + db->connect(dbFile, mStorageUser, mStorageUserPassword); +#else + db->connect(mStorageName, mStorageUser, mStorageUserPassword); +#endif + + // drop the tables. + dropTable(db, MAPS_TBL_NAME); + dropTable(db, ACCOUNTS_TBL_NAME); + dropTable(db, CHARACTERS_TBL_NAME); + dropTable(db, ITEMS_TBL_NAME); + dropTable(db, WORLD_ITEMS_TBL_NAME); + dropTable(db, INVENTORIES_TBL_NAME); + + // recreate the tables. + db->execSql(SQL_MAPS_TABLE); + db->execSql(SQL_ACCOUNTS_TABLE); + db->execSql(SQL_CHARACTERS_TABLE); + db->execSql(SQL_ITEMS_TABLE); + db->execSql(SQL_WORLD_ITEMS_TABLE); + db->execSql(SQL_INVENTORIES_TABLE); + + // populate the tables. + insertAccount(db, "kindjal"); + + db->disconnect(); + } + catch (const DbConnectionFailure& e) { + CPPUNIT_FAIL(e.what()); + } + catch (const DbSqlQueryExecFailure& e) { + CPPUNIT_FAIL(e.what()); + } + catch (const DbDisconnectionFailure& e) { + CPPUNIT_FAIL(e.what()); + } + catch (const std::exception& e) { + CPPUNIT_FAIL(e.what()); + } + catch (...) { + CPPUNIT_FAIL("unexpected exception"); + } +#else + // if we are in this block it means that we are not using a database + // to persist the data from the storage. + // at the moment, Storage assume that the data are persisted in a database + // so let's raise a preprocessing error. +#error "no database backend defined" +#endif +} + + +/** + * Clean the storage. + */ +void +StorageTest::cleanStorage(void) +{ +#if defined (MYSQL_SUPPORT) || defined (POSTGRE_SUPPORT) || \ + defined (SQLITE_SUPPORT) + + // we are using a database to persist the data from the storage. + + using namespace tmwserv::dal; + + std::auto_ptr<DataProvider> db(DataProviderFactory::createDataProvider()); + + try { +#ifdef SQLITE_SUPPORT + std::string dbFile(mStorageName); + dbFile += ".db"; + + // ensure that the file does not exist before the tests begin. + if (PHYSFS_exists(dbFile.c_str())) { + if (PHYSFS_delete(dbFile.c_str()) == 0) { + CPPUNIT_FAIL(PHYSFS_getLastError()); + } + } +#else + db->connect(mStorageName, mStorageUser, mStorageUserPassword); + + // drop the tables. + dropTable(db, MAPS_TBL_NAME); + dropTable(db, ACCOUNTS_TBL_NAME); + dropTable(db, CHARACTERS_TBL_NAME); + dropTable(db, ITEMS_TBL_NAME); + dropTable(db, WORLD_ITEMS_TBL_NAME); + dropTable(db, INVENTORIES_TBL_NAME); + + db->disconnect(); +#endif + } + catch (const DbConnectionFailure& e) { + CPPUNIT_FAIL(e.what()); + } + catch (const DbSqlQueryExecFailure& e) { + CPPUNIT_FAIL(e.what()); + } + catch (const DbDisconnectionFailure& e) { + CPPUNIT_FAIL(e.what()); + } + catch (const std::exception& e) { + CPPUNIT_FAIL(e.what()); + } + catch (...) { + CPPUNIT_FAIL("unexpected exception"); + } +#else + // if we are in this block it means that we are not using a database + // to persist the data from the storage. + // at the moment, Storage assume that the data are persisted in a database + // so let's raise a preprocessing error. +#error "no database backend defined" +#endif +} + + +/** + * Drop a table. + */ +void +StorageTest::dropTable(std::auto_ptr<DataProvider>& db, + const std::string& name) +{ + try { + std::string sql("drop table "); + sql += name; + sql += ";"; + db->execSql(sql); + } + catch (const DbSqlQueryExecFailure& e) { + // ignore, the table may not exist. + } +} + + +/** + * Insert a new account. + */ +void +StorageTest::insertAccount(std::auto_ptr<DataProvider>& db, + const std::string& name) +{ + std::ostringstream sql; + + // the password will be identical to the name. + + sql << "insert into " << ACCOUNTS_TBL_NAME + << "(username, password, email, level, banned) values " + << "('" << name << "', '" << name << "', '" + << name << "@domain', 1, 0);"; + + db->execSql(sql.str()); +} diff --git a/src/tests/teststorage.h b/src/tests/teststorage.h new file mode 100644 index 00000000..f8230735 --- /dev/null +++ b/src/tests/teststorage.h @@ -0,0 +1,132 @@ +/* + * The Mana World Server + * Copyright 2004 The Mana World Development Team + * + * This file is part of The Mana World. + * + * The Mana World is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or any later version. + * + * The Mana World is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with The Mana World; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id$ + */ + + +#ifndef _TMWSERV_TEST_STORAGE_H_ +#define _TMWSERV_TEST_STORAGE_H_ + + +#include <cppunit/extensions/HelperMacros.h> + +#include "../dal/dataproviderfactory.h" + + +/** + * Requirements: + * - if using MySQL or PostgreSQL as backends, then make sure that a user + * named 'guest' with the password 'guest' has enough privileges to + * create tables and populate them in a database named 'tmwteststorage' + * prior to running the teststorage unit tests. + */ + + +using namespace tmwserv::dal; + + +/** + * Unit test for the Storage class. + */ +class StorageTest: public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(StorageTest); + + // add tests to the test suite. + CPPUNIT_TEST(testGetAccount1); + CPPUNIT_TEST(testGetAccount2); + + CPPUNIT_TEST_SUITE_END(); + + + public: + /** + * Set up fixtures. + */ + void + setUp(void); + + + /** + * Tear down fixtures. + */ + void + tearDown(void); + + + /** + * Fetch an existing account from the database. + */ + void + testGetAccount1(void); + + + /** + * Fetch an unexisting account from the database. + */ + void + testGetAccount2(void); + + + private: + /** + * Initialize the storage. + */ + void + initStorage(void); + + + /** + * Clean the storage. + */ + void + cleanStorage(void); + + + /** + * Drop a table. + * + * @param db the database. + * @param name the table name. + */ + void + dropTable(std::auto_ptr<DataProvider>& db, + const std::string& name); + + + /** + * Insert a new account. + * + * @param db the database. + * @param name the user name. + */ + void + insertAccount(std::auto_ptr<DataProvider>&, + const std::string& name); + + + private: + static std::string mStorageName; + static std::string mStorageUser; + static std::string mStorageUserPassword; +}; + + +#endif // _TMWSERV_TEST_STORAGE_H_ |