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 #include <memory.h>
42 #include <db.h>
43
44 #include <errno.h>
45 #include <sys/stat.h>
46
47
48 // TOKU_TEST_FILENAME is defined in the Makefile
49
50 typedef struct {
51 uint32_t db_flags;
52 uint32_t flags;
53 int r_expect;
54 int key;
55 int data;
56 } PUT_TEST;
57
58 typedef struct {
59 PUT_TEST put;
60 uint32_t flags;
61 int r_expect;
62 int key;
63 int data;
64 } GET_TEST;
65
66 enum testtype {NONE=0, TGET=1, TPUT=2, SGET=3, SPUT=4, SPGET=5};
67
68 typedef struct {
69 enum testtype kind;
70 uint32_t flags;
71 int r_expect;
72 int key;
73 int data;
74 } TEST;
75
76 static DB *dbp;
77 static DB_TXN *const null_txn = 0;
78 static DB_ENV *dbenv;
79
80 static void
setup(uint32_t flags)81 setup (uint32_t flags) {
82 int r;
83
84 toku_os_recursive_delete(TOKU_TEST_FILENAME);
85 toku_os_mkdir(TOKU_TEST_FILENAME, S_IRWXU+S_IRWXG+S_IRWXO);
86 /* Open/create primary */
87 r = db_env_create(&dbenv, 0); assert(r == 0);
88 r = dbenv->set_redzone(dbenv, 0); CKERR(r);
89 r = dbenv->open(dbenv, TOKU_TEST_FILENAME, DB_CREATE+DB_PRIVATE+DB_INIT_MPOOL, 0); assert(r == 0);
90 r = db_create(&dbp, dbenv, 0); CKERR(r);
91 dbp->set_errfile(dbp,0); // Turn off those annoying errors
92 if (flags) {
93 r = dbp->set_flags(dbp, flags); CKERR(r);
94 }
95 r = dbp->open(dbp, NULL, "primary.db", NULL, DB_BTREE, DB_CREATE, 0600); CKERR(r);
96 }
97
98 static void
close_dbs(void)99 close_dbs (void) {
100 int r;
101 r = dbp->close(dbp, 0); CKERR(r);
102 r = dbenv->close(dbenv, 0); CKERR(r);
103 }
104
105 static void
insert_bad_flags(DB * db,uint32_t flags,int r_expect,int keyint,int dataint)106 insert_bad_flags (DB* db, uint32_t flags, int r_expect, int keyint, int dataint) {
107 DBT key;
108 DBT data;
109 int r;
110
111 dbt_init(&key, &keyint, sizeof(keyint));
112 dbt_init(&data,&dataint,sizeof(dataint));
113 r = db->put(db, null_txn, &key, &data, flags);
114 CKERR2(r, r_expect);
115 }
116
117 static void
get_bad_flags(DB * db,uint32_t flags,int r_expect,int keyint,int dataint)118 get_bad_flags (DB* db, uint32_t flags, int r_expect, int keyint, int dataint) {
119 DBT key;
120 DBT data;
121 int r;
122
123 dbt_init(&key, &keyint, sizeof(keyint));
124 dbt_init(&data,&dataint,sizeof(dataint));
125 r = db->get(db, null_txn, &key, &data, flags);
126 CKERR2(r, r_expect);
127 //Verify things don't change.
128 assert(*(int*)key.data == keyint);
129 assert(*(int*)data.data == dataint);
130 }
131
132 PUT_TEST put_tests[] = {
133 {0, DB_NODUPDATA, EINVAL, 0, 0}, //r_expect must change to 0, once implemented.
134 {0, 0, 0, 0, 0},
135 {0, DB_NOOVERWRITE, 0, 0, 0},
136 {0, 0, 0, 0, 0},
137 };
138 const int num_put = sizeof(put_tests) / sizeof(put_tests[0]);
139
140 GET_TEST get_tests[] = {
141 {{0, 0, 0, 0, 0}, 0 , 0, 0, 0},
142 {{0, 0, 0, 0, 0}, 0 , 0, 0, 0},
143 {{0, 0, 0, 0, 0}, 0 , 0, 0, 0},
144 {{0, 0, 0, 0, 0}, 0 , 0, 0, 0},
145 {{0, 0, 0, 0, 0}, DB_RMW, EINVAL, 0, 0},
146 {{0, 0, 0, 0, 0}, DB_RMW, EINVAL, 0, 0},
147 };
148 const int num_get = sizeof(get_tests) / sizeof(get_tests[0]);
149
150 int
test_main(int argc,char * const argv[])151 test_main(int argc, char *const argv[]) {
152 int i;
153
154 parse_args(argc, argv);
155
156 for (i = 0; i < num_put; i++) {
157 if (verbose) printf("PutTest [%d]\n", i);
158 setup(put_tests[i].db_flags);
159 insert_bad_flags(dbp, put_tests[i].flags, put_tests[i].r_expect, put_tests[i].key, put_tests[i].data);
160 close_dbs();
161 }
162
163 for (i = 0; i < num_get; i++) {
164 if (verbose) printf("GetTest [%d]\n", i);
165 setup(get_tests[i].put.db_flags);
166 insert_bad_flags(dbp, get_tests[i].put.flags, get_tests[i].put.r_expect, get_tests[i].put.key, get_tests[i].put.data);
167 get_bad_flags(dbp, get_tests[i].flags, get_tests[i].r_expect, get_tests[i].key, get_tests[i].data);
168 close_dbs();
169 }
170
171 return 0;
172 }
173