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 #include "test.h"
40 
41 static int
put_callback(DB * dest_db,DB * src_db,DBT_ARRAY * dest_keys,DBT_ARRAY * dest_vals,const DBT * src_key,const DBT * src_val)42 put_callback(DB *dest_db, DB *src_db, DBT_ARRAY *dest_keys, DBT_ARRAY *dest_vals, const DBT *src_key, const DBT *src_val) {
43     toku_dbt_array_resize(dest_keys, 1);
44     toku_dbt_array_resize(dest_vals, 1);
45     DBT *dest_key = &dest_keys->dbts[0];
46     DBT *dest_val = &dest_vals->dbts[0];
47     (void) dest_db; (void) src_db; (void) dest_key; (void) dest_val; (void) src_key; (void) src_val;
48 
49     lazy_assert(src_db != NULL && dest_db != NULL);
50 
51     if (dest_key->flags == DB_DBT_REALLOC) {
52         toku_free(dest_key->data);
53     }
54     dest_key->flags = DB_DBT_REALLOC;
55     dest_key->data = toku_xmemdup(src_val->data, src_val->size);
56     dest_key->size = src_val->size;
57     dest_val->size = 0;
58 
59     return 0;
60 }
61 
62 int envflags = DB_INIT_MPOOL|DB_CREATE|DB_THREAD|DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_TXN|DB_PRIVATE;
63 
64 static void
run_test(void)65 run_test(void) {
66     int r;
67     DB_ENV *env = NULL;
68     r = db_env_create(&env, 0); assert_zero(r);
69 
70     r = env->set_generate_row_callback_for_put(env, put_callback); assert_zero(r);
71 
72     { int chk_r = env->open(env, TOKU_TEST_FILENAME, envflags, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(chk_r); }
73 
74     DB *src_db = NULL;
75     r = db_create(&src_db, env, 0); assert_zero(r);
76     r = src_db->open(src_db, NULL, "0.tdb", NULL, DB_BTREE, DB_AUTO_COMMIT+DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO); assert_zero(r);
77 
78     DB *dest_db = NULL;
79     r = db_create(&dest_db, env, 0); assert_zero(r);
80     r = dest_db->open(dest_db, NULL, "1.tdb", NULL, DB_BTREE, DB_AUTO_COMMIT+DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO); assert_zero(r);
81 
82     DB_TXN* index_txn = NULL;
83     r = env->txn_begin(env, NULL, &index_txn , 0); assert_zero(r);
84     DB_TXN* put_txn = NULL;
85     r = env->txn_begin(env, NULL, &put_txn , 0); assert_zero(r);
86 
87     DBT key,data;
88     r = src_db->put(
89         src_db,
90         put_txn,
91         dbt_init(&key,  "hello", 6),
92         dbt_init(&data, "there", 6),
93         0
94         );
95 
96     DB_INDEXER *indexer = NULL;
97     r = env->create_indexer(env, index_txn, &indexer, src_db, 1, &dest_db, NULL, 0); assert_zero(r);
98     r = indexer->build(indexer); assert_zero(r);
99     r = indexer->close(indexer); assert_zero(r);
100     r = index_txn->abort(index_txn); assert_zero(r);
101 
102     r = env->txn_checkpoint(env, 0, 0, 0);
103     assert_zero(r);
104 
105     toku_hard_crash_on_purpose();
106 }
107 
108 static void
run_recover(void)109 run_recover(void) {
110     DB_ENV *env;
111     { int chk_r = db_env_create(&env, 0); CKERR(chk_r); }
112     env->set_errfile(env, stderr);
113     { int chk_r = env->open(env, TOKU_TEST_FILENAME, envflags|DB_RECOVER, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(chk_r); }
114     { int chk_r = env->close(env, 0); CKERR(chk_r); }
115 }
116 
117 int
test_main(int argc,char * const argv[])118 test_main(int argc, char * const argv[]) {
119     bool do_test = false;
120     bool do_recover = false;
121 
122     for (int i = 1; i < argc; i++) {
123         char * const arg = argv[i];
124         if (strcmp(arg, "--test") == 0) {
125             do_test = true;
126             continue;
127         }
128         if (strcmp(arg, "--recover") == 0) {
129             do_recover = true;
130             continue;
131         }
132     }
133 
134     if (do_test) {
135         int r;
136         toku_os_recursive_delete(TOKU_TEST_FILENAME);
137         r = toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU+S_IRWXG+S_IRWXO); assert_zero(r);
138         run_test();
139     }
140     if (do_recover) {
141         run_recover();
142     }
143 
144     return 0;
145 }
146 
147