summaryrefslogtreecommitdiff
path: root/src/tests/teststorage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/teststorage.cpp')
-rw-r--r--src/tests/teststorage.cpp310
1 files changed, 310 insertions, 0 deletions
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());
+}