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