Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
077aa60
Refactor: libcrmcommon: Best practices in output unit tests
nrwahl2 Dec 18, 2025
83d45b4
Refactor: libcrmcommon: Reduce duplication for mk_fake_test_output()
nrwahl2 Dec 19, 2025
d81e1f4
Refactor: libcrmcommon: pcmk__output_new test uses common make function
nrwahl2 Dec 19, 2025
e05946b
Refactor: libcrmcommon: pcmk__output_free test uses common make function
nrwahl2 Dec 19, 2025
e26ba87
Refactor: libcrmcommon: Common make func in output_and_clear_error test
nrwahl2 Dec 19, 2025
5dc9902
Refactor: libcrmcommon: Group setup/teardown functions in output tests
nrwahl2 Dec 19, 2025
c004ab9
Refactor: libcrmcommon: Reduce output test setup/teardown duplication
nrwahl2 Dec 19, 2025
8960780
Refactor: libcrmcommon: Reduce duplication of null output create funcs
nrwahl2 Dec 19, 2025
7a98c38
Refactor: libcrmcommon: Reduce duplication of null output message funcs
nrwahl2 Dec 19, 2025
25595e0
Refactor: libcrmcommon: Don't allocate object in pcmk__output_factory_t
nrwahl2 Dec 18, 2025
7a6b353
Refactor: libcrmcommon: Make pcmk__call_message() static
nrwahl2 Dec 20, 2025
15cd3f0
Refactor: libcrmcommon: Make pcmk__register_message() library-private
nrwahl2 Dec 20, 2025
267e48c
Refactor: libcrmcommon: Drop pcmk__output_t:register_message()
nrwahl2 Dec 20, 2025
e60d0ab
Refactor: libcrmcommon: pcmk__quote_cmdline() takes const char *const *
nrwahl2 Dec 19, 2025
802515b
Refactor: libcrmcommon: pcmk__bare_output_new takes const char *const *
nrwahl2 Dec 19, 2025
4f095ff
Refactor: libcrmcommon: pcmk__output_new() takes const char *const *
nrwahl2 Dec 19, 2025
38d1938
Low: libcrmcommon: Avoid memory leak in assert_hr_format()
nrwahl2 Dec 19, 2025
9f85883
Refactor: libcrmcommon: New assert_hr_format_usec()
nrwahl2 Dec 19, 2025
d93ad28
Refactor: libcrmcommon: Drop usec arg from assert_hr_format()
nrwahl2 Dec 19, 2025
3c72cda
Refactor: libcrmcommon: Drop NULL-check of expected in assert_hr_format
nrwahl2 Dec 19, 2025
5a8b471
Refactor: libcrmcommon: New assert_hr_format_alt()
nrwahl2 Dec 19, 2025
b7344ea
Refactor: libcrmcommon: Drop assert_lookup_user() name argument
nrwahl2 Dec 19, 2025
472f515
Refactor: libcrmcommon: Reduce duplication in pcmk__lookup_user() test
nrwahl2 Dec 19, 2025
6c9b528
Refactor: libcrmcommon: Move will_return() calls to assert_lookup_user()
nrwahl2 Dec 19, 2025
e45844a
Refactor: libcrmcommon: Drop assert_lookup_user() uid/gid arguments
nrwahl2 Dec 19, 2025
5e82461
Refactor: libcrmcommon: New assert_lookup_user_one()
nrwahl2 Dec 19, 2025
b33f78a
Refactor: libcrmcommon: Test pcmk__compare_versions() bidirectionally
nrwahl2 Dec 19, 2025
f83a3c7
Refactor: libcrmcommon: Rename assert_compare_version()
nrwahl2 Dec 19, 2025
acc922e
Refactor: libcrmcommon: Split unit test helper into success/fail cases
nrwahl2 Dec 19, 2025
fb32306
Refactor: libcrmcommon: Split part of assert_comment() into macro helper
nrwahl2 Dec 20, 2025
1243586
Refactor: libcrmcommon: Split unit test helpers into NULL/non-NULL cases
nrwahl2 Dec 19, 2025
22ea583
Refactor: libcrmcommon: Split unit test helpers into true/false cases
nrwahl2 Dec 19, 2025
b985ccd
Refactor: libcrmcommon: Split out unit tests for 0xD800 to 0xDFFF
nrwahl2 Dec 19, 2025
3639f15
Refactor: libcrmcommon: Use constant in pcmk__xe_get_score() test
nrwahl2 Dec 20, 2025
7450952
Refactor: libcrmcommon: Use constant in pcmk__xe_set_score() test
nrwahl2 Dec 20, 2025
3f40cad
Refactor: libcrmcommon: Shorten test names for pcmk__xe_set_score()
nrwahl2 Dec 20, 2025
060d5d4
Refactor: libcrmcommon: Functionize table creation in assert_deref()
nrwahl2 Dec 20, 2025
b969779
Refactor: libcrmcommon: Use TEST_ATTR constant in deref test
nrwahl2 Dec 20, 2025
b97958e
Refactor: libcrmcommon: Use TEST_ELEMENT constant in deref test
nrwahl2 Dec 20, 2025
ea44b0c
Low: libcrmcommon: Avoid memory leak in deref test
nrwahl2 Dec 20, 2025
9b972e3
Refactor: libcrmcommon: Ensure xml_string is non-NULL in deref test
nrwahl2 Dec 20, 2025
bc2108e
Refactor: libcrmcommon: Unindent block in deref test
nrwahl2 Dec 20, 2025
41344c0
Refactor: libcrmcommon: Simplify assert_submatch()
nrwahl2 Dec 20, 2025
fe87b4f
Low: libcrmcommon: Convert unit test assertion helpers to macros
nrwahl2 Dec 19, 2025
75df8b0
Refactor: fencer: NULL-check device at start of localhost_is_eligible()
nrwahl2 Dec 20, 2025
ceeae45
Refactor: libcrmcommon: pcmk__g_strv_contains() takes double-const arg
nrwahl2 Dec 20, 2025
3f33dc8
Refactor: libpacemaker: pcmk__check_rules() takes const char *const *
nrwahl2 Dec 20, 2025
eade73c
Refactor: tools: Use const char *const * in cibsecret.c or rsh_fn/rcp_fn
nrwahl2 Dec 20, 2025
d6a2ffc
Refactor: various: Use const char *const * where possible
nrwahl2 Dec 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion daemons/attrd/pacemaker-attrd.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ main(int argc, char **argv)
goto done;
}

rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
rc = pcmk__output_new(&out, args->output_ty, args->output_dest,
(const char *const *) argv);
if ((rc != pcmk_rc_ok) || (out == NULL)) {
attrd_exit_status = CRM_EX_ERROR;
g_set_error(&error, PCMK__EXITC_ERROR, attrd_exit_status,
Expand Down
3 changes: 2 additions & 1 deletion daemons/based/pacemaker-based.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ main(int argc, char **argv)
goto done;
}

rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
rc = pcmk__output_new(&out, args->output_ty, args->output_dest,
(const char *const *) argv);
if (rc != pcmk_rc_ok) {
exit_code = CRM_EX_ERROR;
g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
Expand Down
3 changes: 2 additions & 1 deletion daemons/controld/pacemaker-controld.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ main(int argc, char **argv)
goto done;
}

rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
rc = pcmk__output_new(&out, args->output_ty, args->output_dest,
(const char *const *) argv);
if (rc != pcmk_rc_ok) {
exit_code = CRM_EX_ERROR;
g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
Expand Down
7 changes: 5 additions & 2 deletions daemons/execd/pacemaker-execd.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,8 @@ main(int argc, char **argv)
goto done;
}

rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
rc = pcmk__output_new(&out, args->output_ty, args->output_dest,
(const char *const *) argv);
if (rc != pcmk_rc_ok) {
exit_code = CRM_EX_ERROR;
g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
Expand All @@ -374,7 +375,9 @@ main(int argc, char **argv)

// Open additional log files
if (options.log_files != NULL) {
for (gchar **fname = options.log_files; *fname != NULL; fname++) {
for (const char *const *fname = (const char *const *) options.log_files;
*fname != NULL; fname++) {

rc = pcmk__add_logfile(*fname);

if (rc != pcmk_rc_ok) {
Expand Down
21 changes: 14 additions & 7 deletions daemons/fenced/fenced_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ get_value_for_target(const char *target, const char *values)

mappings = g_strsplit_set(values, "; \t", 0);

for (gchar **mapping = mappings; (*mapping != NULL) && (value == NULL);
mapping++) {
for (const char *const *mapping = (const char *const *) mappings;
(*mapping != NULL) && (value == NULL); mapping++) {

value = get_value_if_matching(target, *mapping);
}
Expand Down Expand Up @@ -962,7 +962,9 @@ build_port_aliases(const char *hostmap, GList **targets)
stripped = g_strstrip(g_strdup(hostmap));
mappings = g_strsplit_set(stripped, "; \t", 0);

for (gchar **mapping = mappings; *mapping != NULL; mapping++) {
for (const char *const *mapping = (const char *const *) mappings;
*mapping != NULL; mapping++) {

gchar **nvpair = NULL;

if (pcmk__str_empty(*mapping)) {
Expand Down Expand Up @@ -1882,7 +1884,9 @@ fenced_register_level(xmlNode *msg, pcmk__action_result_t *result)
*/
gchar **devices = g_strsplit(value, ",", 0);

for (char **dev = devices; (dev != NULL) && (*dev != NULL); dev++) {
for (const char *const *dev = (const char *const *) devices;
(dev != NULL) && (*dev != NULL); dev++) {

pcmk__trace("Adding device '%s' for %s[%d]", *dev, tp->target, id);
tp->levels[id] = g_list_append(tp->levels[id],
pcmk__str_copy(*dev));
Expand Down Expand Up @@ -2144,11 +2148,14 @@ localhost_is_eligible(const fenced_device_t *device, const char *action,
{
bool localhost_is_target = pcmk__str_eq(target, fenced_get_local_node(),
pcmk__str_casei);
const gchar *const *on_target_actions = NULL;

CRM_CHECK((device != NULL) && (action != NULL), return true);

CRM_CHECK(action != NULL, return true);
on_target_actions = (const gchar *const *) device->on_target_actions;

if ((device != NULL) && (device->on_target_actions != NULL)
&& pcmk__g_strv_contains(device->on_target_actions, action)) {
if ((on_target_actions != NULL)
&& pcmk__g_strv_contains(on_target_actions, action)) {

if (!localhost_is_target) {
pcmk__trace("Operation '%s' using %s can only be executed for "
Expand Down
3 changes: 2 additions & 1 deletion daemons/fenced/pacemaker-fenced.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,8 @@ main(int argc, char **argv)
goto done;
}

rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
rc = pcmk__output_new(&out, args->output_ty, args->output_dest,
(const char *const *) argv);
if (rc != pcmk_rc_ok) {
exit_code = CRM_EX_ERROR;
g_set_error(&error, PCMK__EXITC_ERROR, exit_code,
Expand Down
7 changes: 5 additions & 2 deletions daemons/pacemakerd/pacemakerd.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ pacemakerd_features_xml(pcmk__output_t *out, va_list args) {
NULL);
out->begin_list(out, NULL, NULL, PCMK_XE_FEATURES);

for (char **s = feature_list; *s != NULL; s++) {
for (const char *const *s = (const char *const *) feature_list; *s != NULL;
s++) {

pcmk__output_create_xml_text_node(out, PCMK_XE_FEATURE, *s);
}

Expand Down Expand Up @@ -363,7 +365,8 @@ main(int argc, char **argv)
goto done;
}

rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
rc = pcmk__output_new(&out, args->output_ty, args->output_dest,
(const char *const *) argv);
if ((rc != pcmk_rc_ok) || (out == NULL)) {
exit_code = CRM_EX_ERROR;
g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "Error creating output format %s: %s",
Expand Down
3 changes: 2 additions & 1 deletion daemons/schedulerd/pacemaker-schedulerd.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ main(int argc, char **argv)
goto done;
}

rc = pcmk__output_new(&out, args->output_ty, args->output_dest, argv);
rc = pcmk__output_new(&out, args->output_ty, args->output_dest,
(const char *const *) argv);
if ((rc != pcmk_rc_ok) || (out == NULL)) {
exit_code = CRM_EX_FATAL;
g_set_error(&error, PCMK__EXITC_ERROR, exit_code, "Error creating output format %s: %s",
Expand Down
13 changes: 1 addition & 12 deletions include/crm/common/cmdline_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,7 @@ void pcmk__add_arg_group(GOptionContext *context, const char *name,
const char *header, const char *desc,
const GOptionEntry entries[]);

/*!
* \internal
* \brief Prepare the command line for being added to a pcmk__output_t as the
* request
*
* This performs various transformations on the command line arguments, such
* as surrounding arguments containing spaces with quotes and escaping any
* single quotes in the string.
*
* \param[in,out] argv Command line (typically from pcmk__cmdline_preproc())
*/
gchar *pcmk__quote_cmdline(gchar **argv);
gchar *pcmk__quote_cmdline(const char *const *argv);

/*!
* \internal
Expand Down
109 changes: 36 additions & 73 deletions include/crm/common/output_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ typedef struct pcmk__output_s pcmk__output_t;

/*!
* \internal
* \brief The type of a function that creates a ::pcmk__output_t.
* \brief Function for format-specific setup of a \c pcmk__output_t
*
* Instances of this type are passed to pcmk__register_format(), stored in an
* internal data structure, and later accessed by pcmk__output_new(). For
* examples, see pcmk__mk_xml_output() and pcmk__mk_text_output().
* Instances of this type are passed to \c pcmk__register_format(), stored in an
* internal data structure, and later accessed by \c pcmk__output_new(). For
* examples, see \c pcmk__output_setup_text() and \c pcmk__output_setup_xml().
*
* \param[in] argv The list of command line arguments.
* \param[in] out Output object to set up
*/
typedef pcmk__output_t * (*pcmk__output_factory_t)(char **argv);
typedef void (*pcmk__output_setup_fn_t)(pcmk__output_t *out);

/*!
* \internal
Expand Down Expand Up @@ -127,9 +127,10 @@ typedef struct pcmk__supported_format_s {
const char *name;

/*!
* \brief A function that creates a ::pcmk__output_t.
* \internal
* \brief Function that does format-specific setup for a \c pcmk__output_t
*/
pcmk__output_factory_t create;
pcmk__output_setup_fn_t setup_fn;

/*!
* \brief Format-specific command line options. This can be NULL if
Expand All @@ -144,17 +145,19 @@ typedef struct pcmk__supported_format_s {

extern GOptionEntry pcmk__html_output_entries[];

pcmk__output_t *pcmk__mk_html_output(char **argv);
pcmk__output_t *pcmk__mk_log_output(char **argv);
pcmk__output_t *pcmk__mk_none_output(char **argv);
pcmk__output_t *pcmk__mk_text_output(char **argv);
pcmk__output_t *pcmk__mk_xml_output(char **argv);
void pcmk__output_setup_html(pcmk__output_t *out);
void pcmk__output_setup_log(pcmk__output_t *out);
void pcmk__output_setup_none(pcmk__output_t *out);
void pcmk__output_setup_text(pcmk__output_t *out);
void pcmk__output_setup_xml(pcmk__output_t *out);

#define PCMK__SUPPORTED_FORMAT_HTML { "html", pcmk__mk_html_output, pcmk__html_output_entries }
#define PCMK__SUPPORTED_FORMAT_LOG { "log", pcmk__mk_log_output, NULL }
#define PCMK__SUPPORTED_FORMAT_NONE { PCMK_VALUE_NONE, pcmk__mk_none_output, NULL }
#define PCMK__SUPPORTED_FORMAT_TEXT { "text", pcmk__mk_text_output, NULL }
#define PCMK__SUPPORTED_FORMAT_XML { "xml", pcmk__mk_xml_output, NULL }
#define PCMK__SUPPORTED_FORMAT_HTML \
{ "html", pcmk__output_setup_html, pcmk__html_output_entries }
#define PCMK__SUPPORTED_FORMAT_LOG { "log", pcmk__output_setup_log, NULL }
#define PCMK__SUPPORTED_FORMAT_NONE \
{ PCMK_VALUE_NONE, pcmk__output_setup_none, NULL }
#define PCMK__SUPPORTED_FORMAT_TEXT { "text", pcmk__output_setup_text, NULL }
#define PCMK__SUPPORTED_FORMAT_XML { "xml", pcmk__output_setup_xml, NULL }

/*!
* \brief This structure contains everything that makes up a single output
Expand Down Expand Up @@ -294,28 +297,14 @@ struct pcmk__output_s {
*/
void (*reset) (pcmk__output_t *out);

/*!
* \internal
* \brief Register a custom message.
*
* \param[in,out] out The output functions structure.
* \param[in] message_id The name of the message to register. This name
* will be used as the message_id parameter to the
* message function in order to call the custom
* format function.
* \param[in] fn The custom format function to call for message_id.
*/
void (*register_message) (pcmk__output_t *out, const char *message_id,
pcmk__message_fn_t fn);

/*!
* \internal
* \brief Call a previously registered custom message.
*
* \param[in,out] out The output functions structure.
* \param[in] message_id The name of the message to call. This name must
* be the same as the message_id parameter of some
* previous call to register_message.
* previous call to \c pcmk__register_message().
* \param[in] ... Arguments to be passed to the registered function.
*
* \return A standard Pacemaker return code. Generally: 0 if a function was
Expand Down Expand Up @@ -528,21 +517,6 @@ struct pcmk__output_s {
void (*prompt) (const char *prompt, bool echo, char **dest);
};

/*!
* \internal
* \brief Call a formatting function for a previously registered message.
*
* \note This function is for implementing custom formatters. It should not
* be called directly. Instead, call out->message.
*
* \param[in,out] out The output functions structure.
* \param[in] message_id The message to be handled. Unknown messages
* will be ignored.
* \param[in] ... Arguments to be passed to the registered function.
*/
int
pcmk__call_message(pcmk__output_t *out, const char *message_id, ...);

/*!
* \internal
* \brief Free a ::pcmk__output_t structure that was previously created by
Expand Down Expand Up @@ -574,27 +548,28 @@ void pcmk__output_free(pcmk__output_t *out);
* \return Standard Pacemaker return code
*/
int pcmk__output_new(pcmk__output_t **out, const char *fmt_name,
const char *filename, char **argv);
const char *filename, const char *const *argv);

/*!
* \internal
* \brief Register a new output formatter, making it available for use
* the same as a base formatter.
*
* \param[in,out] group A ::GOptionGroup that formatted output related command
* line arguments should be added to. This can be NULL
* for use outside of command line programs.
* \param[in] name The name of the format. This will be used to select a
* format from command line options and for displaying help.
* \param[in] create A function that creates a ::pcmk__output_t.
* \param[in] options Format-specific command line options. These will be
* added to the context. This argument can also be NULL.
* \param[in,out] group Option group that formatted output-related command
* line arguments should be added to. This can be
* \c NULL for use outside of command line programs.
* \param[in] name Format name. This will be used to select a format
* from command line options and for displaying help.
* \param[in] setup_fn Function that initializes a \c pcmk__output_t
* \param[in] options Format-specific command line options. These will be
* added to the context. This argument can also be
* \c NULL.
*
* \return Standard Pacemaker return code
*/
int
pcmk__register_format(GOptionGroup *group, const char *name,
pcmk__output_factory_t create,
pcmk__output_setup_fn_t setup,
const GOptionEntry *options);

/*!
Expand All @@ -620,21 +595,6 @@ pcmk__register_formats(GOptionGroup *group,
void
pcmk__unregister_formats(void);

/*!
* \internal
* \brief Register a function to handle a custom message.
*
* \note This function is for implementing custom formatters. It should not
* be called directly. Instead, call out->register_message.
*
* \param[in,out] out The output functions structure.
* \param[in] message_id The message to be handled.
* \param[in] fn The custom format function to call for message_id.
*/
void
pcmk__register_message(pcmk__output_t *out, const char *message_id,
pcmk__message_fn_t fn);

/*!
* \internal
* \brief Register an entire table of custom formatting functions at once.
Expand Down Expand Up @@ -993,6 +953,9 @@ pcmk__output_select_rc(int old_rc, int new_rc)
* inspect the internal formatters hash table.
*/
GHashTable *pcmk__output_formatters(void);

// Add this one so that we can restore a saved table
void pcmk__set_output_formatters(GHashTable *value);
#endif

#define PCMK__OUTPUT_SPACER_IF(out_obj, cond) \
Expand Down
2 changes: 1 addition & 1 deletion include/crm/common/strings_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pcmk__intkey_table_remove(GHashTable *hash_table, int key)
}

bool pcmk__str_in_list(const char *str, const GList *list, uint32_t flags);
bool pcmk__g_strv_contains(gchar **strv, const gchar *str);
bool pcmk__g_strv_contains(const gchar *const *strv, const gchar *str);

bool pcmk__strcase_any_of(const char *s, ...) G_GNUC_NULL_TERMINATED;
bool pcmk__str_any_of(const char *s, ...) G_GNUC_NULL_TERMINATED;
Expand Down
14 changes: 14 additions & 0 deletions include/crm/common/unittest_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <cmocka.h>

#include <crm/common/output_internal.h> // pcmk__output_t
#include <crm/common/xml.h>

#ifdef __cplusplus
Expand Down Expand Up @@ -103,6 +104,19 @@ void pcmk__cib_test_cleanup(char *out_path);

void pcmk__test_init_logging(const char *name, const char *filename);

void pcmk__output_setup_fake_text(pcmk__output_t *out);
int pcmk__output_test_setup_group(void **state);
int pcmk__output_test_teardown_group(void **state);
void pcmk__set_fake_text_init_succeeds(bool value);
void pcmk__set_testing_output_free(bool value);
void pcmk__set_testing_output_and_clear_error(bool value);
void pcmk__expect_fake_text_free_priv(void);
void pcmk__expect_fake_text_err(void);
void pcmk__output_setup_dummy1(pcmk__output_t *out);
void pcmk__output_setup_dummy2(pcmk__output_t *out);
int pcmk__output_message_dummy1(pcmk__output_t *out, va_list args);
int pcmk__output_message_dummy2(pcmk__output_t *out, va_list args);

/*!
* \internal
* \brief Assert that a statement aborts through pcmk__assert().
Expand Down
1 change: 1 addition & 0 deletions include/pacemaker.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ int pcmk_list_nodes(xmlNode **xml, const char *types);
*/
int pcmk_status(xmlNodePtr *xml);

// @COMPAT Change rule_ids to type const char *const * at a compatibility break
/*!
* \brief Check whether each rule in a list is in effect
*
Expand Down
Loading