diff --git a/lib/common/tests/nvpair/Makefile.am b/lib/common/tests/nvpair/Makefile.am index cfd800a7e1..c6f5984315 100644 --- a/lib/common/tests/nvpair/Makefile.am +++ b/lib/common/tests/nvpair/Makefile.am @@ -1,24 +1,25 @@ # # Copyright 2021-2024 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # include $(top_srcdir)/mk/common.mk include $(top_srcdir)/mk/tap.mk include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. check_PROGRAMS = crm_meta_name_test \ crm_meta_value_test \ pcmk__cmp_nvpair_blocks_test \ pcmk__xe_attr_is_true_test \ pcmk__xe_get_bool_attr_test \ pcmk__xe_get_datetime_test \ pcmk__xe_get_flags_test \ - pcmk__xe_set_bool_attr_test + pcmk__xe_set_bool_attr_test \ + pcmk__unpack_nvpair_block_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/nvpair/pcmk__unpack_nvpair_block_test.c b/lib/common/tests/nvpair/pcmk__unpack_nvpair_block_test.c new file mode 100644 index 0000000000..ec7ba2f499 --- /dev/null +++ b/lib/common/tests/nvpair/pcmk__unpack_nvpair_block_test.c @@ -0,0 +1,187 @@ +/* + * Copyright 2024 the Pacemaker project contributors + * + * The version control history for this file may have further details. + * + * This source code is licensed under the GNU General Public License version 2 + * or later (GPLv2+) WITHOUT ANY WARRANTY. + */ + +#include + +#include +#include + +#define XML_PASSING_RULE \ + "<" PCMK_XE_RULE " " PCMK_XA_ID "='rp' >\n" \ + "<" PCMK_XE_DATE_EXPRESSION " " PCMK_XA_ID "='ep' " \ + PCMK_XA_OPERATION "='" PCMK_VALUE_GT "' " \ + PCMK_XA_START "='1950-01-01 00:00:00' />\n" \ + "\n" + +#define XML_FAILING_RULE \ + "<" PCMK_XE_RULE " " PCMK_XA_ID "='rf' >\n" \ + "<" PCMK_XE_DATE_EXPRESSION " " PCMK_XA_ID "='ef' " \ + PCMK_XA_OPERATION "='" PCMK_VALUE_LT "' " \ + PCMK_XA_END "='1950-01-01 00:00:00' />\n" \ + "\n" + +#define XML_NVPAIRS_1 \ + "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp1-1' " \ + PCMK_XA_NAME "='name1' " PCMK_XA_VALUE "='1' />\n" \ + "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp1-2' " \ + PCMK_XA_NAME "='name2' " PCMK_XA_VALUE "='1' />\n" + +#define XML_NVPAIRS_2 \ + "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp2-1' " \ + PCMK_XA_NAME "='name1' " PCMK_XA_VALUE "='2' />\n" \ + "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp2-2' " \ + PCMK_XA_NAME "='name2' " PCMK_XA_VALUE "='2' />\n" \ + "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp2-3' " \ + PCMK_XA_NAME "='name3' " PCMK_XA_VALUE "='2' />\n" + +static void +invalid_args(void **state) +{ + pcmk__nvpair_unpack_t unpack_data = { + .values = NULL, + .rule_input = { + .now = NULL, + }, + }; + + xmlNode *xml = pcmk__xml_parse(""); + + assert_non_null(xml); + + pcmk__assert_asserts(pcmk__unpack_nvpair_block(NULL, NULL)); + pcmk__assert_asserts(pcmk__unpack_nvpair_block(NULL, &unpack_data)); + pcmk__assert_asserts(pcmk__unpack_nvpair_block(xml, NULL)); + pcmk__assert_asserts(pcmk__unpack_nvpair_block(xml, &unpack_data)); + + unpack_data.values = g_hash_table_new(NULL, NULL); + pcmk__assert_asserts(pcmk__unpack_nvpair_block(NULL, &unpack_data)); + g_hash_table_destroy(unpack_data.values); + + pcmk__xml_free(xml); +} + +static void +with_rules(void **state) { + crm_time_t *now = crm_time_new("2024-01-01 15:00:00"); + pcmk__nvpair_unpack_t unpack_data = { + .values = pcmk__strkey_table(free, free), + .rule_input = { + .now = now, + }, + }; + + xmlNode *xml = NULL; + + xml = pcmk__xml_parse("\n" XML_NVPAIRS_1 XML_PASSING_RULE "\n"); + assert_non_null(xml); + pcmk__unpack_nvpair_block(xml, &unpack_data); + assert_int_equal(g_hash_table_size(unpack_data.values), 2); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name1"), "1"); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name2"), "1"); + pcmk__xml_free(xml); + + xml = pcmk__xml_parse("\n" XML_NVPAIRS_2 XML_FAILING_RULE "\n"); + assert_non_null(xml); + pcmk__unpack_nvpair_block(xml, &unpack_data); + assert_int_equal(g_hash_table_size(unpack_data.values), 2); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name1"), "1"); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name2"), "1"); + assert_null(g_hash_table_lookup(unpack_data.values, "name3")); + + pcmk__xml_free(xml); + crm_time_free(now); + g_hash_table_destroy(unpack_data.values); +} + +static void +without_overwrite(void **state) +{ + pcmk__nvpair_unpack_t unpack_data = { + .values = pcmk__strkey_table(free, free), + .overwrite = false, + }; + + xmlNode *xml = NULL; + + xml = pcmk__xml_parse("\n" XML_NVPAIRS_1 "\n"); + assert_non_null(xml); + pcmk__unpack_nvpair_block(xml, &unpack_data); + assert_int_equal(g_hash_table_size(unpack_data.values), 2); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name1"), "1"); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name2"), "1"); + pcmk__xml_free(xml); + + xml = pcmk__xml_parse("\n" XML_NVPAIRS_2 "\n"); + assert_non_null(xml); + pcmk__unpack_nvpair_block(xml, &unpack_data); + assert_int_equal(g_hash_table_size(unpack_data.values), 3); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name1"), "1"); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name2"), "1"); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name3"), "2"); + pcmk__xml_free(xml); + + g_hash_table_destroy(unpack_data.values); +} + +static void +with_overwrite(void **state) +{ + pcmk__nvpair_unpack_t unpack_data = { + .values = pcmk__strkey_table(free, free), + .overwrite = true, + }; + + xmlNode *xml = NULL; + + xml = pcmk__xml_parse("\n" XML_NVPAIRS_1 "\n"); + assert_non_null(xml); + pcmk__unpack_nvpair_block(xml, &unpack_data); + assert_int_equal(g_hash_table_size(unpack_data.values), 2); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name1"), "1"); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name2"), "1"); + pcmk__xml_free(xml); + + xml = pcmk__xml_parse("\n" XML_NVPAIRS_2 "\n"); + assert_non_null(xml); + pcmk__unpack_nvpair_block(xml, &unpack_data); + assert_int_equal(g_hash_table_size(unpack_data.values), 3); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name1"), "2"); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name2"), "2"); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name3"), "2"); + pcmk__xml_free(xml); + + g_hash_table_destroy(unpack_data.values); +} + +static void +attributes_child(void **state) +{ + pcmk__nvpair_unpack_t unpack_data = { + .values = pcmk__strkey_table(free, free), + }; + + xmlNode *xml = pcmk__xml_parse("\n<" PCMK__XE_ATTRIBUTES ">\n" + XML_NVPAIRS_1 + "\n\n"); + assert_non_null(xml); + pcmk__unpack_nvpair_block(xml, &unpack_data); + assert_int_equal(g_hash_table_size(unpack_data.values), 2); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name1"), "1"); + assert_string_equal(g_hash_table_lookup(unpack_data.values, "name2"), "1"); + pcmk__xml_free(xml); + + g_hash_table_destroy(unpack_data.values); +} + +PCMK__UNIT_TEST(pcmk__xml_test_setup_group, pcmk__xml_test_teardown_group, + cmocka_unit_test(invalid_args), + cmocka_unit_test(with_rules), + cmocka_unit_test(without_overwrite), + cmocka_unit_test(with_overwrite), + cmocka_unit_test(attributes_child))