pacemaker  2.1.6-802a72226b
Scalable High-Availability cluster resource manager
native_find_rsc_test.c
Go to the documentation of this file.
1 /*
2  * Copyright 2022 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 
13 #include <crm/common/xml.h>
14 #include <crm/pengine/internal.h>
15 #include <crm/pengine/status.h>
16 #include <crm/pengine/pe_types.h>
17 
18 /* Needed to access replicas inside a bundle. */
19 #define PE__VARIANT_BUNDLE 1
20 #include <lib/pengine/variant.h>
21 
22 xmlNode *input = NULL;
24 
28 
29 static int
30 setup(void **state) {
31  char *path = NULL;
32 
33  crm_xml_init();
34 
35  path = crm_strdup_printf("%s/crm_mon.xml", getenv("PCMK_CTS_CLI_DIR"));
37  free(path);
38 
39  if (input == NULL) {
40  return 1;
41  }
42 
44 
45  if (data_set == NULL) {
46  return 1;
47  }
48 
50  data_set->input = input;
51 
53 
54  /* Get references to the cluster nodes so we don't have to find them repeatedly. */
55  cluster01 = pe_find_node(data_set->nodes, "cluster01");
56  cluster02 = pe_find_node(data_set->nodes, "cluster02");
57  httpd_bundle_0 = pe_find_node(data_set->nodes, "httpd-bundle-0");
58 
59  /* Get references to several resources we use frequently. */
60  for (GList *iter = data_set->resources; iter != NULL; iter = iter->next) {
61  pe_resource_t *rsc = (pe_resource_t *) iter->data;
62 
63  if (strcmp(rsc->id, "exim-group") == 0) {
64  exim_group = rsc;
65  } else if (strcmp(rsc->id, "httpd-bundle") == 0) {
66  httpd_bundle = rsc;
67  } else if (strcmp(rsc->id, "inactive-clone") == 0) {
68  inactive_clone = rsc;
69  } else if (strcmp(rsc->id, "inactive-group") == 0) {
70  inactive_group = rsc;
71  } else if (strcmp(rsc->id, "mysql-clone-group") == 0) {
72  mysql_clone_group = rsc;
73  } else if (strcmp(rsc->id, "promotable-clone") == 0) {
74  promotable_clone = rsc;
75  }
76  }
77 
78  return 0;
79 }
80 
81 static int
82 teardown(void **state) {
84 
85  return 0;
86 }
87 
88 static void
89 bad_args(void **state) {
90  pe_resource_t *rsc = (pe_resource_t *) g_list_first(data_set->resources)->data;
91  char *id = rsc->id;
92  char *name = NULL;
93 
94  assert_non_null(rsc);
95 
96  assert_null(native_find_rsc(NULL, "dummy", NULL, 0));
97  assert_null(native_find_rsc(rsc, NULL, NULL, 0));
98 
99  /* No resources exist with these names. */
100  name = crm_strdup_printf("%sX", rsc->id);
101  assert_null(native_find_rsc(rsc, name, NULL, 0));
102  free(name);
103 
104  name = crm_strdup_printf("x%s", rsc->id);
105  assert_null(native_find_rsc(rsc, name, NULL, 0));
106  free(name);
107 
108  name = g_ascii_strup(rsc->id, -1);
109  assert_null(native_find_rsc(rsc, name, NULL, 0));
110  g_free(name);
111 
112  /* Fails because resource ID is NULL. */
113  rsc->id = NULL;
114  assert_null(native_find_rsc(rsc, id, NULL, 0));
115  rsc->id = id;
116 }
117 
118 static void
119 primitive_rsc(void **state) {
120  pe_resource_t *dummy = NULL;
121 
122  /* Find the "dummy" resource, which is the only one with that ID in the set. */
123  for (GList *iter = data_set->resources; iter != NULL; iter = iter->next) {
124  pe_resource_t *rsc = (pe_resource_t *) iter->data;
125 
126  if (strcmp(rsc->id, "dummy") == 0) {
127  dummy = rsc;
128  break;
129  }
130  }
131 
132  assert_non_null(dummy);
133 
134  /* Passes because NULL was passed for node, regardless of flags. */
135  assert_ptr_equal(dummy, native_find_rsc(dummy, "dummy", NULL, 0));
136  assert_ptr_equal(dummy, native_find_rsc(dummy, "dummy", NULL, pe_find_current));
137 
138  /* Fails because resource is not a clone (nor cloned). */
139  assert_null(native_find_rsc(dummy, "dummy", NULL, pe_find_clone));
140  assert_null(native_find_rsc(dummy, "dummy", cluster02, pe_find_clone));
141 
142  /* Fails because dummy is not running on cluster01, even with the right flags. */
143  assert_null(native_find_rsc(dummy, "dummy", cluster01, pe_find_current));
144 
145  /* Fails because pe_find_current is required if a node is given. */
146  assert_null(native_find_rsc(dummy, "dummy", cluster02, 0));
147 
148  /* Passes because dummy is running on cluster02. */
149  assert_ptr_equal(dummy, native_find_rsc(dummy, "dummy", cluster02, pe_find_current));
150 }
151 
152 static void
153 group_rsc(void **state) {
154  assert_non_null(exim_group);
155 
156  /* Passes because NULL was passed for node, regardless of flags. */
157  assert_ptr_equal(exim_group, native_find_rsc(exim_group, "exim-group", NULL, 0));
158  assert_ptr_equal(exim_group, native_find_rsc(exim_group, "exim-group", NULL, pe_find_current));
159 
160  /* Fails because resource is not a clone (nor cloned). */
161  assert_null(native_find_rsc(exim_group, "exim-group", NULL, pe_find_clone));
162  assert_null(native_find_rsc(exim_group, "exim-group", cluster01, pe_find_clone));
163 
164  /* Fails because none of exim-group's children are running on cluster01, even with the right flags. */
165  assert_null(native_find_rsc(exim_group, "exim-group", cluster01, pe_find_current));
166 
167  /* Fails because pe_find_current is required if a node is given. */
168  assert_null(native_find_rsc(exim_group, "exim-group", cluster01, 0));
169 
170  /* Passes because one of exim-group's children is running on cluster02. */
171  assert_ptr_equal(exim_group, native_find_rsc(exim_group, "exim-group", cluster02, pe_find_current));
172 }
173 
174 static void
175 inactive_group_rsc(void **state) {
176  assert_non_null(inactive_group);
177 
178  /* Passes because NULL was passed for node, regardless of flags. */
179  assert_ptr_equal(inactive_group, native_find_rsc(inactive_group, "inactive-group", NULL, 0));
180  assert_ptr_equal(inactive_group, native_find_rsc(inactive_group, "inactive-group", NULL, pe_find_current));
181  assert_ptr_equal(inactive_group, native_find_rsc(inactive_group, "inactive-group", NULL, pe_find_inactive));
182 
183  /* Fails because resource is not a clone (nor cloned). */
184  assert_null(native_find_rsc(inactive_group, "inactive-group", NULL, pe_find_clone));
185  assert_null(native_find_rsc(inactive_group, "inactive-group", cluster01, pe_find_clone));
186 
187  /* Fails because none of inactive-group's children are running. */
188  assert_null(native_find_rsc(inactive_group, "inactive-group", cluster01, pe_find_current));
189  assert_null(native_find_rsc(inactive_group, "inactive-group", cluster02, pe_find_current));
190 
191  /* Passes because of flags. */
192  assert_ptr_equal(inactive_group, native_find_rsc(inactive_group, "inactive-group", cluster01, pe_find_inactive));
193  /* Passes because of flags. */
194  assert_ptr_equal(inactive_group, native_find_rsc(inactive_group, "inactive-group", cluster02, pe_find_inactive));
195 }
196 
197 static void
198 group_member_rsc(void **state) {
199  pe_resource_t *public_ip = NULL;
200 
201  /* Find the "Public-IP" resource, a member of "exim-group". */
202  for (GList *iter = exim_group->children; iter != NULL; iter = iter->next) {
203  pe_resource_t *rsc = (pe_resource_t *) iter->data;
204 
205  if (strcmp(rsc->id, "Public-IP") == 0) {
206  public_ip = rsc;
207  break;
208  }
209  }
210 
211  assert_non_null(public_ip);
212 
213  /* Passes because NULL was passed for node, regardless of flags. */
214  assert_ptr_equal(public_ip, native_find_rsc(public_ip, "Public-IP", NULL, 0));
215  assert_ptr_equal(public_ip, native_find_rsc(public_ip, "Public-IP", NULL, pe_find_current));
216 
217  /* Fails because resource is not a clone (nor cloned). */
218  assert_null(native_find_rsc(public_ip, "Public-IP", NULL, pe_find_clone));
219  assert_null(native_find_rsc(public_ip, "Public-IP", cluster02, pe_find_clone));
220 
221  /* Fails because Public-IP is not running on cluster01, even with the right flags. */
222  assert_null(native_find_rsc(public_ip, "Public-IP", cluster01, pe_find_current));
223 
224  /* Fails because pe_find_current is required if a node is given. */
225  assert_null(native_find_rsc(public_ip, "Public-IP", cluster02, 0));
226 
227  /* Passes because Public-IP is running on cluster02. */
228  assert_ptr_equal(public_ip, native_find_rsc(public_ip, "Public-IP", cluster02, pe_find_current));
229 }
230 
231 static void
232 inactive_group_member_rsc(void **state) {
233  pe_resource_t *inactive_dummy_1 = NULL;
234 
235  /* Find the "inactive-dummy-1" resource, a member of "inactive-group". */
236  for (GList *iter = inactive_group->children; iter != NULL; iter = iter->next) {
237  pe_resource_t *rsc = (pe_resource_t *) iter->data;
238 
239  if (strcmp(rsc->id, "inactive-dummy-1") == 0) {
240  inactive_dummy_1 = rsc;
241  break;
242  }
243  }
244 
245  assert_non_null(inactive_dummy_1);
246 
247  /* Passes because NULL was passed for node, regardless of flags. */
248  assert_ptr_equal(inactive_dummy_1, native_find_rsc(inactive_dummy_1, "inactive-dummy-1", NULL, 0));
249  assert_ptr_equal(inactive_dummy_1, native_find_rsc(inactive_dummy_1, "inactive-dummy-1", NULL, pe_find_current));
250 
251  /* Fails because resource is not a clone (nor cloned). */
252  assert_null(native_find_rsc(inactive_dummy_1, "inactive-dummy-1", NULL, pe_find_clone));
253  assert_null(native_find_rsc(inactive_dummy_1, "inactive-dummy-1", cluster01, pe_find_clone));
254 
255  /* Fails because inactive-dummy-1 is not running. */
256  assert_null(native_find_rsc(inactive_dummy_1, "inactive-dummy-1", cluster01, pe_find_current));
257  assert_null(native_find_rsc(inactive_dummy_1, "inactive-dummy-1", cluster02, pe_find_current));
258 
259  /* Passes because of flags. */
260  assert_ptr_equal(inactive_dummy_1, native_find_rsc(inactive_dummy_1, "inactive-dummy-1", cluster01, pe_find_inactive));
261  /* Passes because of flags. */
262  assert_ptr_equal(inactive_dummy_1, native_find_rsc(inactive_dummy_1, "inactive-dummy-1", cluster02, pe_find_inactive));
263 }
264 
265 static void
266 clone_rsc(void **state) {
267  assert_non_null(promotable_clone);
268 
269  /* Passes because NULL was passed for node, regardless of flags. */
270  assert_ptr_equal(promotable_clone, native_find_rsc(promotable_clone, "promotable-clone", NULL, 0));
271  assert_ptr_equal(promotable_clone, native_find_rsc(promotable_clone, "promotable-clone", NULL, pe_find_current));
272  assert_ptr_equal(promotable_clone, native_find_rsc(promotable_clone, "promotable-clone", NULL, pe_find_clone));
273 
274  /* Fails because pe_find_current is required if a node is given. */
275  assert_null(native_find_rsc(promotable_clone, "promotable-clone", cluster01, 0));
276 
277  /* Passes because one of ping-clone's children is running on cluster01. */
278  assert_ptr_equal(promotable_clone, native_find_rsc(promotable_clone, "promotable-clone", cluster01, pe_find_current));
279 
280  /* Fails because pe_find_current is required if a node is given. */
281  assert_null(native_find_rsc(promotable_clone, "promotable-clone", cluster02, 0));
282 
283  /* Passes because one of ping_clone's children is running on cluster02. */
284  assert_ptr_equal(promotable_clone, native_find_rsc(promotable_clone, "promotable-clone", cluster02, pe_find_current));
285 
286  /* Passes for previous reasons, plus includes pe_find_clone check. */
289 }
290 
291 static void
292 inactive_clone_rsc(void **state) {
293  assert_non_null(inactive_clone);
294 
295  /* Passes because NULL was passed for node, regardless of flags. */
296  assert_ptr_equal(inactive_clone, native_find_rsc(inactive_clone, "inactive-clone", NULL, 0));
297  assert_ptr_equal(inactive_clone, native_find_rsc(inactive_clone, "inactive-clone", NULL, pe_find_current));
298  assert_ptr_equal(inactive_clone, native_find_rsc(inactive_clone, "inactive-clone", NULL, pe_find_clone));
299  assert_ptr_equal(inactive_clone, native_find_rsc(inactive_clone, "inactive-clone", NULL, pe_find_inactive));
300 
301  /* Fails because none of inactive-clone's children are running. */
302  assert_null(native_find_rsc(inactive_clone, "inactive-clone", cluster01, pe_find_current|pe_find_clone));
303  assert_null(native_find_rsc(inactive_clone, "inactive-clone", cluster02, pe_find_current|pe_find_clone));
304 
305  /* Passes because of flags. */
306  assert_ptr_equal(inactive_clone, native_find_rsc(inactive_clone, "inactive-clone", cluster01, pe_find_inactive));
307  /* Passes because of flags. */
308  assert_ptr_equal(inactive_clone, native_find_rsc(inactive_clone, "inactive-clone", cluster02, pe_find_inactive));
309 }
310 
311 static void
312 clone_instance_rsc(void **state) {
313  pe_resource_t *promotable_0 = NULL;
314  pe_resource_t *promotable_1 = NULL;
315 
316  /* Find the "promotable-rsc:0" and "promotable-rsc:1" resources, members of "promotable-clone". */
317  for (GList *iter = promotable_clone->children; iter != NULL; iter = iter->next) {
318  pe_resource_t *rsc = (pe_resource_t *) iter->data;
319 
320  if (strcmp(rsc->id, "promotable-rsc:0") == 0) {
321  promotable_0 = rsc;
322  } else if (strcmp(rsc->id, "promotable-rsc:1") == 0) {
323  promotable_1 = rsc;
324  }
325  }
326 
327  assert_non_null(promotable_0);
328  assert_non_null(promotable_1);
329 
330  /* Passes because NULL was passed for node, regardless of flags. */
331  assert_ptr_equal(promotable_0, native_find_rsc(promotable_0, "promotable-rsc:0", NULL, 0));
332  assert_ptr_equal(promotable_0, native_find_rsc(promotable_0, "promotable-rsc:0", NULL, pe_find_current));
333  assert_ptr_equal(promotable_1, native_find_rsc(promotable_1, "promotable-rsc:1", NULL, 0));
334  assert_ptr_equal(promotable_1, native_find_rsc(promotable_1, "promotable-rsc:1", NULL, pe_find_current));
335 
336  /* Fails because pe_find_current is required if a node is given. */
337  assert_null(native_find_rsc(promotable_0, "promotable-rsc:0", cluster02, 0));
338  assert_null(native_find_rsc(promotable_1, "promotable-rsc:1", cluster01, 0));
339 
340  /* Check that the resource is running on the node we expect. */
341  assert_ptr_equal(promotable_0, native_find_rsc(promotable_0, "promotable-rsc:0", cluster02, pe_find_current));
342  assert_null(native_find_rsc(promotable_0, "promotable-rsc:0", cluster01, pe_find_current));
343  assert_ptr_equal(promotable_1, native_find_rsc(promotable_1, "promotable-rsc:1", cluster01, pe_find_current));
344  assert_null(native_find_rsc(promotable_1, "promotable-rsc:1", cluster02, pe_find_current));
345 
346  /* Passes because NULL was passed for node and primitive name was given, with correct flags. */
347  assert_ptr_equal(promotable_0, native_find_rsc(promotable_0, "promotable-rsc", NULL, pe_find_clone));
348 
349  /* Passes because pe_find_any matches any instance's base name. */
350  assert_ptr_equal(promotable_0, native_find_rsc(promotable_0, "promotable-rsc", NULL, pe_find_any));
351  assert_ptr_equal(promotable_1, native_find_rsc(promotable_1, "promotable-rsc", NULL, pe_find_any));
352 
353  /* Passes because pe_find_anon matches. */
354  assert_ptr_equal(promotable_0, native_find_rsc(promotable_0, "promotable-rsc", NULL, pe_find_anon));
355  assert_ptr_equal(promotable_1, native_find_rsc(promotable_1, "promotable-rsc", NULL, pe_find_anon));
356 
357  /* Check that the resource is running on the node we expect. */
358  assert_ptr_equal(promotable_0, native_find_rsc(promotable_0, "promotable-rsc", cluster02, pe_find_any|pe_find_current));
359  assert_ptr_equal(promotable_0, native_find_rsc(promotable_0, "promotable-rsc", cluster02, pe_find_anon|pe_find_current));
360  assert_null(native_find_rsc(promotable_0, "promotable-rsc", cluster01, pe_find_any|pe_find_current));
361  assert_null(native_find_rsc(promotable_0, "promotable-rsc", cluster01, pe_find_anon|pe_find_current));
362  assert_ptr_equal(promotable_1, native_find_rsc(promotable_1, "promotable-rsc", cluster01, pe_find_any|pe_find_current));
363  assert_ptr_equal(promotable_1, native_find_rsc(promotable_1, "promotable-rsc", cluster01, pe_find_anon|pe_find_current));
364  assert_null(native_find_rsc(promotable_1, "promotable-rsc", cluster02, pe_find_any|pe_find_current));
365  assert_null(native_find_rsc(promotable_1, "promotable-rsc", cluster02, pe_find_anon|pe_find_current));
366 
367  /* Fails because incorrect flags were given along with primitive name. */
368  assert_null(native_find_rsc(promotable_0, "promotable-rsc", NULL, pe_find_current));
369  assert_null(native_find_rsc(promotable_1, "promotable-rsc", NULL, pe_find_current));
370 
371  /* And then we check failure possibilities again, except passing promotable_clone
372  * instead of promotable_X as the first argument to native_find_rsc.
373  */
374 
375  /* Fails because pe_find_current is required if a node is given. */
376  assert_null(native_find_rsc(promotable_clone, "promotable-rsc:0", cluster02, 0));
377  assert_null(native_find_rsc(promotable_clone, "promotable-rsc:1", cluster01, 0));
378 
379  /* Check that the resource is running on the node we expect. */
380  assert_ptr_equal(promotable_0, native_find_rsc(promotable_clone, "promotable-rsc:0", cluster02, pe_find_current));
381  assert_ptr_equal(promotable_0, native_find_rsc(promotable_clone, "promotable-rsc", cluster02, pe_find_any|pe_find_current));
382  assert_ptr_equal(promotable_0, native_find_rsc(promotable_clone, "promotable-rsc", cluster02, pe_find_anon|pe_find_current));
383  assert_ptr_equal(promotable_1, native_find_rsc(promotable_clone, "promotable-rsc:1", cluster01, pe_find_current));
384  assert_ptr_equal(promotable_1, native_find_rsc(promotable_clone, "promotable-rsc", cluster01, pe_find_any|pe_find_current));
385  assert_ptr_equal(promotable_1, native_find_rsc(promotable_clone, "promotable-rsc", cluster01, pe_find_anon|pe_find_current));
386 }
387 
388 static void
389 renamed_rsc(void **state) {
390  pe_resource_t *promotable_0 = NULL;
391  pe_resource_t *promotable_1 = NULL;
392 
393  /* Find the "promotable-rsc:0" and "promotable-rsc:1" resources, members of "promotable-clone". */
394  for (GList *iter = promotable_clone->children; iter != NULL; iter = iter->next) {
395  pe_resource_t *rsc = (pe_resource_t *) iter->data;
396 
397  if (strcmp(rsc->id, "promotable-rsc:0") == 0) {
398  promotable_0 = rsc;
399  } else if (strcmp(rsc->id, "promotable-rsc:1") == 0) {
400  promotable_1 = rsc;
401  }
402  }
403 
404  assert_non_null(promotable_0);
405  assert_non_null(promotable_1);
406 
407  /* Passes because pe_find_renamed means the base name matches clone_name. */
408  assert_ptr_equal(promotable_0, native_find_rsc(promotable_0, "promotable-rsc", NULL, pe_find_renamed));
409  assert_ptr_equal(promotable_1, native_find_rsc(promotable_1, "promotable-rsc", NULL, pe_find_renamed));
410 }
411 
412 static void
413 bundle_rsc(void **state) {
414  assert_non_null(httpd_bundle);
415 
416  /* Passes because NULL was passed for node, regardless of flags. */
417  assert_ptr_equal(httpd_bundle, native_find_rsc(httpd_bundle, "httpd-bundle", NULL, 0));
418  assert_ptr_equal(httpd_bundle, native_find_rsc(httpd_bundle, "httpd-bundle", NULL, pe_find_current));
419 
420  /* Fails because resource is not a clone (nor cloned). */
421  assert_null(native_find_rsc(httpd_bundle, "httpd-bundle", NULL, pe_find_clone));
422  assert_null(native_find_rsc(httpd_bundle, "httpd-bundle", cluster01, pe_find_clone));
423 
424  /* Fails because pe_find_current is required if a node is given. */
425  assert_null(native_find_rsc(httpd_bundle, "httpd-bundle", cluster01, 0));
426 
427  /* Passes because one of httpd_bundle's children is running on cluster01. */
428  assert_ptr_equal(httpd_bundle, native_find_rsc(httpd_bundle, "httpd-bundle", cluster01, pe_find_current));
429 }
430 
431 static void
432 bundle_replica_rsc(void **state) {
433  pe__bundle_variant_data_t *bundle_data = NULL;
434  pe__bundle_replica_t *replica_0 = NULL;
435 
436  pe_resource_t *ip_0 = NULL;
437  pe_resource_t *child_0 = NULL;
438  pe_resource_t *container_0 = NULL;
439  pe_resource_t *remote_0 = NULL;
440 
441  get_bundle_variant_data(bundle_data, httpd_bundle);
442  replica_0 = (pe__bundle_replica_t *) bundle_data->replicas->data;
443 
444  ip_0 = replica_0->ip;
445  child_0 = replica_0->child;
446  container_0 = replica_0->container;
447  remote_0 = replica_0->remote;
448 
449  assert_non_null(ip_0);
450  assert_non_null(child_0);
451  assert_non_null(container_0);
452  assert_non_null(remote_0);
453 
454  /* Passes because NULL was passed for node, regardless of flags. */
455  assert_ptr_equal(ip_0, native_find_rsc(ip_0, "httpd-bundle-ip-192.168.122.131", NULL, 0));
456  assert_ptr_equal(child_0, native_find_rsc(child_0, "httpd:0", NULL, 0));
457  assert_ptr_equal(container_0, native_find_rsc(container_0, "httpd-bundle-docker-0", NULL, 0));
458  assert_ptr_equal(remote_0, native_find_rsc(remote_0, "httpd-bundle-0", NULL, 0));
459 
460  /* Fails because pe_find_current is required if a node is given. */
461  assert_null(native_find_rsc(ip_0, "httpd-bundle-ip-192.168.122.131", cluster01, 0));
462  assert_null(native_find_rsc(child_0, "httpd:0", httpd_bundle_0, 0));
463  assert_null(native_find_rsc(container_0, "httpd-bundle-docker-0", cluster01, 0));
464  assert_null(native_find_rsc(remote_0, "httpd-bundle-0", cluster01, 0));
465 
466  /* Check that the resource is running on the node we expect. */
467  assert_ptr_equal(ip_0, native_find_rsc(ip_0, "httpd-bundle-ip-192.168.122.131", cluster01, pe_find_current));
468  assert_null(native_find_rsc(ip_0, "httpd-bundle-ip-192.168.122.131", cluster02, pe_find_current));
469  assert_null(native_find_rsc(ip_0, "httpd-bundle-ip-192.168.122.131", httpd_bundle_0, pe_find_current));
470  assert_ptr_equal(child_0, native_find_rsc(child_0, "httpd:0", httpd_bundle_0, pe_find_current));
471  assert_null(native_find_rsc(child_0, "httpd:0", cluster01, pe_find_current));
472  assert_null(native_find_rsc(child_0, "httpd:0", cluster02, pe_find_current));
473  assert_ptr_equal(container_0, native_find_rsc(container_0, "httpd-bundle-docker-0", cluster01, pe_find_current));
474  assert_null(native_find_rsc(container_0, "httpd-bundle-docker-0", cluster02, pe_find_current));
475  assert_null(native_find_rsc(container_0, "httpd-bundle-docker-0", httpd_bundle_0, pe_find_current));
476  assert_ptr_equal(remote_0, native_find_rsc(remote_0, "httpd-bundle-0", cluster01, pe_find_current));
477  assert_null(native_find_rsc(remote_0, "httpd-bundle-0", cluster02, pe_find_current));
478  assert_null(native_find_rsc(remote_0, "httpd-bundle-0", httpd_bundle_0, pe_find_current));
479 
480  /* Passes because pe_find_any matches any replica's base name. */
481  assert_ptr_equal(child_0, native_find_rsc(child_0, "httpd", NULL, pe_find_any));
482 
483  /* Passes because pe_find_anon matches. */
484  assert_ptr_equal(child_0, native_find_rsc(child_0, "httpd", NULL, pe_find_anon));
485 
486  /* Check that the resource is running on the node we expect. */
487  assert_ptr_equal(child_0, native_find_rsc(child_0, "httpd", httpd_bundle_0, pe_find_any|pe_find_current));
488  assert_ptr_equal(child_0, native_find_rsc(child_0, "httpd", httpd_bundle_0, pe_find_anon|pe_find_current));
489  assert_null(native_find_rsc(child_0, "httpd", cluster01, pe_find_any|pe_find_current));
490  assert_null(native_find_rsc(child_0, "httpd", cluster01, pe_find_anon|pe_find_current));
491  assert_null(native_find_rsc(child_0, "httpd", cluster02, pe_find_any|pe_find_current));
492  assert_null(native_find_rsc(child_0, "httpd", cluster02, pe_find_anon|pe_find_current));
493 
494  /* Fails because incorrect flags were given along with base name. */
495  assert_null(native_find_rsc(child_0, "httpd", NULL, pe_find_current));
496 
497  /* And then we check failure possibilities again, except passing httpd-bundle
498  * instead of X_0 as the first argument to native_find_rsc.
499  */
500 
501  /* Fails because pe_find_current is required if a node is given. */
502  assert_null(native_find_rsc(httpd_bundle, "httpd-bundle-ip-192.168.122.131", cluster01, 0));
503  assert_null(native_find_rsc(httpd_bundle, "httpd:0", httpd_bundle_0, 0));
504  assert_null(native_find_rsc(httpd_bundle, "httpd-bundle-docker-0", cluster01, 0));
505  assert_null(native_find_rsc(httpd_bundle, "httpd-bundle-0", cluster01, 0));
506 
507  /* Check that the resource is running on the node we expect. */
508  assert_ptr_equal(ip_0, native_find_rsc(httpd_bundle, "httpd-bundle-ip-192.168.122.131", cluster01, pe_find_current));
509  assert_ptr_equal(child_0, native_find_rsc(httpd_bundle, "httpd:0", httpd_bundle_0, pe_find_current));
510  assert_ptr_equal(container_0, native_find_rsc(httpd_bundle, "httpd-bundle-docker-0", cluster01, pe_find_current));
511  assert_ptr_equal(remote_0, native_find_rsc(httpd_bundle, "httpd-bundle-0", cluster01, pe_find_current));
512 }
513 
514 static void
515 clone_group_rsc(void **rsc) {
516  assert_non_null(mysql_clone_group);
517 
518  /* Passes because NULL was passed for node, regardless of flags. */
519  assert_ptr_equal(mysql_clone_group, native_find_rsc(mysql_clone_group, "mysql-clone-group", NULL, 0));
520  assert_ptr_equal(mysql_clone_group, native_find_rsc(mysql_clone_group, "mysql-clone-group", NULL, pe_find_current));
521  assert_ptr_equal(mysql_clone_group, native_find_rsc(mysql_clone_group, "mysql-clone-group", NULL, pe_find_clone));
522 
523  /* Fails because pe_find_current is required if a node is given. */
524  assert_null(native_find_rsc(mysql_clone_group, "mysql-clone-group", cluster01, 0));
525 
526  /* Passes because one of mysql-clone-group's children is running on cluster01. */
527  assert_ptr_equal(mysql_clone_group, native_find_rsc(mysql_clone_group, "mysql-clone-group", cluster01, pe_find_current));
528 
529  /* Fails because pe_find_current is required if a node is given. */
530  assert_null(native_find_rsc(mysql_clone_group, "mysql-clone-group", cluster02, 0));
531 
532  /* Passes because one of mysql-clone-group's children is running on cluster02. */
533  assert_ptr_equal(mysql_clone_group, native_find_rsc(mysql_clone_group, "mysql-clone-group", cluster02, pe_find_current));
534 
535  /* Passes for previous reasons, plus includes pe_find_clone check. */
538 }
539 
540 static void
541 clone_group_instance_rsc(void **rsc) {
544 
545  /* Find the "mysql-group:0" and "mysql-group:1" resources, members of "mysql-clone-group". */
546  for (GList *iter = mysql_clone_group->children; iter != NULL; iter = iter->next) {
547  pe_resource_t *rsc = (pe_resource_t *) iter->data;
548 
549  if (strcmp(rsc->id, "mysql-group:0") == 0) {
550  mysql_group_0 = rsc;
551  } else if (strcmp(rsc->id, "mysql-group:1") == 0) {
552  mysql_group_1 = rsc;
553  }
554  }
555 
556  assert_non_null(mysql_group_0);
557  assert_non_null(mysql_group_1);
558 
559  /* Passes because NULL was passed for node, regardless of flags. */
560  assert_ptr_equal(mysql_group_0, native_find_rsc(mysql_group_0, "mysql-group:0", NULL, 0));
561  assert_ptr_equal(mysql_group_0, native_find_rsc(mysql_group_0, "mysql-group:0", NULL, pe_find_current));
562  assert_ptr_equal(mysql_group_1, native_find_rsc(mysql_group_1, "mysql-group:1", NULL, 0));
563  assert_ptr_equal(mysql_group_1, native_find_rsc(mysql_group_1, "mysql-group:1", NULL, pe_find_current));
564 
565  /* Fails because pe_find_current is required if a node is given. */
566  assert_null(native_find_rsc(mysql_group_0, "mysql-group:0", cluster02, 0));
567  assert_null(native_find_rsc(mysql_group_1, "mysql-group:1", cluster01, 0));
568 
569  /* Check that the resource is running on the node we expect. */
570  assert_ptr_equal(mysql_group_0, native_find_rsc(mysql_group_0, "mysql-group:0", cluster02, pe_find_current));
571  assert_null(native_find_rsc(mysql_group_0, "mysql-group:0", cluster01, pe_find_current));
572  assert_ptr_equal(mysql_group_1, native_find_rsc(mysql_group_1, "mysql-group:1", cluster01, pe_find_current));
573  assert_null(native_find_rsc(mysql_group_1, "mysql-group:1", cluster02, pe_find_current));
574 
575  /* Passes because NULL was passed for node and base name was given, with correct flags. */
576  assert_ptr_equal(mysql_group_0, native_find_rsc(mysql_group_0, "mysql-group" , NULL, pe_find_clone));
577 
578  /* Passes because pe_find_any matches any base name. */
579  assert_ptr_equal(mysql_group_0, native_find_rsc(mysql_group_0, "mysql-group" , NULL, pe_find_any));
580  assert_ptr_equal(mysql_group_1, native_find_rsc(mysql_group_1, "mysql-group" , NULL, pe_find_any));
581 
582  /* Passes because pe_find_anon matches. */
583  assert_ptr_equal(mysql_group_0, native_find_rsc(mysql_group_0, "mysql-group" , NULL, pe_find_anon));
584  assert_ptr_equal(mysql_group_1, native_find_rsc(mysql_group_1, "mysql-group" , NULL, pe_find_anon));
585 
586  /* Check that the resource is running on the node we expect. */
589  assert_null(native_find_rsc(mysql_group_0, "mysql-group", cluster01, pe_find_any|pe_find_current));
590  assert_null(native_find_rsc(mysql_group_0, "mysql-group", cluster01, pe_find_anon|pe_find_current));
593  assert_null(native_find_rsc(mysql_group_1, "mysql-group", cluster02, pe_find_any|pe_find_current));
594  assert_null(native_find_rsc(mysql_group_1, "mysql-group", cluster02, pe_find_anon|pe_find_current));
595 
596  /* Fails because incorrect flags were given along with base name. */
597  assert_null(native_find_rsc(mysql_group_0, "mysql-group", NULL, pe_find_current));
598  assert_null(native_find_rsc(mysql_group_1, "mysql-group", NULL, pe_find_current));
599 
600  /* And then we check failure possibilities again, except passing mysql_clone_group
601  * instead of mysql_group_X as the first argument to native_find_rsc.
602  */
603 
604  /* Fails because pe_find_current is required if a node is given. */
605  assert_null(native_find_rsc(mysql_clone_group, "mysql-group:0", cluster02, 0));
606  assert_null(native_find_rsc(mysql_clone_group, "mysql-group:1", cluster01, 0));
607 
608  /* Check that the resource is running on the node we expect. */
609  assert_ptr_equal(mysql_group_0, native_find_rsc(mysql_clone_group, "mysql-group:0", cluster02, pe_find_current));
612  assert_ptr_equal(mysql_group_1, native_find_rsc(mysql_clone_group, "mysql-group:1", cluster01, pe_find_current));
615 }
616 
617 static void
618 clone_group_member_rsc(void **state) {
619  pe_resource_t *mysql_proxy = NULL;
620 
621  /* Find the "mysql-proxy" resource, a member of "mysql-group". */
622  for (GList *iter = mysql_clone_group->children; iter != NULL; iter = iter->next) {
623  pe_resource_t *rsc = (pe_resource_t *) iter->data;
624 
625  if (strcmp(rsc->id, "mysql-group:0") == 0) {
626  for (GList *iter2 = rsc->children; iter2 != NULL; iter2 = iter2->next) {
627  pe_resource_t *child = (pe_resource_t *) iter2->data;
628 
629  if (strcmp(child->id, "mysql-proxy:0") == 0) {
630  mysql_proxy = child;
631  break;
632  }
633  }
634 
635  break;
636  }
637  }
638 
639  assert_non_null(mysql_proxy);
640 
641  /* Passes because NULL was passed for node, regardless of flags. */
642  assert_ptr_equal(mysql_proxy, native_find_rsc(mysql_proxy, "mysql-proxy:0", NULL, 0));
643  assert_ptr_equal(mysql_proxy, native_find_rsc(mysql_proxy, "mysql-proxy:0", NULL, pe_find_current));
644 
645  /* Passes because resource's parent is a clone. */
646  assert_ptr_equal(mysql_proxy, native_find_rsc(mysql_proxy, "mysql-proxy:0", NULL, pe_find_clone));
647  assert_ptr_equal(mysql_proxy, native_find_rsc(mysql_proxy, "mysql-proxy:0", cluster02, pe_find_clone|pe_find_current));
648 
649  /* Fails because mysql-proxy:0 is not running on cluster01, even with the right flags. */
650  assert_null(native_find_rsc(mysql_proxy, "mysql-proxy:0", cluster01, pe_find_current));
651 
652  /* Fails because pe_find_current is required if a node is given. */
653  assert_null(native_find_rsc(mysql_proxy, "mysql-proxy:0", cluster02, 0));
654 
655  /* Passes because mysql-proxy:0 is running on cluster02. */
656  assert_ptr_equal(mysql_proxy, native_find_rsc(mysql_proxy, "mysql-proxy:0", cluster02, pe_find_current));
657 }
658 
659 /* TODO: Add tests for finding on allocated node (passing a node without
660  * pe_find_current, after scheduling, for a resource that is starting/stopping/moving.
661  */
662 PCMK__UNIT_TEST(setup, teardown,
663  cmocka_unit_test(bad_args),
664  cmocka_unit_test(primitive_rsc),
665  cmocka_unit_test(group_rsc),
666  cmocka_unit_test(inactive_group_rsc),
667  cmocka_unit_test(group_member_rsc),
668  cmocka_unit_test(inactive_group_member_rsc),
669  cmocka_unit_test(clone_rsc),
670  cmocka_unit_test(inactive_clone_rsc),
671  cmocka_unit_test(clone_instance_rsc),
672  cmocka_unit_test(renamed_rsc),
673  cmocka_unit_test(bundle_rsc),
674  cmocka_unit_test(bundle_replica_rsc),
675  cmocka_unit_test(clone_group_rsc),
676  cmocka_unit_test(clone_group_instance_rsc),
677  cmocka_unit_test(clone_group_member_rsc))
pe_resource_t * inactive_clone
const char * name
Definition: cib.c:24
void pe_free_working_set(pe_working_set_t *data_set)
Free a working set.
Definition: status.c:50
GList * children
Definition: pe_types.h:409
pe_resource_t * promotable_1
pe_working_set_t * pe_new_working_set(void)
Create a new working set.
Definition: status.c:34
#define pe_flag_no_compat
Definition: pe_types.h:148
match resource not running anywhere
Definition: pe_types.h:105
void crm_xml_init(void)
Initialize the CRM XML subsystem.
Definition: xml.c:2562
pe_resource_t * httpd_bundle
#define pe_flag_no_counts
Don&#39;t count total, disabled and blocked resource instances.
Definition: pe_types.h:143
pe_resource_t * exim_group
pe_resource_t * inactive_group
xmlNode * filename2xml(const char *filename)
Definition: xml.c:1007
PCMK__UNIT_TEST(NULL, NULL, cmocka_unit_test(bad_input), cmocka_unit_test(not_found), cmocka_unit_test(find_attrB), cmocka_unit_test(find_attrA_matching))
GList * resources
Definition: pe_types.h:181
GList * nodes
Definition: pe_types.h:180
pe_node_t * cluster02
pe_node_t * cluster01
pe_resource_t * promotable_0
match only clone instances
Definition: pe_types.h:103
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
pe_working_set_t * data_set
Wrappers for and extensions to libxml2.
pe_node_t * httpd_bundle_0
pe_resource_t * mysql_clone_group
match base name of any clone instance
Definition: pe_types.h:106
xmlNode * input
Definition: pe_types.h:160
uint32_t id
Definition: cpg.c:45
pe_resource_t * promotable_clone
match resource ID or LRM history ID
Definition: pe_types.h:101
Cluster status and scheduling.
pe_resource_t * native_find_rsc(pe_resource_t *rsc, const char *id, const pe_node_t *node, int flags)
Definition: native.c:265
pe_resource_t * mysql_group_0
const char * path
Definition: cib.c:26
gboolean cluster_status(pe_working_set_t *data_set)
Definition: status.c:71
xmlNode * input
pe_resource_t * dummy
pe_node_t * pe_find_node(const GList *node_list, const char *node_name)
Find a node by name in a list of nodes.
Definition: status.c:473
#define pe__set_working_set_flags(working_set, flags_to_set)
Definition: internal.h:65
Data types for cluster status.
pe_resource_t * mysql_group_1
match resource active on specified node
Definition: pe_types.h:104
char * id
Definition: pe_types.h:347
match base name of anonymous clone instances
Definition: pe_types.h:102