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 
88     DB_TXN *txn = null_txn;
89     r = env->txn_begin(env, null_txn, &txn, 0); assert(r == 0); assert(txn != NULL);
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 = 0; ; 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_31(int n)117 static void root_fifo_31(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->commit(txn, 0); 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_31(n);
183     else
184         for (i=0; i<100; i++)
185             root_fifo_31(i);
186     return 0;
187 }
188 
189