]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/apr-util/test/testdbm.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / apr-util / test / testdbm.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "apr.h"
18 #include "apr_general.h"
19 #include "apr_pools.h"
20 #include "apr_errno.h"
21 #include "apr_dbm.h"
22 #include "apr_uuid.h"
23 #include "apr_strings.h"
24 #include "abts.h"
25 #include "testutil.h"
26
27 #define NUM_TABLE_ROWS  1024
28
29 typedef struct {
30     apr_datum_t key;
31     apr_datum_t val;
32     int deleted;
33     int visited;
34 } dbm_table_t;
35
36 static dbm_table_t *generate_table(void)
37 {
38     unsigned int i;
39     apr_uuid_t uuid;
40     dbm_table_t *table = apr_pcalloc(p, sizeof(*table) * NUM_TABLE_ROWS);
41
42     for (i = 0; i < NUM_TABLE_ROWS/2; i++) {
43         apr_uuid_get(&uuid);
44         table[i].key.dptr = apr_pmemdup(p, uuid.data, sizeof(uuid.data));
45         table[i].key.dsize = sizeof(uuid.data);
46         table[i].val.dptr = apr_palloc(p, APR_UUID_FORMATTED_LENGTH);
47         table[i].val.dsize = APR_UUID_FORMATTED_LENGTH;
48         apr_uuid_format(table[i].val.dptr, &uuid);
49     }
50
51     for (; i < NUM_TABLE_ROWS; i++) {
52         apr_uuid_get(&uuid);
53         table[i].val.dptr = apr_pmemdup(p, uuid.data, sizeof(uuid.data));
54         table[i].val.dsize = sizeof(uuid.data);
55         table[i].key.dptr = apr_palloc(p, APR_UUID_FORMATTED_LENGTH);
56         table[i].key.dsize = APR_UUID_FORMATTED_LENGTH;
57         apr_uuid_format(table[i].key.dptr, &uuid);
58     }
59
60     return table;
61 }
62
63 static void test_dbm_store(abts_case *tc, apr_dbm_t *db, dbm_table_t *table)
64 {
65     apr_status_t rv;
66     unsigned int i = NUM_TABLE_ROWS - 1;
67
68     for (; i >= NUM_TABLE_ROWS/2; i--) {
69         rv = apr_dbm_store(db, table[i].key, table[i].val);
70         ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
71         table[i].deleted = FALSE;
72     }
73
74     for (i = 0; i < NUM_TABLE_ROWS/2; i++) {
75         rv = apr_dbm_store(db, table[i].key, table[i].val);
76         ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
77         table[i].deleted = FALSE;
78     }
79 }
80
81 static void test_dbm_fetch(abts_case *tc, apr_dbm_t *db, dbm_table_t *table)
82 {
83     apr_status_t rv;
84     unsigned int i;
85     apr_datum_t val;
86
87     for (i = 0; i < NUM_TABLE_ROWS; i++) {
88         memset(&val, 0, sizeof(val));
89         rv = apr_dbm_fetch(db, table[i].key, &val);
90         if (!table[i].deleted) {
91             ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
92             ABTS_INT_EQUAL(tc, table[i].val.dsize, val.dsize);
93             ABTS_INT_EQUAL(tc, 0, memcmp(table[i].val.dptr, val.dptr, val.dsize));
94             apr_dbm_freedatum(db, val);
95         } else {
96             ABTS_INT_EQUAL(tc, 0, val.dsize);
97         }
98     }
99 }
100
101 static void test_dbm_delete(abts_case *tc, apr_dbm_t *db, dbm_table_t *table)
102 {
103     apr_status_t rv;
104     unsigned int i;
105
106     for (i = 0; i < NUM_TABLE_ROWS; i++) {
107         /* XXX: random */
108         if (i & 1)
109             continue;
110         rv = apr_dbm_delete(db, table[i].key);
111         ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
112         table[i].deleted = TRUE;
113     }
114 }
115
116 static void test_dbm_exists(abts_case *tc, apr_dbm_t *db, dbm_table_t *table)
117 {
118     unsigned int i;
119     int cond;
120
121     for (i = 0; i < NUM_TABLE_ROWS; i++) {
122         cond = apr_dbm_exists(db, table[i].key);
123         if (table[i].deleted) {
124             ABTS_TRUE(tc, cond == 0);
125         } else {
126             ABTS_TRUE(tc, cond != 0);
127         }
128     }
129 }
130
131 static void test_dbm_traversal(abts_case *tc, apr_dbm_t *db, dbm_table_t *table)
132 {
133     apr_status_t rv;
134     unsigned int i;
135     apr_datum_t key;
136
137     rv = apr_dbm_firstkey(db, &key);
138     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
139
140     do {
141         if (key.dptr == NULL || key.dsize == 0)
142             break;
143
144         for (i = 0; i < NUM_TABLE_ROWS; i++) {
145             if (table[i].key.dsize != key.dsize)
146                 continue;
147             if (memcmp(table[i].key.dptr, key.dptr, key.dsize))
148                 continue;
149             ABTS_INT_EQUAL(tc, 0, table[i].deleted);
150             ABTS_INT_EQUAL(tc, 0, table[i].visited);
151             table[i].visited++;
152         }
153
154         rv = apr_dbm_nextkey(db, &key);
155         ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
156     } while (1);
157
158     for (i = 0; i < NUM_TABLE_ROWS; i++) {
159         if (table[i].deleted)
160             continue;
161         ABTS_INT_EQUAL(tc, 1, table[i].visited);
162         table[i].visited = 0;
163     }
164 }
165
166 static void test_dbm(abts_case *tc, void *data)
167 {
168     apr_dbm_t *db;
169     apr_status_t rv;
170     dbm_table_t *table;
171     const char *type = data;
172     const char *file = apr_pstrcat(p, "data/test-", type, NULL);
173
174     rv = apr_dbm_open_ex(&db, type, file, APR_DBM_RWCREATE, APR_OS_DEFAULT, p);
175     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
176
177     if (rv != APR_SUCCESS)
178         return;
179
180     table = generate_table();
181
182     test_dbm_store(tc, db, table);
183     test_dbm_fetch(tc, db, table);
184     test_dbm_delete(tc, db, table);
185     test_dbm_exists(tc, db, table);
186     test_dbm_traversal(tc, db, table);
187
188     apr_dbm_close(db);
189
190     rv = apr_dbm_open_ex(&db, type, file, APR_DBM_READONLY, APR_OS_DEFAULT, p);
191     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
192
193     if (rv != APR_SUCCESS)
194         return;
195
196     test_dbm_exists(tc, db, table);
197     test_dbm_traversal(tc, db, table);
198     test_dbm_fetch(tc, db, table);
199
200     apr_dbm_close(db);
201 }
202
203 abts_suite *testdbm(abts_suite *suite)
204 {
205     suite = ADD_SUITE(suite);
206
207 #if APU_HAVE_GDBM
208     abts_run_test(suite, test_dbm, "gdbm");
209 #endif
210 #if APU_HAVE_NDBM
211     abts_run_test(suite, test_dbm, "ndbm");
212 #endif
213 #if APU_HAVE_SDBM
214     abts_run_test(suite, test_dbm, "sdbm");
215 #endif
216 #if APU_HAVE_DB
217     abts_run_test(suite, test_dbm, "db");
218 #endif
219
220     return suite;
221 }