/* * 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 #if defined (MYSQL_SUPPORT) #include #elif defined (POSTGRE_SUPPORT) #include #endif #include "../dal/dataproviderfactory.h" #include "../utils/logger.h" #include "testdataprovider.h" // register the fixture into the 'registry' 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; /** * Set up fixtures. */ void DataProviderTest::setUp(void) { // reinitialize the database before each test. reinitDb(); // obtain a data provider. try { mDb = DataProviderFactory::createDataProvider(); } catch (const std::runtime_error& e) { CPPUNIT_FAIL(e.what()); } } /** * Tear down fixtures. */ void DataProviderTest::tearDown(void) { mDb->disconnect(); delete mDb; mDb = 0; // clean the database after each test. reinitDb(); } /** * Connection to an existing database. */ void DataProviderTest::testConnection1(void) { LOG("DataProviderTest::testConnection1()"); #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()); } /** * Create a new table in the database. */ void DataProviderTest::testCreateTable1(void) { LOG("DataProviderTest::testCreateTable1()"); #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); CPPUNIT_ASSERT(rs.isEmpty()); mDb->disconnect(); CPPUNIT_ASSERT(!mDb->isConnected()); } /** * Create the same table one more time in the database. */ void DataProviderTest::testCreateTable2(void) { LOG("DataProviderTest::testCreateTable2()"); #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. mDb->execSql(mSqlCreateTable); } /** * Insert a new row to the table. */ void DataProviderTest::testInsert1(void) { LOG("DataProviderTest::testInsert1()"); #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. CPPUNIT_ASSERT(rs.isEmpty()); mDb->disconnect(); CPPUNIT_ASSERT(!mDb->isConnected()); } /** * Insert the same record again. */ void DataProviderTest::testInsert2(void) { LOG("DataProviderTest::testInsert2()"); #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 // as we are violating the primary key uniqueness. mDb->execSql(mSqlInsertRow); } /** * Fetch data from the table. */ void DataProviderTest::testFetch1(void) { LOG("DataProviderTest::testFetch1()"); #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()); std::string id("1"); std::string name("john"); CPPUNIT_ASSERT_EQUAL(id, rs(0, "id")); CPPUNIT_ASSERT_EQUAL(name, rs(0, "name")); mDb->disconnect(); CPPUNIT_ASSERT(!mDb->isConnected()); } /** * Disconnection from an open database. */ void DataProviderTest::testDisconnection1(void) { LOG("DataProviderTest::testDisconnection1()"); #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(); CPPUNIT_ASSERT(!mDb->isConnected()); } /** * Disconnection from a closed database. */ void DataProviderTest::testDisconnection2(void) { LOG("DataProviderTest::testDisconnection2()"); 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 }