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