Skip to content

Commit

Permalink
tests: extend DECLARE_* tests
Browse files Browse the repository at this point in the history
The unsorted datastructures (LIST, DLIST) had no test before this.  Also
add a hash check (mostly to make testing the unsorted lists easier.)

Signed-off-by: David Lamparter <equinox@diac24.net>
  • Loading branch information
eqvinox committed May 21, 2019
1 parent 2214f16 commit 8c3d03b
Show file tree
Hide file tree
Showing 3 changed files with 255 additions and 11 deletions.
25 changes: 25 additions & 0 deletions tests/lib/test_typelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <arpa/inet.h>

#define WNO_ATOMLIST_UNSAFE_FIND

Expand All @@ -33,6 +34,7 @@
#include "memory.h"
#include "monotime.h"
#include "jhash.h"
#include "sha256.h"

#include "tests/helpers/c/prng.h"

Expand All @@ -50,6 +52,21 @@
#define _DECLARE(type, ...) DECLARE_##type(__VA_ARGS__)
#define DECLARE(type, ...) _DECLARE(type, __VA_ARGS__)

#define _S_LIST 0
#define _S_DLIST 0
#define _S_SORTLIST_UNIQ 1
#define _S_SORTLIST_NONUNIQ 1
#define _S_HASH 1
#define _S_SKIPLIST_UNIQ 1
#define _S_SKIPLIST_NONUNIQ 1
#define _S_RBTREE_UNIQ 1
#define _S_RBTREE_NONUNIQ 1
#define _S_ATOMSORT_UNIQ 1
#define _S_ATOMSORT_NONUNIQ 1

#define _IS_SORTED(type) _S_##type
#define IS_SORTED(type) _IS_SORTED(type)

#define _U_SORTLIST_UNIQ 1
#define _U_SORTLIST_NONUNIQ 0
#define _U_HASH 1
Expand Down Expand Up @@ -97,6 +114,12 @@ static void ts_end(void)
printf("%7"PRId64"us total\n", us);
}

#define TYPE LIST
#include "test_typelist.h"

#define TYPE DLIST
#include "test_typelist.h"

#define TYPE SORTLIST_UNIQ
#include "test_typelist.h"

Expand Down Expand Up @@ -134,6 +157,8 @@ int main(int argc, char **argv)
{
srandom(1);

test_LIST();
test_DLIST();
test_SORTLIST_UNIQ();
test_SORTLIST_NONUNIQ();
test_HASH();
Expand Down
239 changes: 228 additions & 11 deletions tests/lib/test_typelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,17 @@
#define list_next_safe concat(TYPE, _next_safe)
#define list_count concat(TYPE, _count)
#define list_add concat(TYPE, _add)
#define list_add_head concat(TYPE, _add_head)
#define list_add_tail concat(TYPE, _add_tail)
#define list_add_after concat(TYPE, _add_after)
#define list_find concat(TYPE, _find)
#define list_find_lt concat(TYPE, _find_lt)
#define list_find_gteq concat(TYPE, _find_gteq)
#define list_del concat(TYPE, _del)
#define list_pop concat(TYPE, _pop)

#define ts_hash concat(ts_hash_, TYPE)

#ifndef REALTYPE
#define REALTYPE TYPE
#endif
Expand All @@ -47,6 +52,7 @@ struct item {
int scratchpad;
};

#if IS_SORTED(REALTYPE)
static int list_cmp(const struct item *a, const struct item *b);

#if IS_HASH(REALTYPE)
Expand Down Expand Up @@ -76,16 +82,67 @@ static int list_cmp(const struct item *a, const struct item *b)
return 0;
}

#else /* !IS_SORTED */
DECLARE(REALTYPE, list, struct item, itm)
#endif

#define NITEM 10000
struct item itm[NITEM];
static struct list_head head = concat(INIT_, REALTYPE)(head);

