Skip to content

Commit

Permalink
Rewrite tests, add map tests
Browse files Browse the repository at this point in the history
  • Loading branch information
goll72 committed Jan 28, 2023
1 parent 49879a3 commit 4077e37
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 19 deletions.
3 changes: 2 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# TODO

- [ ] Add tests
- [x] Add tests
- [ ] Add mocking tests
- [x] Implement `verify-update`
- [x] Synchronize address table state with DNS server(s) on startup
- [x] Better log messages
Expand Down
37 changes: 37 additions & 0 deletions tests/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,41 @@
#define assert(...) \
cr_assert(__VA_ARGS__, #__VA_ARGS__)

/*
* PCG Random Number Generation for C.
*
* Copyright 2014 Melissa O'Neill <oneill@pcg-random.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For additional information about the PCG random number generation scheme,
* including its license and other licensing options, visit
*
* http://www.pcg-random.org
*/
typedef struct { uint64_t state; uint64_t inc; } pcg32_random_t;

pcg32_random_t pcgstate = { 0x853c49e6748fea9bULL, 0xda3e39cb94b95bdbULL };

uint32_t pcg32_random_r(pcg32_random_t *rng)
{
uint64_t oldstate = rng->state;
// Advance internal state
rng->state = oldstate * 6364136223846793005ULL + (rng->inc|1);
// Calculate output function (XSH RR), uses old state for max ILP
uint32_t xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
uint32_t rot = oldstate >> 59u;
return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
}

#endif /* COMMON_H */
2 changes: 1 addition & 1 deletion tests/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ exe_args = {
'link_args' : '-Wl,-zmuldefs'
}

foreach basename : ['conf', 'dns']
foreach basename : ['conf', 'dns', 'map']
test(basename,
executable(basename,
f'test-@basename@.c',
Expand Down
17 changes: 0 additions & 17 deletions tests/test-conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,3 @@ Test(conf, str_to_time_duration_bails_on_invalid_inputs) {
expect(not(str_to_time_duration(&out, "1sss")));
expect(not(str_to_time_duration(&out, "3g,")));
}

Test(conf, servconf_valid_is_valid) {
struct map *map = map_init(4, murmurhash64a);

assert(map);

expect(handle_servconf(map, "server", "port", "1234"));
expect(handle_servconf(map, "server", "key-algo", "hmac-sha1"));
expect(handle_servconf(map, "server", "key-algo", "HMAC-SHA224"));
expect(handle_servconf(map, "server", "max-retry", "0"));
expect(handle_servconf(map, "server", "verify-update", "true"));

servconf_t *servconf = map_get(map, "server", sizeof("server") - 1);

assert(servconf);
free_servconf("server", sizeof("server") - 1, servconf);
}
114 changes: 114 additions & 0 deletions tests/test-map.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#include "common.h"

#include "map.h"
#include "hash.h"

map_decl(str, uint64_t, const char *, uint64_t);
map_decl(self, uint64_t, uint64_t, uint64_t);

map_ops(str) owning = {
.key_alloc = (const char *(*)(const char *))strdup,
.key_free = (void (*)(const char *))free,
.compare = strcmp,
.hash = murmurhash64a
};

uint64_t map_get_self_wrap(map(self) *map, uint64_t key)
{
uint64_t res;
bool found = map_get_self(map, key, &res);

cr_assert(found, "Key not found in map");

return res;
}

Test(map, new_entries_of_same_hash_override_previous) {
map_ops(self) ops = {0};

map(self) *map = map_new_self(16, ops);

for (uint64_t i = 0; i < floor(16 * MAP_LOAD_FACTOR); i++)
map_set_self(map, i, i);

uint64_t used = 0;

for (uint64_t i = 0; i < 2; i++) {
for (uint64_t j = map->size * (i + 1); j < map->size * (i + 2); j++) {
map_set_self(map, j, j % map->size);
used++;
map->used--;
}
}

map_set_self(map, 63, 62);
map_set_self(map, 31, 31);
map_set_self(map, 24, 24);
map_set_self(map, 63, 63);
map_set_self(map, 0, 1);

cr_assert(eq(u64, map_get_self_wrap(map, 63), 63));
cr_assert(eq(u64, map_get_self_wrap(map, 31), 31));
cr_assert(eq(u64, map_get_self_wrap(map, 24), 24));
cr_assert(eq(u64, map_get_self_wrap(map, 0), 1));
cr_assert(eq(u64, map_get_self_wrap(map, 54), 54 % map->size));
cr_assert(eq(u64, map_get_self_wrap(map, 19), 19 % map->size));

map->used += used;
map_free_self(map);
}

#include <criterion/parameterized.h>

ParameterizedTestParameters(map, owning_map_works) {
static size_t initial_size[] = { 1, 2, 4, 5, 8, 12, 16, 32 };
size_t param_size = sizeof initial_size / sizeof initial_size[0];
return cr_make_param_array(size_t, initial_size, param_size);
}

static void loop_gen_rnd(char *buf, pcg32_random_t *state)
{
for (size_t j = 0; j < 24; j++) {
uint64_t rand64 = pcg32_random_r(state);
uint8_t *rand = (uint8_t *)&rand64;

for (size_t k = 0; k < 8; k++)
*buf++ = *rand++;
}
}

ParameterizedTest(size_t *size, map, owning_map_works) {
pcg32_random_t state = pcgstate;

map(str) *map = map_new_str(*size, owning);

for (size_t i = 0; i < 16; i++) {
char *buf = (char[256]){0};

uint64_t val = pcg32_random_r(&state);

loop_gen_rnd(buf, &state);

map_set_str(map, buf, val);
}

cr_assert(eq(sz, map->used, 16), "Wrong map size");

state = pcgstate;

for (size_t i = 0; i < 16; i++) {
char *buf = (char[256]){0};

uint64_t val = pcg32_random_r(&state);

loop_gen_rnd(buf, &state);

uint64_t res;
bool found = map_get_str(map, buf, &res);

cr_assert(found, "Key not found in map");
cr_assert(eq(u64, val , res));
}

map_free_str(map);
}

0 comments on commit 4077e37

Please sign in to comment.