1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 // vim: ft=cpp:expandtab:ts=8:sw=4:softtabstop=4:
3 #ident "$Id$"
4 /*======
5 This file is part of PerconaFT.
6 
7 
8 Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved.
9 
10     PerconaFT is free software: you can redistribute it and/or modify
11     it under the terms of the GNU General Public License, version 2,
12     as published by the Free Software Foundation.
13 
14     PerconaFT is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18 
19     You should have received a copy of the GNU General Public License
20     along with PerconaFT.  If not, see <http://www.gnu.org/licenses/>.
21 
22 ----------------------------------------
23 
24     PerconaFT is free software: you can redistribute it and/or modify
25     it under the terms of the GNU Affero General Public License, version 3,
26     as published by the Free Software Foundation.
27 
28     PerconaFT is distributed in the hope that it will be useful,
29     but WITHOUT ANY WARRANTY; without even the implied warranty of
30     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31     GNU Affero General Public License for more details.
32 
33     You should have received a copy of the GNU Affero General Public License
34     along with PerconaFT.  If not, see <http://www.gnu.org/licenses/>.
35 ======= */
36 
37 #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved."
38 
39 // test txn commit after db close
40 
41 #include "test.h"
42 #include <sys/stat.h>
43 
44 DB_ENV *null_env = NULL;
45 DB *null_db = NULL;
46 DB_TXN *null_txn = NULL;
47 DBC *null_cursor = NULL;
48 int constant = 0;
49 
root_fifo_verify(DB_ENV * env,int n)50 static void root_fifo_verify(DB_ENV *env, int n) {
51     if (verbose) printf("%s:%d %d\n", __FUNCTION__, __LINE__, n);
52     int r;
53 
54     DB_TXN *txn = null_txn;
55     r = env->txn_begin(env, null_txn, &txn, 0); assert(r == 0); assert(txn != NULL);
56 
57     DB *db = null_db;
58     r = db_create(&db, env, 0); assert(r == 0); assert(db != NULL);
59     r = db->open(db, txn, "test.db", 0, DB_BTREE, DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO);
60     assert(r == 0);
61 
62     DBC *cursor = null_cursor;
63     r = db->cursor(db, txn, &cursor, 0); assert(r == 0);
64     int i;
65     for (i = 0; ; i++) {
66         DBT key, val;
67         memset(&key, 0, sizeof key); memset(&val, 0, sizeof val);
68         r = cursor->c_get(cursor, &key, &val, DB_NEXT);
69         if (r != 0) break;
70         int k;
71         assert(key.size == sizeof k);
72         memcpy(&k, key.data, key.size);
73         assert((int)toku_ntohl(k) == i);
74     }
75     if (constant)
76         assert(i==1);
77     else
78         assert(i == n);
79 
80     r = cursor->c_close(cursor); assert(r == 0); cursor = null_cursor;
81 
82     r = txn->commit(txn, 0); assert(r == 0); txn = null_txn;
83 
84     r = db->close(db, 0); assert(r == 0); db = null_db;
85 }
86 
root_fifo_1(int n,int create_outside)87 static void root_fifo_1(int n, int create_outside) {
88     if (verbose) printf("%s:%d %d\n", __FUNCTION__, __LINE__, n);
89     int r;
90 
91     // create the env
92     toku_os_recursive_delete(TOKU_TEST_FILENAME);
93     toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU+S_IRWXG+S_IRWXO);
94 
95     DB_ENV *env = null_env;
96     r = db_env_create(&env, 0); assert(r == 0); assert(env != NULL);
97     r = env->open(env,
98                   TOKU_TEST_FILENAME,
99                   DB_INIT_MPOOL+DB_INIT_LOG+DB_INIT_LOCK+DB_INIT_TXN+DB_PRIVATE+DB_CREATE,
100                   S_IRWXU+S_IRWXG+S_IRWXO);
101     assert(r == 0);
102 
103     if (create_outside) {
104         DB_TXN *txn_open = null_txn;
105         r = env->txn_begin(env, null_txn, &txn_open, 0); assert(r == 0); assert(txn_open != NULL);
106         DB *db_open = null_db;
107         r = db_create(&db_open, env, 0); assert(r == 0); assert(db_open != NULL);
108         r = db_open->open(db_open, txn_open, "test.db", 0, DB_BTREE, DB_CREATE|DB_EXCL, S_IRWXU+S_IRWXG+S_IRWXO);
109         assert(r == 0);
110         r = db_open->close(db_open, 0); assert(r == 0); db_open = null_db;
111         r = txn_open->commit(txn_open, 0); assert(r == 0); txn_open = null_txn;
112     }
113     DB_TXN *txn = null_txn;
114     r = env->txn_begin(env, null_txn, &txn, 0); assert(r == 0); assert(txn != NULL);
115 
116     int i;
117     for (i=0; i<n; i++) {
118         if (verbose>1) {
119             printf("%s-%s:%d   %d\n", __FILE__, __FUNCTION__, __LINE__, i);
120         }
121         DB *db = null_db;
122         r = db_create(&db, env, 0); assert(r == 0); assert(db != NULL);
123 
124         r = db->open(db, txn, "test.db", 0, DB_BTREE, DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO);
125         assert(r == 0);
126 
127         DBT key, val;
128         int k = toku_htonl(i);
129         int v = i;
130         if (constant) {
131             k = v = 0;
132         }
133         r = db->put(db, txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0);
134         assert(r == 0);
135 
136         r = db->close(db, 0); assert(r == 0); db = null_db;
137     }
138 
139     r = txn->commit(txn, 0); assert(r == 0); txn = null_txn;
140 
141     // verify the db
142     root_fifo_verify(env, n);
143 
144     // cleanup
145     r = env->close(env, 0); assert(r == 0); env = null_env;
146 }
147 
test_main(int argc,char * const argv[])148 int test_main(int argc, char *const argv[]) {
149     int i;
150     int n = -1;
151 
152     // parse_args(argc, argv);
153     for (i = 1; i < argc; i++) {
154         if (strcmp(argv[i], "-v") == 0) {
155             verbose++;
156             continue;
157         }
158         if (strcmp(argv[i], "-n") == 0) {
159             if (i+1 < argc)
160                 n = atoi(argv[++i]);
161             continue;
162         }
163         if (strcmp(argv[i], "-q") == 0) {
164             verbose--;
165             if (verbose<0) verbose = 0;
166             continue;
167         }
168         if (strcmp(argv[i], "-c") == 0) {
169             constant = 1;
170             continue;
171         }
172     }
173 
174     if (n >= 0) {
175         root_fifo_1(n, 0);
176         root_fifo_1(n, 1);
177     }
178     else
179         for (i=0; i<100; i++) {
180             root_fifo_1(i, 0);
181             root_fifo_1(i, 1);
182         }
183     return 0;
184 }
185 
186