summaryrefslogtreecommitdiffstats
path: root/src/tests/cmocka/test_sss_ptr_hash.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 05:31:45 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 05:31:45 +0000
commit74aa0bc6779af38018a03fd2cf4419fe85917904 (patch)
tree9cb0681aac9a94a49c153d5823e7a55d1513d91f /src/tests/cmocka/test_sss_ptr_hash.c
parentInitial commit. (diff)
downloadsssd-74aa0bc6779af38018a03fd2cf4419fe85917904.tar.xz
sssd-74aa0bc6779af38018a03fd2cf4419fe85917904.zip
Adding upstream version 2.9.4.upstream/2.9.4
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/tests/cmocka/test_sss_ptr_hash.c')
-rw-r--r--src/tests/cmocka/test_sss_ptr_hash.c232
1 files changed, 232 insertions, 0 deletions
diff --git a/src/tests/cmocka/test_sss_ptr_hash.c b/src/tests/cmocka/test_sss_ptr_hash.c
new file mode 100644
index 0000000..31cf8b7
--- /dev/null
+++ b/src/tests/cmocka/test_sss_ptr_hash.c
@@ -0,0 +1,232 @@
+/*
+ Copyright (C) 2020 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "tests/cmocka/common_mock.h"
+#include "util/sss_ptr_hash.h"
+
+static const int MAX_ENTRIES_AMOUNT = 5;
+
+static void populate_table(hash_table_t *table, int **payloads)
+{
+ char key[2] = {'z', 0};
+
+ for (int i = 0; i < MAX_ENTRIES_AMOUNT; ++i) {
+ payloads[i] = talloc_zero(global_talloc_context, int);
+ assert_non_null(payloads[i]);
+ *payloads[i] = i;
+ key[0] = '0'+(char)i;
+ assert_int_equal(sss_ptr_hash_add(table, key, payloads[i], int), 0);
+ }
+
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT);
+}
+
+static void free_payload_cb(hash_entry_t *item, hash_destroy_enum type, void *pvt)
+{
+ int *counter;
+
+ assert_non_null(item);
+ assert_non_null(item->value.ptr);
+ talloc_zfree(item->value.ptr);
+
+ assert_non_null(pvt);
+ counter = (int *)pvt;
+ (*counter)++;
+}
+
+void test_sss_ptr_hash_with_free_cb(void **state)
+{
+ hash_table_t *table;
+ int free_counter = 0;
+ int *payloads[MAX_ENTRIES_AMOUNT];
+
+ table = sss_ptr_hash_create(global_talloc_context,
+ free_payload_cb,
+ &free_counter);
+ assert_non_null(table);
+
+ populate_table(table, payloads);
+
+ /* check explicit removal from the hash */
+ sss_ptr_hash_delete(table, "1", false);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
+ assert_int_equal(free_counter, 1);
+
+ /* check implicit removal triggered by payload deletion */
+ talloc_free(payloads[3]);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
+ assert_int_equal(free_counter, 2);
+
+ /* try to remove non existent entry */
+ sss_ptr_hash_delete(table, "q", false);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
+ assert_int_equal(free_counter, 2);
+
+ /* clear all */
+ sss_ptr_hash_delete_all(table, false);
+ assert_int_equal((int)hash_count(table), 0);
+ assert_int_equal(free_counter, MAX_ENTRIES_AMOUNT);
+
+ /* check that table is still operable */
+ populate_table(table, payloads);
+ sss_ptr_hash_delete(table, "2", false);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
+ assert_int_equal(free_counter, MAX_ENTRIES_AMOUNT+1);
+
+ talloc_free(table);
+ assert_int_equal(free_counter, MAX_ENTRIES_AMOUNT*2);
+}
+
+void test_sss_ptr_hash_overwrite_with_free_cb(void **state)
+{
+ hash_table_t *table;
+ int free_counter = 0;
+ unsigned long count;
+ char *payload;
+ char *value;
+ errno_t ret;
+
+ table = sss_ptr_hash_create(global_talloc_context,
+ free_payload_cb,
+ &free_counter);
+ assert_non_null(table);
+
+ payload = talloc_strdup(table, "test_value1");
+ assert_non_null(payload);
+ talloc_set_name_const(payload, "char");
+ ret = sss_ptr_hash_add_or_override(table, "test", payload, char);
+ assert_int_equal(ret, 0);
+ count = hash_count(table);
+ assert_int_equal(count, 1);
+ value = sss_ptr_hash_lookup(table, "test", char);
+ assert_ptr_equal(value, payload);
+
+
+ payload = talloc_strdup(table, "test_value2");
+ assert_non_null(payload);
+ talloc_set_name_const(payload, "char");
+ ret = sss_ptr_hash_add_or_override(table, "test", payload, char);
+ assert_int_equal(ret, 0);
+ count = hash_count(table);
+ assert_int_equal(count, 1);
+ value = sss_ptr_hash_lookup(table, "test", char);
+ assert_ptr_equal(value, payload);
+
+ talloc_free(table);
+ assert_int_equal(free_counter, 2);
+}
+
+struct table_wrapper
+{
+ hash_table_t **table;
+};
+
+static void lookup_cb(hash_entry_t *item, hash_destroy_enum type, void *pvt)
+{
+ hash_table_t *table;
+ hash_key_t *keys;
+ unsigned long count;
+ int *value = NULL;
+ int sum = 0;
+
+ assert_non_null(pvt);
+ table = *((struct table_wrapper *)pvt)->table;
+ assert_non_null(table);
+
+ if (type == HASH_TABLE_DESTROY) {
+ /* table is being destroyed */
+ return;
+ }
+
+ assert_int_equal(hash_keys(table, &count, &keys), HASH_SUCCESS);
+ for (unsigned int i = 0; i < count; ++i) {
+ assert_int_equal(keys[i].type, HASH_KEY_STRING);
+ value = sss_ptr_hash_lookup(table, keys[i].c_str, int);
+ assert_non_null(value);
+ sum += *value;
+ }
+ DEBUG(SSSDBG_TRACE_ALL, "sum of all values = %d\n", sum);
+ talloc_free(keys);
+}
+
+/* main difference with `test_sss_ptr_hash_with_free_cb()`
+ * is that table cb here doesn't delete payload so
+ * this is requested via `free_value(s)` arg
+ */
+void test_sss_ptr_hash_with_lookup_cb(void **state)
+{
+ hash_table_t *table;
+ struct table_wrapper wrapper;
+ int *payloads[MAX_ENTRIES_AMOUNT];
+
+ wrapper.table = &table;
+ table = sss_ptr_hash_create(global_talloc_context,
+ lookup_cb,
+ &wrapper);
+ assert_non_null(table);
+
+ populate_table(table, payloads);
+
+ /* check explicit removal from the hash */
+ sss_ptr_hash_delete(table, "2", true);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
+
+ /* check implicit removal triggered by payload deletion */
+ talloc_free(payloads[0]);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
+
+ /* clear all */
+ sss_ptr_hash_delete_all(table, true);
+ assert_int_equal((int)hash_count(table), 0);
+ /* teardown function shall verify there are no leaks
+ * on global_talloc_context and so that payloads[] were freed
+ */
+
+ /* check that table is still operable */
+ populate_table(table, payloads);
+
+ talloc_free(table);
+ /* d-tor triggers hash_destroy() but since cb here doesn free payload
+ * this should be done manually
+ */
+ for (int i = 0; i < MAX_ENTRIES_AMOUNT; ++i) {
+ talloc_free(payloads[i]);
+ }
+}
+
+/* Just smoke test to verify that absence of cb doesn't break anything */
+void test_sss_ptr_hash_without_cb(void **state)
+{
+ hash_table_t *table;
+ int *payloads[MAX_ENTRIES_AMOUNT];
+
+ table = sss_ptr_hash_create(global_talloc_context, NULL, NULL);
+ assert_non_null(table);
+
+ populate_table(table, payloads);
+
+ sss_ptr_hash_delete(table, "4", true);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
+
+ talloc_free(payloads[1]);
+ assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
+
+ sss_ptr_hash_delete_all(table, true);
+ assert_int_equal((int)hash_count(table), 0);
+
+ talloc_free(table);
+}