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
create_non_empty(int n)49 static void create_non_empty(int n) {
50 DB_ENV *env = null_env;
51 int r;
52 r = db_env_create(&env, 0); assert(r == 0); assert(env != NULL);
53 r = env->open(env,
54 TOKU_TEST_FILENAME,
55 DB_INIT_MPOOL+DB_INIT_LOG+DB_INIT_LOCK+DB_INIT_TXN+DB_PRIVATE+DB_CREATE,
56 S_IRWXU+S_IRWXG+S_IRWXO);
57 assert(r == 0);
58
59 DB_TXN *txn = null_txn;
60 r = env->txn_begin(env, null_txn, &txn, 0); assert(r == 0); assert(txn != NULL);
61
62 DB *db = null_db;
63 r = db_create(&db, env, 0); assert(r == 0); assert(db != NULL);
64
65 r = db->open(db, txn, "test.db", 0, DB_BTREE, DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO);
66 assert(r == 0);
67
68 int i;
69 for (i=n; i<2*n; i++) {
70 DBT key, val;
71 int k = toku_htonl(i);
72 r = db->put(db, txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &i, sizeof i), 0);
73 assert(r == 0);
74 }
75
76 r = db->close(db, 0); assert(r == 0); db = null_db;
77
78 r = txn->commit(txn, 0); assert(r == 0); txn = null_txn;
79
80 r = env->close(env, 0); assert(r == 0); env = null_env;
81 }
82
root_fifo_verify(DB_ENV * env,int n)83 static void root_fifo_verify(DB_ENV *env, int n) {
84 if (verbose) printf("%s:%d %d\n", __FUNCTION__, __LINE__, n);
85
86 int r;
87 DB_TXN *txn = null_txn;
88 r = env->txn_begin(env, null_txn, &txn, 0); assert(r == 0); assert(txn != NULL);
89
90 DB *db = null_db;
91 r = db_create(&db, env, 0); assert(r == 0); assert(db != NULL);
92 r = db->open(db, txn, "test.db", 0, DB_BTREE, DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO);
93 assert(r == 0);
94
95 DBC *cursor = null_cursor;
96 r = db->cursor(db, txn, &cursor, 0); assert(r == 0);
97 int i;
98 for (i = n; ; i++) {
99 DBT key, val;
100 memset(&key, 0, sizeof key); memset(&val, 0, sizeof val);
101 r = cursor->c_get(cursor, &key, &val, DB_NEXT);
102 if (r != 0) break;
103 int k;
104 assert(key.size == sizeof k);
105 memcpy(&k, key.data, key.size);
106 assert((int)toku_ntohl(k) == i);
107 }
108 assert(i == 2*n);
109
110 r = cursor->c_close(cursor); assert(r == 0); cursor = null_cursor;
111
112 r = txn->commit(txn, 0); assert(r == 0); txn = null_txn;
113
114 r = db->close(db, 0); assert(r == 0); db = null_db;
115 }
116
root_fifo_32(int n)117 static void root_fifo_32(int n) {
118 if (verbose) printf("%s:%d %d\n", __FUNCTION__, __LINE__, n);
119 int r;
120
121 // create the env
122 toku_os_recursive_delete(TOKU_TEST_FILENAME);
123 toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU+S_IRWXG+S_IRWXO);
124
125 // populate
126 create_non_empty(n);
127
128 DB_ENV *env = null_env;
129 r = db_env_create(&env, 0); assert(r == 0); assert(env != NULL);
130 r = env->open(env,
131 TOKU_TEST_FILENAME,
132 DB_INIT_MPOOL+DB_INIT_LOG+DB_INIT_LOCK+DB_INIT_TXN+DB_PRIVATE+DB_CREATE,
133 S_IRWXU+S_IRWXG+S_IRWXO);
134 assert(r == 0);
135
136 DB_TXN *txn = null_txn;
137 r = env->txn_begin(env, null_txn, &txn, 0); assert(r == 0); assert(txn != NULL);
138
139 int i;
140 for (i=0; i<n; i++) {
141 DB *db = null_db;
142 r = db_create(&db, env, 0); assert(r == 0); assert(db != NULL);
143
144 r = db->open(db, txn, "test.db", 0, DB_BTREE, DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO);
145 assert(r == 0);
146
147 DBT key, val;
148 int k = toku_htonl(i);
149 r = db->put(db, txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &i, sizeof i), 0);
150 assert(r == 0);
151
152 r = db->close(db, 0); assert(r == 0); db = null_db;
153 }
154
155 r = txn->abort(txn); assert(r == 0); txn = null_txn;
156
157 // verify the db
158 root_fifo_verify(env, n);
159
160 // cleanup
161 r = env->close(env, 0); assert(r == 0); env = null_env;
162 }
163
test_main(int argc,char * const argv[])164 int test_main(int argc, char *const argv[]) {
165 int i;
166 int n = -1;
167
168 // parse_args(argc, argv);
169 for (i = 1; i < argc; i++) {
170 if (strcmp(argv[i], "-v") == 0) {
171 verbose = 1;
172 continue;
173 }
174 if (strcmp(argv[i], "-n") == 0) {
175 if (i+1 < argc)
176 n = atoi(argv[++i]);
177 continue;
178 }
179 }
180
181 if (n >= 0)
182 root_fifo_32(n);
183 else
184 for (i=0; i<100; i++)
185 root_fifo_32(i);
186 return 0;
187 }
188
189