Main Page | Class Hierarchy | Data Structures | Directories | File List | Data Fields | Related Pages

TestConstruct01.cpp

00001 /*-
00002  * See the file LICENSE for redistribution information.
00003  *
00004  * Copyright (c) 2000-2005
00005  *      Sleepycat Software.  All rights reserved.
00006  *
00007  * $Id: TestConstruct01.cpp,v 12.1 2005/06/16 20:24:11 bostic Exp $
00008  */
00009 
00010 /*
00011  * Do some regression tests for constructors.
00012  * Run normally (without arguments) it is a simple regression test.
00013  * Run with a numeric argument, it repeats the regression a number
00014  * of times, to try to determine if there are memory leaks.
00015  */
00016 
00017 #ifndef NO_SYSTEM_INCLUDES
00018 #include <sys/types.h>
00019 
00020 #include <iostream.h>
00021 #include <errno.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #ifndef _MSC_VER
00025 #include <unistd.h>
00026 #endif
00027 #endif
00028 
00029 #include <iomanip.h>
00030 #include <db_cxx.h>
00031 
00032 #define ERR(a)  \
00033     do { \
00034       cout << "FAIL: " << (a) << "\n"; sysexit(1); \
00035     } while (0)
00036 
00037 #define ERR2(a1,a2)  \
00038     do { \
00039       cout << "FAIL: " << (a1) << ": " << (a2) << "\n"; sysexit(1); \
00040     } while (0)
00041 
00042 #define ERR3(a1,a2,a3)  \
00043     do { \
00044       cout << "FAIL: " << (a1) << ": " << (a2) << ": " << (a3) << "\n"; sysexit(1); \
00045     } while (0)
00046 
00047 #define CHK(a)   \
00048     do { \
00049       int _ret; \
00050       if ((_ret = (a)) != 0) { \
00051          ERR3("DB function " #a " has bad return", _ret, DbEnv::strerror(_ret)); \
00052       } \
00053     } while (0)
00054 
00055 #ifdef VERBOSE
00056 #define DEBUGOUT(a)          cout << a << "\n"
00057 #else
00058 #define DEBUGOUT(a)
00059 #endif
00060 
00061 #define CONSTRUCT01_DBNAME         "construct01.db"
00062 #define CONSTRUCT01_DBDIR          "."
00063 #define CONSTRUCT01_DBFULLPATH     (CONSTRUCT01_DBDIR "/" CONSTRUCT01_DBNAME)
00064 
00065 int itemcount;                  // count the number of items in the database
00066 
00067 // A good place to put a breakpoint...
00068 //
00069 void sysexit(int status)
00070 {
00071         exit(status);
00072 }
00073 
00074 void check_file_removed(const char *name, int fatal)
00075 {
00076         unlink(name);
00077 #if 0
00078         if (access(name, 0) == 0) {
00079                 if (fatal)
00080                         cout << "FAIL: ";
00081                 cout << "File \"" << name << "\" still exists after run\n";
00082                 if (fatal)
00083                         sysexit(1);
00084         }
00085 #endif
00086 }
00087 
00088 // Check that key/data for 0 - count-1 are already present,
00089 // and write a key/data for count.  The key and data are
00090 // both "0123...N" where N == count-1.
00091 //
00092 // For some reason on Windows, we need to open using the full pathname
00093 // of the file when there is no environment, thus the 'has_env'
00094 // variable.
00095 //
00096 void rundb(Db *db, int count, int has_env)
00097 {
00098         const char *name;
00099 
00100         if (has_env)
00101                 name = CONSTRUCT01_DBNAME;
00102         else
00103                 name = CONSTRUCT01_DBFULLPATH;
00104 
00105         db->set_error_stream(&cerr);
00106 
00107         // We don't really care about the pagesize, but we do want
00108         // to make sure adjusting Db specific variables works before
00109         // opening the db.
00110         //
00111         CHK(db->set_pagesize(1024));
00112         CHK(db->open(NULL, name, NULL, DB_BTREE, count ? 0 : DB_CREATE, 0664));
00113 
00114         // The bit map of keys we've seen
00115         long bitmap = 0;
00116 
00117         // The bit map of keys we expect to see
00118         long expected = (1 << (count+1)) - 1;
00119 
00120         char outbuf[10];
00121         int i;
00122         for (i=0; i<count; i++) {
00123                 outbuf[i] = '0' + i;
00124         }
00125         outbuf[i++] = '\0';
00126         Dbt key(outbuf, i);
00127         Dbt data(outbuf, i);
00128 
00129         DEBUGOUT("Put: " << outbuf);
00130         CHK(db->put(0, &key, &data, DB_NOOVERWRITE));
00131 
00132         // Acquire a cursor for the table.
00133         Dbc *dbcp;
00134         CHK(db->cursor(NULL, &dbcp, 0));
00135 
00136         // Walk through the table, checking
00137         Dbt readkey;
00138         Dbt readdata;
00139         while (dbcp->get(&readkey, &readdata, DB_NEXT) == 0) {
00140                 char *key_string = (char *)readkey.get_data();
00141                 char *data_string = (char *)readdata.get_data();
00142                 DEBUGOUT("Got: " << key_string << ": " << data_string);
00143                 int len = strlen(key_string);
00144                 long bit = (1 << len);
00145                 if (len > count) {
00146                         ERR("reread length is bad");
00147                 }
00148                 else if (strcmp(data_string, key_string) != 0) {
00149                         ERR("key/data don't match");
00150                 }
00151                 else if ((bitmap & bit) != 0) {
00152                         ERR("key already seen");
00153                 }
00154                 else if ((expected & bit) == 0) {
00155                         ERR("key was not expected");
00156                 }
00157                 else {
00158                         bitmap |= bit;
00159                         expected &= ~(bit);
00160                         for (i=0; i<len; i++) {
00161                                 if (key_string[i] != ('0' + i)) {
00162                                         cout << " got " << key_string
00163                                              << " (" << (int)key_string[i] << ")"
00164                                              << ", wanted " << i
00165                                              << " (" << (int)('0' + i) << ")"
00166                                              << " at position " << i << "\n";
00167                                         ERR("key is corrupt");
00168                                 }
00169                         }
00170                 }
00171         }
00172         if (expected != 0) {
00173                 cout << " expected more keys, bitmap is: " << expected << "\n";
00174                 ERR("missing keys in database");
00175         }
00176         CHK(dbcp->close());
00177         CHK(db->close(0));
00178 }
00179 
00180 void t1(int except_flag)
00181 {
00182         cout << "  Running test 1:\n";
00183         Db db(0, except_flag);
00184         rundb(&db, itemcount++, 0);
00185         cout << "  finished.\n";
00186 }
00187 
00188 void t2(int except_flag)
00189 {
00190         cout << "  Running test 2:\n";
00191         Db db(0, except_flag);
00192         rundb(&db, itemcount++, 0);
00193         cout << "  finished.\n";
00194 }
00195 
00196 void t3(int except_flag)
00197 {
00198         cout << "  Running test 3:\n";
00199         Db db(0, except_flag);
00200         rundb(&db, itemcount++, 0);
00201         cout << "  finished.\n";
00202 }
00203 
00204 void t4(int except_flag)
00205 {
00206         cout << "  Running test 4:\n";
00207         DbEnv env(except_flag);
00208         CHK(env.open(CONSTRUCT01_DBDIR, DB_CREATE | DB_INIT_MPOOL, 0));
00209         Db db(&env, 0);
00210         CHK(db.close(0));
00211         CHK(env.close(0));
00212         cout << "  finished.\n";
00213 }
00214 
00215 void t5(int except_flag)
00216 {
00217         cout << "  Running test 5:\n";
00218         DbEnv env(except_flag);
00219         CHK(env.open(CONSTRUCT01_DBDIR, DB_CREATE | DB_INIT_MPOOL, 0));
00220         Db db(&env, 0);
00221         rundb(&db, itemcount++, 1);
00222         // Note we cannot reuse the old Db!
00223         Db anotherdb(&env, 0);
00224 
00225         anotherdb.set_errpfx("test5");
00226         rundb(&anotherdb, itemcount++, 1);
00227         CHK(env.close(0));
00228         cout << "  finished.\n";
00229 }
00230 
00231 void t6(int except_flag)
00232 {
00233         cout << "  Running test 6:\n";
00234 
00235         /* From user [#2939] */
00236         int err;
00237 
00238         DbEnv* penv = new DbEnv(DB_CXX_NO_EXCEPTIONS);
00239         penv->set_cachesize(0, 32 * 1024, 0);
00240         penv->open(CONSTRUCT01_DBDIR, DB_CREATE | DB_PRIVATE | DB_INIT_MPOOL, 0);
00241 
00242         //LEAK: remove this block and leak disappears
00243         Db* pdb = new Db(penv,0);
00244         if ((err = pdb->close(0)) != 0) {
00245                 fprintf(stderr, "Error closing Db: %s\n", db_strerror(err));
00246         }
00247         delete pdb;
00248         //LEAK: remove this block and leak disappears
00249 
00250         if ((err = penv->close(0)) != 0) {
00251                 fprintf(stderr, "Error closing DbEnv: %s\n", db_strerror(err));
00252         }
00253         delete penv;
00254 
00255         cout << "  finished.\n";
00256 }
00257 
00258 // remove any existing environment or database
00259 void removeall()
00260 {
00261     {
00262         DbEnv tmpenv(DB_CXX_NO_EXCEPTIONS);
00263         (void)tmpenv.remove(CONSTRUCT01_DBDIR, DB_FORCE);
00264     }
00265 
00266         check_file_removed(CONSTRUCT01_DBFULLPATH, 1);
00267         for (int i=0; i<8; i++) {
00268                 char buf[20];
00269                 sprintf(buf, "__db.00%d", i);
00270                 check_file_removed(buf, 1);
00271         }
00272 }
00273 
00274 int doall(int except_flag)
00275 {
00276         itemcount = 0;
00277         try {
00278                 // before and after the run, removing any
00279                 // old environment/database.
00280                 //
00281                 removeall();
00282                 t1(except_flag);
00283                 t2(except_flag);
00284                 t3(except_flag);
00285                 t4(except_flag);
00286                 t5(except_flag);
00287                 t6(except_flag);
00288 
00289                 removeall();
00290                 return 0;
00291         }
00292         catch (DbException &dbe) {
00293                 ERR2("EXCEPTION RECEIVED", dbe.what());
00294         }
00295         return 1;
00296 }
00297 
00298 int main(int argc, char *argv[])
00299 {
00300         int iterations = 1;
00301         if (argc > 1) {
00302                 iterations = atoi(argv[1]);
00303                 if (iterations < 0) {
00304                         ERR("Usage:  construct01 count");
00305                 }
00306         }
00307         for (int i=0; i<iterations; i++) {
00308                 if (iterations != 0) {
00309                         cout << "(" << i << "/" << iterations << ") ";
00310                 }
00311                 cout << "construct01 running:\n";
00312                 if (doall(DB_CXX_NO_EXCEPTIONS) != 0) {
00313                         ERR("SOME TEST FAILED FOR NO-EXCEPTION TEST");
00314                 }
00315                 else if (doall(0) != 0) {
00316                         ERR("SOME TEST FAILED FOR EXCEPTION TEST");
00317                 }
00318                 else {
00319                         cout << "\nALL TESTS SUCCESSFUL\n";
00320                 }
00321         }
00322         return 0;
00323 }

Generated on Sun Dec 25 12:14:52 2005 for Berkeley DB 4.4.16 by  doxygen 1.4.2