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