1251876Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251876Speter * contributor license agreements. See the NOTICE file distributed with 3251876Speter * this work for additional information regarding copyright ownership. 4251876Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251876Speter * (the "License"); you may not use this file except in compliance with 6251876Speter * the License. You may obtain a copy of the License at 7251876Speter * 8251876Speter * http://www.apache.org/licenses/LICENSE-2.0 9251876Speter * 10251876Speter * Unless required by applicable law or agreed to in writing, software 11251876Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251876Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251876Speter * See the License for the specific language governing permissions and 14251876Speter * limitations under the License. 15251876Speter */ 16251876Speter 17251876Speter#include "apr.h" 18251876Speter#include "apr_general.h" 19251876Speter#include "apr_pools.h" 20251876Speter#include "apr_errno.h" 21251876Speter#include "apr_dbm.h" 22251876Speter#include "apr_uuid.h" 23251876Speter#include "apr_strings.h" 24251876Speter#include "abts.h" 25251876Speter#include "testutil.h" 26251876Speter 27251876Speter#define NUM_TABLE_ROWS 1024 28251876Speter 29251876Spetertypedef struct { 30251876Speter apr_datum_t key; 31251876Speter apr_datum_t val; 32251876Speter int deleted; 33251876Speter int visited; 34251876Speter} dbm_table_t; 35251876Speter 36251876Speterstatic dbm_table_t *generate_table(void) 37251876Speter{ 38251876Speter unsigned int i; 39251876Speter apr_uuid_t uuid; 40251876Speter dbm_table_t *table = apr_pcalloc(p, sizeof(*table) * NUM_TABLE_ROWS); 41251876Speter 42251876Speter for (i = 0; i < NUM_TABLE_ROWS/2; i++) { 43251876Speter apr_uuid_get(&uuid); 44251876Speter table[i].key.dptr = apr_pmemdup(p, uuid.data, sizeof(uuid.data)); 45251876Speter table[i].key.dsize = sizeof(uuid.data); 46251876Speter table[i].val.dptr = apr_palloc(p, APR_UUID_FORMATTED_LENGTH); 47251876Speter table[i].val.dsize = APR_UUID_FORMATTED_LENGTH; 48251876Speter apr_uuid_format(table[i].val.dptr, &uuid); 49251876Speter } 50251876Speter 51251876Speter for (; i < NUM_TABLE_ROWS; i++) { 52251876Speter apr_uuid_get(&uuid); 53251876Speter table[i].val.dptr = apr_pmemdup(p, uuid.data, sizeof(uuid.data)); 54251876Speter table[i].val.dsize = sizeof(uuid.data); 55251876Speter table[i].key.dptr = apr_palloc(p, APR_UUID_FORMATTED_LENGTH); 56251876Speter table[i].key.dsize = APR_UUID_FORMATTED_LENGTH; 57251876Speter apr_uuid_format(table[i].key.dptr, &uuid); 58251876Speter } 59251876Speter 60251876Speter return table; 61251876Speter} 62251876Speter 63251876Speterstatic void test_dbm_store(abts_case *tc, apr_dbm_t *db, dbm_table_t *table) 64251876Speter{ 65251876Speter apr_status_t rv; 66251876Speter unsigned int i = NUM_TABLE_ROWS - 1; 67251876Speter 68251876Speter for (; i >= NUM_TABLE_ROWS/2; i--) { 69251876Speter rv = apr_dbm_store(db, table[i].key, table[i].val); 70251876Speter ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 71251876Speter table[i].deleted = FALSE; 72251876Speter } 73251876Speter 74251876Speter for (i = 0; i < NUM_TABLE_ROWS/2; i++) { 75251876Speter rv = apr_dbm_store(db, table[i].key, table[i].val); 76251876Speter ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 77251876Speter table[i].deleted = FALSE; 78251876Speter } 79251876Speter} 80251876Speter 81251876Speterstatic void test_dbm_fetch(abts_case *tc, apr_dbm_t *db, dbm_table_t *table) 82251876Speter{ 83251876Speter apr_status_t rv; 84251876Speter unsigned int i; 85251876Speter apr_datum_t val; 86251876Speter 87251876Speter for (i = 0; i < NUM_TABLE_ROWS; i++) { 88251876Speter memset(&val, 0, sizeof(val)); 89251876Speter rv = apr_dbm_fetch(db, table[i].key, &val); 90251876Speter if (!table[i].deleted) { 91251876Speter ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 92251876Speter ABTS_INT_EQUAL(tc, table[i].val.dsize, val.dsize); 93251876Speter ABTS_INT_EQUAL(tc, 0, memcmp(table[i].val.dptr, val.dptr, val.dsize)); 94251876Speter apr_dbm_freedatum(db, val); 95251876Speter } else { 96251876Speter ABTS_INT_EQUAL(tc, 0, val.dsize); 97251876Speter } 98251876Speter } 99251876Speter} 100251876Speter 101251876Speterstatic void test_dbm_delete(abts_case *tc, apr_dbm_t *db, dbm_table_t *table) 102251876Speter{ 103251876Speter apr_status_t rv; 104251876Speter unsigned int i; 105251876Speter 106251876Speter for (i = 0; i < NUM_TABLE_ROWS; i++) { 107251876Speter /* XXX: random */ 108251876Speter if (i & 1) 109251876Speter continue; 110251876Speter rv = apr_dbm_delete(db, table[i].key); 111251876Speter ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 112251876Speter table[i].deleted = TRUE; 113251876Speter } 114251876Speter} 115251876Speter 116251876Speterstatic void test_dbm_exists(abts_case *tc, apr_dbm_t *db, dbm_table_t *table) 117251876Speter{ 118251876Speter unsigned int i; 119251876Speter int cond; 120251876Speter 121251876Speter for (i = 0; i < NUM_TABLE_ROWS; i++) { 122251876Speter cond = apr_dbm_exists(db, table[i].key); 123251876Speter if (table[i].deleted) { 124251876Speter ABTS_TRUE(tc, cond == 0); 125251876Speter } else { 126251876Speter ABTS_TRUE(tc, cond != 0); 127251876Speter } 128251876Speter } 129251876Speter} 130251876Speter 131251876Speterstatic void test_dbm_traversal(abts_case *tc, apr_dbm_t *db, dbm_table_t *table) 132251876Speter{ 133251876Speter apr_status_t rv; 134251876Speter unsigned int i; 135251876Speter apr_datum_t key; 136251876Speter 137251876Speter rv = apr_dbm_firstkey(db, &key); 138251876Speter ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 139251876Speter 140251876Speter do { 141251876Speter if (key.dptr == NULL || key.dsize == 0) 142251876Speter break; 143251876Speter 144251876Speter for (i = 0; i < NUM_TABLE_ROWS; i++) { 145251876Speter if (table[i].key.dsize != key.dsize) 146251876Speter continue; 147251876Speter if (memcmp(table[i].key.dptr, key.dptr, key.dsize)) 148251876Speter continue; 149251876Speter ABTS_INT_EQUAL(tc, 0, table[i].deleted); 150251876Speter ABTS_INT_EQUAL(tc, 0, table[i].visited); 151251876Speter table[i].visited++; 152251876Speter } 153251876Speter 154251876Speter rv = apr_dbm_nextkey(db, &key); 155251876Speter ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 156251876Speter } while (1); 157251876Speter 158251876Speter for (i = 0; i < NUM_TABLE_ROWS; i++) { 159251876Speter if (table[i].deleted) 160251876Speter continue; 161251876Speter ABTS_INT_EQUAL(tc, 1, table[i].visited); 162251876Speter table[i].visited = 0; 163251876Speter } 164251876Speter} 165251876Speter 166251876Speterstatic void test_dbm(abts_case *tc, void *data) 167251876Speter{ 168251876Speter apr_dbm_t *db; 169251876Speter apr_status_t rv; 170251876Speter dbm_table_t *table; 171251876Speter const char *type = data; 172251876Speter const char *file = apr_pstrcat(p, "data/test-", type, NULL); 173251876Speter 174251876Speter rv = apr_dbm_open_ex(&db, type, file, APR_DBM_RWCREATE, APR_OS_DEFAULT, p); 175251876Speter ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 176251876Speter 177251876Speter if (rv != APR_SUCCESS) 178251876Speter return; 179251876Speter 180251876Speter table = generate_table(); 181251876Speter 182251876Speter test_dbm_store(tc, db, table); 183251876Speter test_dbm_fetch(tc, db, table); 184251876Speter test_dbm_delete(tc, db, table); 185251876Speter test_dbm_exists(tc, db, table); 186251876Speter test_dbm_traversal(tc, db, table); 187251876Speter 188251876Speter apr_dbm_close(db); 189251876Speter 190251876Speter rv = apr_dbm_open_ex(&db, type, file, APR_DBM_READONLY, APR_OS_DEFAULT, p); 191251876Speter ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); 192251876Speter 193251876Speter if (rv != APR_SUCCESS) 194251876Speter return; 195251876Speter 196251876Speter test_dbm_exists(tc, db, table); 197251876Speter test_dbm_traversal(tc, db, table); 198251876Speter test_dbm_fetch(tc, db, table); 199251876Speter 200251876Speter apr_dbm_close(db); 201251876Speter} 202251876Speter 203251876Speterabts_suite *testdbm(abts_suite *suite) 204251876Speter{ 205251876Speter suite = ADD_SUITE(suite); 206251876Speter 207251876Speter#if APU_HAVE_GDBM 208251876Speter abts_run_test(suite, test_dbm, "gdbm"); 209251876Speter#endif 210251876Speter#if APU_HAVE_NDBM 211251876Speter abts_run_test(suite, test_dbm, "ndbm"); 212251876Speter#endif 213251876Speter#if APU_HAVE_SDBM 214251876Speter abts_run_test(suite, test_dbm, "sdbm"); 215251876Speter#endif 216251876Speter#if APU_HAVE_DB 217251876Speter abts_run_test(suite, test_dbm, "db"); 218251876Speter#endif 219251876Speter 220251876Speter return suite; 221251876Speter} 222