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

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