xref: /freebsd/contrib/netbsd-tests/lib/libc/db/t_db_hash_seq.c (revision c22165b4f1f5d38b681921797a44b3ba8c13b7e0)
1*640235e2SEnji Cooper /*	$NetBSD: t_db_hash_seq.c,v 1.2 2015/06/22 22:35:51 christos Exp $	*/
2*640235e2SEnji Cooper 
3*640235e2SEnji Cooper /*-
4*640235e2SEnji Cooper  * Copyright (c) 2015 The NetBSD Foundation, Inc.
5*640235e2SEnji Cooper  * All rights reserved.
6*640235e2SEnji Cooper  *
7*640235e2SEnji Cooper  * This code is derived from software contributed to The NetBSD Foundation
8*640235e2SEnji Cooper  * by Christos Zoulas.
9*640235e2SEnji Cooper  *
10*640235e2SEnji Cooper  * Redistribution and use in source and binary forms, with or without
11*640235e2SEnji Cooper  * modification, are permitted provided that the following conditions
12*640235e2SEnji Cooper  * are met:
13*640235e2SEnji Cooper  * 1. Redistributions of source code must retain the above copyright
14*640235e2SEnji Cooper  *    notice, this list of conditions and the following disclaimer.
15*640235e2SEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
16*640235e2SEnji Cooper  *    notice, this list of conditions and the following disclaimer in the
17*640235e2SEnji Cooper  *    documentation and/or other materials provided with the distribution.
18*640235e2SEnji Cooper  *
19*640235e2SEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20*640235e2SEnji Cooper  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21*640235e2SEnji Cooper  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22*640235e2SEnji Cooper  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23*640235e2SEnji Cooper  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24*640235e2SEnji Cooper  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25*640235e2SEnji Cooper  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26*640235e2SEnji Cooper  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27*640235e2SEnji Cooper  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28*640235e2SEnji Cooper  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29*640235e2SEnji Cooper  * POSSIBILITY OF SUCH DAMAGE.
30*640235e2SEnji Cooper  */
31*640235e2SEnji Cooper #include <sys/cdefs.h>
32*640235e2SEnji Cooper __RCSID("$NetBSD: t_db_hash_seq.c,v 1.2 2015/06/22 22:35:51 christos Exp $");
33*640235e2SEnji Cooper 
34*640235e2SEnji Cooper #include <sys/types.h>
35*640235e2SEnji Cooper #include <sys/socket.h>
36*640235e2SEnji Cooper #include <db.h>
37*640235e2SEnji Cooper #include <stdio.h>
38*640235e2SEnji Cooper #include <string.h>
39*640235e2SEnji Cooper #include <errno.h>
40*640235e2SEnji Cooper #include <stdlib.h>
41*640235e2SEnji Cooper #include <fcntl.h>
42*640235e2SEnji Cooper #include <syslog.h>
43*640235e2SEnji Cooper #include <netinet/in.h>
44*640235e2SEnji Cooper 
45*640235e2SEnji Cooper #define ATF
46*640235e2SEnji Cooper 
47*640235e2SEnji Cooper struct conf {
48*640235e2SEnji Cooper 	struct sockaddr_storage	c_ss;
49*640235e2SEnji Cooper 	int			c_lmask;
50*640235e2SEnji Cooper 	int			c_port;
51*640235e2SEnji Cooper 	int			c_proto;
52*640235e2SEnji Cooper 	int			c_family;
53*640235e2SEnji Cooper 	int			c_uid;
54*640235e2SEnji Cooper 	int			c_nfail;
55*640235e2SEnji Cooper 	char			c_name[128];
56*640235e2SEnji Cooper 	int			c_rmask;
57*640235e2SEnji Cooper 	int			c_duration;
58*640235e2SEnji Cooper };
59*640235e2SEnji Cooper 
60*640235e2SEnji Cooper struct dbinfo {
61*640235e2SEnji Cooper 	int count;
62*640235e2SEnji Cooper 	time_t last;
63*640235e2SEnji Cooper 	char id[64];
64*640235e2SEnji Cooper };
65*640235e2SEnji Cooper 
66*640235e2SEnji Cooper #ifdef ATF
67*640235e2SEnji Cooper #include <atf-c.h>
68*640235e2SEnji Cooper 
69*640235e2SEnji Cooper #define DO_ERR(msg, ...)	ATF_REQUIRE_MSG(0, msg, __VA_ARGS__)
70*640235e2SEnji Cooper #define DO_WARNX(msg, ...)	ATF_REQUIRE_MSG(0, msg, __VA_ARGS__)
71*640235e2SEnji Cooper #else
72*640235e2SEnji Cooper #include <err.h>
73*640235e2SEnji Cooper 
74*640235e2SEnji Cooper #define DO_ERR(fmt, ...)	err(EXIT_FAILURE, fmt, __VA_ARGS__)
75*640235e2SEnji Cooper #define DO_WARNX(fmt, ...)	warnx(fmt, __VA_ARGS__)
76*640235e2SEnji Cooper #endif
77*640235e2SEnji Cooper 
78*640235e2SEnji Cooper #define DO_DEBUG(fmt, ...)	fprintf(stderr, fmt, __VA_ARGS__)
79*640235e2SEnji Cooper 
80*640235e2SEnji Cooper static HASHINFO openinfo = {
81*640235e2SEnji Cooper 	4096,		/* bsize */
82*640235e2SEnji Cooper 	32,		/* ffactor */
83*640235e2SEnji Cooper 	256,		/* nelem */
84*640235e2SEnji Cooper 	8 * 1024 * 1024,/* cachesize */
85*640235e2SEnji Cooper 	NULL,		/* hash() */
86*640235e2SEnji Cooper 	0		/* lorder */
87*640235e2SEnji Cooper };
88*640235e2SEnji Cooper 
89*640235e2SEnji Cooper static int debug = 0;
90*640235e2SEnji Cooper 
91*640235e2SEnji Cooper static int
state_close(DB * db)92*640235e2SEnji Cooper state_close(DB *db)
93*640235e2SEnji Cooper {
94*640235e2SEnji Cooper 	if (db == NULL)
95*640235e2SEnji Cooper 		return -1;
96*640235e2SEnji Cooper 	if ((*db->close)(db) == -1)
97*640235e2SEnji Cooper 		DO_ERR("%s: can't close db", __func__);
98*640235e2SEnji Cooper 	return 0;
99*640235e2SEnji Cooper }
100*640235e2SEnji Cooper 
101*640235e2SEnji Cooper static DB *
state_open(const char * dbname,int flags,mode_t perm)102*640235e2SEnji Cooper state_open(const char *dbname, int flags, mode_t perm)
103*640235e2SEnji Cooper {
104*640235e2SEnji Cooper 	DB *db;
105*640235e2SEnji Cooper 
106*640235e2SEnji Cooper 	db = dbopen(dbname, flags, perm, DB_HASH, &openinfo);
107*640235e2SEnji Cooper 	if (db == NULL) {
108*640235e2SEnji Cooper 		if (errno == ENOENT && (flags & O_CREAT) == 0)
109*640235e2SEnji Cooper 			return NULL;
110*640235e2SEnji Cooper 		DO_ERR("%s: can't open `%s'", __func__, dbname);
111*640235e2SEnji Cooper 	}
112*640235e2SEnji Cooper 	return db;
113*640235e2SEnji Cooper }
114*640235e2SEnji Cooper 
115*640235e2SEnji Cooper static int
state_sizecheck(const DBT * t)116*640235e2SEnji Cooper state_sizecheck(const DBT *t)
117*640235e2SEnji Cooper {
118*640235e2SEnji Cooper 	if (sizeof(struct conf) == t->size)
119*640235e2SEnji Cooper 		return 0;
120*640235e2SEnji Cooper 	DO_WARNX("Key size mismatch %zu != %zu", sizeof(struct conf), t->size);
121*640235e2SEnji Cooper 	return 0;
122*640235e2SEnji Cooper }
123*640235e2SEnji Cooper 
124*640235e2SEnji Cooper static int
state_del(DB * db,const struct conf * c)125*640235e2SEnji Cooper state_del(DB *db, const struct conf *c)
126*640235e2SEnji Cooper {
127*640235e2SEnji Cooper 	int rv;
128*640235e2SEnji Cooper 	DBT k;
129*640235e2SEnji Cooper 
130*640235e2SEnji Cooper 	if (db == NULL)
131*640235e2SEnji Cooper 		return -1;
132*640235e2SEnji Cooper 
133*640235e2SEnji Cooper 	k.data = __UNCONST(c);
134*640235e2SEnji Cooper 	k.size = sizeof(*c);
135*640235e2SEnji Cooper 
136*640235e2SEnji Cooper 	switch (rv = (*db->del)(db, &k, 1)) {
137*640235e2SEnji Cooper 	case 0:
138*640235e2SEnji Cooper 	case 1:
139*640235e2SEnji Cooper 		if (debug > 1) {
140*640235e2SEnji Cooper 			DO_DEBUG("%s: returns %d", __func__, rv);
141*640235e2SEnji Cooper 			(*db->sync)(db, 0);
142*640235e2SEnji Cooper 		}
143*640235e2SEnji Cooper 		return 0;
144*640235e2SEnji Cooper 	default:
145*640235e2SEnji Cooper 		DO_ERR("%s: failed", __func__);
146*640235e2SEnji Cooper 		return -1;
147*640235e2SEnji Cooper 	}
148*640235e2SEnji Cooper }
149*640235e2SEnji Cooper 
150*640235e2SEnji Cooper #if 0
151*640235e2SEnji Cooper static int
152*640235e2SEnji Cooper state_get(DB *db, const struct conf *c, struct dbinfo *dbi)
153*640235e2SEnji Cooper {
154*640235e2SEnji Cooper 	int rv;
155*640235e2SEnji Cooper 	DBT k, v;
156*640235e2SEnji Cooper 
157*640235e2SEnji Cooper 	if (db == NULL)
158*640235e2SEnji Cooper 		return -1;
159*640235e2SEnji Cooper 
160*640235e2SEnji Cooper 	k.data = __UNCONST(c);
161*640235e2SEnji Cooper 	k.size = sizeof(*c);
162*640235e2SEnji Cooper 
163*640235e2SEnji Cooper 	switch (rv = (*db->get)(db, &k, &v, 0)) {
164*640235e2SEnji Cooper 	case 0:
165*640235e2SEnji Cooper 	case 1:
166*640235e2SEnji Cooper 		if (rv)
167*640235e2SEnji Cooper 			memset(dbi, 0, sizeof(*dbi));
168*640235e2SEnji Cooper 		else
169*640235e2SEnji Cooper 			memcpy(dbi, v.data, sizeof(*dbi));
170*640235e2SEnji Cooper 		if (debug > 1)
171*640235e2SEnji Cooper 			DO_DEBUG("%s: returns %d", __func__, rv);
172*640235e2SEnji Cooper 		return 0;
173*640235e2SEnji Cooper 	default:
174*640235e2SEnji Cooper 		DO_ERR("%s: failed", __func__);
175*640235e2SEnji Cooper 		return -1;
176*640235e2SEnji Cooper 	}
177*640235e2SEnji Cooper }
178*640235e2SEnji Cooper #endif
179*640235e2SEnji Cooper 
180*640235e2SEnji Cooper static int
state_put(DB * db,const struct conf * c,const struct dbinfo * dbi)181*640235e2SEnji Cooper state_put(DB *db, const struct conf *c, const struct dbinfo *dbi)
182*640235e2SEnji Cooper {
183*640235e2SEnji Cooper 	int rv;
184*640235e2SEnji Cooper 	DBT k, v;
185*640235e2SEnji Cooper 
186*640235e2SEnji Cooper 	if (db == NULL)
187*640235e2SEnji Cooper 		return -1;
188*640235e2SEnji Cooper 
189*640235e2SEnji Cooper 	k.data = __UNCONST(c);
190*640235e2SEnji Cooper 	k.size = sizeof(*c);
191*640235e2SEnji Cooper 	v.data = __UNCONST(dbi);
192*640235e2SEnji Cooper 	v.size = sizeof(*dbi);
193*640235e2SEnji Cooper 
194*640235e2SEnji Cooper 	switch (rv = (*db->put)(db, &k, &v, 0)) {
195*640235e2SEnji Cooper 	case 0:
196*640235e2SEnji Cooper 		if (debug > 1) {
197*640235e2SEnji Cooper 			DO_DEBUG("%s: returns %d", __func__, rv);
198*640235e2SEnji Cooper 			(*db->sync)(db, 0);
199*640235e2SEnji Cooper 		}
200*640235e2SEnji Cooper 		return 0;
201*640235e2SEnji Cooper 	case 1:
202*640235e2SEnji Cooper 		errno = EEXIST;
203*640235e2SEnji Cooper 		/*FALLTHROUGH*/
204*640235e2SEnji Cooper 	default:
205*640235e2SEnji Cooper 		DO_ERR("%s: failed", __func__);
206*640235e2SEnji Cooper 	}
207*640235e2SEnji Cooper }
208*640235e2SEnji Cooper 
209*640235e2SEnji Cooper static int
state_iterate(DB * db,struct conf * c,struct dbinfo * dbi,unsigned int first)210*640235e2SEnji Cooper state_iterate(DB *db, struct conf *c, struct dbinfo *dbi, unsigned int first)
211*640235e2SEnji Cooper {
212*640235e2SEnji Cooper 	int rv;
213*640235e2SEnji Cooper 	DBT k, v;
214*640235e2SEnji Cooper 
215*640235e2SEnji Cooper 	if (db == NULL)
216*640235e2SEnji Cooper 		return -1;
217*640235e2SEnji Cooper 
218*640235e2SEnji Cooper 	first = first ? R_FIRST : R_NEXT;
219*640235e2SEnji Cooper 
220*640235e2SEnji Cooper 	switch (rv = (*db->seq)(db, &k, &v, first)) {
221*640235e2SEnji Cooper 	case 0:
222*640235e2SEnji Cooper 		if (state_sizecheck(&k) == -1)
223*640235e2SEnji Cooper 			return -1;
224*640235e2SEnji Cooper 		memcpy(c, k.data, sizeof(*c));
225*640235e2SEnji Cooper 		memcpy(dbi, v.data, sizeof(*dbi));
226*640235e2SEnji Cooper 		if (debug > 1)
227*640235e2SEnji Cooper 			DO_DEBUG("%s: returns %d", __func__, rv);
228*640235e2SEnji Cooper 		return 1;
229*640235e2SEnji Cooper 	case 1:
230*640235e2SEnji Cooper 		if (debug > 1)
231*640235e2SEnji Cooper 			DO_DEBUG("%s: returns %d", __func__, rv);
232*640235e2SEnji Cooper 		return 0;
233*640235e2SEnji Cooper 	default:
234*640235e2SEnji Cooper 		DO_ERR("%s: failed", __func__);
235*640235e2SEnji Cooper 		return -1;
236*640235e2SEnji Cooper 	}
237*640235e2SEnji Cooper }
238*640235e2SEnji Cooper 
239*640235e2SEnji Cooper #define MAXB 100
240*640235e2SEnji Cooper 
241*640235e2SEnji Cooper static int
testdb(int skip)242*640235e2SEnji Cooper testdb(int skip)
243*640235e2SEnji Cooper {
244*640235e2SEnji Cooper 	size_t i;
245*640235e2SEnji Cooper 	int f;
246*640235e2SEnji Cooper 	char flag[MAXB];
247*640235e2SEnji Cooper 	DB *db;
248*640235e2SEnji Cooper 	struct conf c;
249*640235e2SEnji Cooper 	struct dbinfo d;
250*640235e2SEnji Cooper 
251*640235e2SEnji Cooper 	db = state_open(NULL, O_RDWR|O_CREAT|O_TRUNC, 0600);
252*640235e2SEnji Cooper 	if (db == NULL)
253*640235e2SEnji Cooper 		DO_ERR("%s: cannot open `%s'", __func__, "foo");
254*640235e2SEnji Cooper 
255*640235e2SEnji Cooper 	memset(&c, 0, sizeof(c));
256*640235e2SEnji Cooper 	memset(&d, 0, sizeof(d));
257*640235e2SEnji Cooper 	memset(flag, 0, sizeof(flag));
258*640235e2SEnji Cooper 
259*640235e2SEnji Cooper 	for (i = 0; i < __arraycount(flag); i++) {
260*640235e2SEnji Cooper 		c.c_port = i;
261*640235e2SEnji Cooper 		state_put(db, &c, &d);
262*640235e2SEnji Cooper 	}
263*640235e2SEnji Cooper 
264*640235e2SEnji Cooper 	for (f = 1, i = 0; state_iterate(db, &c, &d, f) == 1; f = 0, i++) {
265*640235e2SEnji Cooper 		if (debug > 1)
266*640235e2SEnji Cooper 			DO_DEBUG("%zu %d\n", i, c.c_port);
267*640235e2SEnji Cooper 		if (flag[c.c_port])
268*640235e2SEnji Cooper 			DO_WARNX("Already visited %d", c.c_port);
269*640235e2SEnji Cooper 		flag[c.c_port] = 1;
270*640235e2SEnji Cooper 		if (skip == 0 || c.c_port % skip != 0)
271*640235e2SEnji Cooper 			continue;
272*640235e2SEnji Cooper 		state_del(db, &c);
273*640235e2SEnji Cooper 	}
274*640235e2SEnji Cooper 	state_close(db);
275*640235e2SEnji Cooper 	for (i = 0; i < __arraycount(flag); i++) {
276*640235e2SEnji Cooper 		if (flag[i] == 0)
277*640235e2SEnji Cooper 			DO_WARNX("Not visited %zu", i);
278*640235e2SEnji Cooper 	}
279*640235e2SEnji Cooper 	return 0;
280*640235e2SEnji Cooper }
281*640235e2SEnji Cooper 
282*640235e2SEnji Cooper #ifndef ATF
283*640235e2SEnji Cooper int
main(int argc,char * argv[])284*640235e2SEnji Cooper main(int argc, char *argv[])
285*640235e2SEnji Cooper {
286*640235e2SEnji Cooper 	return testdb(6);
287*640235e2SEnji Cooper }
288*640235e2SEnji Cooper #else
289*640235e2SEnji Cooper 
290*640235e2SEnji Cooper ATF_TC(test_hash_del_none);
ATF_TC_HEAD(test_hash_del_none,tc)291*640235e2SEnji Cooper ATF_TC_HEAD(test_hash_del_none, tc)
292*640235e2SEnji Cooper {
293*640235e2SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Check sequential scan of hash tables deleting none");
294*640235e2SEnji Cooper }
295*640235e2SEnji Cooper 
ATF_TC_BODY(test_hash_del_none,tc)296*640235e2SEnji Cooper ATF_TC_BODY(test_hash_del_none, tc)
297*640235e2SEnji Cooper {
298*640235e2SEnji Cooper 	testdb(0);
299*640235e2SEnji Cooper }
300*640235e2SEnji Cooper 
301*640235e2SEnji Cooper ATF_TC(test_hash_del_all);
ATF_TC_HEAD(test_hash_del_all,tc)302*640235e2SEnji Cooper ATF_TC_HEAD(test_hash_del_all, tc)
303*640235e2SEnji Cooper {
304*640235e2SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Check sequential scan of hash tables deleting all");
305*640235e2SEnji Cooper }
306*640235e2SEnji Cooper 
ATF_TC_BODY(test_hash_del_all,tc)307*640235e2SEnji Cooper ATF_TC_BODY(test_hash_del_all, tc)
308*640235e2SEnji Cooper {
309*640235e2SEnji Cooper 	testdb(1);
310*640235e2SEnji Cooper }
311*640235e2SEnji Cooper 
312*640235e2SEnji Cooper ATF_TC(test_hash_del_alt);
ATF_TC_HEAD(test_hash_del_alt,tc)313*640235e2SEnji Cooper ATF_TC_HEAD(test_hash_del_alt, tc)
314*640235e2SEnji Cooper {
315*640235e2SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Check sequential scan of hash tables alternating deletets");
316*640235e2SEnji Cooper }
317*640235e2SEnji Cooper 
ATF_TC_BODY(test_hash_del_alt,tc)318*640235e2SEnji Cooper ATF_TC_BODY(test_hash_del_alt, tc)
319*640235e2SEnji Cooper {
320*640235e2SEnji Cooper 	testdb(2);
321*640235e2SEnji Cooper }
322*640235e2SEnji Cooper 
323*640235e2SEnji Cooper ATF_TC(test_hash_del_every_7);
ATF_TC_HEAD(test_hash_del_every_7,tc)324*640235e2SEnji Cooper ATF_TC_HEAD(test_hash_del_every_7, tc)
325*640235e2SEnji Cooper {
326*640235e2SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "Check sequential scan of hash tables deleting every 7 elements");
327*640235e2SEnji Cooper }
328*640235e2SEnji Cooper 
ATF_TC_BODY(test_hash_del_every_7,tc)329*640235e2SEnji Cooper ATF_TC_BODY(test_hash_del_every_7, tc)
330*640235e2SEnji Cooper {
331*640235e2SEnji Cooper 	testdb(7);
332*640235e2SEnji Cooper }
333*640235e2SEnji Cooper 
ATF_TP_ADD_TCS(tp)334*640235e2SEnji Cooper ATF_TP_ADD_TCS(tp)
335*640235e2SEnji Cooper {
336*640235e2SEnji Cooper 	ATF_TP_ADD_TC(tp, test_hash_del_none);
337*640235e2SEnji Cooper 	ATF_TP_ADD_TC(tp, test_hash_del_all);
338*640235e2SEnji Cooper 	ATF_TP_ADD_TC(tp, test_hash_del_alt);
339*640235e2SEnji Cooper 	ATF_TP_ADD_TC(tp, test_hash_del_every_7);
340*640235e2SEnji Cooper 
341*640235e2SEnji Cooper 	return 0;
342*640235e2SEnji Cooper }
343*640235e2SEnji Cooper #endif
344