1*d3dc0d63Sriastradh /* $NetBSD: t_cdb.c,v 1.4 2023/08/08 10:36:17 riastradh Exp $ */
2fe9380cfSjoerg /*-
3fe9380cfSjoerg * Copyright (c) 2012 The NetBSD Foundation, Inc.
4fe9380cfSjoerg * All rights reserved.
5fe9380cfSjoerg *
6fe9380cfSjoerg * This code is derived from software contributed to The NetBSD Foundation
7fe9380cfSjoerg * by Joerg Sonnenberger.
8fe9380cfSjoerg *
9fe9380cfSjoerg * Redistribution and use in source and binary forms, with or without
10fe9380cfSjoerg * modification, are permitted provided that the following conditions
11fe9380cfSjoerg * are met:
12fe9380cfSjoerg *
13fe9380cfSjoerg * 1. Redistributions of source code must retain the above copyright
14fe9380cfSjoerg * notice, this list of conditions and the following disclaimer.
15fe9380cfSjoerg * 2. Redistributions in binary form must reproduce the above copyright
16fe9380cfSjoerg * notice, this list of conditions and the following disclaimer in
17fe9380cfSjoerg * the documentation and/or other materials provided with the
18fe9380cfSjoerg * distribution.
19fe9380cfSjoerg *
20fe9380cfSjoerg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21fe9380cfSjoerg * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22fe9380cfSjoerg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23fe9380cfSjoerg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24fe9380cfSjoerg * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25fe9380cfSjoerg * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26fe9380cfSjoerg * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27fe9380cfSjoerg * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28fe9380cfSjoerg * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29fe9380cfSjoerg * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30fe9380cfSjoerg * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31fe9380cfSjoerg * SUCH DAMAGE.
32fe9380cfSjoerg */
33fe9380cfSjoerg
34fe9380cfSjoerg #include <sys/cdefs.h>
35*d3dc0d63Sriastradh __RCSID("$NetBSD: t_cdb.c,v 1.4 2023/08/08 10:36:17 riastradh Exp $");
36fe9380cfSjoerg
37fe9380cfSjoerg #include <atf-c.h>
38e56151abSchristos
39e56151abSchristos #include <sys/stat.h>
40e56151abSchristos
41fe9380cfSjoerg #include <assert.h>
42fe9380cfSjoerg #include <cdbr.h>
43fe9380cfSjoerg #include <cdbw.h>
44fe9380cfSjoerg #include <fcntl.h>
45fe9380cfSjoerg #include <stdlib.h>
46fe9380cfSjoerg #include <string.h>
47fe9380cfSjoerg #include <unistd.h>
48fe9380cfSjoerg
49fe9380cfSjoerg #define MAXKEYS 16384
50fe9380cfSjoerg
51fe9380cfSjoerg static const char database_name[] = "test.cdb";
52fe9380cfSjoerg
53fe9380cfSjoerg uint32_t keys[MAXKEYS];
54fe9380cfSjoerg
55fe9380cfSjoerg static int
cmp_keys(const void * a_,const void * b_)56fe9380cfSjoerg cmp_keys(const void *a_, const void *b_)
57fe9380cfSjoerg {
58fe9380cfSjoerg uint32_t a = *(const uint32_t *)a_;
59fe9380cfSjoerg uint32_t b = *(const uint32_t *)b_;
60fe9380cfSjoerg
61fe9380cfSjoerg return a > b ? 1 : (a < b ? 1 : 0);
62fe9380cfSjoerg }
63fe9380cfSjoerg
64fe9380cfSjoerg static void
init_keys(size_t len)65fe9380cfSjoerg init_keys(size_t len)
66fe9380cfSjoerg {
67fe9380cfSjoerg uint32_t sorted_keys[MAXKEYS];
68fe9380cfSjoerg size_t i;
69fe9380cfSjoerg
70fe9380cfSjoerg assert(len <= MAXKEYS);
71fe9380cfSjoerg
72fe9380cfSjoerg if (len == 0)
73fe9380cfSjoerg return;
74fe9380cfSjoerg
75fe9380cfSjoerg do {
76fe9380cfSjoerg for (i = 0; i < len; ++i)
77fe9380cfSjoerg sorted_keys[i] = keys[i] = arc4random();
78fe9380cfSjoerg
79fe9380cfSjoerg qsort(sorted_keys, len, sizeof(*sorted_keys), cmp_keys);
80fe9380cfSjoerg for (i = 1; i < len; ++i) {
81fe9380cfSjoerg if (sorted_keys[i - 1] == sorted_keys[i])
82fe9380cfSjoerg break;
83fe9380cfSjoerg }
84fe9380cfSjoerg } while (i != len);
85fe9380cfSjoerg }
86fe9380cfSjoerg
87fe9380cfSjoerg static void
write_database(size_t len)88fe9380cfSjoerg write_database(size_t len)
89fe9380cfSjoerg {
90fe9380cfSjoerg struct cdbw *db;
91fe9380cfSjoerg int fd;
92fe9380cfSjoerg size_t i;
93fe9380cfSjoerg uint32_t buf[2];
94fe9380cfSjoerg
95fe9380cfSjoerg ATF_REQUIRE((db = cdbw_open()) != NULL);
96fe9380cfSjoerg ATF_REQUIRE((fd = creat(database_name, S_IRUSR|S_IWUSR)) != -1);
97fe9380cfSjoerg for (i = 0; i < len; ++i) {
98fe9380cfSjoerg buf[0] = i;
99fe9380cfSjoerg buf[1] = keys[i];
100fe9380cfSjoerg ATF_REQUIRE(cdbw_put(db, &keys[i], sizeof(keys[i]),
101fe9380cfSjoerg buf, sizeof(buf)) == 0);
102fe9380cfSjoerg }
103*d3dc0d63Sriastradh ATF_REQUIRE(cdbw_output(db, fd, "test database", arc4random) == 0);
104fe9380cfSjoerg cdbw_close(db);
105fe9380cfSjoerg ATF_REQUIRE(close(fd) == 0);
106fe9380cfSjoerg }
107fe9380cfSjoerg
108fe9380cfSjoerg static void
check_database(size_t len)109fe9380cfSjoerg check_database(size_t len)
110fe9380cfSjoerg {
111fe9380cfSjoerg struct cdbr *db;
112fe9380cfSjoerg size_t i, data_len;
113fe9380cfSjoerg const void *data;
114fe9380cfSjoerg uint32_t buf[2];
115fe9380cfSjoerg
116fe9380cfSjoerg ATF_REQUIRE((db = cdbr_open(database_name, CDBR_DEFAULT)) != NULL);
117fe9380cfSjoerg ATF_REQUIRE_EQ(cdbr_entries(db), len);
118fe9380cfSjoerg for (i = 0; i < len; ++i) {
119fe9380cfSjoerg ATF_REQUIRE(cdbr_find(db, &keys[i], sizeof(keys[i]),
120fe9380cfSjoerg &data, &data_len) != -1);
121fe9380cfSjoerg ATF_REQUIRE_EQ(data_len, sizeof(buf));
122fe9380cfSjoerg memcpy(buf, data, sizeof(buf));
123fe9380cfSjoerg ATF_REQUIRE_EQ(buf[0], i);
124fe9380cfSjoerg ATF_REQUIRE_EQ(buf[1], keys[i]);
125fe9380cfSjoerg }
126fe9380cfSjoerg cdbr_close(db);
127fe9380cfSjoerg }
128fe9380cfSjoerg
129fe9380cfSjoerg ATF_TC_WITH_CLEANUP(cdb);
130fe9380cfSjoerg
ATF_TC_HEAD(cdb,tc)131fe9380cfSjoerg ATF_TC_HEAD(cdb, tc)
132fe9380cfSjoerg {
133fe9380cfSjoerg
134fe9380cfSjoerg atf_tc_set_md_var(tc, "descr", "Test cdb(5) reading and writing");
135fe9380cfSjoerg }
136fe9380cfSjoerg
ATF_TC_BODY(cdb,tc)137fe9380cfSjoerg ATF_TC_BODY(cdb, tc)
138fe9380cfSjoerg {
139fe9380cfSjoerg size_t i, sizes[] = { 0, 16, 64, 1024, 2048 };
140fe9380cfSjoerg for (i = 0; i < __arraycount(sizes); ++i) {
141fe9380cfSjoerg init_keys(sizes[i]);
142fe9380cfSjoerg write_database(sizes[i]);
143fe9380cfSjoerg check_database(sizes[i]);
144fe9380cfSjoerg unlink(database_name);
145fe9380cfSjoerg }
146fe9380cfSjoerg }
147fe9380cfSjoerg
ATF_TC_CLEANUP(cdb,tc)148fe9380cfSjoerg ATF_TC_CLEANUP(cdb, tc)
149fe9380cfSjoerg {
150fe9380cfSjoerg
151fe9380cfSjoerg unlink(database_name);
152fe9380cfSjoerg }
153fe9380cfSjoerg
ATF_TP_ADD_TCS(tp)154fe9380cfSjoerg ATF_TP_ADD_TCS(tp)
155fe9380cfSjoerg {
156fe9380cfSjoerg
157fe9380cfSjoerg ATF_TP_ADD_TC(tp, cdb);
158fe9380cfSjoerg
159fe9380cfSjoerg return atf_no_error();
160fe9380cfSjoerg }
161fe9380cfSjoerg
162