Blame SOURCES/0023-TESTS-added-sss_ptr_hash-unit-test.patch

0d097b
From 88b23bf50dd1c12413f3314639de2c3909bd9098 Mon Sep 17 00:00:00 2001
0d097b
From: Alexey Tikhonov <atikhono@redhat.com>
0d097b
Date: Tue, 28 Jan 2020 19:26:08 +0100
0d097b
Subject: [PATCH 23/23] TESTS: added sss_ptr_hash unit test
0d097b
MIME-Version: 1.0
0d097b
Content-Type: text/plain; charset=UTF-8
0d097b
Content-Transfer-Encoding: 8bit
0d097b
0d097b
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
0d097b
---
0d097b
 Makefile.am                          |   1 +
0d097b
 src/tests/cmocka/test_sss_ptr_hash.c | 193 +++++++++++++++++++++++++++
0d097b
 src/tests/cmocka/test_utils.c        |   9 ++
0d097b
 src/tests/cmocka/test_utils.h        |   6 +
0d097b
 4 files changed, 209 insertions(+)
0d097b
 create mode 100644 src/tests/cmocka/test_sss_ptr_hash.c
0d097b
0d097b
diff --git a/Makefile.am b/Makefile.am
0d097b
index 57ba51356..c991f2aa0 100644
0d097b
--- a/Makefile.am
0d097b
+++ b/Makefile.am
0d097b
@@ -3054,6 +3054,7 @@ test_ipa_idmap_LDADD = \
0d097b
 test_utils_SOURCES = \
0d097b
     src/tests/cmocka/test_utils.c \
0d097b
     src/tests/cmocka/test_string_utils.c \
0d097b
+    src/tests/cmocka/test_sss_ptr_hash.c \
0d097b
     src/p11_child/p11_child_common_utils.c \
0d097b
     $(NULL)
0d097b
 if BUILD_SSH
