OpenDNSSEC-enforcer
1.3.8
|
00001 /* 00002 * $Id: test_database.c 3811 2010-08-26 15:05:19Z jakob $ 00003 * 00004 * Copyright (c) 2008-2009 Nominet UK. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00019 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00020 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00021 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00023 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00024 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00025 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 */ 00028 00029 /*+ 00030 * test_database.c - Test Database Functions 00031 * 00032 * Description: 00033 * Tests the various database functions. 00034 * 00035 * There are no separate tests for connection and disconnection; of 00036 * necessity, the tests must connect to the database in order to run. 00037 * 00038 * N.B. The various environment variables to control database access must 00039 * be set before running this code - see "test_routines_database" for 00040 * details. 00041 -*/ 00042 00043 #include <stdlib.h> 00044 00045 #include "CUnit/Basic.h" 00046 00047 #include "ksm/database.h" 00048 #include "ksm/database_statement.h" 00049 #include "test_routines.h" 00050 00051 00052 /*+ 00053 * TestDbExecuteSql - Check Execution of SQL 00054 * 00055 * Description: 00056 * Executes an SQL statement but does not attempt to do anything else. 00057 * This just checks that the basic connection and execution is OK. 00058 -*/ 00059 00060 static void TestDbExecuteSql(void) 00061 { 00062 DB_RESULT result; /* Result object */ 00063 char* sql; /* Constructed query */ 00064 int status; /* Status return */ 00065 00066 sql = DqsCountInit("TEST_BASIC"); 00067 DqsEnd(&sql); 00068 status = DbExecuteSql(DbHandle(), sql, &result); 00069 CU_ASSERT_EQUAL(status, 0); 00070 DqsFree(sql); 00071 00072 DbFreeResult(result); 00073 00074 return; 00075 } 00076 00077 00078 /*+ 00079 * TestDatabaseAccess - Check Functions in database_access.c 00080 * 00081 * Description: 00082 * Executes an SQL query statement and accesses the result. This 00083 * checks more or less all the functions in database_access.c 00084 -*/ 00085 00086 static void TestDatabaseAccess(void) 00087 { 00088 DB_RESULT result; /* Result object */ 00089 DB_ROW row; /* Row object */ 00090 char* sql; /* Constructed query */ 00091 int status; /* Status return */ 00092 char* string; /* String from the row */ 00093 00094 sql = DqsInit("TEST_BASIC"); 00095 DqsOrderBy(&sql, "SVALUE"); 00096 DqsEnd(&sql); 00097 status = DbExecuteSql(DbHandle(), sql, &result); 00098 CU_ASSERT_EQUAL(status, 0); 00099 DqsFree(sql); 00100 00101 /* 00102 * Fetch each row and check the SVALUE field: 00103 * 00104 * The first fetch checks that the function copes with a NULL field. 00105 */ 00106 00107 status = DbFetchRow(result, &row); 00108 CU_ASSERT_EQUAL(status, 0); 00109 status = DbString(row, 2, &string); 00110 CU_ASSERT_EQUAL(status, 0); 00111 CU_ASSERT_PTR_NULL(string); 00112 DbFreeRow(row); 00113 00114 /* Second row */ 00115 00116 status = DbFetchRow(result, &row); 00117 CU_ASSERT_EQUAL(status, 0); 00118 status = DbString(row, 2, &string); 00119 CU_ASSERT_EQUAL(status, 0); 00120 CU_ASSERT_STRING_EQUAL(string, "ABC"); 00121 DbStringFree(string); 00122 DbFreeRow(row); 00123 00124 /* Last row */ 00125 00126 status = DbFetchRow(result, &row); 00127 CU_ASSERT_EQUAL(status, 0); 00128 status = DbString(row, 2, &string); 00129 CU_ASSERT_EQUAL(status, 0); 00130 CU_ASSERT_STRING_EQUAL(string, "DEF"); 00131 DbStringFree(string); 00132 DbFreeRow(row); 00133 00134 /* Fetch again should indicate end of file */ 00135 00136 status = DbFetchRow(result, &row); 00137 CU_ASSERT_EQUAL(status, -1); 00138 /* TODO put back 00139 CU_ASSERT_PTR_NULL(row); */ 00140 00141 /* Free up the result set */ 00142 00143 DbFreeResult(result); 00144 00145 return; 00146 } 00147 00148 00149 /*+ 00150 * TestDbExecuteSqlNoResult 00151 * 00152 * Description: 00153 * Tests the named function by adding a row to the table, and checking 00154 * that the insertion succeeded. 00155 -*/ 00156 00157 static void TestDbExecuteSqlNoResult(void) 00158 { 00159 int rowcount; /* Number of rows returned */ 00160 char* sql; /* Constructed query */ 00161 int status; /* Status return */ 00162 int where = 0; /* WHERE clause count */ 00163 00164 sql = DisInit("TEST_BASIC"); 00165 DisAppendInt(&sql, 400); 00166 DisAppendString(&sql, "GHI"); 00167 DisAppendString(&sql, NULL); 00168 DisEnd(&sql); 00169 status = DbExecuteSqlNoResult(DbHandle(), sql); 00170 CU_ASSERT_EQUAL(status, 0); 00171 DisFree(sql); 00172 00173 /* Check that our row got into the table */ 00174 00175 sql = DqsCountInit("TEST_BASIC"); 00176 DqsConditionInt(&sql, "IVALUE", DQS_COMPARE_EQ, 400, where++); 00177 DqsEnd(&sql); 00178 status = DbIntQuery(DbHandle(), &rowcount, sql); 00179 CU_ASSERT_EQUAL(status, 0); 00180 DqsFree(sql); 00181 00182 CU_ASSERT_EQUAL(rowcount, 1); 00183 00184 return; 00185 } 00186 00187 00188 /*+ 00189 * TestDbIntQuery - Check Integer Query 00190 * 00191 * Description: 00192 * Extracts a row from the database and extracts an integer field from it. 00193 * This test also checks DbInt(). 00194 -*/ 00195 00196 static void TestDbIntQuery(void) 00197 { 00198 int rowcount; /* Number of rows returned */ 00199 char* sql; /* Constructed query */ 00200 int status; /* Status return */ 00201 int where = 0; /* WHERE clause count */ 00202 00203 /* Check that only one row has IVALUE = 200 */ 00204 00205 sql = DqsCountInit("TEST_BASIC"); 00206 DqsConditionInt(&sql, "IVALUE", DQS_COMPARE_EQ, 200, where++); 00207 DqsEnd(&sql); 00208 status = DbIntQuery(DbHandle(), &rowcount, sql); 00209 DqsFree(sql); 00210 00211 CU_ASSERT_EQUAL(status, 0); 00212 00213 CU_ASSERT_EQUAL(rowcount, 1); 00214 00215 return; 00216 } 00217 00218 00219 /*+ 00220 * TestDbStringBuffer 00221 * 00222 * Description: 00223 * Tests DbStringBuffer by getting a known value into a user buffer. 00224 -*/ 00225 00226 static void TestDbStringBuffer(void) 00227 { 00228 char buffer[128]; /* User buffer */ 00229 DB_RESULT result; /* Result object */ 00230 DB_ROW row; /* Row object */ 00231 char* sql; /* Constructed query */ 00232 int status; /* Status return */ 00233 int where = 0; /* WHERE clause index */ 00234 00235 sql = DqsInit("TEST_BASIC"); 00236 DqsConditionString(&sql, "SVALUE", DQS_COMPARE_EQ, "ABC", where++); 00237 DqsEnd(&sql); 00238 status = DbExecuteSql(DbHandle(), sql, &result); 00239 CU_ASSERT_EQUAL(status, 0); 00240 DqsFree(sql); 00241 00242 /* Fetch the only row and get the value from the SVALUE field */ 00243 00244 status = DbFetchRow(result, &row); 00245 CU_ASSERT_EQUAL(status, 0); 00246 status = DbStringBuffer(row, 2, buffer, sizeof(buffer)); 00247 CU_ASSERT_EQUAL(status, 0); 00248 CU_ASSERT_STRING_EQUAL(buffer, "ABC"); 00249 DbFreeRow(row); 00250 00251 /* Fetch again should indicate end of file */ 00252 00253 status = DbFetchRow(result, &row); 00254 CU_ASSERT_EQUAL(status, -1); 00255 /* TODO put back 00256 CU_ASSERT_PTR_NULL(row); */ 00257 00258 /* Tidy up */ 00259 00260 DbFreeResult(result); 00261 00262 return; 00263 } 00264 00265 00266 /*+ 00267 * TestDbLastRowId - Check last Row ID 00268 * 00269 * Description: 00270 * Inserts two rows and checks that the row IDs differ by one. Doing the 00271 * test this way does not assume anything about what is currently in the 00272 * database. 00273 -*/ 00274 00275 static void TestDbLastRowId(void) 00276 { 00277 DB_ID first_id = 0; /* ID of first insertion */ 00278 DB_ID second_id = 0; /* ID of second insertion */ 00279 char* sql = NULL; /* SQL statement */ 00280 int status; /* Status return */ 00281 00282 /* Construct the insertion statement */ 00283 00284 sql = DisInit("TEST_BASIC"); 00285 CU_ASSERT_PTR_NOT_NULL(sql); 00286 00287 DisAppendInt(&sql, 500); 00288 DisAppendString(&sql, "XYZZY"); 00289 DisAppendString(&sql, "20090101"); 00290 DisEnd(&sql); 00291 00292 /* Insert and store row IDs */ 00293 00294 status = DbExecuteSqlNoResult(DbHandle(), sql); 00295 CU_ASSERT_EQUAL(status, 0); 00296 00297 status = DbLastRowId(DbHandle(), &first_id); 00298 CU_ASSERT_EQUAL(status, 0); 00299 CU_ASSERT_NOT_EQUAL(first_id, 0); 00300 00301 status = DbExecuteSqlNoResult(DbHandle(), sql); 00302 CU_ASSERT_EQUAL(status, 0); 00303 00304 status = DbLastRowId(DbHandle(), &second_id); 00305 CU_ASSERT_EQUAL(status, 0); 00306 CU_ASSERT_EQUAL(second_id, (first_id + 1)); 00307 00308 /* ... and tidy up */ 00309 00310 DisFree(sql); 00311 00312 return; 00313 00314 } 00315 00316 static void TestDbCommit(void) 00317 { 00318 int rowcount; /* Number of rows returned */ 00319 char* sql; /* Constructed query */ 00320 int status; /* Status return */ 00321 int where = 0; /* WHERE clause count */ 00322 00323 status = DbBeginTransaction(); 00324 CU_ASSERT_EQUAL(status, 0); 00325 00326 sql = DisInit("TEST_BASIC"); 00327 DisAppendInt(&sql, 600); 00328 DisAppendString(&sql, "JKL"); 00329 DisAppendString(&sql, NULL); 00330 DisEnd(&sql); 00331 status = DbExecuteSqlNoResult(DbHandle(), sql); 00332 CU_ASSERT_EQUAL(status, 0); 00333 DisFree(sql); 00334 00335 status = DbCommit(); 00336 CU_ASSERT_EQUAL(status, 0); 00337 00338 /* Check that our row got into the table */ 00339 00340 sql = DqsCountInit("TEST_BASIC"); 00341 DqsConditionInt(&sql, "IVALUE", DQS_COMPARE_EQ, 600, where++); 00342 DqsEnd(&sql); 00343 status = DbIntQuery(DbHandle(), &rowcount, sql); 00344 CU_ASSERT_EQUAL(status, 0); 00345 DqsFree(sql); 00346 00347 CU_ASSERT_EQUAL(rowcount, 1); 00348 00349 return; 00350 } 00351 00352 static void TestDbRollback(void) 00353 { 00354 int rowcount; /* Number of rows returned */ 00355 char* sql; /* Constructed query */ 00356 int status; /* Status return */ 00357 int where = 0; /* WHERE clause count */ 00358 00359 status = DbBeginTransaction(); 00360 CU_ASSERT_EQUAL(status, 0); 00361 00362 sql = DisInit("TEST_BASIC"); 00363 DisAppendInt(&sql, 700); 00364 DisAppendString(&sql, "MNO"); 00365 DisAppendString(&sql, NULL); 00366 DisEnd(&sql); 00367 status = DbExecuteSqlNoResult(DbHandle(), sql); 00368 CU_ASSERT_EQUAL(status, 0); 00369 DisFree(sql); 00370 00371 /* Check that our row got into the table */ 00372 sql = DqsCountInit("TEST_BASIC"); 00373 DqsConditionInt(&sql, "IVALUE", DQS_COMPARE_EQ, 700, where++); 00374 DqsEnd(&sql); 00375 status = DbIntQuery(DbHandle(), &rowcount, sql); 00376 CU_ASSERT_EQUAL(status, 0); 00377 CU_ASSERT_EQUAL(rowcount, 1); 00378 00379 /* Do the rollback */ 00380 status = DbRollback(); 00381 CU_ASSERT_EQUAL(status, 0); 00382 00383 /* Check that our row has now gone */ 00384 status = DbIntQuery(DbHandle(), &rowcount, sql); 00385 CU_ASSERT_EQUAL(status, 0); 00386 CU_ASSERT_EQUAL(rowcount, 0); 00387 DqsFree(sql); 00388 00389 return; 00390 } 00391 00392 00393 /*+ 00394 * TestDdb - Create Test Suite 00395 * 00396 * Description: 00397 * Adds the test suite to the CUnit test registry and adds all the tests 00398 * to it. 00399 * 00400 * Arguments: 00401 * None. 00402 * 00403 * Returns: 00404 * int 00405 * Return status. 0 => Success. 00406 */ 00407 00408 int TestDb(void); /* Declaration */ 00409 int TestDb(void) 00410 { 00411 struct test_testdef tests[] = { 00412 {"TestDbExecuteSql", TestDbExecuteSql}, 00413 {"TestDatabaseAccess", TestDatabaseAccess}, 00414 {"TestDbExecuteSqlNoResult", TestDbExecuteSqlNoResult}, 00415 {"TestDbIntQuery", TestDbIntQuery}, 00416 {"TestDbStringBuffer", TestDbStringBuffer}, 00417 {"TestDbLastRowId", TestDbLastRowId}, 00418 {"TestDbCommit", TestDbCommit}, 00419 {"TestDbRollback", TestDbRollback}, 00420 {NULL, NULL} 00421 }; 00422 00423 return TcuCreateSuite("Db", TdbSetup, TdbTeardown, tests); 00424 }