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