0d097b
diff --git a/src/tests/cmocka/test_sss_ptr_hash.c b/src/tests/cmocka/test_sss_ptr_hash.c
0d097b
new file mode 100644
0d097b
index 000000000..1458238f5
0d097b
--- /dev/null
0d097b
+++ b/src/tests/cmocka/test_sss_ptr_hash.c
0d097b
@@ -0,0 +1,193 @@
0d097b
+/*
0d097b
+    Copyright (C) 2020 Red Hat
0d097b
+
0d097b
+    This program is free software; you can redistribute it and/or modify
0d097b
+    it under the terms of the GNU General Public License as published by
0d097b
+    the Free Software Foundation; either version 3 of the License, or
0d097b
+    (at your option) any later version.
0d097b
+
0d097b
+    This program is distributed in the hope that it will be useful,
0d097b
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
0d097b
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0d097b
+    GNU General Public License for more details.
0d097b
+
0d097b
+    You should have received a copy of the GNU General Public License
0d097b
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0d097b
+*/
0d097b
+
0d097b
+#include "tests/cmocka/common_mock.h"
0d097b
+#include "util/sss_ptr_hash.h"
0d097b
+
0d097b
+static const int MAX_ENTRIES_AMOUNT = 5;
0d097b
+
0d097b
+static void populate_table(hash_table_t *table, int **payloads)
0d097b
+{
0d097b
+    char key[2] = {'z', 0};
0d097b
+
0d097b
+    for (int i = 0; i < MAX_ENTRIES_AMOUNT; ++i) {
0d097b
+        payloads[i] = talloc_zero(global_talloc_context, int);
0d097b
+        assert_non_null(payloads[i]);
0d097b
+        *payloads[i] = i;
0d097b
+        key[0] = '0'+(char)i;
0d097b
+        assert_int_equal(sss_ptr_hash_add(table, key, payloads[i], int), 0);
0d097b
+    }
0d097b
+
0d097b
+    assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT);
0d097b
+}
0d097b
+
0d097b
+static void free_payload_cb(hash_entry_t *item, hash_destroy_enum type, void *pvt)
0d097b
+{
0d097b
+    int *counter;
0d097b
+
0d097b
+    assert_non_null(item);
0d097b
+    assert_non_null(item->value.ptr);
0d097b
+    talloc_zfree(item->value.ptr);
0d097b
+
0d097b
+    assert_non_null(pvt);
0d097b
+    counter = (int *)pvt;
0d097b
+    (*counter)++;
0d097b
+}
0d097b
+
0d097b
+void test_sss_ptr_hash_with_free_cb(void **state)
0d097b
+{
0d097b
+    hash_table_t *table;
0d097b
+    int free_counter = 0;
0d097b
+    int *payloads[MAX_ENTRIES_AMOUNT];
0d097b
+
0d097b
+    table = sss_ptr_hash_create(global_talloc_context,
0d097b
+                                free_payload_cb,
0d097b
+                                &free_counter);
0d097b
+    assert_non_null(table);
0d097b
+
0d097b
+    populate_table(table, payloads);
0d097b
+
0d097b
+    /* check explicit removal from the hash */
0d097b
+    sss_ptr_hash_delete(table, "1", false);
0d097b
+    assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
0d097b
+    assert_int_equal(free_counter, 1);
0d097b
+
0d097b
+    /* check implicit removal triggered by payload deletion */
0d097b
+    talloc_free(payloads[3]);
0d097b
+    assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
0d097b
+    assert_int_equal(free_counter, 2);
0d097b
+
0d097b
+    /* try to remove non existent entry */
0d097b
+    sss_ptr_hash_delete(table, "q", false);
0d097b
+    assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
0d097b
+    assert_int_equal(free_counter, 2);
0d097b
+
0d097b
+    /* clear all */
0d097b
+    sss_ptr_hash_delete_all(table, false);
0d097b
+    assert_int_equal((int)hash_count(table), 0);
0d097b
+    assert_int_equal(free_counter, MAX_ENTRIES_AMOUNT);
0d097b
+
0d097b
+    /* check that table is still operable */
0d097b
+    populate_table(table, payloads);
0d097b
+    sss_ptr_hash_delete(table, "2", false);
0d097b
+    assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
0d097b
+    assert_int_equal(free_counter, MAX_ENTRIES_AMOUNT+1);
0d097b
+
0d097b
+    talloc_free(table);
0d097b
+    assert_int_equal(free_counter, MAX_ENTRIES_AMOUNT*2);
0d097b
+}
0d097b
+
0d097b
+struct table_wrapper
0d097b
+{
0d097b
+    hash_table_t **table;
0d097b
+};
0d097b
+
0d097b
+static void lookup_cb(hash_entry_t *item, hash_destroy_enum type, void *pvt)
0d097b
+{
0d097b
+    hash_table_t *table;
0d097b
+    hash_key_t *keys;
0d097b
+    unsigned long count;
0d097b
+    int *value = NULL;
0d097b
+    int sum = 0;
0d097b
+
0d097b
+    assert_non_null(pvt);
0d097b
+    table = *((struct table_wrapper *)pvt)->table;
0d097b
+    assert_non_null(table);
0d097b
+
0d097b
+    if (type == HASH_TABLE_DESTROY) {
0d097b
+        /* table is being destroyed */
0d097b
+        return;
0d097b
+    }
0d097b
+
0d097b
+    assert_int_equal(hash_keys(table, &count, &keys), HASH_SUCCESS);
0d097b
+    for (unsigned int i = 0; i < count; ++i) {
0d097b
+        assert_int_equal(keys[i].type, HASH_KEY_STRING);
0d097b
+        value = sss_ptr_hash_lookup(table, keys[i].c_str, int);
0d097b
+        assert_non_null(value);
0d097b
+        sum += *value;
0d097b
+    }
0d097b
+    DEBUG(SSSDBG_TRACE_ALL, "sum of all values = %d\n", sum);
0d097b
+    talloc_free(keys);
0d097b
+}
0d097b
+
0d097b
+/* main difference with `test_sss_ptr_hash_with_free_cb()`
0d097b
+ * is that table cb here doesn't delete payload so
0d097b
+ * this is requested via `free_value(s)` arg
0d097b
+ */
0d097b
+void test_sss_ptr_hash_with_lookup_cb(void **state)
0d097b
+{
0d097b
+    hash_table_t *table;
0d097b
+    struct table_wrapper wrapper;
0d097b
+    int *payloads[MAX_ENTRIES_AMOUNT];
0d097b
+
0d097b
+    wrapper.table = &table;
0d097b
+    table = sss_ptr_hash_create(global_talloc_context,
0d097b
+                                lookup_cb,
0d097b
+                                &wrapper);
0d097b
+    assert_non_null(table);
0d097b
+
0d097b
+    populate_table(table, payloads);
0d097b
+
0d097b
+    /* check explicit removal from the hash */
0d097b
+    sss_ptr_hash_delete(table, "2", true);
0d097b
+    assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
0d097b
+
0d097b
+    /* check implicit removal triggered by payload deletion */
0d097b
+    talloc_free(payloads[0]);
0d097b
+    assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
0d097b
+
0d097b
+    /* clear all */
0d097b
+    sss_ptr_hash_delete_all(table, true);
0d097b
+    assert_int_equal((int)hash_count(table), 0);
0d097b
+    /* teardown function shall verify there are no leaks
0d097b
+     * on global_talloc_context and so that payloads[] were freed
0d097b
+     */
0d097b
+
0d097b
+    /* check that table is still operable */
0d097b
+    populate_table(table, payloads);
0d097b
+
0d097b
+    talloc_free(table);
0d097b
+    /* d-tor triggers hash_destroy() but since cb here doesn free payload
0d097b
+     * this should be done manually
0d097b
+     */
0d097b
+    for (int i = 0; i < MAX_ENTRIES_AMOUNT; ++i) {
0d097b
+        talloc_free(payloads[i]);
0d097b
+    }
0d097b
+}
0d097b
+
0d097b
+/* Just smoke test to verify that absence of cb doesn't break anything */
0d097b
+void test_sss_ptr_hash_without_cb(void **state)
0d097b
+{
0d097b
+    hash_table_t *table;
0d097b
+    int *payloads[MAX_ENTRIES_AMOUNT];
0d097b
+
0d097b
+    table = sss_ptr_hash_create(global_talloc_context, NULL, NULL);
0d097b
+    assert_non_null(table);
0d097b
+
0d097b
+    populate_table(table, payloads);
0d097b
+
0d097b
+    sss_ptr_hash_delete(table, "4", true);
0d097b
+    assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-1);
0d097b
+
0d097b
+    talloc_free(payloads[1]);
0d097b
+    assert_int_equal((int)hash_count(table), MAX_ENTRIES_AMOUNT-2);
0d097b
+
0d097b
+    sss_ptr_hash_delete_all(table, true);
0d097b
+    assert_int_equal((int)hash_count(table), 0);
0d097b
+
0d097b
+    talloc_free(table);
0d097b
+}
0d097b
diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c
0d097b
index 666f32903..c5eda4dd2 100644
0d097b
--- a/src/tests/cmocka/test_utils.c
0d097b
+++ b/src/tests/cmocka/test_utils.c
0d097b
@@ -2055,6 +2055,15 @@ int main(int argc, const char *argv[])
0d097b
         cmocka_unit_test_setup_teardown(test_sss_get_domain_mappings_content,
0d097b
                                         setup_dom_list_with_subdomains,
0d097b
                                         teardown_dom_list),
