root/lib/pengine/tests/native/native_find_rsc_test.c

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

DEFINITIONS

This source file includes following definitions.
  1. setup
  2. teardown
  3. bad_args
  4. primitive_rsc
  5. group_rsc
  6. inactive_group_rsc
  7. group_member_rsc
  8. inactive_group_member_rsc
  9. clone_rsc
  10. inactive_clone_rsc
  11. clone_instance_rsc
  12. renamed_rsc
  13. bundle_rsc
  14. bundle_first_replica
  15. bundle_replica_rsc
  16. clone_group_rsc
  17. clone_group_instance_rsc
  18. clone_group_member_rsc

   1 /*
   2  * Copyright 2022-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 <crm/common/unittest_internal.h>
  13 #include <crm/common/scheduler.h>
  14 #include <crm/common/xml.h>
  15 #include <crm/pengine/internal.h>
  16 #include <crm/pengine/status.h>
  17 
  18 xmlNode *input = NULL;
  19 pcmk_scheduler_t *scheduler = NULL;
  20 
  21 pcmk_node_t *cluster01, *cluster02, *httpd_bundle_0;
  22 pcmk_resource_t *exim_group, *inactive_group;
  23 pcmk_resource_t *promotable_clone, *inactive_clone;
  24 pcmk_resource_t *httpd_bundle, *mysql_clone_group;
  25 
  26 static int
  27 setup(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
  28     char *path = NULL;
  29 
  30     crm_xml_init();
  31 
  32     path = crm_strdup_printf("%s/crm_mon.xml", getenv("PCMK_CTS_CLI_DIR"));
  33     input = pcmk__xml_read(path);
  34     free(path);
  35 
  36     if (input == NULL) {
  37         return 1;
  38     }
  39 
  40     scheduler = pe_new_working_set();
  41 
  42     if (scheduler == NULL) {
  43         return 1;
  44     }
  45 
  46     pcmk__set_scheduler_flags(scheduler,
  47                               pcmk_sched_no_counts|pcmk_sched_no_compat);
  48     scheduler->input = input;
  49 
  50     cluster_status(scheduler);
  51 
  52     /* Get references to the cluster nodes so we don't have to find them repeatedly. */
  53     cluster01 = pcmk_find_node(scheduler, "cluster01");
  54     cluster02 = pcmk_find_node(scheduler, "cluster02");
  55     httpd_bundle_0 = pcmk_find_node(scheduler, "httpd-bundle-0");
  56 
  57     /* Get references to several resources we use frequently. */
  58     for (GList *iter = scheduler->resources; iter != NULL; iter = iter->next) {
  59         pcmk_resource_t *rsc = (pcmk_resource_t *) iter->data;
  60 
  61         if (strcmp(rsc->id, "exim-group") == 0) {
  62             exim_group = rsc;
  63         } else if (strcmp(rsc->id, "httpd-bundle") == 0) {
  64             httpd_bundle = rsc;
  65         } else if (strcmp(rsc->id, "inactive-clone") == 0) {
  66             inactive_clone = rsc;
  67         } else if (strcmp(rsc->id, "inactive-group") == 0) {
  68             inactive_group = rsc;
  69         } else if (strcmp(rsc->id, "mysql-clone-group") == 0) {
  70             mysql_clone_group = rsc;
  71         } else if (strcmp(rsc->id, "promotable-clone") == 0) {
  72             promotable_clone = rsc;
  73         }
  74     }
  75 
  76     return 0;
  77 }
  78 
  79 static int
  80 teardown(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
  81     pe_free_working_set(scheduler);
  82 
  83     return 0;
  84 }
  85 
  86 static void
  87 bad_args(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
  88     pcmk_resource_t *rsc = g_list_first(scheduler->resources)->data;
  89     char *id = rsc->id;
  90     char *name = NULL;
  91 
  92     assert_non_null(rsc);
  93 
  94     assert_null(native_find_rsc(NULL, "dummy", NULL, 0));
  95     assert_null(native_find_rsc(rsc, NULL, NULL, 0));
  96 
  97     /* No resources exist with these names. */
  98     name = crm_strdup_printf("%sX", rsc->id);
  99     assert_null(native_find_rsc(rsc, name, NULL, 0));
 100     free(name);
 101 
 102     name = crm_strdup_printf("x%s", rsc->id);
 103     assert_null(native_find_rsc(rsc, name, NULL, 0));
 104     free(name);
 105 
 106     name = g_ascii_strup(rsc->id, -1);
 107     assert_null(native_find_rsc(rsc, name, NULL, 0));
 108     g_free(name);
 109 
 110     /* Fails because resource ID is NULL. */
 111     rsc->id = NULL;
 112     assert_null(native_find_rsc(rsc, id, NULL, 0));
 113     rsc->id = id;
 114 }
 115 
 116 static void
 117 primitive_rsc(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
 118     pcmk_resource_t *dummy = NULL;
 119 
 120     /* Find the "dummy" resource, which is the only one with that ID in the set. */
 121     for (GList *iter = scheduler->resources; iter != NULL; iter = iter->next) {
 122         pcmk_resource_t *rsc = (pcmk_resource_t *) iter->data;
 123 
 124         if (strcmp(rsc->id, "dummy") == 0) {
 125             dummy = rsc;
 126             break;
 127         }
 128     }
 129 
 130     assert_non_null(dummy);
 131 
 132     /* Passes because NULL was passed for node, regardless of flags. */
 133     assert_ptr_equal(dummy, native_find_rsc(dummy, "dummy", NULL, 0));
 134     assert_ptr_equal(dummy,
 135                      native_find_rsc(dummy, "dummy", NULL,
 136                                      pcmk_rsc_match_current_node));
 137 
 138     /* Fails because resource is not a clone (nor cloned). */
 139     assert_null(native_find_rsc(dummy, "dummy", NULL,
 140                                 pcmk_rsc_match_clone_only));
 141     assert_null(native_find_rsc(dummy, "dummy", cluster02,
 142                                 pcmk_rsc_match_clone_only));
 143 
 144     /* Fails because dummy is not running on cluster01, even with the right flags. */
 145     assert_null(native_find_rsc(dummy, "dummy", cluster01,
 146                                 pcmk_rsc_match_current_node));
 147 
 148     // Fails because pcmk_rsc_match_current_node is required if a node is given
 149     assert_null(native_find_rsc(dummy, "dummy", cluster02, 0));
 150 
 151     /* Passes because dummy is running on cluster02. */
 152     assert_ptr_equal(dummy,
 153                      native_find_rsc(dummy, "dummy", cluster02,
 154                                      pcmk_rsc_match_current_node));
 155 }
 156 
 157 static void
 158 group_rsc(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
 159     assert_non_null(exim_group);
 160 
 161     /* Passes because NULL was passed for node, regardless of flags. */
 162     assert_ptr_equal(exim_group, native_find_rsc(exim_group, "exim-group", NULL, 0));
 163     assert_ptr_equal(exim_group,
 164                      native_find_rsc(exim_group, "exim-group", NULL,
 165                                      pcmk_rsc_match_current_node));
 166 
 167     /* Fails because resource is not a clone (nor cloned). */
 168     assert_null(native_find_rsc(exim_group, "exim-group", NULL,
 169                                 pcmk_rsc_match_clone_only));
 170     assert_null(native_find_rsc(exim_group, "exim-group", cluster01,
 171                                 pcmk_rsc_match_clone_only));
 172 
 173     /* Fails because none of exim-group's children are running on cluster01, even with the right flags. */
 174     assert_null(native_find_rsc(exim_group, "exim-group", cluster01,
 175                                 pcmk_rsc_match_current_node));
 176 
 177     // Fails because pcmk_rsc_match_current_node is required if a node is given
 178     assert_null(native_find_rsc(exim_group, "exim-group", cluster01, 0));
 179 
 180     /* Passes because one of exim-group's children is running on cluster02. */
 181     assert_ptr_equal(exim_group,
 182                      native_find_rsc(exim_group, "exim-group", cluster02,
 183                                      pcmk_rsc_match_current_node));
 184 }
 185 
 186 static void
 187 inactive_group_rsc(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
 188     assert_non_null(inactive_group);
 189 
 190     /* Passes because NULL was passed for node, regardless of flags. */
 191     assert_ptr_equal(inactive_group, native_find_rsc(inactive_group, "inactive-group", NULL, 0));
 192     assert_ptr_equal(inactive_group,
 193                      native_find_rsc(inactive_group, "inactive-group", NULL,
 194                                      pcmk_rsc_match_current_node));
 195 
 196     /* Fails because resource is not a clone (nor cloned). */
 197     assert_null(native_find_rsc(inactive_group, "inactive-group", NULL,
 198                                 pcmk_rsc_match_clone_only));
 199     assert_null(native_find_rsc(inactive_group, "inactive-group", cluster01,
 200                                 pcmk_rsc_match_clone_only));
 201 
 202     /* Fails because none of inactive-group's children are running. */
 203     assert_null(native_find_rsc(inactive_group, "inactive-group", cluster01,
 204                                 pcmk_rsc_match_current_node));
 205     assert_null(native_find_rsc(inactive_group, "inactive-group", cluster02,
 206                                 pcmk_rsc_match_current_node));
 207 }
 208 
 209 static void
 210 group_member_rsc(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
 211     pcmk_resource_t *public_ip = NULL;
 212 
 213     /* Find the "Public-IP" resource, a member of "exim-group". */
 214     for (GList *iter = exim_group->children; iter != NULL; iter = iter->next) {
 215         pcmk_resource_t *rsc = (pcmk_resource_t *) iter->data;
 216 
 217         if (strcmp(rsc->id, "Public-IP") == 0) {
 218             public_ip = rsc;
 219             break;
 220         }
 221     }
 222 
 223     assert_non_null(public_ip);
 224 
 225     /* Passes because NULL was passed for node, regardless of flags. */
 226     assert_ptr_equal(public_ip, native_find_rsc(public_ip, "Public-IP", NULL, 0));
 227     assert_ptr_equal(public_ip,
 228                      native_find_rsc(public_ip, "Public-IP", NULL,
 229                                      pcmk_rsc_match_current_node));
 230 
 231     /* Fails because resource is not a clone (nor cloned). */
 232     assert_null(native_find_rsc(public_ip, "Public-IP", NULL,
 233                                 pcmk_rsc_match_clone_only));
 234     assert_null(native_find_rsc(public_ip, "Public-IP", cluster02,
 235                                 pcmk_rsc_match_clone_only));
 236 
 237     /* Fails because Public-IP is not running on cluster01, even with the right flags. */
 238     assert_null(native_find_rsc(public_ip, "Public-IP", cluster01,
 239                                 pcmk_rsc_match_current_node));
 240 
 241     // Fails because pcmk_rsc_match_current_node is required if a node is given
 242     assert_null(native_find_rsc(public_ip, "Public-IP", cluster02, 0));
 243 
 244     /* Passes because Public-IP is running on cluster02. */
 245     assert_ptr_equal(public_ip,
 246                      native_find_rsc(public_ip, "Public-IP", cluster02,
 247                                      pcmk_rsc_match_current_node));
 248 }
 249 
 250 static void
 251 inactive_group_member_rsc(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
 252     pcmk_resource_t *inactive_dummy_1 = NULL;
 253 
 254     /* Find the "inactive-dummy-1" resource, a member of "inactive-group". */
 255     for (GList *iter = inactive_group->children; iter != NULL; iter = iter->next) {
 256         pcmk_resource_t *rsc = (pcmk_resource_t *) iter->data;
 257 
 258         if (strcmp(rsc->id, "inactive-dummy-1") == 0) {
 259             inactive_dummy_1 = rsc;
 260             break;
 261         }
 262     }
 263 
 264     assert_non_null(inactive_dummy_1);
 265 
 266     /* Passes because NULL was passed for node, regardless of flags. */
 267     assert_ptr_equal(inactive_dummy_1, native_find_rsc(inactive_dummy_1, "inactive-dummy-1", NULL, 0));
 268     assert_ptr_equal(inactive_dummy_1,
 269                      native_find_rsc(inactive_dummy_1, "inactive-dummy-1", NULL,
 270                                      pcmk_rsc_match_current_node));
 271 
 272     /* Fails because resource is not a clone (nor cloned). */
 273     assert_null(native_find_rsc(inactive_dummy_1, "inactive-dummy-1", NULL,
 274                                 pcmk_rsc_match_clone_only));
 275     assert_null(native_find_rsc(inactive_dummy_1, "inactive-dummy-1", cluster01,
 276                                 pcmk_rsc_match_clone_only));
 277 
 278     /* Fails because inactive-dummy-1 is not running. */
 279     assert_null(native_find_rsc(inactive_dummy_1, "inactive-dummy-1", cluster01,
 280                                 pcmk_rsc_match_current_node));
 281     assert_null(native_find_rsc(inactive_dummy_1, "inactive-dummy-1", cluster02,
 282                                 pcmk_rsc_match_current_node));
 283 }
 284 
 285 static void
 286 clone_rsc(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
 287     assert_non_null(promotable_clone);
 288 
 289     /* Passes because NULL was passed for node, regardless of flags. */
 290     assert_ptr_equal(promotable_clone, native_find_rsc(promotable_clone, "promotable-clone", NULL, 0));
 291     assert_ptr_equal(promotable_clone,
 292                      native_find_rsc(promotable_clone, "promotable-clone", NULL,
 293                                      pcmk_rsc_match_current_node));
 294     assert_ptr_equal(promotable_clone,
 295                      native_find_rsc(promotable_clone, "promotable-clone", NULL,
 296                                      pcmk_rsc_match_clone_only));
 297 
 298     // Fails because pcmk_rsc_match_current_node is required if a node is given
 299     assert_null(native_find_rsc(promotable_clone, "promotable-clone", cluster01, 0));
 300 
 301     /* Passes because one of ping-clone's children is running on cluster01. */
 302     assert_ptr_equal(promotable_clone,
 303                      native_find_rsc(promotable_clone, "promotable-clone",
 304                                      cluster01, pcmk_rsc_match_current_node));
 305 
 306     // Fails because pcmk_rsc_match_current_node is required if a node is given
 307     assert_null(native_find_rsc(promotable_clone, "promotable-clone", cluster02, 0));
 308 
 309     /* Passes because one of ping_clone's children is running on cluster02. */
 310     assert_ptr_equal(promotable_clone,
 311                      native_find_rsc(promotable_clone, "promotable-clone",
 312                                      cluster02, pcmk_rsc_match_current_node));
 313 
 314     // Passes for previous reasons, plus includes pcmk_rsc_match_clone_only
 315     assert_ptr_equal(promotable_clone,
 316                      native_find_rsc(promotable_clone, "promotable-clone",
 317                                      cluster01,
 318                                      pcmk_rsc_match_clone_only
 319                                      |pcmk_rsc_match_current_node));
 320     assert_ptr_equal(promotable_clone,
 321                      native_find_rsc(promotable_clone, "promotable-clone",
 322                                      cluster02,
 323                                      pcmk_rsc_match_clone_only
 324                                      |pcmk_rsc_match_current_node));
 325 }
 326 
 327 static void
 328 inactive_clone_rsc(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
 329     assert_non_null(inactive_clone);
 330 
 331     /* Passes because NULL was passed for node, regardless of flags. */
 332     assert_ptr_equal(inactive_clone, native_find_rsc(inactive_clone, "inactive-clone", NULL, 0));
 333     assert_ptr_equal(inactive_clone,
 334                      native_find_rsc(inactive_clone, "inactive-clone", NULL,
 335                                      pcmk_rsc_match_current_node));
 336     assert_ptr_equal(inactive_clone,
 337                      native_find_rsc(inactive_clone, "inactive-clone", NULL,
 338                                      pcmk_rsc_match_clone_only));
 339 
 340     /* Fails because none of inactive-clone's children are running. */
 341     assert_null(native_find_rsc(inactive_clone, "inactive-clone", cluster01,
 342                                 pcmk_rsc_match_current_node
 343                                 |pcmk_rsc_match_clone_only));
 344     assert_null(native_find_rsc(inactive_clone, "inactive-clone", cluster02,
 345                                 pcmk_rsc_match_current_node
 346                                 |pcmk_rsc_match_clone_only));
 347 }
 348 
 349 static void
 350 clone_instance_rsc(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
 351     pcmk_resource_t *promotable_0 = NULL;
 352     pcmk_resource_t *promotable_1 = NULL;
 353 
 354     /* Find the "promotable-rsc:0" and "promotable-rsc:1" resources, members of "promotable-clone". */
 355     for (GList *iter = promotable_clone->children; iter != NULL; iter = iter->next) {
 356         pcmk_resource_t *rsc = (pcmk_resource_t *) iter->data;
 357 
 358         if (strcmp(rsc->id, "promotable-rsc:0") == 0) {
 359             promotable_0 = rsc;
 360         } else if (strcmp(rsc->id, "promotable-rsc:1") == 0) {
 361             promotable_1 = rsc;
 362         }
 363     }
 364 
 365     assert_non_null(promotable_0);
 366     assert_non_null(promotable_1);
 367 
 368     /* Passes because NULL was passed for node, regardless of flags. */
 369     assert_ptr_equal(promotable_0, native_find_rsc(promotable_0, "promotable-rsc:0", NULL, 0));
 370     assert_ptr_equal(promotable_0,
 371                      native_find_rsc(promotable_0, "promotable-rsc:0", NULL,
 372                                      pcmk_rsc_match_current_node));
 373     assert_ptr_equal(promotable_1, native_find_rsc(promotable_1, "promotable-rsc:1", NULL, 0));
 374     assert_ptr_equal(promotable_1,
 375                      native_find_rsc(promotable_1, "promotable-rsc:1", NULL,
 376                                      pcmk_rsc_match_current_node));
 377 
 378     // Fails because pcmk_rsc_match_current_node is required if a node is given
 379     assert_null(native_find_rsc(promotable_0, "promotable-rsc:0", cluster02, 0));
 380     assert_null(native_find_rsc(promotable_1, "promotable-rsc:1", cluster01, 0));
 381 
 382     /* Check that the resource is running on the node we expect. */
 383     assert_ptr_equal(promotable_0,
 384                      native_find_rsc(promotable_0, "promotable-rsc:0",
 385                                      cluster02, pcmk_rsc_match_current_node));
 386     assert_null(native_find_rsc(promotable_0, "promotable-rsc:0", cluster01,
 387                                 pcmk_rsc_match_current_node));
 388     assert_ptr_equal(promotable_1,
 389                      native_find_rsc(promotable_1, "promotable-rsc:1",
 390                                      cluster01, pcmk_rsc_match_current_node));
 391     assert_null(native_find_rsc(promotable_1, "promotable-rsc:1", cluster02,
 392                                 pcmk_rsc_match_current_node));
 393 
 394     /* Passes because NULL was passed for node and primitive name was given, with correct flags. */
 395     assert_ptr_equal(promotable_0,
 396                      native_find_rsc(promotable_0, "promotable-rsc", NULL,
 397                                      pcmk_rsc_match_clone_only));
 398 
 399     // Passes because pcmk_rsc_match_basename matches any instance's base name
 400     assert_ptr_equal(promotable_0,
 401                      native_find_rsc(promotable_0, "promotable-rsc", NULL,
 402                                      pcmk_rsc_match_basename));
 403     assert_ptr_equal(promotable_1,
 404                      native_find_rsc(promotable_1, "promotable-rsc", NULL,
 405                                      pcmk_rsc_match_basename));
 406 
 407     // Passes because pcmk_rsc_match_anon_basename matches
 408     assert_ptr_equal(promotable_0,
 409                      native_find_rsc(promotable_0, "promotable-rsc", NULL,
 410                                      pcmk_rsc_match_anon_basename));
 411     assert_ptr_equal(promotable_1,
 412                      native_find_rsc(promotable_1, "promotable-rsc", NULL,
 413                                      pcmk_rsc_match_anon_basename));
 414 
 415     /* Check that the resource is running on the node we expect. */
 416     assert_ptr_equal(promotable_0,
 417                      native_find_rsc(promotable_0, "promotable-rsc", cluster02,
 418                                      pcmk_rsc_match_basename
 419                                      |pcmk_rsc_match_current_node));
 420     assert_ptr_equal(promotable_0,
 421                      native_find_rsc(promotable_0, "promotable-rsc", cluster02,
 422                                      pcmk_rsc_match_anon_basename
 423                                      |pcmk_rsc_match_current_node));
 424     assert_null(native_find_rsc(promotable_0, "promotable-rsc", cluster01,
 425                                 pcmk_rsc_match_basename
 426                                 |pcmk_rsc_match_current_node));
 427     assert_null(native_find_rsc(promotable_0, "promotable-rsc", cluster01,
 428                                 pcmk_rsc_match_anon_basename
 429                                 |pcmk_rsc_match_current_node));
 430     assert_ptr_equal(promotable_1,
 431                      native_find_rsc(promotable_1, "promotable-rsc", cluster01,
 432                                      pcmk_rsc_match_basename
 433                                      |pcmk_rsc_match_current_node));
 434     assert_ptr_equal(promotable_1,
 435                      native_find_rsc(promotable_1, "promotable-rsc", cluster01,
 436                                      pcmk_rsc_match_anon_basename
 437                                      |pcmk_rsc_match_current_node));
 438     assert_null(native_find_rsc(promotable_1, "promotable-rsc", cluster02,
 439                                 pcmk_rsc_match_basename
 440                                 |pcmk_rsc_match_current_node));
 441     assert_null(native_find_rsc(promotable_1, "promotable-rsc", cluster02,
 442                                 pcmk_rsc_match_anon_basename
 443                                 |pcmk_rsc_match_current_node));
 444 
 445     /* Fails because incorrect flags were given along with primitive name. */
 446     assert_null(native_find_rsc(promotable_0, "promotable-rsc", NULL,
 447                                 pcmk_rsc_match_current_node));
 448     assert_null(native_find_rsc(promotable_1, "promotable-rsc", NULL,
 449                                 pcmk_rsc_match_current_node));
 450 
 451     /* And then we check failure possibilities again, except passing promotable_clone
 452      * instead of promotable_X as the first argument to native_find_rsc.
 453      */
 454 
 455     // Fails because pcmk_rsc_match_current_node is required if a node is given
 456     assert_null(native_find_rsc(promotable_clone, "promotable-rsc:0", cluster02, 0));
 457     assert_null(native_find_rsc(promotable_clone, "promotable-rsc:1", cluster01, 0));
 458 
 459     /* Check that the resource is running on the node we expect. */
 460     assert_ptr_equal(promotable_0,
 461                      native_find_rsc(promotable_clone, "promotable-rsc:0",
 462                                      cluster02, pcmk_rsc_match_current_node));
 463     assert_ptr_equal(promotable_0,
 464                      native_find_rsc(promotable_clone, "promotable-rsc",
 465                                      cluster02,
 466                                      pcmk_rsc_match_basename
 467                                      |pcmk_rsc_match_current_node));
 468     assert_ptr_equal(promotable_0,
 469                      native_find_rsc(promotable_clone, "promotable-rsc",
 470                                      cluster02,
 471                                      pcmk_rsc_match_anon_basename
 472                                      |pcmk_rsc_match_current_node));
 473     assert_ptr_equal(promotable_1,
 474                      native_find_rsc(promotable_clone, "promotable-rsc:1",
 475                                      cluster01, pcmk_rsc_match_current_node));
 476     assert_ptr_equal(promotable_1,
 477                      native_find_rsc(promotable_clone, "promotable-rsc",
 478                                      cluster01,
 479                                      pcmk_rsc_match_basename
 480                                      |pcmk_rsc_match_current_node));
 481     assert_ptr_equal(promotable_1,
 482                      native_find_rsc(promotable_clone, "promotable-rsc",
 483                                      cluster01,
 484                                      pcmk_rsc_match_anon_basename
 485                                      |pcmk_rsc_match_current_node));
 486 }
 487 
 488 static void
 489 renamed_rsc(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
 490     pcmk_resource_t *promotable_0 = NULL;
 491     pcmk_resource_t *promotable_1 = NULL;
 492 
 493     /* Find the "promotable-rsc:0" and "promotable-rsc:1" resources, members of "promotable-clone". */
 494     for (GList *iter = promotable_clone->children; iter != NULL; iter = iter->next) {
 495         pcmk_resource_t *rsc = (pcmk_resource_t *) iter->data;
 496 
 497         if (strcmp(rsc->id, "promotable-rsc:0") == 0) {
 498             promotable_0 = rsc;
 499         } else if (strcmp(rsc->id, "promotable-rsc:1") == 0) {
 500             promotable_1 = rsc;
 501         }
 502     }
 503 
 504     assert_non_null(promotable_0);
 505     assert_non_null(promotable_1);
 506 
 507     // Passes because pcmk_rsc_match_history means base name matches clone_name
 508     assert_ptr_equal(promotable_0,
 509                      native_find_rsc(promotable_0, "promotable-rsc", NULL,
 510                                      pcmk_rsc_match_history));
 511     assert_ptr_equal(promotable_1,
 512                      native_find_rsc(promotable_1, "promotable-rsc", NULL,
 513                                      pcmk_rsc_match_history));
 514 }
 515 
 516 static void
 517 bundle_rsc(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
 518     assert_non_null(httpd_bundle);
 519 
 520     /* Passes because NULL was passed for node, regardless of flags. */
 521     assert_ptr_equal(httpd_bundle, native_find_rsc(httpd_bundle, "httpd-bundle", NULL, 0));
 522     assert_ptr_equal(httpd_bundle,
 523                      native_find_rsc(httpd_bundle, "httpd-bundle", NULL,
 524                                      pcmk_rsc_match_current_node));
 525 
 526     /* Fails because resource is not a clone (nor cloned). */
 527     assert_null(native_find_rsc(httpd_bundle, "httpd-bundle", NULL,
 528                                 pcmk_rsc_match_clone_only));
 529     assert_null(native_find_rsc(httpd_bundle, "httpd-bundle", cluster01,
 530                                 pcmk_rsc_match_clone_only));
 531 
 532     // Fails because pcmk_rsc_match_current_node is required if a node is given
 533     assert_null(native_find_rsc(httpd_bundle, "httpd-bundle", cluster01, 0));
 534 
 535     /* Passes because one of httpd_bundle's children is running on cluster01. */
 536     assert_ptr_equal(httpd_bundle,
 537                      native_find_rsc(httpd_bundle, "httpd-bundle", cluster01,
 538                                      pcmk_rsc_match_current_node));
 539 }
 540 
 541 static bool
 542 bundle_first_replica(pcmk__bundle_replica_t *replica, void *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 543 {
 544     pcmk_resource_t *ip_0 = replica->ip;
 545     pcmk_resource_t *child_0 = replica->child;
 546     pcmk_resource_t *container_0 = replica->container;
 547     pcmk_resource_t *remote_0 = replica->remote;
 548 
 549     assert_non_null(ip_0);
 550     assert_non_null(child_0);
 551     assert_non_null(container_0);
 552     assert_non_null(remote_0);
 553 
 554     /* Passes because NULL was passed for node, regardless of flags. */
 555     assert_ptr_equal(ip_0, native_find_rsc(ip_0, "httpd-bundle-ip-192.168.122.131", NULL, 0));
 556     assert_ptr_equal(child_0, native_find_rsc(child_0, "httpd:0", NULL, 0));
 557     assert_ptr_equal(container_0, native_find_rsc(container_0, "httpd-bundle-docker-0", NULL, 0));
 558     assert_ptr_equal(remote_0, native_find_rsc(remote_0, "httpd-bundle-0", NULL, 0));
 559 
 560     // Fails because pcmk_rsc_match_current_node is required if a node is given
 561     assert_null(native_find_rsc(ip_0, "httpd-bundle-ip-192.168.122.131", cluster01, 0));
 562     assert_null(native_find_rsc(child_0, "httpd:0", httpd_bundle_0, 0));
 563     assert_null(native_find_rsc(container_0, "httpd-bundle-docker-0", cluster01, 0));
 564     assert_null(native_find_rsc(remote_0, "httpd-bundle-0", cluster01, 0));
 565 
 566     /* Check that the resource is running on the node we expect. */
 567     assert_ptr_equal(ip_0,
 568                      native_find_rsc(ip_0, "httpd-bundle-ip-192.168.122.131",
 569                                      cluster01, pcmk_rsc_match_current_node));
 570     assert_null(native_find_rsc(ip_0, "httpd-bundle-ip-192.168.122.131",
 571                                 cluster02, pcmk_rsc_match_current_node));
 572     assert_null(native_find_rsc(ip_0, "httpd-bundle-ip-192.168.122.131",
 573                                 httpd_bundle_0, pcmk_rsc_match_current_node));
 574     assert_ptr_equal(child_0,
 575                      native_find_rsc(child_0, "httpd:0", httpd_bundle_0,
 576                                      pcmk_rsc_match_current_node));
 577     assert_null(native_find_rsc(child_0, "httpd:0", cluster01,
 578                                 pcmk_rsc_match_current_node));
 579     assert_null(native_find_rsc(child_0, "httpd:0", cluster02,
 580                                 pcmk_rsc_match_current_node));
 581     assert_ptr_equal(container_0,
 582                      native_find_rsc(container_0, "httpd-bundle-docker-0",
 583                                      cluster01, pcmk_rsc_match_current_node));
 584     assert_null(native_find_rsc(container_0, "httpd-bundle-docker-0", cluster02,
 585                                 pcmk_rsc_match_current_node));
 586     assert_null(native_find_rsc(container_0, "httpd-bundle-docker-0",
 587                                 httpd_bundle_0, pcmk_rsc_match_current_node));
 588     assert_ptr_equal(remote_0,
 589                      native_find_rsc(remote_0, "httpd-bundle-0", cluster01,
 590                                      pcmk_rsc_match_current_node));
 591     assert_null(native_find_rsc(remote_0, "httpd-bundle-0", cluster02,
 592                                 pcmk_rsc_match_current_node));
 593     assert_null(native_find_rsc(remote_0, "httpd-bundle-0", httpd_bundle_0,
 594                                 pcmk_rsc_match_current_node));
 595 
 596     // Passes because pcmk_rsc_match_basename matches any replica's base name
 597     assert_ptr_equal(child_0,
 598                      native_find_rsc(child_0, "httpd", NULL,
 599                                      pcmk_rsc_match_basename));
 600 
 601     // Passes because pcmk_rsc_match_anon_basename matches
 602     assert_ptr_equal(child_0,
 603                      native_find_rsc(child_0, "httpd", NULL,
 604                                      pcmk_rsc_match_anon_basename));
 605 
 606     /* Check that the resource is running on the node we expect. */
 607     assert_ptr_equal(child_0,
 608                      native_find_rsc(child_0, "httpd", httpd_bundle_0,
 609                                      pcmk_rsc_match_basename
 610                                      |pcmk_rsc_match_current_node));
 611     assert_ptr_equal(child_0,
 612                      native_find_rsc(child_0, "httpd", httpd_bundle_0,
 613                                      pcmk_rsc_match_anon_basename
 614                                      |pcmk_rsc_match_current_node));
 615     assert_null(native_find_rsc(child_0, "httpd", cluster01,
 616                                 pcmk_rsc_match_basename
 617                                 |pcmk_rsc_match_current_node));
 618     assert_null(native_find_rsc(child_0, "httpd", cluster01,
 619                                 pcmk_rsc_match_anon_basename
 620                                 |pcmk_rsc_match_current_node));
 621     assert_null(native_find_rsc(child_0, "httpd", cluster02,
 622                                 pcmk_rsc_match_basename
 623                                 |pcmk_rsc_match_current_node));
 624     assert_null(native_find_rsc(child_0, "httpd", cluster02,
 625                                 pcmk_rsc_match_anon_basename
 626                                 |pcmk_rsc_match_current_node));
 627 
 628     /* Fails because incorrect flags were given along with base name. */
 629     assert_null(native_find_rsc(child_0, "httpd", NULL,
 630                                 pcmk_rsc_match_current_node));
 631 
 632     /* And then we check failure possibilities again, except passing httpd-bundle
 633      * instead of X_0 as the first argument to native_find_rsc.
 634      */
 635 
 636     // Fails because pcmk_rsc_match_current_node is required if a node is given
 637     assert_null(native_find_rsc(httpd_bundle, "httpd-bundle-ip-192.168.122.131", cluster01, 0));
 638     assert_null(native_find_rsc(httpd_bundle, "httpd:0", httpd_bundle_0, 0));
 639     assert_null(native_find_rsc(httpd_bundle, "httpd-bundle-docker-0", cluster01, 0));
 640     assert_null(native_find_rsc(httpd_bundle, "httpd-bundle-0", cluster01, 0));
 641 
 642     /* Check that the resource is running on the node we expect. */
 643     assert_ptr_equal(ip_0,
 644                      native_find_rsc(httpd_bundle,
 645                                      "httpd-bundle-ip-192.168.122.131",
 646                                      cluster01, pcmk_rsc_match_current_node));
 647     assert_ptr_equal(child_0,
 648                      native_find_rsc(httpd_bundle, "httpd:0", httpd_bundle_0,
 649                                      pcmk_rsc_match_current_node));
 650     assert_ptr_equal(container_0,
 651                      native_find_rsc(httpd_bundle, "httpd-bundle-docker-0",
 652                                      cluster01, pcmk_rsc_match_current_node));
 653     assert_ptr_equal(remote_0,
 654                      native_find_rsc(httpd_bundle, "httpd-bundle-0", cluster01,
 655                                      pcmk_rsc_match_current_node));
 656     return false; // Do not iterate through any further replicas
 657 }
 658 
 659 static void
 660 bundle_replica_rsc(void **state)
     /* [previous][next][first][last][top][bottom][index][help] */
 661 {
 662     pe__foreach_bundle_replica(httpd_bundle, bundle_first_replica, NULL);
 663 }
 664 
 665 static void
 666 clone_group_rsc(void **rsc) {
     /* [previous][next][first][last][top][bottom][index][help] */
 667     assert_non_null(mysql_clone_group);
 668 
 669     /* Passes because NULL was passed for node, regardless of flags. */
 670     assert_ptr_equal(mysql_clone_group, native_find_rsc(mysql_clone_group, "mysql-clone-group", NULL, 0));
 671     assert_ptr_equal(mysql_clone_group,
 672                      native_find_rsc(mysql_clone_group, "mysql-clone-group",
 673                                      NULL, pcmk_rsc_match_current_node));
 674     assert_ptr_equal(mysql_clone_group,
 675                      native_find_rsc(mysql_clone_group, "mysql-clone-group",
 676                                      NULL, pcmk_rsc_match_clone_only));
 677 
 678     // Fails because pcmk_rsc_match_current_node is required if a node is given
 679     assert_null(native_find_rsc(mysql_clone_group, "mysql-clone-group", cluster01, 0));
 680 
 681     /* Passes because one of mysql-clone-group's children is running on cluster01. */
 682     assert_ptr_equal(mysql_clone_group,
 683                      native_find_rsc(mysql_clone_group, "mysql-clone-group",
 684                                      cluster01, pcmk_rsc_match_current_node));
 685 
 686     // Fails because pcmk_rsc_match_current_node is required if a node is given
 687     assert_null(native_find_rsc(mysql_clone_group, "mysql-clone-group", cluster02, 0));
 688 
 689     /* Passes because one of mysql-clone-group's children is running on cluster02. */
 690     assert_ptr_equal(mysql_clone_group,
 691                      native_find_rsc(mysql_clone_group, "mysql-clone-group",
 692                                      cluster02, pcmk_rsc_match_current_node));
 693 
 694     // Passes for previous reasons, plus includes pcmk_rsc_match_clone_only
 695     assert_ptr_equal(mysql_clone_group,
 696                      native_find_rsc(mysql_clone_group, "mysql-clone-group",
 697                                      cluster01,
 698                                      pcmk_rsc_match_clone_only
 699                                      |pcmk_rsc_match_current_node));
 700     assert_ptr_equal(mysql_clone_group,
 701                      native_find_rsc(mysql_clone_group, "mysql-clone-group",
 702                                      cluster02,
 703                                      pcmk_rsc_match_clone_only
 704                                      |pcmk_rsc_match_current_node));
 705 }
 706 
 707 static void
 708 clone_group_instance_rsc(void **rsc) {
     /* [previous][next][first][last][top][bottom][index][help] */
 709     pcmk_resource_t *mysql_group_0 = NULL;
 710     pcmk_resource_t *mysql_group_1 = NULL;
 711 
 712     /* Find the "mysql-group:0" and "mysql-group:1" resources, members of "mysql-clone-group". */
 713     for (GList *iter = mysql_clone_group->children; iter != NULL; iter = iter->next) {
 714         pcmk_resource_t *rsc = (pcmk_resource_t *) iter->data;
 715 
 716         if (strcmp(rsc->id, "mysql-group:0") == 0) {
 717             mysql_group_0 = rsc;
 718         } else if (strcmp(rsc->id, "mysql-group:1") == 0) {
 719             mysql_group_1 = rsc;
 720         }
 721     }
 722 
 723     assert_non_null(mysql_group_0);
 724     assert_non_null(mysql_group_1);
 725 
 726     /* Passes because NULL was passed for node, regardless of flags. */
 727     assert_ptr_equal(mysql_group_0, native_find_rsc(mysql_group_0, "mysql-group:0", NULL, 0));
 728     assert_ptr_equal(mysql_group_0,
 729                      native_find_rsc(mysql_group_0, "mysql-group:0", NULL,
 730                                      pcmk_rsc_match_current_node));
 731     assert_ptr_equal(mysql_group_1, native_find_rsc(mysql_group_1, "mysql-group:1", NULL, 0));
 732     assert_ptr_equal(mysql_group_1,
 733                      native_find_rsc(mysql_group_1, "mysql-group:1", NULL,
 734                                      pcmk_rsc_match_current_node));
 735 
 736     // Fails because pcmk_rsc_match_current_node is required if a node is given
 737     assert_null(native_find_rsc(mysql_group_0, "mysql-group:0", cluster02, 0));
 738     assert_null(native_find_rsc(mysql_group_1, "mysql-group:1", cluster01, 0));
 739 
 740     /* Check that the resource is running on the node we expect. */
 741     assert_ptr_equal(mysql_group_0,
 742                      native_find_rsc(mysql_group_0, "mysql-group:0", cluster02,
 743                                      pcmk_rsc_match_current_node));
 744     assert_null(native_find_rsc(mysql_group_0, "mysql-group:0", cluster01,
 745                                 pcmk_rsc_match_current_node));
 746     assert_ptr_equal(mysql_group_1,
 747                      native_find_rsc(mysql_group_1, "mysql-group:1", cluster01,
 748                                      pcmk_rsc_match_current_node));
 749     assert_null(native_find_rsc(mysql_group_1, "mysql-group:1", cluster02,
 750                                 pcmk_rsc_match_current_node));
 751 
 752     /* Passes because NULL was passed for node and base name was given, with correct flags. */
 753     assert_ptr_equal(mysql_group_0,
 754                      native_find_rsc(mysql_group_0, "mysql-group" , NULL,
 755                                      pcmk_rsc_match_clone_only));
 756 
 757     // Passes because pcmk_rsc_match_basename matches any base name
 758     assert_ptr_equal(mysql_group_0,
 759                      native_find_rsc(mysql_group_0, "mysql-group" , NULL,
 760                                      pcmk_rsc_match_basename));
 761     assert_ptr_equal(mysql_group_1,
 762                      native_find_rsc(mysql_group_1, "mysql-group" , NULL,
 763                                      pcmk_rsc_match_basename));
 764 
 765     // Passes because pcmk_rsc_match_anon_basename matches
 766     assert_ptr_equal(mysql_group_0,
 767                      native_find_rsc(mysql_group_0, "mysql-group" , NULL,
 768                                      pcmk_rsc_match_anon_basename));
 769     assert_ptr_equal(mysql_group_1,
 770                      native_find_rsc(mysql_group_1, "mysql-group" , NULL,
 771                                      pcmk_rsc_match_anon_basename));
 772 
 773     /* Check that the resource is running on the node we expect. */
 774     assert_ptr_equal(mysql_group_0,
 775                      native_find_rsc(mysql_group_0, "mysql-group", cluster02,
 776                                      pcmk_rsc_match_basename
 777                                      |pcmk_rsc_match_current_node));
 778     assert_ptr_equal(mysql_group_0,
 779                      native_find_rsc(mysql_group_0, "mysql-group", cluster02,
 780                                      pcmk_rsc_match_anon_basename
 781                                      |pcmk_rsc_match_current_node));
 782     assert_null(native_find_rsc(mysql_group_0, "mysql-group", cluster01,
 783                                 pcmk_rsc_match_basename
 784                                 |pcmk_rsc_match_current_node));
 785     assert_null(native_find_rsc(mysql_group_0, "mysql-group", cluster01,
 786                                 pcmk_rsc_match_anon_basename
 787                                 |pcmk_rsc_match_current_node));
 788     assert_ptr_equal(mysql_group_1,
 789                      native_find_rsc(mysql_group_1, "mysql-group", cluster01,
 790                                      pcmk_rsc_match_basename
 791                                      |pcmk_rsc_match_current_node));
 792     assert_ptr_equal(mysql_group_1,
 793                      native_find_rsc(mysql_group_1, "mysql-group", cluster01,
 794                                      pcmk_rsc_match_anon_basename
 795                                      |pcmk_rsc_match_current_node));
 796     assert_null(native_find_rsc(mysql_group_1, "mysql-group", cluster02,
 797                                 pcmk_rsc_match_basename
 798                                 |pcmk_rsc_match_current_node));
 799     assert_null(native_find_rsc(mysql_group_1, "mysql-group", cluster02,
 800                                 pcmk_rsc_match_anon_basename
 801                                 |pcmk_rsc_match_current_node));
 802 
 803     /* Fails because incorrect flags were given along with base name. */
 804     assert_null(native_find_rsc(mysql_group_0, "mysql-group", NULL,
 805                                 pcmk_rsc_match_current_node));
 806     assert_null(native_find_rsc(mysql_group_1, "mysql-group", NULL,
 807                                 pcmk_rsc_match_current_node));
 808 
 809     /* And then we check failure possibilities again, except passing mysql_clone_group
 810      * instead of mysql_group_X as the first argument to native_find_rsc.
 811      */
 812 
 813     // Fails because pcmk_rsc_match_current_node is required if a node is given
 814     assert_null(native_find_rsc(mysql_clone_group, "mysql-group:0", cluster02, 0));
 815     assert_null(native_find_rsc(mysql_clone_group, "mysql-group:1", cluster01, 0));
 816 
 817     /* Check that the resource is running on the node we expect. */
 818     assert_ptr_equal(mysql_group_0,
 819                      native_find_rsc(mysql_clone_group, "mysql-group:0",
 820                                      cluster02, pcmk_rsc_match_current_node));
 821     assert_ptr_equal(mysql_group_0,
 822                      native_find_rsc(mysql_clone_group, "mysql-group",
 823                                      cluster02,
 824                                      pcmk_rsc_match_basename
 825                                      |pcmk_rsc_match_current_node));
 826     assert_ptr_equal(mysql_group_0,
 827                      native_find_rsc(mysql_clone_group, "mysql-group",
 828                                      cluster02,
 829                                      pcmk_rsc_match_anon_basename
 830                                      |pcmk_rsc_match_current_node));
 831     assert_ptr_equal(mysql_group_1,
 832                      native_find_rsc(mysql_clone_group, "mysql-group:1",
 833                                      cluster01, pcmk_rsc_match_current_node));
 834     assert_ptr_equal(mysql_group_1,
 835                      native_find_rsc(mysql_clone_group, "mysql-group",
 836                                      cluster01,
 837                                      pcmk_rsc_match_basename
 838                                      |pcmk_rsc_match_current_node));
 839     assert_ptr_equal(mysql_group_1,
 840                      native_find_rsc(mysql_clone_group, "mysql-group",
 841                                      cluster01,
 842                                      pcmk_rsc_match_anon_basename
 843                                      |pcmk_rsc_match_current_node));
 844 }
 845 
 846 static void
 847 clone_group_member_rsc(void **state) {
     /* [previous][next][first][last][top][bottom][index][help] */
 848     pcmk_resource_t *mysql_proxy = NULL;
 849 
 850     /* Find the "mysql-proxy" resource, a member of "mysql-group". */
 851     for (GList *iter = mysql_clone_group->children; iter != NULL; iter = iter->next) {
 852         pcmk_resource_t *rsc = (pcmk_resource_t *) iter->data;
 853 
 854         if (strcmp(rsc->id, "mysql-group:0") == 0) {
 855             for (GList *iter2 = rsc->children; iter2 != NULL; iter2 = iter2->next) {
 856                 pcmk_resource_t *child = (pcmk_resource_t *) iter2->data;
 857 
 858                 if (strcmp(child->id, "mysql-proxy:0") == 0) {
 859                     mysql_proxy = child;
 860                     break;
 861                 }
 862             }
 863 
 864             break;
 865         }
 866     }
 867 
 868     assert_non_null(mysql_proxy);
 869 
 870     /* Passes because NULL was passed for node, regardless of flags. */
 871     assert_ptr_equal(mysql_proxy, native_find_rsc(mysql_proxy, "mysql-proxy:0", NULL, 0));
 872     assert_ptr_equal(mysql_proxy,
 873                      native_find_rsc(mysql_proxy, "mysql-proxy:0", NULL,
 874                                      pcmk_rsc_match_current_node));
 875 
 876     /* Passes because resource's parent is a clone. */
 877     assert_ptr_equal(mysql_proxy,
 878                      native_find_rsc(mysql_proxy, "mysql-proxy:0", NULL,
 879                                      pcmk_rsc_match_clone_only));
 880     assert_ptr_equal(mysql_proxy,
 881                      native_find_rsc(mysql_proxy, "mysql-proxy:0", cluster02,
 882                                      pcmk_rsc_match_clone_only
 883                                      |pcmk_rsc_match_current_node));
 884 
 885     /* Fails because mysql-proxy:0 is not running on cluster01, even with the right flags. */
 886     assert_null(native_find_rsc(mysql_proxy, "mysql-proxy:0", cluster01,
 887                                 pcmk_rsc_match_current_node));
 888 
 889     // Fails because pcmk_rsc_match_current_node is required if a node is given
 890     assert_null(native_find_rsc(mysql_proxy, "mysql-proxy:0", cluster02, 0));
 891 
 892     /* Passes because mysql-proxy:0 is running on cluster02. */
 893     assert_ptr_equal(mysql_proxy,
 894                      native_find_rsc(mysql_proxy, "mysql-proxy:0", cluster02,
 895                                      pcmk_rsc_match_current_node));
 896 }
 897 
 898 /* TODO: Add tests for finding on assigned node (passing a node without
 899  * pcmk_rsc_match_current_node, after scheduling, for a resource that is
 900  * starting/stopping/moving.
 901  */
 902 PCMK__UNIT_TEST(setup, teardown,
 903                 cmocka_unit_test(bad_args),
 904                 cmocka_unit_test(primitive_rsc),
 905                 cmocka_unit_test(group_rsc),
 906                 cmocka_unit_test(inactive_group_rsc),
 907                 cmocka_unit_test(group_member_rsc),
 908                 cmocka_unit_test(inactive_group_member_rsc),
 909                 cmocka_unit_test(clone_rsc),
 910                 cmocka_unit_test(inactive_clone_rsc),
 911                 cmocka_unit_test(clone_instance_rsc),
 912                 cmocka_unit_test(renamed_rsc),
 913                 cmocka_unit_test(bundle_rsc),
 914                 cmocka_unit_test(bundle_replica_rsc),
 915                 cmocka_unit_test(clone_group_rsc),
 916                 cmocka_unit_test(clone_group_instance_rsc),
 917                 cmocka_unit_test(clone_group_member_rsc))

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