diff --git a/include/crm/common/output_internal.h b/include/crm/common/output_internal.h index 4cc7036b4ae..fde8d6ee235 100644 --- a/include/crm/common/output_internal.h +++ b/include/crm/common/output_internal.h @@ -997,6 +997,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) \ diff --git a/include/crm/common/unittest_internal.h b/include/crm/common/unittest_internal.h index 02b91253d24..d65f83e1f8f 100644 --- a/include/crm/common/unittest_internal.h +++ b/include/crm/common/unittest_internal.h @@ -21,7 +21,7 @@ #include -#include +#include // pcmk__output_t #ifdef __cplusplus extern "C" { @@ -138,6 +138,19 @@ void pcmk__cib_test_cleanup(char *out_path); void pcmk__test_init_logging(const char *name, const char *filename); +pcmk__output_t *pcmk__mk_fake_text_output(char **argv); +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); +pcmk__output_t *pcmk__output_null_create1(char **argv); +pcmk__output_t *pcmk__output_null_create2(char **argv); +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(). diff --git a/lib/common/output.c b/lib/common/output.c index 56130b26278..1d6bba9533b 100644 --- a/lib/common/output.c +++ b/lib/common/output.c @@ -25,6 +25,12 @@ GHashTable * pcmk__output_formatters(void) { return formatters; } + +void +pcmk__set_output_formatters(GHashTable *value) +{ + formatters = value; +} // LCOV_EXCL_STOP #endif diff --git a/lib/common/tests/output/pcmk__call_message_test.c b/lib/common/tests/output/pcmk__call_message_test.c index 8077fce2ba0..f6db3480d21 100644 --- a/lib/common/tests/output/pcmk__call_message_test.c +++ b/lib/common/tests/output/pcmk__call_message_test.c @@ -14,71 +14,36 @@ #include static int -default_message_fn(pcmk__output_t *out, va_list args) { +default_message_fn(pcmk__output_t *out, va_list args) +{ function_called(); return pcmk_rc_ok; } static int -failed_message_fn(pcmk__output_t *out, va_list args) { +failed_message_fn(pcmk__output_t *out, va_list args) +{ function_called(); return pcmk_rc_no_output; } static int -message_fn_1(pcmk__output_t *out, va_list args) { +message_fn_1(pcmk__output_t *out, va_list args) +{ function_called(); return pcmk_rc_ok; } static int -message_fn_2(pcmk__output_t *out, va_list args) { +message_fn_2(pcmk__output_t *out, va_list args) +{ function_called(); return pcmk_rc_ok; } -static bool -fake_text_init(pcmk__output_t *out) { - return true; -} - -static void -fake_text_free_priv(pcmk__output_t *out) { - /* This function intentionally left blank */ -} - -static pcmk__output_t * -mk_fake_text_output(char **argv) { - pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t)); - - if (retval == NULL) { - return NULL; - } - - retval->fmt_name = "text"; - retval->init = fake_text_init; - retval->free_priv = fake_text_free_priv; - - retval->register_message = pcmk__register_message; - retval->message = pcmk__call_message; - - return retval; -} - -static int -setup(void **state) { - pcmk__register_format(NULL, "text", mk_fake_text_output, NULL); - return 0; -} - -static int -teardown(void **state) { - pcmk__unregister_formats(); - return 0; -} - static void -no_such_message(void **state) { +no_such_message(void **state) +{ pcmk__output_t *out = NULL; pcmk__output_new(&out, "text", NULL, NULL); @@ -91,7 +56,8 @@ no_such_message(void **state) { } static void -message_return_value(void **state) { +message_return_value(void **state) +{ pcmk__output_t *out = NULL; pcmk__message_entry_t entries[] = { @@ -115,7 +81,8 @@ message_return_value(void **state) { } static void -wrong_format(void **state) { +wrong_format(void **state) +{ pcmk__output_t *out = NULL; pcmk__message_entry_t entries[] = { @@ -132,7 +99,8 @@ wrong_format(void **state) { } static void -default_called(void **state) { +default_called(void **state) +{ pcmk__output_t *out = NULL; pcmk__message_entry_t entries[] = { @@ -150,8 +118,8 @@ default_called(void **state) { pcmk__output_free(out); } -PCMK__UNIT_TEST(NULL, NULL, - cmocka_unit_test_setup_teardown(no_such_message, setup, teardown), - cmocka_unit_test_setup_teardown(message_return_value, setup, teardown), - cmocka_unit_test_setup_teardown(wrong_format, setup, teardown), - cmocka_unit_test_setup_teardown(default_called, setup, teardown)) +PCMK__UNIT_TEST(pcmk__output_test_setup_group, pcmk__output_test_teardown_group, + cmocka_unit_test(no_such_message), + cmocka_unit_test(message_return_value), + cmocka_unit_test(wrong_format), + cmocka_unit_test(default_called)) diff --git a/lib/common/tests/output/pcmk__output_and_clear_error_test.c b/lib/common/tests/output/pcmk__output_and_clear_error_test.c index 98406147e3b..c627e315493 100644 --- a/lib/common/tests/output/pcmk__output_and_clear_error_test.c +++ b/lib/common/tests/output/pcmk__output_and_clear_error_test.c @@ -15,56 +15,25 @@ #include -static bool -fake_text_init(pcmk__output_t *out) { - return true; -} - -static void -fake_text_free_priv(pcmk__output_t *out) { - /* This function intentionally left blank */ -} - -G_GNUC_PRINTF(2, 3) -static void -fake_text_err(pcmk__output_t *out, const char *format, ...) { - function_called(); -} - -static pcmk__output_t * -mk_fake_text_output(char **argv) { - pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t)); - - if (retval == NULL) { - return NULL; - } - - retval->fmt_name = "text"; - retval->init = fake_text_init; - retval->free_priv = fake_text_free_priv; - - retval->register_message = pcmk__register_message; - retval->message = pcmk__call_message; - - retval->err = fake_text_err; - - return retval; -} - static int -setup(void **state) { - pcmk__register_format(NULL, "text", mk_fake_text_output, NULL); +setup(void **state) +{ + pcmk__set_testing_output_and_clear_error(true); + pcmk__output_test_setup_group(state); return 0; } static int -teardown(void **state) { - pcmk__unregister_formats(); +teardown(void **state) +{ + pcmk__output_test_teardown_group(state); + pcmk__set_testing_output_and_clear_error(false); return 0; } static void -standard_usage(void **state) { +standard_usage(void **state) +{ GError *error = NULL; pcmk__output_t *out = NULL; @@ -72,12 +41,12 @@ standard_usage(void **state) { g_set_error(&error, PCMK__RC_ERROR, pcmk_rc_bad_nvpair, "some error message"); - expect_function_call(fake_text_err); + pcmk__expect_fake_text_err(); pcmk__output_and_clear_error(&error, out); pcmk__output_free(out); assert_null(error); } -PCMK__UNIT_TEST(NULL, NULL, - cmocka_unit_test_setup_teardown(standard_usage, setup, teardown)) +PCMK__UNIT_TEST(setup, teardown, + cmocka_unit_test(standard_usage)) diff --git a/lib/common/tests/output/pcmk__output_free_test.c b/lib/common/tests/output/pcmk__output_free_test.c index 31b97f99c22..e8555cc7126 100644 --- a/lib/common/tests/output/pcmk__output_free_test.c +++ b/lib/common/tests/output/pcmk__output_free_test.c @@ -14,72 +14,44 @@ #include static int -null_message_fn(pcmk__output_t *out, va_list args) { - return pcmk_rc_ok; -} - -static bool -fake_text_init(pcmk__output_t *out) { - return true; -} - -static void -fake_text_free_priv(pcmk__output_t *out) { - function_called(); - /* This function intentionally left blank */ -} - -static pcmk__output_t * -mk_fake_text_output(char **argv) { - pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t)); - - if (retval == NULL) { - return NULL; - } - - retval->fmt_name = "text"; - retval->init = fake_text_init; - retval->free_priv = fake_text_free_priv; - - retval->register_message = pcmk__register_message; - retval->message = pcmk__call_message; - - return retval; -} - -static int -setup(void **state) { - pcmk__register_format(NULL, "text", mk_fake_text_output, NULL); +setup(void **state) +{ + pcmk__set_testing_output_free(true); + pcmk__output_test_setup_group(state); return 0; } static int -teardown(void **state) { - pcmk__unregister_formats(); +teardown(void **state) +{ + pcmk__output_test_teardown_group(state); + pcmk__set_testing_output_free(false); return 0; } static void -no_messages(void **state) { +no_messages(void **state) +{ pcmk__output_t *out = NULL; pcmk__output_new(&out, "text", NULL, NULL); - expect_function_call(fake_text_free_priv); + pcmk__expect_fake_text_free_priv(); pcmk__output_free(out); } static void -messages(void **state) { +messages(void **state) +{ pcmk__output_t *out = NULL; pcmk__output_new(&out, "text", NULL, NULL); - pcmk__register_message(out, "fake", null_message_fn); + pcmk__register_message(out, "fake", pcmk__output_message_dummy1); - expect_function_call(fake_text_free_priv); + pcmk__expect_fake_text_free_priv(); pcmk__output_free(out); } -PCMK__UNIT_TEST(NULL, NULL, - cmocka_unit_test_setup_teardown(no_messages, setup, teardown), - cmocka_unit_test_setup_teardown(messages, setup, teardown)) +PCMK__UNIT_TEST(setup, teardown, + cmocka_unit_test(no_messages), + cmocka_unit_test(messages)) diff --git a/lib/common/tests/output/pcmk__output_new_test.c b/lib/common/tests/output/pcmk__output_new_test.c index 9025c4a095d..d071ff4ea34 100644 --- a/lib/common/tests/output/pcmk__output_new_test.c +++ b/lib/common/tests/output/pcmk__output_new_test.c @@ -15,71 +15,38 @@ #include "mock_private.h" -static bool init_succeeds = true; - -static bool -fake_text_init(pcmk__output_t *out) { - return init_succeeds; -} - -static void -fake_text_free_priv(pcmk__output_t *out) { - /* This function intentionally left blank */ -} - -/* "text" is the default for pcmk__output_new. */ -static pcmk__output_t * -mk_fake_text_output(char **argv) { - pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t)); - - if (retval == NULL) { - return NULL; - } - - retval->fmt_name = "text"; - retval->init = fake_text_init; - retval->free_priv = fake_text_free_priv; - - retval->register_message = pcmk__register_message; - retval->message = pcmk__call_message; - - return retval; -} - -static int -setup(void **state) { - pcmk__register_format(NULL, "text", mk_fake_text_output, NULL); - return 0; -} - -static int -teardown(void **state) { - pcmk__unregister_formats(); - return 0; -} - static void -empty_formatters(void **state) { +empty_formatters(void **state) +{ + GHashTable *formatters = pcmk__output_formatters(); pcmk__output_t *out = NULL; + pcmk__set_output_formatters(NULL); pcmk__assert_asserts(pcmk__output_new(&out, "fake", NULL, NULL)); + pcmk__set_output_formatters(formatters); } static void -invalid_params(void **state) { - /* This must be called with the setup/teardown functions so formatters is not NULL. */ +invalid_params(void **state) +{ + /* This must be called with the setup/teardown functions so that formatters + * is not NULL + */ pcmk__assert_asserts(pcmk__output_new(NULL, "fake", NULL, NULL)); } static void -no_such_format(void **state) { +no_such_format(void **state) +{ pcmk__output_t *out = NULL; - assert_int_equal(pcmk__output_new(&out, "fake", NULL, NULL), pcmk_rc_unknown_format); + assert_int_equal(pcmk__output_new(&out, "fake", NULL, NULL), + pcmk_rc_unknown_format); } static void -create_fails(void **state) { +create_fails(void **state) +{ pcmk__output_t *out = NULL; pcmk__mock_calloc = true; // calloc() will return NULL @@ -92,11 +59,13 @@ create_fails(void **state) { } static void -fopen_fails(void **state) { +fopen_fails(void **state) +{ pcmk__output_t *out = NULL; pcmk__mock_fopen = true; -#if defined(HAVE_FOPEN64) && defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) && (SIZEOF_LONG < 8) +#if defined(HAVE_FOPEN64) && defined(_FILE_OFFSET_BITS) \ + && (_FILE_OFFSET_BITS == 64) && (SIZEOF_LONG < 8) expect_string(__wrap_fopen64, pathname, "destfile"); expect_string(__wrap_fopen64, mode, "w"); will_return(__wrap_fopen64, EPERM); @@ -112,16 +81,18 @@ fopen_fails(void **state) { } static void -init_fails(void **state) { +init_fails(void **state) +{ pcmk__output_t *out = NULL; - init_succeeds = false; + pcmk__set_fake_text_init_succeeds(false); assert_int_equal(pcmk__output_new(&out, "text", NULL, NULL), ENOMEM); - init_succeeds = true; + pcmk__set_fake_text_init_succeeds(true); } static void -everything_succeeds(void **state) { +everything_succeeds(void **state) +{ pcmk__output_t *out = NULL; assert_int_equal(pcmk__output_new(&out, "text", NULL, NULL), pcmk_rc_ok); @@ -135,21 +106,23 @@ everything_succeeds(void **state) { } static void -no_fmt_name_given(void **state) { +no_fmt_name_given(void **state) +{ pcmk__output_t *out = NULL; + // "text" is the default format for pcmk__output_new() assert_int_equal(pcmk__output_new(&out, NULL, NULL, NULL), pcmk_rc_ok); assert_string_equal(out->fmt_name, "text"); pcmk__output_free(out); } -PCMK__UNIT_TEST(NULL, NULL, +PCMK__UNIT_TEST(pcmk__output_test_setup_group, pcmk__output_test_teardown_group, cmocka_unit_test(empty_formatters), - cmocka_unit_test_setup_teardown(invalid_params, setup, teardown), - cmocka_unit_test_setup_teardown(no_such_format, setup, teardown), - cmocka_unit_test_setup_teardown(create_fails, setup, teardown), - cmocka_unit_test_setup_teardown(init_fails, setup, teardown), - cmocka_unit_test_setup_teardown(fopen_fails, setup, teardown), - cmocka_unit_test_setup_teardown(everything_succeeds, setup, teardown), - cmocka_unit_test_setup_teardown(no_fmt_name_given, setup, teardown)) + cmocka_unit_test(invalid_params), + cmocka_unit_test(no_such_format), + cmocka_unit_test(create_fails), + cmocka_unit_test(init_fails), + cmocka_unit_test(fopen_fails), + cmocka_unit_test(everything_succeeds), + cmocka_unit_test(no_fmt_name_given)) diff --git a/lib/common/tests/output/pcmk__register_format_test.c b/lib/common/tests/output/pcmk__register_format_test.c index f32ff99f593..29a1ba3d173 100644 --- a/lib/common/tests/output/pcmk__register_format_test.c +++ b/lib/common/tests/output/pcmk__register_format_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 the Pacemaker project contributors + * Copyright 2022-2025 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -11,48 +11,51 @@ #include -static pcmk__output_t * -null_create_fn(char **argv) { - return NULL; -} - -static pcmk__output_t * -null_create_fn_2(char **argv) { - return NULL; -} - static void -invalid_params(void **state) { +invalid_params(void **state) +{ pcmk__assert_asserts(pcmk__register_format(NULL, "fake", NULL, NULL)); - pcmk__assert_asserts(pcmk__register_format(NULL, "", null_create_fn, NULL)); - pcmk__assert_asserts(pcmk__register_format(NULL, NULL, null_create_fn, NULL)); + pcmk__assert_asserts(pcmk__register_format(NULL, "", + pcmk__output_null_create1, + NULL)); + pcmk__assert_asserts(pcmk__register_format(NULL, NULL, + pcmk__output_null_create1, + NULL)); } static void -add_format(void **state) { +add_format(void **state) +{ + int rc = pcmk_rc_ok; GHashTable *formatters = NULL; - gpointer value; + gpointer value = NULL; /* For starters, there should be no formatters defined. */ assert_null(pcmk__output_formatters()); - /* Add a fake formatter and check that it's the only item in the hash table. */ - assert_int_equal(pcmk__register_format(NULL, "fake", null_create_fn, NULL), pcmk_rc_ok); + /* Add a fake formatter and check that it's the only item in the hash + * table + */ + rc = pcmk__register_format(NULL, "fake", pcmk__output_null_create1, NULL); + assert_int_equal(rc, pcmk_rc_ok); + formatters = pcmk__output_formatters(); assert_int_equal(g_hash_table_size(formatters), 1); value = g_hash_table_lookup(formatters, "fake"); - assert_ptr_equal(value, null_create_fn); + assert_ptr_equal(value, pcmk__output_null_create1); - /* Add a second fake formatter which should overwrite the first one, leaving - * only one item in the hash table but pointing at the new function. + /* Add a second fake formatter that should overwrite the first one, leaving + * only one item (with the new function) in the hash table */ - assert_int_equal(pcmk__register_format(NULL, "fake", null_create_fn_2, NULL), pcmk_rc_ok); + rc = pcmk__register_format(NULL, "fake", pcmk__output_null_create2, NULL); + assert_int_equal(rc, pcmk_rc_ok); + formatters = pcmk__output_formatters(); assert_int_equal(g_hash_table_size(formatters), 1); value = g_hash_table_lookup(formatters, "fake"); - assert_ptr_equal(value, null_create_fn_2); + assert_ptr_equal(value, pcmk__output_null_create2); pcmk__unregister_formats(); } diff --git a/lib/common/tests/output/pcmk__register_formats_test.c b/lib/common/tests/output/pcmk__register_formats_test.c index 236e4d99863..7743bc12ddf 100644 --- a/lib/common/tests/output/pcmk__register_formats_test.c +++ b/lib/common/tests/output/pcmk__register_formats_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 the Pacemaker project contributors + * Copyright 2022-2025 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -11,29 +11,21 @@ #include -static pcmk__output_t * -null_create_fn(char **argv) { - return NULL; -} - -static pcmk__output_t * -null_create_fn_2(char **argv) { - return NULL; -} - static void -no_formats(void **state) { +no_formats(void **state) +{ pcmk__register_formats(NULL, NULL); assert_null(pcmk__output_formatters()); } static void -invalid_entries(void **state) { +invalid_entries(void **state) +{ /* Here, we can only test that an empty name won't be added. A NULL name is * the marker for the end of the format table. */ pcmk__supported_format_t formats[] = { - { "", null_create_fn, NULL }, + { "", pcmk__output_null_create1, NULL }, { NULL }, }; @@ -41,12 +33,13 @@ invalid_entries(void **state) { } static void -valid_entries(void **state) { +valid_entries(void **state) +{ GHashTable *formatters = NULL; pcmk__supported_format_t formats[] = { - { "fmt1", null_create_fn, NULL }, - { "fmt2", null_create_fn_2, NULL }, + { "fmt1", pcmk__output_null_create1, NULL }, + { "fmt2", pcmk__output_null_create2, NULL }, { NULL }, }; @@ -54,19 +47,22 @@ valid_entries(void **state) { formatters = pcmk__output_formatters(); assert_int_equal(g_hash_table_size(formatters), 2); - assert_ptr_equal(g_hash_table_lookup(formatters, "fmt1"), null_create_fn); - assert_ptr_equal(g_hash_table_lookup(formatters, "fmt2"), null_create_fn_2); + assert_ptr_equal(g_hash_table_lookup(formatters, "fmt1"), + pcmk__output_null_create1); + assert_ptr_equal(g_hash_table_lookup(formatters, "fmt2"), + pcmk__output_null_create2); pcmk__unregister_formats(); } static void -duplicate_keys(void **state) { +duplicate_keys(void **state) +{ GHashTable *formatters = NULL; pcmk__supported_format_t formats[] = { - { "fmt1", null_create_fn, NULL }, - { "fmt1", null_create_fn_2, NULL }, + { "fmt1", pcmk__output_null_create1, NULL }, + { "fmt1", pcmk__output_null_create2, NULL }, { NULL }, }; @@ -74,18 +70,20 @@ duplicate_keys(void **state) { formatters = pcmk__output_formatters(); assert_int_equal(g_hash_table_size(formatters), 1); - assert_ptr_equal(g_hash_table_lookup(formatters, "fmt1"), null_create_fn_2); + assert_ptr_equal(g_hash_table_lookup(formatters, "fmt1"), + pcmk__output_null_create2); pcmk__unregister_formats(); } static void -duplicate_values(void **state) { +duplicate_values(void **state) +{ GHashTable *formatters = NULL; pcmk__supported_format_t formats[] = { - { "fmt1", null_create_fn, NULL }, - { "fmt2", null_create_fn, NULL }, + { "fmt1", pcmk__output_null_create1, NULL }, + { "fmt2", pcmk__output_null_create1, NULL }, { NULL }, }; @@ -93,8 +91,10 @@ duplicate_values(void **state) { formatters = pcmk__output_formatters(); assert_int_equal(g_hash_table_size(formatters), 2); - assert_ptr_equal(g_hash_table_lookup(formatters, "fmt1"), null_create_fn); - assert_ptr_equal(g_hash_table_lookup(formatters, "fmt2"), null_create_fn); + assert_ptr_equal(g_hash_table_lookup(formatters, "fmt1"), + pcmk__output_null_create1); + assert_ptr_equal(g_hash_table_lookup(formatters, "fmt2"), + pcmk__output_null_create1); pcmk__unregister_formats(); } diff --git a/lib/common/tests/output/pcmk__register_message_test.c b/lib/common/tests/output/pcmk__register_message_test.c index bf80b15241a..381063ec6ab 100644 --- a/lib/common/tests/output/pcmk__register_message_test.c +++ b/lib/common/tests/output/pcmk__register_message_test.c @@ -15,72 +15,27 @@ #include "../../crmcommon_private.h" -static int -null_message_fn(pcmk__output_t *out, va_list args) { - return pcmk_rc_ok; -} - -static int -null_message_fn_2(pcmk__output_t *out, va_list args) { - return pcmk_rc_ok; -} - -static bool -fake_text_init(pcmk__output_t *out) { - return true; -} - -static void -fake_text_free_priv(pcmk__output_t *out) { - /* This function intentionally left blank */ -} - -static pcmk__output_t * -mk_fake_text_output(char **argv) { - pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t)); - - if (retval == NULL) { - return NULL; - } - - retval->fmt_name = "text"; - retval->init = fake_text_init; - retval->free_priv = fake_text_free_priv; - - retval->register_message = pcmk__register_message; - retval->message = pcmk__call_message; - - return retval; -} - -static int -setup(void **state) { - pcmk__register_format(NULL, "text", mk_fake_text_output, NULL); - return 0; -} - -static int -teardown(void **state) { - pcmk__unregister_formats(); - return 0; -} - static void -null_params(void **state) { +null_params(void **state) +{ pcmk__output_t *out = NULL; pcmk__output_new(&out, "text", NULL, NULL); - pcmk__assert_asserts(pcmk__register_message(NULL, "fake", null_message_fn)); - pcmk__assert_asserts(pcmk__register_message(out, NULL, null_message_fn)); - pcmk__assert_asserts(pcmk__register_message(out, "", null_message_fn)); + pcmk__assert_asserts(pcmk__register_message(NULL, "fake", + pcmk__output_message_dummy1)); + pcmk__assert_asserts(pcmk__register_message(out, NULL, + pcmk__output_message_dummy1)); + pcmk__assert_asserts(pcmk__register_message(out, "", + pcmk__output_message_dummy1)); pcmk__assert_asserts(pcmk__register_message(out, "fake", NULL)); pcmk__output_free(out); } static void -add_message(void **state) { +add_message(void **state) +{ pcmk__output_t *out = NULL; pcmk__bare_output_new(&out, "text", NULL, NULL); @@ -89,20 +44,22 @@ add_message(void **state) { assert_int_equal(g_hash_table_size(out->messages), 0); /* Add a fake function and check that it's the only item in the hash table. */ - pcmk__register_message(out, "fake", null_message_fn); + pcmk__register_message(out, "fake", pcmk__output_message_dummy1); assert_int_equal(g_hash_table_size(out->messages), 1); - assert_ptr_equal(g_hash_table_lookup(out->messages, "fake"), null_message_fn); + assert_ptr_equal(g_hash_table_lookup(out->messages, "fake"), + pcmk__output_message_dummy1); /* Add a second fake function which should overwrite the first one, leaving * only one item in the hash table but pointing at the new function. */ - pcmk__register_message(out, "fake", null_message_fn_2); + pcmk__register_message(out, "fake", pcmk__output_message_dummy2); assert_int_equal(g_hash_table_size(out->messages), 1); - assert_ptr_equal(g_hash_table_lookup(out->messages, "fake"), null_message_fn_2); + assert_ptr_equal(g_hash_table_lookup(out->messages, "fake"), + pcmk__output_message_dummy2); pcmk__output_free(out); } -PCMK__UNIT_TEST(NULL, NULL, - cmocka_unit_test_setup_teardown(null_params, setup, teardown), - cmocka_unit_test_setup_teardown(add_message, setup, teardown)) +PCMK__UNIT_TEST(pcmk__output_test_setup_group, pcmk__output_test_teardown_group, + cmocka_unit_test(null_params), + cmocka_unit_test(add_message)) diff --git a/lib/common/tests/output/pcmk__register_messages_test.c b/lib/common/tests/output/pcmk__register_messages_test.c index 8326f892713..ef08f52319f 100644 --- a/lib/common/tests/output/pcmk__register_messages_test.c +++ b/lib/common/tests/output/pcmk__register_messages_test.c @@ -15,66 +15,17 @@ #include "../../crmcommon_private.h" -static int -null_message_fn(pcmk__output_t *out, va_list args) { - return pcmk_rc_ok; -} - -static int -null_message_fn_2(pcmk__output_t *out, va_list args) { - return pcmk_rc_ok; -} - -static bool -fake_text_init(pcmk__output_t *out) { - return true; -} - -static void -fake_text_free_priv(pcmk__output_t *out) { - /* This function intentionally left blank */ -} - -static pcmk__output_t * -mk_fake_text_output(char **argv) { - pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t)); - - if (retval == NULL) { - return NULL; - } - - retval->fmt_name = "text"; - retval->init = fake_text_init; - retval->free_priv = fake_text_free_priv; - - retval->register_message = pcmk__register_message; - retval->message = pcmk__call_message; - - return retval; -} - -static int -setup(void **state) { - pcmk__register_format(NULL, "text", mk_fake_text_output, NULL); - return 0; -} - -static int -teardown(void **state) { - pcmk__unregister_formats(); - return 0; -} - static void -invalid_entries(void **state) { +invalid_entries(void **state) +{ pcmk__output_t *out = NULL; pcmk__message_entry_t entries[] = { /* We can't test a NULL message_id here because that's the marker for * the end of the table. */ - { "", "", null_message_fn }, - { "", NULL, null_message_fn }, + { "", "", pcmk__output_message_dummy1 }, + { "", NULL, pcmk__output_message_dummy1 }, { "", "text", NULL }, { NULL }, }; @@ -88,12 +39,13 @@ invalid_entries(void **state) { } static void -valid_entries(void **state) { +valid_entries(void **state) +{ pcmk__output_t *out = NULL; pcmk__message_entry_t entries[] = { - { "msg1", "text", null_message_fn }, - { "msg2", "text", null_message_fn_2 }, + { "msg1", "text", pcmk__output_message_dummy1 }, + { "msg2", "text", pcmk__output_message_dummy2 }, { NULL }, }; @@ -101,19 +53,22 @@ valid_entries(void **state) { pcmk__register_messages(out, entries); assert_int_equal(g_hash_table_size(out->messages), 2); - assert_ptr_equal(g_hash_table_lookup(out->messages, "msg1"), null_message_fn); - assert_ptr_equal(g_hash_table_lookup(out->messages, "msg2"), null_message_fn_2); + assert_ptr_equal(g_hash_table_lookup(out->messages, "msg1"), + pcmk__output_message_dummy1); + assert_ptr_equal(g_hash_table_lookup(out->messages, "msg2"), + pcmk__output_message_dummy2); pcmk__output_free(out); } static void -duplicate_message_ids(void **state) { +duplicate_message_ids(void **state) +{ pcmk__output_t *out = NULL; pcmk__message_entry_t entries[] = { - { "msg1", "text", null_message_fn }, - { "msg1", "text", null_message_fn_2 }, + { "msg1", "text", pcmk__output_message_dummy1 }, + { "msg1", "text", pcmk__output_message_dummy2 }, { NULL }, }; @@ -121,18 +76,20 @@ duplicate_message_ids(void **state) { pcmk__register_messages(out, entries); assert_int_equal(g_hash_table_size(out->messages), 1); - assert_ptr_equal(g_hash_table_lookup(out->messages, "msg1"), null_message_fn_2); + assert_ptr_equal(g_hash_table_lookup(out->messages, "msg1"), + pcmk__output_message_dummy2); pcmk__output_free(out); } static void -duplicate_functions(void **state) { +duplicate_functions(void **state) +{ pcmk__output_t *out = NULL; pcmk__message_entry_t entries[] = { - { "msg1", "text", null_message_fn }, - { "msg2", "text", null_message_fn }, + { "msg1", "text", pcmk__output_message_dummy1 }, + { "msg2", "text", pcmk__output_message_dummy1 }, { NULL }, }; @@ -140,18 +97,21 @@ duplicate_functions(void **state) { pcmk__register_messages(out, entries); assert_int_equal(g_hash_table_size(out->messages), 2); - assert_ptr_equal(g_hash_table_lookup(out->messages, "msg1"), null_message_fn); - assert_ptr_equal(g_hash_table_lookup(out->messages, "msg2"), null_message_fn); + assert_ptr_equal(g_hash_table_lookup(out->messages, "msg1"), + pcmk__output_message_dummy1); + assert_ptr_equal(g_hash_table_lookup(out->messages, "msg2"), + pcmk__output_message_dummy1); pcmk__output_free(out); } static void -default_handler(void **state) { +default_handler(void **state) +{ pcmk__output_t *out = NULL; pcmk__message_entry_t entries[] = { - { "msg1", "default", null_message_fn }, + { "msg1", "default", pcmk__output_message_dummy1 }, { NULL }, }; @@ -159,18 +119,20 @@ default_handler(void **state) { pcmk__register_messages(out, entries); assert_int_equal(g_hash_table_size(out->messages), 1); - assert_ptr_equal(g_hash_table_lookup(out->messages, "msg1"), null_message_fn); + assert_ptr_equal(g_hash_table_lookup(out->messages, "msg1"), + pcmk__output_message_dummy1); pcmk__output_free(out); } static void -override_default_handler(void **state) { +override_default_handler(void **state) +{ pcmk__output_t *out = NULL; pcmk__message_entry_t entries[] = { - { "msg1", "default", null_message_fn }, - { "msg1", "text", null_message_fn_2 }, + { "msg1", "default", pcmk__output_message_dummy1 }, + { "msg1", "text", pcmk__output_message_dummy2 }, { NULL }, }; @@ -178,15 +140,16 @@ override_default_handler(void **state) { pcmk__register_messages(out, entries); assert_int_equal(g_hash_table_size(out->messages), 1); - assert_ptr_equal(g_hash_table_lookup(out->messages, "msg1"), null_message_fn_2); + assert_ptr_equal(g_hash_table_lookup(out->messages, "msg1"), + pcmk__output_message_dummy2); pcmk__output_free(out); } -PCMK__UNIT_TEST(NULL, NULL, - cmocka_unit_test_setup_teardown(invalid_entries, setup, teardown), - cmocka_unit_test_setup_teardown(valid_entries, setup, teardown), - cmocka_unit_test_setup_teardown(duplicate_message_ids, setup, teardown), - cmocka_unit_test_setup_teardown(duplicate_functions, setup, teardown), - cmocka_unit_test_setup_teardown(default_handler, setup, teardown), - cmocka_unit_test_setup_teardown(override_default_handler, setup, teardown)) +PCMK__UNIT_TEST(pcmk__output_test_setup_group, pcmk__output_test_teardown_group, + cmocka_unit_test(invalid_entries), + cmocka_unit_test(valid_entries), + cmocka_unit_test(duplicate_message_ids), + cmocka_unit_test(duplicate_functions), + cmocka_unit_test(default_handler), + cmocka_unit_test(override_default_handler)) diff --git a/lib/common/tests/output/pcmk__unregister_formats_test.c b/lib/common/tests/output/pcmk__unregister_formats_test.c index da8d9d6b72b..6c979cb1d40 100644 --- a/lib/common/tests/output/pcmk__unregister_formats_test.c +++ b/lib/common/tests/output/pcmk__unregister_formats_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 the Pacemaker project contributors + * Copyright 2022-2025 the Pacemaker project contributors * * The version control history for this file may have further details. * @@ -11,23 +11,20 @@ #include -static pcmk__output_t * -null_create_fn(char **argv) { - return NULL; -} - static void -invalid_params(void **state) { - /* This is basically just here to make sure that calling pcmk__unregister_formats - * with formatters=NULL doesn't segfault. +invalid_params(void **state) +{ + /* This is basically just here to make sure that calling + * pcmk__unregister_formats with formatters set to NULL doesn't segfault */ pcmk__unregister_formats(); assert_null(pcmk__output_formatters()); } static void -non_null_formatters(void **state) { - pcmk__register_format(NULL, "fake", null_create_fn, NULL); +non_null_formatters(void **state) +{ + pcmk__register_format(NULL, "fake", pcmk__output_null_create1, NULL); pcmk__unregister_formats(); assert_null(pcmk__output_formatters()); diff --git a/lib/common/unittest.c b/lib/common/unittest.c index 5f3a448d399..66fa748af0c 100644 --- a/lib/common/unittest.c +++ b/lib/common/unittest.c @@ -18,6 +18,10 @@ // LCOV_EXCL_START +static bool fake_text_init_succeeds = true; +static bool testing_output_free = false; +static bool testing_output_and_clear_error = false; + void pcmk__assert_validates(xmlNode *xml) { @@ -172,4 +176,120 @@ pcmk__test_init_logging(const char *name, const char *filename) } } + +// Output test utilities + +static bool +fake_text_init(pcmk__output_t *out) +{ + return fake_text_init_succeeds; +} + +static void +fake_text_free_priv(pcmk__output_t *out) +{ + if (testing_output_free) { + function_called(); + } +} + +G_GNUC_PRINTF(2, 3) +static void +fake_text_err(pcmk__output_t *out, const char *format, ...) +{ + if (testing_output_and_clear_error) { + function_called(); + } +} + +pcmk__output_t * +pcmk__mk_fake_text_output(char **argv) +{ + pcmk__output_t *retval = calloc(1, sizeof(pcmk__output_t)); + + if (retval == NULL) { + return NULL; + } + + retval->fmt_name = "text"; + + retval->init = fake_text_init; + retval->free_priv = fake_text_free_priv; + + retval->register_message = pcmk__register_message; + retval->message = pcmk__call_message; + + retval->err = fake_text_err; + + return retval; +} + +int +pcmk__output_test_setup_group(void **state) +{ + pcmk__register_format(NULL, "text", pcmk__mk_fake_text_output, NULL); + return 0; +} + +int +pcmk__output_test_teardown_group(void **state) +{ + pcmk__unregister_formats(); + return 0; +} + +void +pcmk__set_fake_text_init_succeeds(bool value) +{ + fake_text_init_succeeds = value; +} + +void +pcmk__set_testing_output_free(bool value) +{ + testing_output_free = value; +} + +void +pcmk__set_testing_output_and_clear_error(bool value) +{ + testing_output_and_clear_error = value; +} + +void +pcmk__expect_fake_text_free_priv(void) +{ + expect_function_call(fake_text_free_priv); +} + +void +pcmk__expect_fake_text_err(void) +{ + expect_function_call(fake_text_err); +} + +pcmk__output_t * +pcmk__output_null_create1(char **argv) +{ + return NULL; +} + +pcmk__output_t * +pcmk__output_null_create2(char **argv) +{ + return NULL; +} + +int +pcmk__output_message_dummy1(pcmk__output_t *out, va_list args) +{ + return pcmk_rc_ok; +} + +int +pcmk__output_message_dummy2(pcmk__output_t *out, va_list args) +{ + return pcmk_rc_ok; +} + // LCOV_EXCL_STOP