2
* See the file LICENSE for redistribution information.
4
* Copyright (c) 2000-2002
5
* Sleepycat Software. All rights reserved.
11
* Do some regression tests for constructors.
12
* Run normally (without arguments) it is a simple regression test.
13
* Run with a numeric argument, it repeats the regression a number
14
* of times, to try to determine if there are memory leaks.
17
#ifndef NO_SYSTEM_INCLUDES
18
#include <sys/types.h>
34
cout << "FAIL: " << (a) << "\n"; sysexit(1); \
39
cout << "FAIL: " << (a1) << ": " << (a2) << "\n"; sysexit(1); \
42
#define ERR3(a1,a2,a3) \
44
cout << "FAIL: " << (a1) << ": " << (a2) << ": " << (a3) << "\n"; sysexit(1); \
50
if ((_ret = (a)) != 0) { \
51
ERR3("DB function " #a " has bad return", _ret, DbEnv::strerror(_ret)); \
56
#define DEBUGOUT(a) cout << a << "\n"
61
#define CONSTRUCT01_DBNAME "construct01.db"
62
#define CONSTRUCT01_DBDIR "."
63
#define CONSTRUCT01_DBFULLPATH (CONSTRUCT01_DBDIR "/" CONSTRUCT01_DBNAME)
65
int itemcount; // count the number of items in the database
67
// A good place to put a breakpoint...
69
void sysexit(int status)
74
void check_file_removed(const char *name, int fatal)
78
if (access(name, 0) == 0) {
81
cout << "File \"" << name << "\" still exists after run\n";
88
// Check that key/data for 0 - count-1 are already present,
89
// and write a key/data for count. The key and data are
90
// both "0123...N" where N == count-1.
92
// For some reason on Windows, we need to open using the full pathname
93
// of the file when there is no environment, thus the 'has_env'
96
void rundb(Db *db, int count, int has_env)
101
name = CONSTRUCT01_DBNAME;
103
name = CONSTRUCT01_DBFULLPATH;
105
db->set_error_stream(&cerr);
107
// We don't really care about the pagesize, but we do want
108
// to make sure adjusting Db specific variables works before
111
CHK(db->set_pagesize(1024));
112
CHK(db->open(NULL, name, NULL, DB_BTREE, count ? 0 : DB_CREATE, 0664));
114
// The bit map of keys we've seen
117
// The bit map of keys we expect to see
118
long expected = (1 << (count+1)) - 1;
122
for (i=0; i<count; i++) {
129
DEBUGOUT("Put: " << outbuf);
130
CHK(db->put(0, &key, &data, DB_NOOVERWRITE));
132
// Acquire a cursor for the table.
134
CHK(db->cursor(NULL, &dbcp, 0));
136
// Walk through the table, checking
139
while (dbcp->get(&readkey, &readdata, DB_NEXT) == 0) {
140
char *key_string = (char *)readkey.get_data();
141
char *data_string = (char *)readdata.get_data();
142
DEBUGOUT("Got: " << key_string << ": " << data_string);
143
int len = strlen(key_string);
144
long bit = (1 << len);
146
ERR("reread length is bad");
148
else if (strcmp(data_string, key_string) != 0) {
149
ERR("key/data don't match");
151
else if ((bitmap & bit) != 0) {
152
ERR("key already seen");
154
else if ((expected & bit) == 0) {
155
ERR("key was not expected");
160
for (i=0; i<len; i++) {
161
if (key_string[i] != ('0' + i)) {
162
cout << " got " << key_string
163
<< " (" << (int)key_string[i] << ")"
165
<< " (" << (int)('0' + i) << ")"
166
<< " at position " << i << "\n";
167
ERR("key is corrupt");
173
cout << " expected more keys, bitmap is: " << expected << "\n";
174
ERR("missing keys in database");
180
void t1(int except_flag)
182
cout << " Running test 1:\n";
183
Db db(0, except_flag);
184
rundb(&db, itemcount++, 0);
185
cout << " finished.\n";
188
void t2(int except_flag)
190
cout << " Running test 2:\n";
191
Db db(0, except_flag);
192
rundb(&db, itemcount++, 0);
193
cout << " finished.\n";
196
void t3(int except_flag)
198
cout << " Running test 3:\n";
199
Db db(0, except_flag);
200
rundb(&db, itemcount++, 0);
201
cout << " finished.\n";
204
void t4(int except_flag)
206
cout << " Running test 4:\n";
207
DbEnv env(except_flag);
208
CHK(env.open(CONSTRUCT01_DBDIR, DB_CREATE | DB_INIT_MPOOL, 0));
212
cout << " finished.\n";
215
void t5(int except_flag)
217
cout << " Running test 5:\n";
218
DbEnv env(except_flag);
219
CHK(env.open(CONSTRUCT01_DBDIR, DB_CREATE | DB_INIT_MPOOL, 0));
221
rundb(&db, itemcount++, 1);
222
// Note we cannot reuse the old Db!
223
Db anotherdb(&env, 0);
225
anotherdb.set_errpfx("test5");
226
rundb(&anotherdb, itemcount++, 1);
228
cout << " finished.\n";
231
void t6(int except_flag)
233
cout << " Running test 6:\n";
235
/* From user [#2939] */
238
DbEnv* penv = new DbEnv(DB_CXX_NO_EXCEPTIONS);
239
penv->set_cachesize(0, 32 * 1024, 0);
240
penv->open(CONSTRUCT01_DBDIR, DB_CREATE | DB_PRIVATE | DB_INIT_MPOOL, 0);
242
//LEAK: remove this block and leak disappears
243
Db* pdb = new Db(penv,0);
244
if ((err = pdb->close(0)) != 0) {
245
fprintf(stderr, "Error closing Db: %s\n", db_strerror(err));
248
//LEAK: remove this block and leak disappears
250
if ((err = penv->close(0)) != 0) {
251
fprintf(stderr, "Error closing DbEnv: %s\n", db_strerror(err));
255
// Make sure we get a message from C++ layer reminding us to close.
256
cerr << "expected error: ";
258
DbEnv foo(DB_CXX_NO_EXCEPTIONS);
259
foo.open(CONSTRUCT01_DBDIR, DB_CREATE, 0);
261
cerr << "should have received error.\n";
262
cout << " finished.\n";
265
// remove any existing environment or database
269
DbEnv tmpenv(DB_CXX_NO_EXCEPTIONS);
270
(void)tmpenv.remove(CONSTRUCT01_DBDIR, DB_FORCE);
273
check_file_removed(CONSTRUCT01_DBFULLPATH, 1);
274
for (int i=0; i<8; i++) {
276
sprintf(buf, "__db.00%d", i);
277
check_file_removed(buf, 1);
281
int doall(int except_flag)
285
// before and after the run, removing any
286
// old environment/database.
299
catch (DbException &dbe) {
300
ERR2("EXCEPTION RECEIVED", dbe.what());
305
int main(int argc, char *argv[])
309
iterations = atoi(argv[1]);
310
if (iterations < 0) {
311
ERR("Usage: construct01 count");
314
for (int i=0; i<iterations; i++) {
315
if (iterations != 0) {
316
cout << "(" << i << "/" << iterations << ") ";
318
cout << "construct01 running:\n";
319
if (doall(DB_CXX_NO_EXCEPTIONS) != 0) {
320
ERR("SOME TEST FAILED FOR NO-EXCEPTION TEST");
322
else if (doall(0) != 0) {
323
ERR("SOME TEST FAILED FOR EXCEPTION TEST");
326
cout << "\nALL TESTS SUCCESSFUL\n";