static void ts_hash(const char *text, const char *expect)
{
int64_t us = monotime_since(&ref, NULL);
SHA256_CTX ctx;
struct item *item;
unsigned i = 0;
uint8_t hash[32];
char hashtext[65];
uint32_t count;

count = htonl(list_count(&head));

SHA256_Init(&ctx);
SHA256_Update(&ctx, &count, sizeof(count));

for_each (list, &head, item) {
struct {
uint32_t val_upper, val_lower, index;
} hashitem = {
htonl(item->val >> 32),
htonl(item->val & 0xFFFFFFFFULL),
htonl(i),
};
SHA256_Update(&ctx, &hashitem, sizeof(hashitem));
i++;
assert(i < count);
}
SHA256_Final(hash, &ctx);

for (i = 0; i < sizeof(hash); i++)
sprintf(hashtext + i * 2, "%02x", hash[i]);

printf("%7"PRId64"us %-25s %s%s\n", us, text,
expect ? " " : "*", hashtext);
if (expect && strcmp(expect, hashtext)) {
printf("%-21s %s\n", "EXPECTED:", expect);
assert(0);
}
monotime(&ref);
}
/* hashes will have different item ordering */
#if IS_HASH(REALTYPE)
#define ts_hashx(pos, csum) ts_hash(pos, NULL)
#else
#define ts_hashx(pos, csum) ts_hash(pos, csum)
#endif

static void concat(test_, TYPE)(void)
{
size_t i, j, k, l;
struct prng *prng;
struct item *item, *prev;
struct item dummy;
struct item *item, *prev __attribute__((unused));
struct item dummy __attribute__((unused));

memset(itm, 0, sizeof(itm));
for (i = 0; i < NITEM; i++)
Expand All @@ -95,10 +152,11 @@ static void concat(test_, TYPE)(void)
ts_start();

list_init(&head);
ts_ref("init");

assert(list_first(&head) == NULL);

ts_hash("init", "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119");

#if IS_SORTED(REALTYPE)
prng = prng_new(0);
k = 0;
for (i = 0; i < NITEM; i++) {
Expand All @@ -112,7 +170,7 @@ static void concat(test_, TYPE)(void)
}
assert(list_count(&head) == k);
assert(list_first(&head) != NULL);
ts_ref("fill");
ts_hashx("fill", "a538546a6e6ab0484e925940aa8dd02fd934408bbaed8cb66a0721841584d838");

k = 0;
prev = NULL;
Expand Down Expand Up @@ -151,8 +209,8 @@ static void concat(test_, TYPE)(void)
list_del(&head, &dummy);
}
}
ts_ref("add-dup");
#else /* !IS_UNIQ(TYPE) */
ts_hashx("add-dup", "a538546a6e6ab0484e925940aa8dd02fd934408bbaed8cb66a0721841584d838");
#else /* !IS_UNIQ(REALTYPE) */
for (i = 0; i < NITEM; i++) {
j = prng_rand(prng) % NITEM;
memset(&dummy, 0, sizeof(dummy));
Expand Down Expand Up @@ -181,7 +239,7 @@ static void concat(test_, TYPE)(void)
assert(list_next(&head, &dummy)->val > j);
list_del(&head, &dummy);
}
ts_ref("add-dup+find_{lt,gteq}");
ts_hash("add-dup+find_{lt,gteq}", "a538546a6e6ab0484e925940aa8dd02fd934408bbaed8cb66a0721841584d838");
#endif
#if !IS_HASH(REALTYPE)
prng_free(prng);
Expand Down Expand Up @@ -225,7 +283,7 @@ static void concat(test_, TYPE)(void)
}
}
assert(l + list_count(&head) == k);
ts_ref("del");
ts_hashx("del", "cb2e5d80f08a803ef7b56c15e981b681adcea214bebc2f55e12e0bfb242b07ca");

for_each_safe(list, &head, item) {
assert(item->scratchpad != 0);
Expand All @@ -237,7 +295,161 @@ static void concat(test_, TYPE)(void)
}
}
assert(l + list_count(&head) == k);
ts_ref("for_each_safe+del");
ts_hashx("for_each_safe+del", "e0beb71dd963a75af05b722b8e71b61b304587d860c8accdc4349067542b86bb");

#else /* !IS_SORTED */
prng = prng_new(0);
k = 0;
for (i = 0; i < NITEM; i++) {
j = prng_rand(prng) % NITEM;
if (itm[j].scratchpad == 0) {
list_add_tail(&head, &itm[j]);
itm[j].scratchpad = 1;
k++;
}
}
assert(list_count(&head) == k);
assert(list_first(&head) != NULL);
ts_hash("fill / add_tail", "eabfcf1413936daaf20965abced95762f45110a6619b84aac7d38481bce4ea19");

for (i = 0; i < NITEM / 2; i++) {
j = prng_rand(prng) % NITEM;
if (itm[j].scratchpad == 1) {
list_del(&head, &itm[j]);
itm[j].scratchpad = 0;
k--;
}
}
ts_hash("del-prng", "86d568a95eb429dab3162976c5a5f3f75aabc835932cd682aa280b6923549564");

