Use of pre_cleanups is not the default for reslists.
[apr-util.git] / test / testdbm.c
blob89d8d2f90d0dee559890a0a21a804d3250292eaf
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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"
27 #define NUM_TABLE_ROWS 1024
29 typedef struct {
30 apr_datum_t key;
31 apr_datum_t val;
32 int deleted;
33 int visited;
34 } dbm_table_t;
36 static dbm_table_t *generate_table(void)
38 unsigned int i;
39 apr_uuid_t uuid;
40 dbm_table_t *table = apr_pcalloc(p, sizeof(*table) * NUM_TABLE_ROWS);
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);
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);
60 return table;
63 static void test_dbm_store(abts_case *tc, apr_dbm_t *db, dbm_table_t *table)
65 apr_status_t rv;
66 unsigned int i = NUM_TABLE_ROWS - 1;
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;
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;
81 static void test_dbm_fetch(abts_case *tc, apr_dbm_t *db, dbm_table_t *table)
83 apr_status_t rv;
84 unsigned int i;
85 apr_datum_t val;
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);
101 static void test_dbm_delete(abts_case *tc, apr_dbm_t *db, dbm_table_t *table)
103 apr_status_t rv;
104 unsigned int i;
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;
116 static void test_dbm_exists(abts_case *tc, apr_dbm_t *db, dbm_table_t *table)
118 unsigned int i;
119 int cond;
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);
131 static void test_dbm_traversal(abts_case *tc, apr_dbm_t *db, dbm_table_t *table)
133 apr_status_t rv;
134 unsigned int i;
135 apr_datum_t key;
137 rv = apr_dbm_firstkey(db, &key);
138 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
140 do {
141 if (key.dptr == NULL || key.dsize == 0)
142 break;
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++;
154 rv = apr_dbm_nextkey(db, &key);
155 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
156 } while (1);
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;
166 static void test_dbm(abts_case *tc, void *data)
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);
174 rv = apr_dbm_open_ex(&db, type, file, APR_DBM_RWCREATE, APR_OS_DEFAULT, p);
175 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
177 if (rv != APR_SUCCESS)
178 return;
180 table = generate_table();
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);
188 apr_dbm_close(db);
190 rv = apr_dbm_open_ex(&db, type, file, APR_DBM_READONLY, APR_OS_DEFAULT, p);
191 ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
193 if (rv != APR_SUCCESS)
194 return;
196 test_dbm_exists(tc, db, table);
197 test_dbm_traversal(tc, db, table);
198 test_dbm_fetch(tc, db, table);
200 apr_dbm_close(db);
203 abts_suite *testdbm(abts_suite *suite)
205 suite = ADD_SUITE(suite);
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
220 return suite;