-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: lib: hashmap: tests for hashmap library
Add tests for public API of `<zephyr/sys/hash_map.h>` Signed-off-by: Chris Friedt <cfriedt@meta.com>
- Loading branch information
1 parent
0bda7b3
commit e607684
Showing
14 changed files
with
458 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Copyright (c) 2022 Meta | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(hash_map) | ||
|
||
FILE(GLOB app_sources src/*.c) | ||
target_sources(app PRIVATE ${app_sources}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Copyright (c) 2022 Meta | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
config TEST_LIB_HASH_MAP_MAX_ENTRIES | ||
int "Maximum number of Hashmap entries" | ||
default 40 | ||
help | ||
When benchmarking the performance of the Hashmap, it helps to be able | ||
to vary the number of entries to insert or remove from the hash table | ||
in a convenient way. This option translates to MANY in the test sources. | ||
|
||
CONFIG_TEST_LIB_HASH_MAP_MAX_ENTRIES | ||
|
||
Of course, using realloc(), we are limited by the amount of available | ||
heap memory. For test scenarios using the Minimal C library, the heap | ||
size is controlled via | ||
|
||
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE | ||
|
||
For native_posix_64, the number of entries can be configured | ||
independently of the arena size since the native libc is used. | ||
|
||
source "Kconfig.zephyr" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Copyright (c) 2022 Meta | ||
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
CONFIG_ZTEST=y | ||
CONFIG_ZTEST_NEW_API=y | ||
|
||
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=8192 | ||
CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=8192 | ||
CONFIG_PICOLIBC_HEAP_SIZE=8192 | ||
|
||
CONFIG_SYS_HASH_FUNC32=y | ||
CONFIG_SYS_HASH_MAP=y | ||
|
||
CONFIG_TEST_LIB_HASH_MAP_MAX_ENTRIES=40 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Copyright (c) 2022 Meta | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdlib.h> | ||
|
||
#include <zephyr/ztest.h> | ||
#include <zephyr/sys/hash_map.h> | ||
|
||
#include "_main.h" | ||
|
||
SYS_HASHMAP_DEFINE(map); | ||
SYS_HASHMAP_DEFAULT_DEFINE_ADVANCED(custom_load_factor_map, sys_hash32, realloc, | ||
SYS_HASHMAP_CONFIG(SIZE_MAX, CUSTOM_LOAD_FACTOR)); | ||
|
||
static void *setup(void) | ||
{ | ||
printk("CONFIG_TEST_LIB_HASH_MAP_MAX_ENTRIES: %u\n", CONFIG_TEST_LIB_HASH_MAP_MAX_ENTRIES); | ||
|
||
return NULL; | ||
} | ||
|
||
static void after(void *arg) | ||
{ | ||
ARG_UNUSED(arg); | ||
|
||
(void)sys_hashmap_clear(&map, NULL, NULL); | ||
(void)sys_hashmap_clear(&custom_load_factor_map, NULL, NULL); | ||
} | ||
|
||
ZTEST_SUITE(hash_map, NULL, setup, NULL, after, NULL); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/* | ||
* Copyright (c) 2022 Meta | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#ifndef ZEPHYR_TESTS_LIB_HASH_MAP_SRC_MAIN_H_ | ||
#define ZEPHYR_TESTS_LIB_HASH_MAP_SRC_MAIN_H_ | ||
|
||
#include <zephyr/sys/hash_map.h> | ||
|
||
#define MANY CONFIG_TEST_LIB_HASH_MAP_MAX_ENTRIES | ||
#define CUSTOM_LOAD_FACTOR 42 | ||
|
||
extern struct sys_hashmap map; | ||
extern struct sys_hashmap custom_load_factor_map; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* Copyright (c) 2022 Meta | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <zephyr/ztest.h> | ||
#include <zephyr/sys/hash_map.h> | ||
|
||
#include "_main.h" | ||
|
||
ZTEST(hash_map, test_clear_no_callback) | ||
{ | ||
const size_t N = 10; | ||
|
||
zassert_true(sys_hashmap_is_empty(&map)); | ||
for (size_t i = 0; i < N; ++i) { | ||
zassert_equal(1, sys_hashmap_insert(&map, i, i, NULL)); | ||
} | ||
|
||
zassert_equal(N, sys_hashmap_size(&map)); | ||
|
||
sys_hashmap_clear(&map, NULL, NULL); | ||
zassert_true(sys_hashmap_is_empty(&map)); | ||
} | ||
|
||
static void clear_callback(uint64_t key, uint64_t value, void *cookie) | ||
{ | ||
bool *cleared = (bool *)cookie; | ||
|
||
zassert_true(key < 10); | ||
cleared[key] = true; | ||
} | ||
|
||
ZTEST(hash_map, test_clear_callback) | ||
{ | ||
bool cleared[10] = {0}; | ||
|
||
zassert_true(sys_hashmap_is_empty(&map)); | ||
for (size_t i = 0; i < ARRAY_SIZE(cleared); ++i) { | ||
zassert_equal(1, sys_hashmap_insert(&map, i, i, NULL)); | ||
} | ||
|
||
zassert_equal(ARRAY_SIZE(cleared), sys_hashmap_size(&map)); | ||
|
||
sys_hashmap_clear(&map, clear_callback, cleared); | ||
zassert_true(sys_hashmap_is_empty(&map)); | ||
|
||
for (size_t i = 0; i < ARRAY_SIZE(cleared); ++i) { | ||
zassert_true(cleared[i], "entry %zu was not cleared", i + 1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright (c) 2022 Meta | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdlib.h> | ||
|
||
#include <zephyr/ztest.h> | ||
#include <zephyr/sys/hash_map.h> | ||
|
||
#include "_main.h" | ||
|
||
ZTEST(hash_map, test_empty) | ||
{ | ||
/* test size 0 */ | ||
zassert_true(sys_hashmap_is_empty(&map)); | ||
|
||
/* test size 1 */ | ||
zassume_equal(1, sys_hashmap_insert(&map, 1, 1, NULL)); | ||
zassert_false(sys_hashmap_is_empty(&map)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Copyright (c) 2022 Meta | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <zephyr/ztest.h> | ||
#include <zephyr/sys/hash_map.h> | ||
|
||
#include "_main.h" | ||
|
||
static void foreach_callback(uint64_t key, uint64_t value, void *cookie) | ||
{ | ||
bool *called = (bool *)cookie; | ||
|
||
zassert_true(key < 10); | ||
called[key] = true; | ||
} | ||
|
||
ZTEST(hash_map, test_foreach) | ||
{ | ||
bool called[10] = {0}; | ||
|
||
zassert_true(sys_hashmap_is_empty(&map)); | ||
|
||
for (size_t i = 0; i < ARRAY_SIZE(called); ++i) { | ||
zassert_equal(1, sys_hashmap_insert(&map, i, i, NULL)); | ||
} | ||
|
||
zassert_equal(ARRAY_SIZE(called), sys_hashmap_size(&map)); | ||
|
||
sys_hashmap_foreach(&map, foreach_callback, called); | ||
for (size_t i = 0; i < ARRAY_SIZE(called); ++i) { | ||
zassert_true(called[i], "entry %zu was not called", i + 1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Copyright (c) 2022 Meta | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <zephyr/ztest.h> | ||
#include <zephyr/sys/hash_map.h> | ||
|
||
#include "_main.h" | ||
|
||
ZTEST(hash_map, test_get_true) | ||
{ | ||
int ret; | ||
uint64_t value = 0x42; | ||
|
||
zassert_true(sys_hashmap_is_empty(&map)); | ||
zassert_equal(1, sys_hashmap_insert(&map, 0, 0, NULL)); | ||
zassert_true(sys_hashmap_get(&map, 0, NULL)); | ||
zassert_true(sys_hashmap_get(&map, 0, &value)); | ||
zassert_equal(0, value); | ||
|
||
for (size_t i = 1; i < MANY; ++i) { | ||
ret = sys_hashmap_insert(&map, i, i, NULL); | ||
zassert_equal(1, ret, "failed to insert (%zu, %zu): %d", i, i, ret); | ||
} | ||
|
||
for (size_t i = 0; i < MANY; ++i) { | ||
zassert_true(sys_hashmap_get(&map, i, NULL)); | ||
} | ||
} | ||
|
||
ZTEST(hash_map, test_get_false) | ||
{ | ||
int ret; | ||
uint64_t value = 0x42; | ||
|
||
zassert_true(sys_hashmap_is_empty(&map)); | ||
|
||
zassert_false(sys_hashmap_get(&map, 73, &value)); | ||
zassert_equal(value, 0x42); | ||
|
||
for (size_t i = 0; i < MANY; ++i) { | ||
ret = sys_hashmap_insert(&map, i, i, NULL); | ||
zassert_equal(1, ret, "failed to insert (%zu, %zu): %d", i, i, ret); | ||
} | ||
|
||
zassert_false(sys_hashmap_get(&map, 0x4242424242424242ULL, NULL)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
* Copyright (c) 2022 Meta | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <stdlib.h> | ||
|
||
#include <zephyr/ztest.h> | ||
#include <zephyr/sys/hash_map.h> | ||
|
||
#include "_main.h" | ||
|
||
ZTEST(hash_map, test_insert_no_replacement) | ||
{ | ||
zassert_true(sys_hashmap_is_empty(&map)); | ||
|
||
zassert_equal(1, sys_hashmap_insert(&map, 1, 1, NULL)); | ||
zassert_equal(1, sys_hashmap_size(&map)); | ||
zassert_true(sys_hashmap_contains_key(&map, 1)); | ||
|
||
zassert_equal(1, sys_hashmap_insert(&map, 2, 2, NULL)); | ||
zassert_equal(2, sys_hashmap_size(&map)); | ||
zassert_true(sys_hashmap_contains_key(&map, 2)); | ||
} | ||
|
||
ZTEST(hash_map, test_insert_replacement) | ||
{ | ||
uint64_t old_value; | ||
|
||
zassert_true(sys_hashmap_is_empty(&map)); | ||
|
||
zassert_equal(1, sys_hashmap_insert(&map, 1, 1, NULL)); | ||
zassert_equal(1, sys_hashmap_size(&map)); | ||
zassert_true(sys_hashmap_contains_key(&map, 1)); | ||
|
||
old_value = 0x42; | ||
zassert_equal(0, sys_hashmap_insert(&map, 1, 2, &old_value)); | ||
zassert_equal(1, old_value); | ||
zassert_equal(1, sys_hashmap_size(&map)); | ||
zassert_true(sys_hashmap_contains_key(&map, 1)); | ||
} | ||
|
||
ZTEST(hash_map, test_insert_many) | ||
{ | ||
int ret; | ||
|
||
zassert_true(sys_hashmap_is_empty(&map)); | ||
|
||
for (size_t i = 0; i < MANY; ++i) { | ||
ret = sys_hashmap_insert(&map, i, i, NULL); | ||
zassert_equal(1, ret, "failed to insert (%zu, %zu): %d", i, i, ret); | ||
zassert_equal(i + 1, sys_hashmap_size(&map)); | ||
} | ||
|
||
for (size_t i = 0; i < MANY; ++i) { | ||
zassert_true(sys_hashmap_contains_key(&map, i)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright (c) 2022 Meta | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <zephyr/ztest.h> | ||
#include <zephyr/sys/hash_map.h> | ||
|
||
#include "_main.h" | ||
|
||
ZTEST(hash_map, test_load_factor_default) | ||
{ | ||
int ret; | ||
uint32_t load_factor; | ||
|
||
zassert_true(sys_hashmap_is_empty(&map)); | ||
zassert_equal(0, sys_hashmap_load_factor(&map)); | ||
|
||
for (size_t i = 0; i < MANY; ++i) { | ||
ret = sys_hashmap_insert(&map, i, i, NULL); | ||
zassert_equal(1, ret, "failed to insert (%zu, %zu): %d", i, i, ret); | ||
load_factor = sys_hashmap_load_factor(&map); | ||
zassert_true(load_factor > 0 && load_factor <= SYS_HASHMAP_DEFAULT_LOAD_FACTOR); | ||
} | ||
|
||
for (size_t i = MANY; i > 0; --i) { | ||
zassert_equal(true, sys_hashmap_remove(&map, i - 1, NULL)); | ||
load_factor = sys_hashmap_load_factor(&map); | ||
zassert_true(load_factor <= SYS_HASHMAP_DEFAULT_LOAD_FACTOR); | ||
} | ||
} | ||
|
||
ZTEST(hash_map, test_load_factor_custom) | ||
{ | ||
int ret; | ||
uint32_t load_factor; | ||
struct sys_hashmap *const map = &custom_load_factor_map; | ||
|
||
zassert_equal(map->config->load_factor, CUSTOM_LOAD_FACTOR); | ||
|
||
zassert_true(sys_hashmap_is_empty(map)); | ||
zassert_equal(0, sys_hashmap_load_factor(map)); | ||
|
||
for (size_t i = 0; i < MANY; ++i) { | ||
ret = sys_hashmap_insert(map, i, i, NULL); | ||
zassert_equal(1, ret, "failed to insert (%zu, %zu): %d", i, i, ret); | ||
load_factor = sys_hashmap_load_factor(map); | ||
zassert_true(load_factor > 0 && load_factor <= CUSTOM_LOAD_FACTOR); | ||
} | ||
|
||
for (size_t i = MANY; i > 0; --i) { | ||
zassert_equal(true, sys_hashmap_remove(map, i - 1, NULL)); | ||
load_factor = sys_hashmap_load_factor(map); | ||
zassert_true(load_factor >= 0 && load_factor <= CUSTOM_LOAD_FACTOR); | ||
} | ||
} |
Oops, something went wrong.