diff options
Diffstat (limited to 'lib/common/tests/output')
-rw-r--r-- | lib/common/tests/output/Makefile.am | 24 | ||||
-rw-r--r-- | lib/common/tests/output/pcmk__call_message_test.c | 156 | ||||
-rw-r--r-- | lib/common/tests/output/pcmk__output_and_clear_error_test.c | 82 | ||||
-rw-r--r-- | lib/common/tests/output/pcmk__output_free_test.c | 84 | ||||
-rw-r--r-- | lib/common/tests/output/pcmk__output_new_test.c | 148 | ||||
-rw-r--r-- | lib/common/tests/output/pcmk__register_format_test.c | 63 | ||||
-rw-r--r-- | lib/common/tests/output/pcmk__register_formats_test.c | 108 | ||||
-rw-r--r-- | lib/common/tests/output/pcmk__register_message_test.c | 107 | ||||
-rw-r--r-- | lib/common/tests/output/pcmk__register_messages_test.c | 191 | ||||
-rw-r--r-- | lib/common/tests/output/pcmk__unregister_formats_test.c | 39 |
10 files changed, 1002 insertions, 0 deletions
diff --git a/lib/common/tests/output/Makefile.am b/lib/common/tests/output/Makefile.am new file mode 100644 index 0000000..6ac7b5f --- /dev/null +++ b/lib/common/tests/output/Makefile.am @@ -0,0 +1,24 @@ +# +# Copyright 2021-2022 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__call_message_test \ + pcmk__output_and_clear_error_test \ + pcmk__output_free_test \ + pcmk__output_new_test \ + pcmk__register_format_test \ + pcmk__register_formats_test \ + pcmk__register_message_test \ + pcmk__register_messages_test \ + pcmk__unregister_formats_test + +TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/output/pcmk__call_message_test.c b/lib/common/tests/output/pcmk__call_message_test.c new file mode 100644 index 0000000..824eac7 --- /dev/null +++ b/lib/common/tests/output/pcmk__call_message_test.c @@ -0,0 +1,156 @@ +/* + * Copyright 2022 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 <crm/common/unittest_internal.h> +#include <crm/common/output_internal.h> + +static int +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) { + function_called(); + return pcmk_rc_no_output; +} + +static int +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) { + 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) { + pcmk__output_t *out = NULL; + + pcmk__output_new(&out, "text", NULL, NULL); + + assert_int_equal(out->message(out, "fake"), EINVAL); + pcmk__assert_asserts(out->message(out, "")); + pcmk__assert_asserts(out->message(out, NULL)); + + pcmk__output_free(out); +} + +static void +message_return_value(void **state) { + pcmk__output_t *out = NULL; + + pcmk__message_entry_t entries[] = { + { "msg1", "text", message_fn_1 }, + { "msg2", "text", message_fn_2 }, + { "fail", "text", failed_message_fn }, + { NULL }, + }; + + pcmk__output_new(&out, "text", NULL, NULL); + pcmk__register_messages(out, entries); + + expect_function_call(message_fn_1); + assert_int_equal(out->message(out, "msg1"), pcmk_rc_ok); + expect_function_call(message_fn_2); + assert_int_equal(out->message(out, "msg2"), pcmk_rc_ok); + expect_function_call(failed_message_fn); + assert_int_equal(out->message(out, "fail"), pcmk_rc_no_output); + + pcmk__output_free(out); +} + +static void +wrong_format(void **state) { + pcmk__output_t *out = NULL; + + pcmk__message_entry_t entries[] = { + { "msg1", "xml", message_fn_1 }, + { NULL }, + }; + + pcmk__output_new(&out, "text", NULL, NULL); + pcmk__register_messages(out, entries); + + assert_int_equal(out->message(out, "msg1"), EINVAL); + + pcmk__output_free(out); +} + +static void +default_called(void **state) { + pcmk__output_t *out = NULL; + + pcmk__message_entry_t entries[] = { + { "msg1", "default", default_message_fn }, + { "msg1", "xml", message_fn_1 }, + { NULL }, + }; + + pcmk__output_new(&out, "text", NULL, NULL); + pcmk__register_messages(out, entries); + + expect_function_call(default_message_fn); + assert_int_equal(out->message(out, "msg1"), pcmk_rc_ok); + + 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)) 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 new file mode 100644 index 0000000..f54ed8a --- /dev/null +++ b/lib/common/tests/output/pcmk__output_and_clear_error_test.c @@ -0,0 +1,82 @@ +/* + * Copyright 2022-2023 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 <crm/common/unittest_internal.h> +#include <crm/common/output_internal.h> + +#include <glib.h> + +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); + return 0; +} + +static int +teardown(void **state) { + pcmk__unregister_formats(); + return 0; +} + +static void +standard_usage(void **state) { + GError *error = NULL; + pcmk__output_t *out = NULL; + + pcmk__output_new(&out, "text", NULL, NULL); + g_set_error(&error, PCMK__RC_ERROR, pcmk_rc_bad_nvpair, + "some error message"); + + expect_function_call(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)) diff --git a/lib/common/tests/output/pcmk__output_free_test.c b/lib/common/tests/output/pcmk__output_free_test.c new file mode 100644 index 0000000..ef074d1 --- /dev/null +++ b/lib/common/tests/output/pcmk__output_free_test.c @@ -0,0 +1,84 @@ +/* + * Copyright 2022 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 <crm/common/unittest_internal.h> +#include <crm/common/output_internal.h> + +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); + return 0; +} + +static int +teardown(void **state) { + pcmk__unregister_formats(); + return 0; +} + +static void +no_messages(void **state) { + pcmk__output_t *out = NULL; + + pcmk__output_new(&out, "text", NULL, NULL); + + expect_function_call(fake_text_free_priv); + pcmk__output_free(out); +} + +static void +messages(void **state) { + pcmk__output_t *out = NULL; + + pcmk__output_new(&out, "text", NULL, NULL); + pcmk__register_message(out, "fake", null_message_fn); + + expect_function_call(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)) diff --git a/lib/common/tests/output/pcmk__output_new_test.c b/lib/common/tests/output/pcmk__output_new_test.c new file mode 100644 index 0000000..de4268c --- /dev/null +++ b/lib/common/tests/output/pcmk__output_new_test.c @@ -0,0 +1,148 @@ +/* + * Copyright 2022 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 <crm/common/unittest_internal.h> +#include <crm/common/output_internal.h> + +#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) { + pcmk__output_t *out = NULL; + + pcmk__assert_asserts(pcmk__output_new(&out, "fake", NULL, NULL)); +} + +static void +invalid_params(void **state) { + /* This must be called with the setup/teardown functions so formatters is not NULL. */ + pcmk__assert_asserts(pcmk__output_new(NULL, "fake", NULL, NULL)); +} + +static void +no_such_format(void **state) { + pcmk__output_t *out = NULL; + + assert_int_equal(pcmk__output_new(&out, "fake", NULL, NULL), pcmk_rc_unknown_format); +} + +static void +create_fails(void **state) { + pcmk__output_t *out = NULL; + + pcmk__mock_calloc = true; // calloc() will return NULL + + expect_value(__wrap_calloc, nmemb, 1); + expect_value(__wrap_calloc, size, sizeof(pcmk__output_t)); + assert_int_equal(pcmk__output_new(&out, "text", NULL, NULL), ENOMEM); + + pcmk__mock_calloc = false; // Use real calloc() +} + +static void +fopen_fails(void **state) { + pcmk__output_t *out = NULL; + + pcmk__mock_fopen = true; + expect_string(__wrap_fopen, pathname, "destfile"); + expect_string(__wrap_fopen, mode, "w"); + will_return(__wrap_fopen, EPERM); + + assert_int_equal(pcmk__output_new(&out, "text", "destfile", NULL), EPERM); + + pcmk__mock_fopen = false; +} + +static void +init_fails(void **state) { + pcmk__output_t *out = NULL; + + init_succeeds = false; + assert_int_equal(pcmk__output_new(&out, "text", NULL, NULL), ENOMEM); + init_succeeds = true; +} + +static void +everything_succeeds(void **state) { + pcmk__output_t *out = NULL; + + assert_int_equal(pcmk__output_new(&out, "text", NULL, NULL), pcmk_rc_ok); + assert_string_equal(out->fmt_name, "text"); + assert_ptr_equal(out->dest, stdout); + assert_false(out->quiet); + assert_non_null(out->messages); + assert_string_equal(getenv("OCF_OUTPUT_FORMAT"), "text"); + + pcmk__output_free(out); +} + +static void +no_fmt_name_given(void **state) { + pcmk__output_t *out = NULL; + + 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, + 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)) diff --git a/lib/common/tests/output/pcmk__register_format_test.c b/lib/common/tests/output/pcmk__register_format_test.c new file mode 100644 index 0000000..bcbde48 --- /dev/null +++ b/lib/common/tests/output/pcmk__register_format_test.c @@ -0,0 +1,63 @@ +/* + * Copyright 2022 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 <crm/common/unittest_internal.h> +#include <crm/common/output_internal.h> + +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) { + 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)); +} + +static void +add_format(void **state) { + GHashTable *formatters = NULL; + gpointer value; + + /* 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); + 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); + + /* 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. + */ + assert_int_equal(pcmk__register_format(NULL, "fake", null_create_fn_2, NULL), 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); + + pcmk__unregister_formats(); +} + +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(invalid_params), + cmocka_unit_test(add_format)) diff --git a/lib/common/tests/output/pcmk__register_formats_test.c b/lib/common/tests/output/pcmk__register_formats_test.c new file mode 100644 index 0000000..4be2d78 --- /dev/null +++ b/lib/common/tests/output/pcmk__register_formats_test.c @@ -0,0 +1,108 @@ +/* + * Copyright 2022 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 <crm/common/unittest_internal.h> +#include <crm/common/output_internal.h> + +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) { + pcmk__register_formats(NULL, NULL); + assert_null(pcmk__output_formatters()); +} + +static void +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 }, + { NULL }, + }; + + pcmk__assert_asserts(pcmk__register_formats(NULL, formats)); +} + +static void +valid_entries(void **state) { + GHashTable *formatters = NULL; + + pcmk__supported_format_t formats[] = { + { "fmt1", null_create_fn, NULL }, + { "fmt2", null_create_fn_2, NULL }, + { NULL }, + }; + + pcmk__register_formats(NULL, formats); + + 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); + + pcmk__unregister_formats(); +} + +static void +duplicate_keys(void **state) { + GHashTable *formatters = NULL; + + pcmk__supported_format_t formats[] = { + { "fmt1", null_create_fn, NULL }, + { "fmt1", null_create_fn_2, NULL }, + { NULL }, + }; + + pcmk__register_formats(NULL, formats); + + 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); + + pcmk__unregister_formats(); +} + +static void +duplicate_values(void **state) { + GHashTable *formatters = NULL; + + pcmk__supported_format_t formats[] = { + { "fmt1", null_create_fn, NULL }, + { "fmt2", null_create_fn, NULL }, + { NULL }, + }; + + pcmk__register_formats(NULL, formats); + + 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); + + pcmk__unregister_formats(); +} + +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(no_formats), + cmocka_unit_test(invalid_entries), + cmocka_unit_test(valid_entries), + cmocka_unit_test(duplicate_keys), + cmocka_unit_test(duplicate_values)) diff --git a/lib/common/tests/output/pcmk__register_message_test.c b/lib/common/tests/output/pcmk__register_message_test.c new file mode 100644 index 0000000..4b4a282 --- /dev/null +++ b/lib/common/tests/output/pcmk__register_message_test.c @@ -0,0 +1,107 @@ +/* + * Copyright 2022-2023 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 <crm/common/unittest_internal.h> +#include <crm/common/output_internal.h> + +#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) { + 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(out, "fake", NULL)); + + pcmk__output_free(out); +} + +static void +add_message(void **state) { + pcmk__output_t *out = NULL; + + pcmk__bare_output_new(&out, "text", NULL, NULL); + + /* For starters, there should be no messages defined. */ + 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); + assert_int_equal(g_hash_table_size(out->messages), 1); + assert_ptr_equal(g_hash_table_lookup(out->messages, "fake"), null_message_fn); + + /* 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); + assert_int_equal(g_hash_table_size(out->messages), 1); + assert_ptr_equal(g_hash_table_lookup(out->messages, "fake"), null_message_fn_2); + + 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)) diff --git a/lib/common/tests/output/pcmk__register_messages_test.c b/lib/common/tests/output/pcmk__register_messages_test.c new file mode 100644 index 0000000..3fdd759 --- /dev/null +++ b/lib/common/tests/output/pcmk__register_messages_test.c @@ -0,0 +1,191 @@ +/* + * Copyright 2022-2023 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 <crm/common/unittest_internal.h> +#include <crm/common/output_internal.h> + +#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) { + 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 }, + { "", "text", NULL }, + { NULL }, + }; + + pcmk__bare_output_new(&out, "text", NULL, NULL); + + pcmk__assert_asserts(pcmk__register_messages(out, entries)); + assert_int_equal(g_hash_table_size(out->messages), 0); + + pcmk__output_free(out); +} + +static void +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 }, + { NULL }, + }; + + pcmk__bare_output_new(&out, "text", NULL, NULL); + + 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); + + pcmk__output_free(out); +} + +static void +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 }, + { NULL }, + }; + + pcmk__bare_output_new(&out, "text", NULL, NULL); + + 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); + + pcmk__output_free(out); +} + +static void +duplicate_functions(void **state) { + pcmk__output_t *out = NULL; + + pcmk__message_entry_t entries[] = { + { "msg1", "text", null_message_fn }, + { "msg2", "text", null_message_fn }, + { NULL }, + }; + + pcmk__bare_output_new(&out, "text", NULL, NULL); + + 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); + + pcmk__output_free(out); +} + +static void +default_handler(void **state) { + pcmk__output_t *out = NULL; + + pcmk__message_entry_t entries[] = { + { "msg1", "default", null_message_fn }, + { NULL }, + }; + + pcmk__bare_output_new(&out, "text", NULL, NULL); + + 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); + + pcmk__output_free(out); +} + +static void +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 }, + { NULL }, + }; + + pcmk__bare_output_new(&out, "text", NULL, NULL); + + 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); + + 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)) diff --git a/lib/common/tests/output/pcmk__unregister_formats_test.c b/lib/common/tests/output/pcmk__unregister_formats_test.c new file mode 100644 index 0000000..0631c95 --- /dev/null +++ b/lib/common/tests/output/pcmk__unregister_formats_test.c @@ -0,0 +1,39 @@ +/* + * Copyright 2022 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 <crm/common/unittest_internal.h> +#include <crm/common/output_internal.h> + +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. + */ + pcmk__unregister_formats(); + assert_null(pcmk__output_formatters()); +} + +static void +non_null_formatters(void **state) { + pcmk__register_format(NULL, "fake", null_create_fn, NULL); + + pcmk__unregister_formats(); + assert_null(pcmk__output_formatters()); +} + +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(invalid_params), + cmocka_unit_test(non_null_formatters)) |