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