root/lib/common/tests/nvpair/pcmk_unpack_nvpair_blocks_test.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. null_xml
  2. null_table
  3. rule_passes
  4. rule_fails
  5. element_name
  6. first_id

   1 /*
   2  * Copyright 2024 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU General Public License version 2
   7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <glib.h>
  13 #include <libxml/tree.h>
  14 
  15 #include <crm/common/unittest_internal.h>
  16 
  17 #include <crm/common/iso8601.h>
  18 #include <crm/common/xml.h>
  19 
  20 /* The test XML is designed so that:
  21  * - The blocks are, lowest score to highest, #2 #3 #1 (to test sorting)
  22  * - The first block can be used to test rule evaluation by setting "now"
  23  * - The first block has a different element name than the other two,
  24  *   to test specifying an element name
  25  * - The middle block can be used to test ID precedence
  26 */
  27 #define XML_BLOCKS                                                  \
  28     "<xml>\n"                                                       \
  29       "<" PCMK_XE_META_ATTRIBUTES " " PCMK_XA_ID "='ia1' "          \
  30           PCMK_XA_SCORE "='100' >"                                  \
  31           "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp1-1' "            \
  32               PCMK_XA_NAME "='name1' " PCMK_XA_VALUE "='1' />\n"    \
  33           "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp1-2' "            \
  34               PCMK_XA_NAME "='name2' " PCMK_XA_VALUE "='1' />\n"    \
  35           "<" PCMK_XE_RULE " " PCMK_XA_ID "='rp' >\n"               \
  36             "<" PCMK_XE_DATE_EXPRESSION " " PCMK_XA_ID "='ep' "     \
  37                 PCMK_XA_OPERATION "='" PCMK_VALUE_GT "' "           \
  38                 PCMK_XA_START "='2024-11-05 00:00:00' />\n"         \
  39           "</" PCMK_XE_RULE ">\n"                                   \
  40       "</" PCMK_XE_META_ATTRIBUTES ">\n"                            \
  41       "<" PCMK_XE_INSTANCE_ATTRIBUTES " " PCMK_XA_ID "='ia2' "      \
  42           PCMK_XA_SCORE "='2' >"                                    \
  43           "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp2-1' "            \
  44               PCMK_XA_NAME "='name1' " PCMK_XA_VALUE "='2' />\n"    \
  45           "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp2-2' "            \
  46               PCMK_XA_NAME "='name2' " PCMK_XA_VALUE "='2' />\n"    \
  47           "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp2-3' "            \
  48               PCMK_XA_NAME "='name3' " PCMK_XA_VALUE "='2' />\n"    \
  49       "</" PCMK_XE_INSTANCE_ATTRIBUTES ">\n"                        \
  50       "<" PCMK_XE_INSTANCE_ATTRIBUTES " " PCMK_XA_ID "='ia3' "      \
  51           PCMK_XA_SCORE "='30' >"                                   \
  52           "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp3-1' "            \
  53               PCMK_XA_NAME "='name1' " PCMK_XA_VALUE "='3' />\n"    \
  54           "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp3-2' "            \
  55               PCMK_XA_NAME "='name2' " PCMK_XA_VALUE "='3' />\n"    \
  56           "<" PCMK_XE_NVPAIR " " PCMK_XA_ID "='nvp3-3' "            \
  57               PCMK_XA_NAME "='name3' " PCMK_XA_VALUE "='3' />\n"    \
  58       "</" PCMK_XE_INSTANCE_ATTRIBUTES ">\n"                        \
  59     "</xml>\n"
  60 
  61 
  62 static void
  63 null_xml(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
  64 {
  65     GHashTable *values = pcmk__strkey_table(free, free);
  66     crm_time_t *now = crm_time_new("2024-01-01 15:00:00");
  67     crm_time_t *next_change = crm_time_new("2024-01-01 20:00:00");
  68     pcmk_rule_input_t rule_input = {
  69         .now = now,
  70     };
  71 
  72     // This mainly tests that it doesn't crash
  73     pcmk_unpack_nvpair_blocks(NULL, PCMK_XE_INSTANCE_ATTRIBUTES, "id1",
  74                               &rule_input, values, next_change);
  75     assert_int_equal(g_hash_table_size(values), 0);
  76     g_hash_table_destroy(values);
  77     crm_time_free(now);
  78     crm_time_free(next_change);
  79 }
  80 
  81 static void
  82 null_table(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
  83 {
  84     xmlNode *xml = pcmk__xml_parse(XML_BLOCKS);
  85     crm_time_t *now = crm_time_new("2024-01-01 15:00:00");
  86     crm_time_t *next_change = crm_time_new("2024-01-01 20:00:00");
  87     pcmk_rule_input_t rule_input = {
  88         .now = now,
  89     };
  90 
  91     assert_non_null(xml);
  92     pcmk__assert_asserts(pcmk_unpack_nvpair_blocks(xml,
  93                                                    PCMK_XE_INSTANCE_ATTRIBUTES,
  94                                                    "id1", &rule_input, NULL,
  95                                                    next_change));
  96     pcmk__xml_free(xml);
  97     crm_time_free(next_change);
  98     crm_time_free(now);
  99 }
 100 
 101 static void
 102 rule_passes(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104     xmlNode *xml = pcmk__xml_parse(XML_BLOCKS);
 105     crm_time_t *now = crm_time_new("2024-11-06 15:00:00");
 106     crm_time_t *next_change = crm_time_new("2024-11-06 20:00:00");
 107     GHashTable *values = pcmk__strkey_table(free, free);
 108     pcmk_rule_input_t rule_input = {
 109         .now = now,
 110     };
 111 
 112     assert_non_null(xml);
 113     pcmk_unpack_nvpair_blocks(xml, NULL, "id1", &rule_input, values,
 114                               next_change);
 115     assert_int_equal(g_hash_table_size(values), 3);
 116     assert_string_equal(g_hash_table_lookup(values, "name1"), "1");
 117     assert_string_equal(g_hash_table_lookup(values, "name2"), "1");
 118     assert_string_equal(g_hash_table_lookup(values, "name3"), "3");
 119 
 120     pcmk__xml_free(xml);
 121     crm_time_free(next_change);
 122     crm_time_free(now);
 123     g_hash_table_destroy(values);
 124 }
 125 
 126 static void
 127 rule_fails(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129     xmlNode *xml = pcmk__xml_parse(XML_BLOCKS);
 130     crm_time_t *now = crm_time_new("2024-11-04 15:00:00");
 131     crm_time_t *next_change = crm_time_new("2024-11-05 20:00:00");
 132     crm_time_t *expected_next_change = crm_time_new("2024-11-05 00:00:01");
 133     GHashTable *values = pcmk__strkey_table(free, free);
 134     pcmk_rule_input_t rule_input = {
 135         .now = now,
 136     };
 137 
 138     // This also tests that next_change is set when appropriate
 139 
 140     assert_non_null(xml);
 141     pcmk_unpack_nvpair_blocks(xml, NULL, "id1", &rule_input, values,
 142                               next_change);
 143     assert_int_equal(g_hash_table_size(values), 3);
 144     assert_string_equal(g_hash_table_lookup(values, "name1"), "3");
 145     assert_string_equal(g_hash_table_lookup(values, "name2"), "3");
 146     assert_string_equal(g_hash_table_lookup(values, "name3"), "3");
 147     assert_int_equal(crm_time_compare(next_change, expected_next_change), 0);
 148 
 149     pcmk__xml_free(xml);
 150     crm_time_free(now);
 151     crm_time_free(next_change);
 152     crm_time_free(expected_next_change);
 153     g_hash_table_destroy(values);
 154 }
 155 
 156 static void
 157 element_name(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 158 {
 159     xmlNode *xml = pcmk__xml_parse(XML_BLOCKS);
 160     crm_time_t *now = crm_time_new("2024-11-06 15:00:00");
 161     GHashTable *values = pcmk__strkey_table(free, free);
 162     pcmk_rule_input_t rule_input = {
 163         .now = now,
 164     };
 165 
 166     assert_non_null(xml);
 167 
 168     /* This also tests that NULL first_id and next_change are handled without
 169      * problems
 170      */
 171 
 172     pcmk_unpack_nvpair_blocks(xml, PCMK_XE_META_ATTRIBUTES, NULL, &rule_input,
 173                               values, NULL);
 174     assert_int_equal(g_hash_table_size(values), 2);
 175     assert_string_equal(g_hash_table_lookup(values, "name1"), "1");
 176     assert_string_equal(g_hash_table_lookup(values, "name2"), "1");
 177     assert_null(g_hash_table_lookup(values, "name3"));
 178     g_hash_table_remove_all(values);
 179 
 180     pcmk_unpack_nvpair_blocks(xml, PCMK_XE_INSTANCE_ATTRIBUTES, NULL,
 181                               &rule_input, values, NULL);
 182     assert_int_equal(g_hash_table_size(values), 3);
 183     assert_string_equal(g_hash_table_lookup(values, "name1"), "3");
 184     assert_string_equal(g_hash_table_lookup(values, "name2"), "3");
 185     assert_string_equal(g_hash_table_lookup(values, "name3"), "3");
 186 
 187     pcmk__xml_free(xml);
 188     crm_time_free(now);
 189     g_hash_table_destroy(values);
 190 }
 191 
 192 static void
 193 first_id(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 194 {
 195     xmlNode *xml = pcmk__xml_parse(XML_BLOCKS);
 196     GHashTable *values = pcmk__strkey_table(free, free);
 197 
 198     assert_non_null(xml);
 199 
 200     // This also tests that NULL rule_input is handled without problems
 201 
 202     pcmk_unpack_nvpair_blocks(xml, NULL, "ia2", NULL, values, NULL);
 203     assert_int_equal(g_hash_table_size(values), 3);
 204     assert_string_equal(g_hash_table_lookup(values, "name1"), "2");
 205     assert_string_equal(g_hash_table_lookup(values, "name2"), "2");
 206     assert_string_equal(g_hash_table_lookup(values, "name3"), "2");
 207 
 208     pcmk__xml_free(xml);
 209     g_hash_table_destroy(values);
 210 }
 211 
 212 PCMK__UNIT_TEST(pcmk__xml_test_setup_group, pcmk__xml_test_teardown_group,
 213                 cmocka_unit_test(null_xml),
 214                 cmocka_unit_test(null_table),
 215                 cmocka_unit_test(rule_passes),
 216                 cmocka_unit_test(rule_fails),
 217                 cmocka_unit_test(element_name),
 218                 cmocka_unit_test(first_id))

/* [previous][next][first][last][top][bottom][index][help] */