00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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;
00066
00067
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
00089
00090
00091
00092
00093
00094
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
00108
00109
00110
00111 CHK(db->set_pagesize(1024));
00112 CHK(db->open(NULL, name, NULL, DB_BTREE, count ? 0 : DB_CREATE, 0664));
00113
00114
00115 long bitmap = 0;
00116
00117
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
00133 Dbc *dbcp;
00134 CHK(db->cursor(NULL, &dbcp, 0));
00135
00136
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
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
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
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
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
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
00279
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 }