diff --git a/include/crm/common/Makefile.am b/include/crm/common/Makefile.am index a211b82a00..b53810f3f3 100644 --- a/include/crm/common/Makefile.am +++ b/include/crm/common/Makefile.am @@ -1,46 +1,47 @@ # # 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 General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # MAINTAINERCLEANFILES = Makefile.in headerdir=$(pkgincludedir)/crm/common header_HEADERS = acl.h \ actions.h \ agents.h \ cib.h \ ipc.h \ ipc_controld.h \ ipc_pacemakerd.h \ ipc_schedulerd.h \ iso8601.h \ logging.h \ logging_compat.h \ mainloop.h \ nodes.h \ nvpair.h \ options.h \ output.h \ + probes.h \ resources.h \ results.h \ roles.h \ rules.h \ scheduler.h \ scheduler_types.h \ schemas.h \ scores.h \ strings.h \ util.h \ util_compat.h \ xml.h \ xml_compat.h \ xml_io.h \ xml_names.h noinst_HEADERS = $(wildcard *internal.h) diff --git a/include/crm/common/actions.h b/include/crm/common/actions.h index 23925d1d7d..63e2eac6aa 100644 --- a/include/crm/common/actions.h +++ b/include/crm/common/actions.h @@ -1,96 +1,93 @@ /* * 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_ACTIONS__H #define PCMK__CRM_COMMON_ACTIONS__H #include // bool #include // strcasecmp() #include // gboolean, guint #include // xmlNode #include // lrmd_event_data_t #include +#include #ifdef __cplusplus extern "C" { #endif /*! * \file * \brief APIs related to actions * \ingroup core */ //! Default timeout (in milliseconds) for non-metadata actions #define PCMK_DEFAULT_ACTION_TIMEOUT_MS 20000 // Action names as strings #define PCMK_ACTION_CANCEL "cancel" #define PCMK_ACTION_CLEAR_FAILCOUNT "clear_failcount" #define PCMK_ACTION_CLONE_ONE_OR_MORE "clone-one-or-more" #define PCMK_ACTION_DELETE "delete" #define PCMK_ACTION_DEMOTE "demote" #define PCMK_ACTION_DEMOTED "demoted" #define PCMK_ACTION_DO_SHUTDOWN "do_shutdown" #define PCMK_ACTION_LIST "list" #define PCMK_ACTION_LRM_DELETE "lrm_delete" #define PCMK_ACTION_LOAD_STOPPED "load_stopped" #define PCMK_ACTION_MAINTENANCE_NODES "maintenance_nodes" #define PCMK_ACTION_META_DATA "meta-data" #define PCMK_ACTION_METADATA "metadata" #define PCMK_ACTION_MIGRATE_FROM "migrate_from" #define PCMK_ACTION_MIGRATE_TO "migrate_to" #define PCMK_ACTION_MONITOR "monitor" #define PCMK_ACTION_NOTIFIED "notified" #define PCMK_ACTION_NOTIFY "notify" #define PCMK_ACTION_OFF "off" #define PCMK_ACTION_ON "on" #define PCMK_ACTION_ONE_OR_MORE "one-or-more" #define PCMK_ACTION_PROMOTE "promote" #define PCMK_ACTION_PROMOTED "promoted" #define PCMK_ACTION_REBOOT "reboot" #define PCMK_ACTION_RELOAD "reload" #define PCMK_ACTION_RELOAD_AGENT "reload-agent" #define PCMK_ACTION_RUNNING "running" #define PCMK_ACTION_START "start" #define PCMK_ACTION_STATUS "status" #define PCMK_ACTION_STONITH "stonith" #define PCMK_ACTION_STOP "stop" #define PCMK_ACTION_STOPPED "stopped" #define PCMK_ACTION_VALIDATE_ALL "validate-all" // For parsing various action-related string specifications gboolean parse_op_key(const char *key, char **rsc_id, char **op_type, guint *interval_ms); gboolean decode_transition_key(const char *key, char **uuid, int *transition_id, int *action_id, int *target_rc); gboolean decode_transition_magic(const char *magic, char **uuid, int *transition_id, int *action_id, int *op_status, int *op_rc, int *target_rc); // @COMPAT Either these shouldn't be in libcrmcommon or lrmd_event_data_t should int rsc_op_expected_rc(const lrmd_event_data_t *event); gboolean did_rsc_op_fail(lrmd_event_data_t *event, int target_rc); bool crm_op_needs_metadata(const char *rsc_class, const char *op); xmlNode *crm_create_op_xml(xmlNode *parent, const char *prefix, const char *task, const char *interval_spec, const char *timeout); -bool pcmk_is_probe(const char *task, guint interval); -bool pcmk_xe_is_probe(const xmlNode *xml_op); -bool pcmk_xe_mask_probe_failure(const xmlNode *xml_op); - #ifdef __cplusplus } #endif #endif // PCMK__CRM_COMMON_ACTIONS__H diff --git a/include/crm/common/probes.h b/include/crm/common/probes.h new file mode 100644 index 0000000000..8bd4264d63 --- /dev/null +++ b/include/crm/common/probes.h @@ -0,0 +1,35 @@ +/* + * 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 Lesser General Public License + * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. + */ + +#ifndef PCMK__CRM_COMMON_PROBES__H +#define PCMK__CRM_COMMON_PROBES__H + +#include // bool +#include // guint +#include // xmlNode + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * \file + * \brief Scheduler API for probes + * \ingroup core + */ + +bool pcmk_is_probe(const char *task, guint interval); +bool pcmk_xe_is_probe(const xmlNode *xml_op); +bool pcmk_xe_mask_probe_failure(const xmlNode *xml_op); + +#ifdef __cplusplus +} +#endif + +#endif // PCMK__CRM_COMMON_PROBES__H diff --git a/lib/common/probes.c b/lib/common/probes.c index 39a39058d5..776b911e02 100644 --- a/lib/common/probes.c +++ b/lib/common/probes.c @@ -1,84 +1,85 @@ /* * 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. */ #include // pcmk__str_eq(), etc. #include // NULL #include // bool, true, false #include // guint #include // xmlNode #include // PCMK_META_INTERVAL +#include #include // PCMK_XA_OPERATION /*! * \brief Check whether an action name and interval represent a probe * * \param[in] task Action name * \param[in] interval_ms Action interval in milliseconds * * \return true if \p task is \c PCMK_ACTION_MONITOR and \p interval_ms is 0, * otherwise false */ bool pcmk_is_probe(const char *task, guint interval_ms) { // @COMPAT This should be made inline at an API compatibility break return (interval_ms == 0) && pcmk__str_eq(task, PCMK_ACTION_MONITOR, pcmk__str_none); } /*! * \brief Check whether an action history entry represents a probe * * \param[in] xml XML of action history entry * * \return true if \p xml is for a probe action, otherwise false */ bool pcmk_xe_is_probe(const xmlNode *xml) { int interval_ms = 0; if (xml == NULL) { return false; } pcmk__scan_min_int(crm_element_value(xml, PCMK_META_INTERVAL), &interval_ms, 0); return pcmk_is_probe(crm_element_value(xml, PCMK_XA_OPERATION), interval_ms); } /*! * \brief Check whether an action history entry represents a maskable probe * * \param[in] xml XML of action history entry * * \return true if \p xml is for a failed probe action that should be treated as * successful, otherwise false */ bool pcmk_xe_mask_probe_failure(const xmlNode *xml) { int exec_status = PCMK_EXEC_UNKNOWN; int exit_status = PCMK_OCF_OK; if (!pcmk_xe_is_probe(xml)) { return false; } crm_element_value_int(xml, PCMK__XA_OP_STATUS, &exec_status); crm_element_value_int(xml, PCMK__XA_RC_CODE, &exit_status); return (exit_status == PCMK_OCF_NOT_INSTALLED) || (exit_status == PCMK_OCF_INVALID_PARAM) || (exec_status == PCMK_EXEC_NOT_INSTALLED); } diff --git a/lib/common/tests/probes/pcmk_is_probe_test.c b/lib/common/tests/probes/pcmk_is_probe_test.c index 835aac1a33..2ab7792f85 100644 --- a/lib/common/tests/probes/pcmk_is_probe_test.c +++ b/lib/common/tests/probes/pcmk_is_probe_test.c @@ -1,25 +1,26 @@ /* * Copyright 2021-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 +#include #include static void is_probe_test(void **state) { assert_false(pcmk_is_probe(NULL, 0)); assert_false(pcmk_is_probe("", 0)); assert_false(pcmk_is_probe("blahblah", 0)); assert_false(pcmk_is_probe("monitor", 1)); assert_true(pcmk_is_probe("monitor", 0)); } PCMK__UNIT_TEST(NULL, NULL, cmocka_unit_test(is_probe_test)) diff --git a/lib/common/tests/probes/pcmk_xe_is_probe_test.c b/lib/common/tests/probes/pcmk_xe_is_probe_test.c index acbc16acf6..1b7df31c8e 100644 --- a/lib/common/tests/probes/pcmk_xe_is_probe_test.c +++ b/lib/common/tests/probes/pcmk_xe_is_probe_test.c @@ -1,54 +1,55 @@ /* * Copyright 2021-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 +#include #include static void op_is_probe_test(void **state) { xmlNode *node = NULL; assert_false(pcmk_xe_is_probe(NULL)); node = pcmk__xml_parse("<" PCMK__XE_LRM_RSC_OP "/>"); assert_false(pcmk_xe_is_probe(node)); pcmk__xml_free(node); node = pcmk__xml_parse("<" PCMK__XE_LRM_RSC_OP " " PCMK__XA_OPERATION_KEY "=\"blah\" " PCMK_META_INTERVAL "=\"30s\"/>"); assert_false(pcmk_xe_is_probe(node)); pcmk__xml_free(node); node = pcmk__xml_parse("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"30s\"/>"); assert_false(pcmk_xe_is_probe(node)); pcmk__xml_free(node); node = pcmk__xml_parse("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_START "\" " PCMK_META_INTERVAL "=\"0\"/>"); assert_false(pcmk_xe_is_probe(node)); pcmk__xml_free(node); node = pcmk__xml_parse("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\"/>"); assert_true(pcmk_xe_is_probe(node)); pcmk__xml_free(node); } PCMK__UNIT_TEST(pcmk__xml_test_setup_group, pcmk__xml_test_teardown_group, cmocka_unit_test(op_is_probe_test)) diff --git a/lib/common/tests/probes/pcmk_xe_mask_probe_failure_test.c b/lib/common/tests/probes/pcmk_xe_mask_probe_failure_test.c index b34670bc69..2e12eb4c4b 100644 --- a/lib/common/tests/probes/pcmk_xe_mask_probe_failure_test.c +++ b/lib/common/tests/probes/pcmk_xe_mask_probe_failure_test.c @@ -1,333 +1,334 @@ /* * Copyright 2021-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 +#include #include static void op_is_not_probe_test(void **state) { xmlNode *node = NULL; /* Not worth testing this thoroughly since it's just a duplicate of whether * pcmk_op_is_probe works or not. */ node = pcmk__xml_parse("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_START "\" " PCMK_META_INTERVAL "=\"0\"/>"); assert_false(pcmk_xe_mask_probe_failure(node)); pcmk__xml_free(node); } static void op_does_not_have_right_values_test(void **state) { xmlNode *node = NULL; char *s = NULL; node = pcmk__xml_parse("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\"/>"); assert_false(pcmk_xe_mask_probe_failure(node)); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"\"/>", PCMK_OCF_OK); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); } static void check_values_test(void **state) { xmlNode *node = NULL; char *s = NULL; /* PCMK_EXEC_NOT_SUPPORTED */ s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_OK, PCMK_EXEC_NOT_SUPPORTED); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_INSTALLED, PCMK_EXEC_NOT_SUPPORTED); node = pcmk__xml_parse(s); assert_true(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); /* PCMK_EXEC_DONE */ s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_OK, PCMK_EXEC_DONE); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_INVALID_PARAM, PCMK_EXEC_DONE); node = pcmk__xml_parse(s); assert_true(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_INSTALLED, PCMK_EXEC_DONE); node = pcmk__xml_parse(s); assert_true(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_CONFIGURED, PCMK_EXEC_DONE); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_RUNNING, PCMK_EXEC_DONE); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); /* PCMK_EXEC_NOT_INSTALLED */ s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_OK, PCMK_EXEC_NOT_INSTALLED); node = pcmk__xml_parse(s); assert_true(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_INSTALLED, PCMK_EXEC_NOT_INSTALLED); node = pcmk__xml_parse(s); assert_true(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); /* PCMK_EXEC_ERROR */ s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_OK, PCMK_EXEC_ERROR); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_INVALID_PARAM, PCMK_EXEC_ERROR); node = pcmk__xml_parse(s); assert_true(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_INSTALLED, PCMK_EXEC_ERROR); node = pcmk__xml_parse(s); assert_true(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_CONFIGURED, PCMK_EXEC_ERROR); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_RUNNING, PCMK_EXEC_ERROR); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); /* PCMK_EXEC_ERROR_HARD */ s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_OK, PCMK_EXEC_ERROR_HARD); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_INVALID_PARAM, PCMK_EXEC_ERROR_HARD); node = pcmk__xml_parse(s); assert_true(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_INSTALLED, PCMK_EXEC_ERROR_HARD); node = pcmk__xml_parse(s); assert_true(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_CONFIGURED, PCMK_EXEC_ERROR_HARD); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_RUNNING, PCMK_EXEC_ERROR_HARD); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); /* PCMK_EXEC_ERROR_FATAL */ s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_OK, PCMK_EXEC_ERROR_FATAL); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_INVALID_PARAM, PCMK_EXEC_ERROR_FATAL); node = pcmk__xml_parse(s); assert_true(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_INSTALLED, PCMK_EXEC_ERROR_FATAL); node = pcmk__xml_parse(s); assert_true(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_CONFIGURED, PCMK_EXEC_ERROR_FATAL); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); s = crm_strdup_printf("<" PCMK__XE_LRM_RSC_OP " " PCMK_XA_OPERATION "=\"" PCMK_ACTION_MONITOR "\" " PCMK_META_INTERVAL "=\"0\" " PCMK__XA_RC_CODE "=\"%d\" " PCMK__XA_OP_STATUS "=\"%d\"/>", PCMK_OCF_NOT_RUNNING, PCMK_EXEC_ERROR_FATAL); node = pcmk__xml_parse(s); assert_false(pcmk_xe_mask_probe_failure(node)); free(s); pcmk__xml_free(node); } PCMK__UNIT_TEST(pcmk__xml_test_setup_group, pcmk__xml_test_teardown_group, cmocka_unit_test(op_is_not_probe_test), cmocka_unit_test(op_does_not_have_right_values_test), cmocka_unit_test(check_values_test))