Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/include/crm/common/nodes.h b/include/crm/common/nodes.h
index 150b29f1e7..a4f1977002 100644
--- a/include/crm/common/nodes.h
+++ b/include/crm/common/nodes.h
@@ -1,190 +1,219 @@
/*
* Copyright 2004-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
#ifndef PCMK__CRM_COMMON_NODES__H
# define PCMK__CRM_COMMON_NODES__H
#include <stdbool.h> // bool
#include <glib.h> // gboolean, GList, GHashTable
#include <crm/common/scheduler_types.h> // pcmk_resource_t, pcmk_scheduler_t
#ifdef __cplusplus
extern "C" {
#endif
/*!
* \file
* \brief Scheduler API for nodes
* \ingroup core
*/
// Special node attributes
#define PCMK_NODE_ATTR_MAINTENANCE "maintenance"
#define PCMK_NODE_ATTR_STANDBY "standby"
#define PCMK_NODE_ATTR_TERMINATE "terminate"
-//! Possible node types
-enum node_type {
- pcmk_node_variant_cluster = 1, //!< Cluster layer node
- pcmk_node_variant_remote = 2, //!< Pacemaker Remote node
-
- node_ping = 0, //!< \deprecated Do not use
+// @COMPAT Make this internal when we can break API backward compatibility
+//!@{
+//! \deprecated Do not use (public access will be removed in a future release)
+enum node_type { // Possible node types
+ pcmk_node_variant_cluster = 1, // Cluster layer node
+ pcmk_node_variant_remote = 2, // Pacemaker Remote node
+
+ node_ping = 0, // deprecated
#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
- //! \deprecated Use pcmk_node_variant_cluster instead
node_member = pcmk_node_variant_cluster,
-
- //! \deprecated Use pcmk_node_variant_remote instead
node_remote = pcmk_node_variant_remote,
#endif
};
+//!@}
-//! When to probe a resource on a node (as specified in location constraints)
+// When to probe a resource on a node (as specified in location constraints)
+// @COMPAT Make this internal when we can break API backward compatibility
+//!@{
+//! \deprecated Do not use (public access will be removed in a future release)
enum pe_discover_e {
- pcmk_probe_always = 0, //! Always probe resource on node
- pcmk_probe_never = 1, //! Never probe resource on node
- pcmk_probe_exclusive = 2, //! Probe only on designated nodes
+ pcmk_probe_always = 0, // Always probe resource on node
+ pcmk_probe_never = 1, // Never probe resource on node
+ pcmk_probe_exclusive = 2, // Probe only on designated nodes
#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
- //! \deprecated Use pcmk_probe_always instead
pe_discover_always = pcmk_probe_always,
-
- //! \deprecated Use pcmk_probe_never instead
pe_discover_never = pcmk_probe_never,
-
- //! \deprecated Use pcmk_probe_exclusive instead
pe_discover_exclusive = pcmk_probe_exclusive,
#endif
};
+//!@}
-//! Basic node information (all node objects for the same node share this)
+// Basic node information (all node objects for the same node share this)
+// @COMPAT Make this internal when we can break API backward compatibility
+//!@{
+//! \deprecated Do not use (public access will be removed in a future release)
struct pe_node_shared_s {
- const char *id; //!< Node ID at the cluster layer
- const char *uname; //!< Node name in cluster
- enum node_type type; //!< Node variant
+ const char *id; // Node ID at the cluster layer
+ const char *uname; // Node name in cluster
+ enum node_type type; // Node variant
// @TODO Convert these into a flag group
- gboolean online; //!< Whether online
- gboolean standby; //!< Whether in standby mode
- gboolean standby_onfail; //!< Whether in standby mode due to on-fail
- gboolean pending; //!< Whether controller membership is pending
- gboolean unclean; //!< Whether node requires fencing
- gboolean unseen; //!< Whether node has never joined cluster
- gboolean shutdown; //!< Whether shutting down
- gboolean expected_up; //!< Whether expected join state is member
- gboolean is_dc; //!< Whether node is cluster's DC
- gboolean maintenance; //!< Whether in maintenance mode
- gboolean rsc_discovery_enabled; //!< Whether probes are allowed on node
-
- /*!
+
+ //! \deprecated Call pcmk_node_is_online() instead
+ gboolean online; // Whether online
+
+ gboolean standby; // Whether in standby mode
+ gboolean standby_onfail; // Whether in standby mode due to on-fail
+
+ //! \deprecated Call pcmk_node_is_pending() instead
+ gboolean pending; // Whether controller membership is pending
+
+ //! \deprecated Call !pcmk_node_is_clean() instead
+ gboolean unclean; // Whether node requires fencing
+
+ gboolean unseen; // Whether node has never joined cluster
+
+ //! \deprecated Call pcmk_node_is_shutting_down() instead
+ gboolean shutdown; // Whether shutting down
+ gboolean expected_up; // Whether expected join state is member
+ gboolean is_dc; // Whether node is cluster's DC
+
+ //! \deprecated Call pcmk_node_is_in_maintenance() instead
+ gboolean maintenance; // Whether in maintenance mode
+
+ gboolean rsc_discovery_enabled; // Whether probes are allowed on node
+
+ /*
* Whether this is a guest node whose guest resource must be recovered or a
* remote node that must be fenced
*/
gboolean remote_requires_reset;
- /*!
+ /*
* Whether this is a Pacemaker Remote node that was fenced since it was last
* connected by the cluster
*/
gboolean remote_was_fenced;
- /*!
+ /*
* Whether this is a Pacemaker Remote node previously marked in its
* node state as being in maintenance mode
*/
gboolean remote_maintenance;
- gboolean unpacked; //!< Whether node history has been unpacked
+ gboolean unpacked; // Whether node history has been unpacked
- /*!
+ /*
* Number of resources active on this node (valid after CIB status section
* has been unpacked, as long as pcmk_sched_no_counts was not set)
*/
int num_resources;
- //! Remote connection resource for node, if it is a Pacemaker Remote node
+ // Remote connection resource for node, if it is a Pacemaker Remote node
pcmk_resource_t *remote_rsc;
- GList *running_rsc; //!< List of resources active on node
- GList *allocated_rsc; //!< List of resources assigned to node
- GHashTable *attrs; //!< Node attributes
- GHashTable *utilization; //!< Node utilization attributes
- GHashTable *digest_cache; //!< Cache of calculated resource digests
+ GList *running_rsc; // List of resources active on node
+ GList *allocated_rsc; // List of resources assigned to node
+ GHashTable *attrs; // Node attributes
+ GHashTable *utilization; // Node utilization attributes
+ GHashTable *digest_cache; // Cache of calculated resource digests
- /*!
+ /*
* Sum of priorities of all resources active on node and on any guest nodes
* connected to this node, with +1 for promoted instances (used to compare
* nodes for PCMK_OPT_PRIORITY_FENCING_DELAY)
*/
int priority;
- pcmk_scheduler_t *data_set; //!< Cluster that node is part of
+ pcmk_scheduler_t *data_set; // Cluster that node is part of
};
+//!@}
-//! Implementation of pcmk_node_t
+// Implementation of pcmk_node_t
+// @COMPAT Make contents internal when we can break API backward compatibility
+//!@{
+//! \deprecated Do not use (public access will be removed in a future release)
struct pe_node_s {
- int weight; //!< Node score for a given resource
- gboolean fixed; //!< \deprecated Do not use
- int count; //!< Counter reused by assignment and promotion code
- struct pe_node_shared_s *details; //!< Basic node information
+ int weight; // Node score for a given resource
+ gboolean fixed; // \deprecated Do not use
+ int count; // Counter reused by assignment and promotion code
+ struct pe_node_shared_s *details; // Basic node information
// @COMPAT This should be enum pe_discover_e
- int rsc_discover_mode; //!< Probe mode (enum pe_discover_e)
+ int rsc_discover_mode; // Probe mode (enum pe_discover_e)
};
+//!@}
+
+bool pcmk_node_is_online(const pcmk_node_t *node);
+bool pcmk_node_is_pending(const pcmk_node_t *node);
+bool pcmk_node_is_clean(const pcmk_node_t *node);
+bool pcmk_node_is_shutting_down(const pcmk_node_t *node);
+bool pcmk_node_is_in_maintenance(const pcmk_node_t *node);
+bool pcmk_foreach_active_resource(pcmk_node_t *node,
+ bool (*fn)(pcmk_resource_t *, void *),
+ void *user_data);
/*!
* \internal
* \brief Return a string suitable for logging as a node name
*
* \param[in] node Node to return a node name string for
*
* \return Node name if available, otherwise node ID if available,
* otherwise "unspecified node" if node is NULL or "unidentified node"
* if node has neither a name nor ID.
*/
static inline const char *
pcmk__node_name(const pcmk_node_t *node)
{
if (node == NULL) {
return "unspecified node";
} else if (node->details->uname != NULL) {
return node->details->uname;
} else if (node->details->id != NULL) {
return node->details->id;
} else {
return "unidentified node";
}
}
/*!
* \internal
* \brief Check whether two node objects refer to the same node
*
* \param[in] node1 First node object to compare
* \param[in] node2 Second node object to compare
*
* \return true if \p node1 and \p node2 refer to the same node
*/
static inline bool
pcmk__same_node(const pcmk_node_t *node1, const pcmk_node_t *node2)
{
return (node1 != NULL) && (node2 != NULL)
&& (node1->details == node2->details);
}
#ifdef __cplusplus
}
#endif
#endif // PCMK__CRM_COMMON_NODES__H
diff --git a/lib/common/nodes.c b/lib/common/nodes.c
index b79a52e270..7e9e2d2820 100644
--- a/lib/common/nodes.c
+++ b/lib/common/nodes.c
@@ -1,26 +1,138 @@
/*
* Copyright 2022-2024 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
#include <crm_internal.h>
+#include <libxml/tree.h> // xmlNode
#include <crm/common/nvpair.h>
+/*!
+ * \internal
+ * \brief Check whether a node is online
+ *
+ * \param[in] node Node to check
+ *
+ * \return true if \p node is online, otherwise false
+ */
+bool
+pcmk_node_is_online(const pcmk_node_t *node)
+{
+ return (node != NULL) && node->details->online;
+}
+
+/*!
+ * \internal
+ * \brief Check whether a node is pending
+ *
+ * Check whether a node is pending. A node is pending if it is a member of the
+ * cluster but not the controller group, which means it is in the process of
+ * either joining or leaving the cluster.
+ *
+ * \param[in] node Node to check
+ *
+ * \return true if \p node is pending, otherwise false
+ */
+bool
+pcmk_node_is_pending(const pcmk_node_t *node)
+{
+ return (node != NULL) && node->details->pending;
+}
+
+/*!
+ * \internal
+ * \brief Check whether a node is clean
+ *
+ * Check whether a node is clean. A node is clean if it is a cluster node or
+ * remote node that has been seen by the cluster at least once, or the
+ * startup-fencing cluster option is false; and the node, and its host if a
+ * guest or bundle node, are not scheduled to be fenced.
+ *
+ * \param[in] node Node to check
+ *
+ * \return true if \p node is clean, otherwise false
+ */
+bool
+pcmk_node_is_clean(const pcmk_node_t *node)
+{
+ return (node != NULL) && !(node->details->unclean);
+}
+
+/*!
+ * \internal
+ * \brief Check whether a node is shutting down
+ *
+ * \param[in] node Node to check
+ *
+ * \return true if \p node is shutting down, otherwise false
+ */
+bool
+pcmk_node_is_shutting_down(const pcmk_node_t *node)
+{
+ return (node != NULL) && node->details->shutdown;
+}
+
+/*!
+ * \internal
+ * \brief Check whether a node is in maintenance mode
+ *
+ * \param[in] node Node to check
+ *
+ * \return true if \p node is in maintenance mode, otherwise false
+ */
+bool
+pcmk_node_is_in_maintenance(const pcmk_node_t *node)
+{
+ return (node != NULL) && node->details->maintenance;
+}
+
+/*!
+ * \internal
+ * \brief Call a function for each resource active on a node
+ *
+ * Call a caller-supplied function with a caller-supplied argument for each
+ * resource that is active on a given node. If the function returns false, this
+ * function will return immediately without processing any remaining resources.
+ *
+ * \param[in] node Node to check
+ *
+ * \return Result of last call of \p fn (or false if none)
+ */
+bool
+pcmk_foreach_active_resource(pcmk_node_t *node,
+ bool (*fn)(pcmk_resource_t *, void *),
+ void *user_data)
+{
+ bool result = false;
+
+ if ((node != NULL) && (fn != NULL)) {
+ for (GList *item = node->details->running_rsc; item != NULL;
+ item = item->next) {
+
+ result = fn((pcmk_resource_t *) item->data, user_data);
+ if (!result) {
+ break;
+ }
+ }
+ }
+ return result;
+}
+
void
pcmk__xe_add_node(xmlNode *xml, const char *node, int nodeid)
{
CRM_ASSERT(xml != NULL);
if (node != NULL) {
crm_xml_add(xml, PCMK__XA_ATTR_HOST, node);
}
if (nodeid > 0) {
crm_xml_add_int(xml, PCMK__XA_ATTR_HOST_ID, nodeid);
}
}
diff --git a/lib/common/tests/nodes/Makefile.am b/lib/common/tests/nodes/Makefile.am
index fc19925dd6..67c223dbbd 100644
--- a/lib/common/tests/nodes/Makefile.am
+++ b/lib/common/tests/nodes/Makefile.am
@@ -1,16 +1,22 @@
#
# Copyright 2024 the Pacemaker project contributors
#
# The version control history for this file may have further details.
#
# This source code is licensed under the GNU General Public License version 2
# or later (GPLv2+) WITHOUT ANY WARRANTY.
#
include $(top_srcdir)/mk/tap.mk
include $(top_srcdir)/mk/unittest.mk
# Add "_test" to the end of all test program names to simplify .gitignore.
-check_PROGRAMS = pcmk__xe_add_node_test
+check_PROGRAMS = pcmk_foreach_active_resource_test \
+ pcmk_node_is_clean_test \
+ pcmk_node_is_in_maintenance_test \
+ pcmk_node_is_online_test \
+ pcmk_node_is_pending_test \
+ pcmk_node_is_shutting_down_test \
+ pcmk__xe_add_node_test
TESTS = $(check_PROGRAMS)
diff --git a/lib/common/tests/nodes/pcmk_foreach_active_resource_test.c b/lib/common/tests/nodes/pcmk_foreach_active_resource_test.c
new file mode 100644
index 0000000000..2402789230
--- /dev/null
+++ b/lib/common/tests/nodes/pcmk_foreach_active_resource_test.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2024 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
+ *
+ * This source code is licensed under the GNU General Public License version 2
+ * or later (GPLv2+) WITHOUT ANY WARRANTY.
+ */
+
+#include <crm_internal.h>
+
+#include <stdio.h> // NULL
+#include <glib.h> // GList, TRUE, FALSE
+
+#include <crm/common/nodes.h>
+#include <crm/common/resources.h>
+#include <crm/common/unittest_internal.h>
+
+static int counter = 1;
+static int return_false = -1;
+
+static char rsc1_id[] = "rsc1";
+static char rsc2_id[] = "rsc2";
+static char rsc3_id[] = "rsc3";
+
+static pcmk_resource_t rsc1 = {
+ .id = rsc1_id,
+};
+static pcmk_resource_t rsc2 = {
+ .id = rsc2_id,
+};
+static pcmk_resource_t rsc3 = {
+ .id = rsc3_id,
+};
+
+static bool
+fn(pcmk_resource_t *rsc, void *user_data)
+{
+ char *expected_id = crm_strdup_printf("rsc%d", counter);
+
+ assert_string_equal(rsc->id, expected_id);
+ free(expected_id);
+
+ return counter++ != return_false;
+}
+
+static void
+null_args(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .running_rsc = NULL,
+ };
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ counter = 1;
+
+ // These just test that it doesn't crash
+ pcmk_foreach_active_resource(NULL, NULL, NULL);
+ pcmk_foreach_active_resource(&node, NULL, NULL);
+
+ pcmk_foreach_active_resource(NULL, fn, NULL);
+ assert_int_equal(counter, 1);
+}
+
+static void
+list_of_0(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .running_rsc = NULL,
+ };
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ counter = 1;
+ pcmk_foreach_active_resource(&node, fn, NULL);
+ assert_int_equal(counter, 1);
+}
+
+static void
+list_of_1(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .running_rsc = NULL,
+ };
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ shared.running_rsc = g_list_append(shared.running_rsc, &rsc1);
+
+ counter = 1;
+ pcmk_foreach_active_resource(&node, fn, NULL);
+ assert_int_equal(counter, 2);
+
+ g_list_free(shared.running_rsc);
+}
+
+static void
+list_of_3(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .running_rsc = NULL,
+ };
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ shared.running_rsc = g_list_append(shared.running_rsc, &rsc1);
+ shared.running_rsc = g_list_append(shared.running_rsc, &rsc2);
+ shared.running_rsc = g_list_append(shared.running_rsc, &rsc3);
+
+ counter = 1;
+ pcmk_foreach_active_resource(&node, fn, NULL);
+ assert_int_equal(counter, 4);
+
+ g_list_free(shared.running_rsc);
+}
+
+static void
+list_of_3_return_false(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .running_rsc = NULL,
+ };
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ shared.running_rsc = g_list_append(shared.running_rsc, &rsc1);
+ shared.running_rsc = g_list_append(shared.running_rsc, &rsc2);
+ shared.running_rsc = g_list_append(shared.running_rsc, &rsc3);
+
+ counter = 1;
+ return_false = 2;
+ pcmk_foreach_active_resource(&node, fn, NULL);
+ assert_int_equal(counter, 3);
+
+ g_list_free(shared.running_rsc);
+}
+
+PCMK__UNIT_TEST(NULL, NULL,
+ cmocka_unit_test(null_args),
+ cmocka_unit_test(list_of_0),
+ cmocka_unit_test(list_of_1),
+ cmocka_unit_test(list_of_3),
+ cmocka_unit_test(list_of_3_return_false))
diff --git a/lib/common/tests/nodes/pcmk_node_is_clean_test.c b/lib/common/tests/nodes/pcmk_node_is_clean_test.c
new file mode 100644
index 0000000000..0534633fdf
--- /dev/null
+++ b/lib/common/tests/nodes/pcmk_node_is_clean_test.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2024 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
+ *
+ * This source code is licensed under the GNU General Public License version 2
+ * or later (GPLv2+) WITHOUT ANY WARRANTY.
+ */
+
+#include <crm_internal.h>
+
+#include <stdio.h> // NULL
+#include <glib.h> // TRUE, FALSE
+
+#include <crm/common/nodes.h>
+#include <crm/common/unittest_internal.h>
+
+static void
+null_is_unclean(void **state)
+{
+ assert_false(pcmk_node_is_clean(NULL));
+}
+
+static void
+node_is_clean(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .unclean = FALSE,
+ };
+
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ assert_true(pcmk_node_is_clean(&node));
+}
+
+static void
+node_is_unclean(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .unclean = TRUE,
+ };
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ assert_false(pcmk_node_is_clean(&node));
+}
+
+PCMK__UNIT_TEST(NULL, NULL,
+ cmocka_unit_test(null_is_unclean),
+ cmocka_unit_test(node_is_clean),
+ cmocka_unit_test(node_is_unclean))
diff --git a/lib/common/tests/nodes/pcmk_node_is_in_maintenance_test.c b/lib/common/tests/nodes/pcmk_node_is_in_maintenance_test.c
new file mode 100644
index 0000000000..45a3b6fdca
--- /dev/null
+++ b/lib/common/tests/nodes/pcmk_node_is_in_maintenance_test.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2024 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
+ *
+ * This source code is licensed under the GNU General Public License version 2
+ * or later (GPLv2+) WITHOUT ANY WARRANTY.
+ */
+
+#include <crm_internal.h>
+
+#include <stdio.h> // NULL
+#include <glib.h> // TRUE, FALSE
+
+#include <crm/common/nodes.h>
+#include <crm/common/unittest_internal.h>
+
+static void
+null_is_not_in_maintenance(void **state)
+{
+ assert_false(pcmk_node_is_in_maintenance(NULL));
+}
+
+static void
+node_is_in_maintenance(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .maintenance = TRUE,
+ };
+
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ assert_true(pcmk_node_is_in_maintenance(&node));
+}
+
+static void
+node_is_not_in_maintenance(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .maintenance = FALSE,
+ };
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ assert_false(pcmk_node_is_in_maintenance(&node));
+}
+
+PCMK__UNIT_TEST(NULL, NULL,
+ cmocka_unit_test(null_is_not_in_maintenance),
+ cmocka_unit_test(node_is_in_maintenance),
+ cmocka_unit_test(node_is_not_in_maintenance))
diff --git a/lib/common/tests/nodes/pcmk_node_is_online_test.c b/lib/common/tests/nodes/pcmk_node_is_online_test.c
new file mode 100644
index 0000000000..d22e3b4dd3
--- /dev/null
+++ b/lib/common/tests/nodes/pcmk_node_is_online_test.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2024 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
+ *
+ * This source code is licensed under the GNU General Public License version 2
+ * or later (GPLv2+) WITHOUT ANY WARRANTY.
+ */
+
+#include <crm_internal.h>
+
+#include <stdio.h> // NULL
+#include <glib.h> // TRUE, FALSE
+
+#include <crm/common/nodes.h>
+#include <crm/common/unittest_internal.h>
+
+static void
+null_is_offline(void **state)
+{
+ assert_false(pcmk_node_is_online(NULL));
+}
+
+static void
+node_is_online(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .online = TRUE,
+ };
+
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ assert_true(pcmk_node_is_online(&node));
+}
+
+static void
+node_is_offline(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .online = FALSE,
+ };
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ assert_false(pcmk_node_is_online(&node));
+}
+
+PCMK__UNIT_TEST(NULL, NULL,
+ cmocka_unit_test(null_is_offline),
+ cmocka_unit_test(node_is_online),
+ cmocka_unit_test(node_is_offline))
diff --git a/lib/common/tests/nodes/pcmk_node_is_pending_test.c b/lib/common/tests/nodes/pcmk_node_is_pending_test.c
new file mode 100644
index 0000000000..9f2abca4e9
--- /dev/null
+++ b/lib/common/tests/nodes/pcmk_node_is_pending_test.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2024 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
+ *
+ * This source code is licensed under the GNU General Public License version 2
+ * or later (GPLv2+) WITHOUT ANY WARRANTY.
+ */
+
+#include <crm_internal.h>
+
+#include <stdio.h> // NULL
+#include <glib.h> // TRUE, FALSE
+
+#include <crm/common/nodes.h>
+#include <crm/common/unittest_internal.h>
+
+static void
+null_is_not_pending(void **state)
+{
+ assert_false(pcmk_node_is_pending(NULL));
+}
+
+static void
+node_is_pending(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .pending = TRUE,
+ };
+
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ assert_true(pcmk_node_is_pending(&node));
+}
+
+static void
+node_is_not_pending(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .pending = FALSE,
+ };
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ assert_false(pcmk_node_is_pending(&node));
+}
+
+PCMK__UNIT_TEST(NULL, NULL,
+ cmocka_unit_test(null_is_not_pending),
+ cmocka_unit_test(node_is_pending),
+ cmocka_unit_test(node_is_not_pending))
diff --git a/lib/common/tests/nodes/pcmk_node_is_shutting_down_test.c b/lib/common/tests/nodes/pcmk_node_is_shutting_down_test.c
new file mode 100644
index 0000000000..b6054b07dd
--- /dev/null
+++ b/lib/common/tests/nodes/pcmk_node_is_shutting_down_test.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2024 the Pacemaker project contributors
+ *
+ * The version control history for this file may have further details.
+ *
+ * This source code is licensed under the GNU General Public License version 2
+ * or later (GPLv2+) WITHOUT ANY WARRANTY.
+ */
+
+#include <crm_internal.h>
+
+#include <stdio.h> // NULL
+#include <glib.h> // TRUE, FALSE
+
+#include <crm/common/nodes.h>
+#include <crm/common/unittest_internal.h>
+
+static void
+null_is_not_shutting_down(void **state)
+{
+ assert_false(pcmk_node_is_shutting_down(NULL));
+}
+
+static void
+node_is_shutting_down(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .shutdown = TRUE,
+ };
+
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ assert_true(pcmk_node_is_shutting_down(&node));
+}
+
+static void
+node_is_not_shutting_down(void **state)
+{
+ struct pe_node_shared_s shared = {
+ .shutdown = FALSE,
+ };
+ pcmk_node_t node = {
+ .details = &shared,
+ };
+
+ assert_false(pcmk_node_is_shutting_down(&node));
+}
+
+PCMK__UNIT_TEST(NULL, NULL,
+ cmocka_unit_test(null_is_not_shutting_down),
+ cmocka_unit_test(node_is_shutting_down),
+ cmocka_unit_test(node_is_not_shutting_down))

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 23, 4:19 PM (17 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1018872
Default Alt Text
(26 KB)

Event Timeline