#include <mergeq.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
const char *
_umem_debug_init()
{
return ("default,verbose");
}
const char *
_umem_logging_init(void)
{
return ("fail,contents");
}
void *
mergeq_alloc(size_t size)
{
return (malloc(size));
}
void
mergeq_free(void *buf, size_t size)
{
free(buf);
}
static int
mqt_int(void *first, void *second, void **outp, void *arg)
{
uintptr_t a, b, c;
a = (uintptr_t)first;
b = (uintptr_t)second;
c = a + b;
*outp = (void *)c;
return (0);
}
static int
mqt_append(void *first, void *second, void **outp, void *arg)
{
char *out;
if (asprintf(&out, "%s%s", first, second) != -1) {
*outp = out;
return (0);
}
return (-1);
}
static int
mqt_fatal(void *first, void *second, void **outp, void *arg)
{
return (-1);
}
typedef struct mq_test {
const char *mq_desc;
mergeq_proc_f *mq_proc;
int mq_rval;
int mq_uerr;
boolean_t mq_strcmp;
void *mq_result;
void **mq_args;
} mq_test_t;
static void *mqt_empty_args[] = { NULL };
static void *mqt_single_args[] = { (void *)42, NULL };
static void *mqt_double_args[] = { (void *)42, (void *)27, NULL };
static void *mqt_wrap_args[] = {
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, NULL
};
static void *mqt_grow_args[] = {
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, (void *)1, (void *)1, (void *)1, (void *)1,
(void *)1, (void *)1, NULL
};
static void *mqt_order_args[] = { "l", "e", "g", "e", "n", "d", " ", "o", "f",
" ", "z", "e", "l", "d", "a", NULL };
static mq_test_t mq_tests[] = {
{ "empty", mqt_int, 0, 0, B_FALSE, NULL, mqt_empty_args },
{ "single", mqt_int, 0, 0, B_FALSE, (void *)42, mqt_single_args },
{ "double", mqt_int, 0, 0, B_FALSE, (void *)69, mqt_double_args },
{ "wrap", mqt_int, 0, 0, B_FALSE, (void *)64, mqt_wrap_args },
{ "grow", mqt_int, 0, 0, B_FALSE, (void *)92, mqt_grow_args },
{ "fatal", mqt_fatal, MERGEQ_UERROR, -1, B_FALSE, NULL,
mqt_double_args },
{ "order", mqt_append, 0, 0, B_TRUE, "alegend of zeld", mqt_order_args }
};
#define NMQ_TESTS (sizeof (mq_tests) / sizeof (mq_test_t))
static void
mq_test_run(mergeq_t *mqp, mq_test_t *mqt)
{
int ret, err;
void **itemp = mqt->mq_args;
void *out;
while (*itemp != NULL) {
if ((ret = mergeq_add(mqp, *itemp)) != 0) {
(void) fprintf(stderr,
"test %s: failed to add item: %s\n",
mqt->mq_desc, strerror(errno));
exit(1);
}
itemp++;
}
ret = mergeq_merge(mqp, mqt->mq_proc, NULL, &out, &err);
if (ret != mqt->mq_rval) {
(void) fprintf(stderr, "test %s: got incorrect rval. "
"Expected %d, got %d\n", mqt->mq_desc, mqt->mq_rval, ret);
exit(1);
}
if (ret == MERGEQ_UERROR && err != mqt->mq_uerr) {
(void) fprintf(stderr, "test %s: got incorrect user error. "
"Expected %d, got %d\n", mqt->mq_desc, mqt->mq_uerr, err);
exit(1);
}
if (ret == 0) {
if (mqt->mq_strcmp == B_TRUE &&
strcmp(out, mqt->mq_result) != 0) {
(void) fprintf(stderr, "test %s: got unexpected "
"result: %s, expected %s\n", mqt->mq_desc, out,
mqt->mq_result);
exit(1);
} else if (mqt->mq_strcmp == B_FALSE && out != mqt->mq_result) {
(void) fprintf(stderr, "test %s: got unexpected "
"result: %p, expected %p\n", mqt->mq_desc, out,
mqt->mq_result);
exit(1);
}
}
}
int
main(void)
{
int ret, i, t;
mergeq_t *mqp;
int nthreads[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, -1 };
for (t = 0; nthreads[t] != -1; t++) {
printf("Beginning tests with %d threads\n", nthreads[t]);
if ((ret = mergeq_init(&mqp, nthreads[t])) != 0) {
fprintf(stderr, "failed to init mergeq: %s\n",
strerror(errno));
return (1);
}
for (i = 0; i < NMQ_TESTS; i++) {
mq_test_run(mqp, &mq_tests[i]);
}
mergeq_fini(mqp);
}
return (0);
}