l = 0;
while ((item = list_pop(&head))) {
assert(item->scratchpad != 0);

item->scratchpad = 0;
l++;
}
assert(l == k);
assert(list_count(&head) == 0);
assert(list_first(&head) == NULL);
ts_hash("pop", "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119");

prng_free(prng);
prng = prng_new(0x1e5a2d69);

k = 0;
for (i = 0; i < NITEM; i++) {
j = prng_rand(prng) % NITEM;
if (itm[j].scratchpad == 0) {
list_add_head(&head, &itm[j]);
itm[j].scratchpad = 1;
k++;
}
}
assert(list_count(&head) == k);
assert(list_first(&head) != NULL);
ts_hash("fill / add_head", "3084d8f8a28b8c756ccc0a92d60d86f6d776273734ddc3f9e1d89526f5ca2795");

for (i = 0; i < NITEM / 2; i++) {
j = prng_rand(prng) % NITEM;
if (itm[j].scratchpad == 1) {
list_del(&head, &itm[j]);
itm[j].scratchpad = 0;
k--;
}
}
ts_hash("del-prng", "dc916fa7ea4418792c7c8232d74df2887f9975ead4222f4b977be6bc0b52285e");

l = 0;
while ((item = list_pop(&head))) {
assert(item->scratchpad != 0);

item->scratchpad = 0;
l++;
}
assert(l == k);
assert(list_count(&head) == 0);
assert(list_first(&head) == NULL);
ts_hash("pop", "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119");

prng_free(prng);
prng = prng_new(0x692d1e5a);

k = 0;
for (i = 0; i < NITEM; i++) {
j = prng_rand(prng) % NITEM;
if (itm[j].scratchpad == 0) {
if (prng_rand(prng) & 1) {
list_add_tail(&head, &itm[j]);
} else {
list_add_head(&head, &itm[j]);
}
itm[j].scratchpad = 1;
k++;
}
}
assert(list_count(&head) == k);
assert(list_first(&head) != NULL);
ts_hash("fill / add_{head,tail}", "93fa180a575c96e4b6c3775c2de7843ee3254dd6ed5af699bbe155f994114b06");

for (i = 0; i < NITEM * 3; i++) {
int op = prng_rand(prng);
j = prng_rand(prng) % NITEM;

if (op & 1) {
/* delete or pop */
if (op & 2) {
item = list_pop(&head);
if (!item)
continue;
} else {
item = &itm[j];
if (item->scratchpad == 0)
continue;
list_del(&head, item);
}
item->scratchpad = 0;
k--;
} else {
item = &itm[j];
if (item->scratchpad != 0)
continue;

item->scratchpad = 1;
k++;

switch ((op >> 1) & 3) {
case 0:
list_add_head(&head, item);
break;
case 1:
list_add_tail(&head, item);
break;
case 2:
case 3:
prev = NULL;
l = 0;
do {
j = prng_rand(prng) % NITEM;
prev = &itm[j];
if (prev->scratchpad == 0
|| prev == item)
prev = NULL;
l++;
} while (!prev && l < 10);
list_add_after(&head, prev, item);
break;
default:
assert(0);
}
}
}
assert(list_count(&head) == k);
assert(list_first(&head) != NULL);
ts_hash("prng add/del", "8c5dd192505c8cc8337f9b936f88e90dbc5854cb3fd7391c47189d131fa399fd");

l = 0;
#endif

while ((item = list_pop(&head))) {
assert(item->scratchpad != 0);
Expand All @@ -248,14 +460,16 @@ static void concat(test_, TYPE)(void)
assert(l == k);
assert(list_count(&head) == 0);
assert(list_first(&head) == NULL);
ts_ref("pop");
ts_hash("pop", "df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119");

list_fini(&head);
ts_ref("fini");
ts_end();
printf("%s end\n", str(TYPE));
}

#undef ts_hashx

#undef item
#undef itm
#undef head
Expand All @@ -271,6 +485,9 @@ static void concat(test_, TYPE)(void)
#undef list_next_safe
#undef list_count
#undef list_add
#undef list_add_head
#undef list_add_tail
#undef list_add_after
#undef list_find
#undef list_find_lt
#undef list_find_gteq
Expand Down

0 comments on commit 8c3d03b

Please sign in to comment.