0d097b
+        cmocka_unit_test_setup_teardown(test_sss_ptr_hash_with_free_cb,
0d097b
+                                        setup_leak_tests,
0d097b
+                                        teardown_leak_tests),
0d097b
+        cmocka_unit_test_setup_teardown(test_sss_ptr_hash_with_lookup_cb,
0d097b
+                                        setup_leak_tests,
0d097b
+                                        teardown_leak_tests),
0d097b
+        cmocka_unit_test_setup_teardown(test_sss_ptr_hash_without_cb,
0d097b
+                                        setup_leak_tests,
0d097b
+                                        teardown_leak_tests),
0d097b
     };
0d097b
 
0d097b
     /* Set debug level to invalid value so we can decide if -d 0 was used. */
0d097b
diff --git a/src/tests/cmocka/test_utils.h b/src/tests/cmocka/test_utils.h
0d097b
index e93e0da25..44b9479f9 100644
0d097b
--- a/src/tests/cmocka/test_utils.h
0d097b
+++ b/src/tests/cmocka/test_utils.h
0d097b
@@ -33,4 +33,10 @@ void test_guid_blob_to_string_buf(void **state);
0d097b
 void test_get_last_x_chars(void **state);
0d097b
 void test_concatenate_string_array(void **state);
0d097b
 
0d097b
+/* from src/tests/cmocka/test_sss_ptr_hash.c */
0d097b
+void test_sss_ptr_hash_with_free_cb(void **state);
0d097b
+void test_sss_ptr_hash_with_lookup_cb(void **state);
0d097b
+void test_sss_ptr_hash_without_cb(void **state);
0d097b
+
0d097b
+
0d097b
 #endif /* __TESTS__CMOCKA__TEST_UTILS_H__ */
0d097b
-- 
0d097b
2.20.1
0d097b