1*bc1f688bSRobert Mustacchi /*
2*bc1f688bSRobert Mustacchi  * This file and its contents are supplied under the terms of the
3*bc1f688bSRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4*bc1f688bSRobert Mustacchi  * You may only use this file in accordance with the terms of version
5*bc1f688bSRobert Mustacchi  * 1.0 of the CDDL.
6*bc1f688bSRobert Mustacchi  *
7*bc1f688bSRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8*bc1f688bSRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9*bc1f688bSRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10*bc1f688bSRobert Mustacchi  */
11*bc1f688bSRobert Mustacchi 
12*bc1f688bSRobert Mustacchi /*
13*bc1f688bSRobert Mustacchi  * Copyright 2015 Joyent, Inc.
14*bc1f688bSRobert Mustacchi  */
15*bc1f688bSRobert Mustacchi 
16*bc1f688bSRobert Mustacchi /*
17*bc1f688bSRobert Mustacchi  * mergeq testing routines
18*bc1f688bSRobert Mustacchi  */
19*bc1f688bSRobert Mustacchi 
20*bc1f688bSRobert Mustacchi #include <mergeq.h>
21*bc1f688bSRobert Mustacchi #include <stdio.h>
22*bc1f688bSRobert Mustacchi #include <errno.h>
23*bc1f688bSRobert Mustacchi #include <string.h>
24*bc1f688bSRobert Mustacchi #include <stdlib.h>
25*bc1f688bSRobert Mustacchi 
26*bc1f688bSRobert Mustacchi const char *
_umem_debug_init()27*bc1f688bSRobert Mustacchi _umem_debug_init()
28*bc1f688bSRobert Mustacchi {
29*bc1f688bSRobert Mustacchi 	return ("default,verbose");
30*bc1f688bSRobert Mustacchi }
31*bc1f688bSRobert Mustacchi 
32*bc1f688bSRobert Mustacchi const char *
_umem_logging_init(void)33*bc1f688bSRobert Mustacchi _umem_logging_init(void)
34*bc1f688bSRobert Mustacchi {
35*bc1f688bSRobert Mustacchi 	return ("fail,contents");
36*bc1f688bSRobert Mustacchi }
37*bc1f688bSRobert Mustacchi 
38*bc1f688bSRobert Mustacchi void *
mergeq_alloc(size_t size)39*bc1f688bSRobert Mustacchi mergeq_alloc(size_t size)
40*bc1f688bSRobert Mustacchi {
41*bc1f688bSRobert Mustacchi 	return (malloc(size));
42*bc1f688bSRobert Mustacchi }
43*bc1f688bSRobert Mustacchi 
44*bc1f688bSRobert Mustacchi /*ARGSUSED*/
45*bc1f688bSRobert Mustacchi void
mergeq_free(void * buf,size_t size)46*bc1f688bSRobert Mustacchi mergeq_free(void *buf, size_t size)
47*bc1f688bSRobert Mustacchi {
48*bc1f688bSRobert Mustacchi 	free(buf);
49*bc1f688bSRobert Mustacchi }
50*bc1f688bSRobert Mustacchi 
51*bc1f688bSRobert Mustacchi static int
mqt_int(void * first,void * second,void ** outp,void * arg)52*bc1f688bSRobert Mustacchi mqt_int(void *first, void *second, void **outp, void *arg)
53*bc1f688bSRobert Mustacchi {
54*bc1f688bSRobert Mustacchi 	uintptr_t a, b, c;
55*bc1f688bSRobert Mustacchi 	a = (uintptr_t)first;
56*bc1f688bSRobert Mustacchi 	b = (uintptr_t)second;
57*bc1f688bSRobert Mustacchi 	c = a + b;
58*bc1f688bSRobert Mustacchi 	*outp = (void *)c;
59*bc1f688bSRobert Mustacchi 
60*bc1f688bSRobert Mustacchi 	return (0);
61*bc1f688bSRobert Mustacchi }
62*bc1f688bSRobert Mustacchi 
63*bc1f688bSRobert Mustacchi static int
mqt_append(void * first,void * second,void ** outp,void * arg)64*bc1f688bSRobert Mustacchi mqt_append(void *first, void *second, void **outp, void *arg)
65*bc1f688bSRobert Mustacchi {
66*bc1f688bSRobert Mustacchi 	char *out;
67*bc1f688bSRobert Mustacchi 
68*bc1f688bSRobert Mustacchi 	/* Yes, this leaks, don't worry about it for the test */
69*bc1f688bSRobert Mustacchi 	if (asprintf(&out, "%s%s", first, second) != -1) {
70*bc1f688bSRobert Mustacchi 		*outp = out;
71*bc1f688bSRobert Mustacchi 		return (0);
72*bc1f688bSRobert Mustacchi 	}
73*bc1f688bSRobert Mustacchi 	return (-1);
74*bc1f688bSRobert Mustacchi }
75*bc1f688bSRobert Mustacchi 
76*bc1f688bSRobert Mustacchi static int
mqt_fatal(void * first,void * second,void ** outp,void * arg)77*bc1f688bSRobert Mustacchi mqt_fatal(void *first, void *second, void **outp, void *arg)
78*bc1f688bSRobert Mustacchi {
79*bc1f688bSRobert Mustacchi 	return (-1);
80*bc1f688bSRobert Mustacchi }
81*bc1f688bSRobert Mustacchi 
82*bc1f688bSRobert Mustacchi /*
83*bc1f688bSRobert Mustacchi  * Test structures and cases. We really want mq_args to be a flexible array
84*bc1f688bSRobert Mustacchi  * member, but then we cant initialize it. Thus we set a fixed size number of
85*bc1f688bSRobert Mustacchi  * entries.
86*bc1f688bSRobert Mustacchi  */
87*bc1f688bSRobert Mustacchi typedef struct mq_test {
88*bc1f688bSRobert Mustacchi 	const char	*mq_desc;	/* test description/name */
89*bc1f688bSRobert Mustacchi 	mergeq_proc_f	*mq_proc;	/* processing function */
90*bc1f688bSRobert Mustacchi 	int		mq_rval;	/* mergeq_merge return value */
91*bc1f688bSRobert Mustacchi 	int		mq_uerr;	/* user error, if any */
92*bc1f688bSRobert Mustacchi 	boolean_t	mq_strcmp;	/* use strcmp rather than == */
93*bc1f688bSRobert Mustacchi 	void		*mq_result;	/* expected result */
94*bc1f688bSRobert Mustacchi 	void		**mq_args;	/* argument array */
95*bc1f688bSRobert Mustacchi } mq_test_t;
96*bc1f688bSRobert Mustacchi 
97*bc1f688bSRobert Mustacchi static void *mqt_empty_args[] = { NULL };
98*bc1f688bSRobert Mustacchi static void *mqt_single_args[] = { (void *)42, NULL };
99*bc1f688bSRobert Mustacchi static void *mqt_double_args[] = { (void *)42, (void *)27, NULL };
100*bc1f688bSRobert Mustacchi static void *mqt_wrap_args[] = {
101*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
102*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
103*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
104*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
105*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
106*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
107*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
108*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
109*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
110*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
111*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, NULL
112*bc1f688bSRobert Mustacchi };
113*bc1f688bSRobert Mustacchi static void *mqt_grow_args[] = {
114*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
115*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
116*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
117*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
118*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
119*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
120*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
121*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
122*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
123*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
124*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
125*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
126*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
127*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
128*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
129*bc1f688bSRobert Mustacchi 	(void *)1, (void *)1, NULL
130*bc1f688bSRobert Mustacchi };
131*bc1f688bSRobert Mustacchi static void *mqt_order_args[] = { "l", "e", "g", "e", "n", "d", " ", "o", "f",
132*bc1f688bSRobert Mustacchi 	" ", "z", "e", "l", "d", "a", NULL };
133*bc1f688bSRobert Mustacchi 
134*bc1f688bSRobert Mustacchi 
135*bc1f688bSRobert Mustacchi static mq_test_t mq_tests[] = {
136*bc1f688bSRobert Mustacchi 	{ "empty", mqt_int, 0, 0, B_FALSE, NULL, mqt_empty_args },
137*bc1f688bSRobert Mustacchi 	{ "single", mqt_int, 0, 0, B_FALSE, (void *)42, mqt_single_args },
138*bc1f688bSRobert Mustacchi 	{ "double", mqt_int, 0, 0, B_FALSE, (void *)69, mqt_double_args },
139*bc1f688bSRobert Mustacchi 	{ "wrap", mqt_int, 0, 0, B_FALSE, (void *)64, mqt_wrap_args },
140*bc1f688bSRobert Mustacchi 	{ "grow", mqt_int, 0, 0, B_FALSE, (void *)92, mqt_grow_args },
141*bc1f688bSRobert Mustacchi 	{ "fatal", mqt_fatal, MERGEQ_UERROR, -1, B_FALSE, NULL,
142*bc1f688bSRobert Mustacchi 	    mqt_double_args },
143*bc1f688bSRobert Mustacchi 	{ "order", mqt_append, 0, 0, B_TRUE, "alegend of zeld", mqt_order_args }
144*bc1f688bSRobert Mustacchi };
145*bc1f688bSRobert Mustacchi 
146*bc1f688bSRobert Mustacchi #define	NMQ_TESTS (sizeof (mq_tests) / sizeof (mq_test_t))
147*bc1f688bSRobert Mustacchi 
148*bc1f688bSRobert Mustacchi static void
mq_test_run(mergeq_t * mqp,mq_test_t * mqt)149*bc1f688bSRobert Mustacchi mq_test_run(mergeq_t *mqp, mq_test_t *mqt)
150*bc1f688bSRobert Mustacchi {
151*bc1f688bSRobert Mustacchi 	int ret, err;
152*bc1f688bSRobert Mustacchi 	void **itemp = mqt->mq_args;
153*bc1f688bSRobert Mustacchi 	void *out;
154*bc1f688bSRobert Mustacchi 
155*bc1f688bSRobert Mustacchi 	while (*itemp != NULL) {
156*bc1f688bSRobert Mustacchi 		if ((ret = mergeq_add(mqp, *itemp)) != 0) {
157*bc1f688bSRobert Mustacchi 			(void) fprintf(stderr,
158*bc1f688bSRobert Mustacchi 			    "test %s: failed to add item: %s\n",
159*bc1f688bSRobert Mustacchi 			    mqt->mq_desc, strerror(errno));
160*bc1f688bSRobert Mustacchi 			exit(1);
161*bc1f688bSRobert Mustacchi 		}
162*bc1f688bSRobert Mustacchi 		itemp++;
163*bc1f688bSRobert Mustacchi 	}
164*bc1f688bSRobert Mustacchi 
165*bc1f688bSRobert Mustacchi 	ret = mergeq_merge(mqp, mqt->mq_proc, NULL, &out, &err);
166*bc1f688bSRobert Mustacchi 	if (ret != mqt->mq_rval) {
167*bc1f688bSRobert Mustacchi 		(void) fprintf(stderr, "test %s: got incorrect rval. "
168*bc1f688bSRobert Mustacchi 		    "Expected %d, got %d\n", mqt->mq_desc, mqt->mq_rval, ret);
169*bc1f688bSRobert Mustacchi 		exit(1);
170*bc1f688bSRobert Mustacchi 	}
171*bc1f688bSRobert Mustacchi 
172*bc1f688bSRobert Mustacchi 	if (ret == MERGEQ_UERROR && err != mqt->mq_uerr) {
173*bc1f688bSRobert Mustacchi 		(void) fprintf(stderr, "test %s: got incorrect user error. "
174*bc1f688bSRobert Mustacchi 		    "Expected %d, got %d\n", mqt->mq_desc, mqt->mq_uerr, err);
175*bc1f688bSRobert Mustacchi 		exit(1);
176*bc1f688bSRobert Mustacchi 	}
177*bc1f688bSRobert Mustacchi 
178*bc1f688bSRobert Mustacchi 	if (ret == 0) {
179*bc1f688bSRobert Mustacchi 		if (mqt->mq_strcmp == B_TRUE &&
180*bc1f688bSRobert Mustacchi 		    strcmp(out, mqt->mq_result) != 0) {
181*bc1f688bSRobert Mustacchi 			(void) fprintf(stderr, "test %s: got unexpected "
182*bc1f688bSRobert Mustacchi 			    "result: %s, expected %s\n", mqt->mq_desc, out,
183*bc1f688bSRobert Mustacchi 			    mqt->mq_result);
184*bc1f688bSRobert Mustacchi 			exit(1);
185*bc1f688bSRobert Mustacchi 		} else if (mqt->mq_strcmp == B_FALSE && out != mqt->mq_result) {
186*bc1f688bSRobert Mustacchi 			(void) fprintf(stderr, "test %s: got unexpected "
187*bc1f688bSRobert Mustacchi 			    "result: %p, expected %p\n", mqt->mq_desc, out,
188*bc1f688bSRobert Mustacchi 			    mqt->mq_result);
189*bc1f688bSRobert Mustacchi 			exit(1);
190*bc1f688bSRobert Mustacchi 		}
191*bc1f688bSRobert Mustacchi 	}
192*bc1f688bSRobert Mustacchi }
193*bc1f688bSRobert Mustacchi 
194*bc1f688bSRobert Mustacchi int
main(void)195*bc1f688bSRobert Mustacchi main(void)
196*bc1f688bSRobert Mustacchi {
197*bc1f688bSRobert Mustacchi 	int ret, i, t;
198*bc1f688bSRobert Mustacchi 	mergeq_t *mqp;
199*bc1f688bSRobert Mustacchi 	int nthreads[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, -1 };
200*bc1f688bSRobert Mustacchi 
201*bc1f688bSRobert Mustacchi 	for (t = 0; nthreads[t] != -1; t++) {
202*bc1f688bSRobert Mustacchi 		printf("Beginning tests with %d threads\n", nthreads[t]);
203*bc1f688bSRobert Mustacchi 		if ((ret = mergeq_init(&mqp, nthreads[t])) != 0) {
204*bc1f688bSRobert Mustacchi 			fprintf(stderr, "failed to init mergeq: %s\n",
205*bc1f688bSRobert Mustacchi 			    strerror(errno));
206*bc1f688bSRobert Mustacchi 			return (1);
207*bc1f688bSRobert Mustacchi 		}
208*bc1f688bSRobert Mustacchi 
209*bc1f688bSRobert Mustacchi 		for (i = 0; i < NMQ_TESTS; i++) {
210*bc1f688bSRobert Mustacchi 			mq_test_run(mqp, &mq_tests[i]);
211*bc1f688bSRobert Mustacchi 		}
212*bc1f688bSRobert Mustacchi 
213*bc1f688bSRobert Mustacchi 		mergeq_fini(mqp);
214*bc1f688bSRobert Mustacchi 	}
215*bc1f688bSRobert Mustacchi 
216*bc1f688bSRobert Mustacchi 	return (0);
217*bc1f688bSRobert Mustacchi }
218