diff --git a/doc/sphinx/Pacemaker_Development/helpers.rst b/doc/sphinx/Pacemaker_Development/helpers.rst index f459c64249..3fcb48daf4 100644 --- a/doc/sphinx/Pacemaker_Development/helpers.rst +++ b/doc/sphinx/Pacemaker_Development/helpers.rst @@ -1,486 +1,521 @@ C Development Helpers --------------------- .. index:: single: unit testing Refactoring ########### Pacemaker uses an optional tool called `coccinelle `_ to do automatic refactoring. coccinelle is a very complicated tool that can be difficult to understand, and the existing documentation makes it pretty tough to get started. Much of the documentation is either aimed at kernel developers or takes the form of grammars. However, it can apply very complex transformations across an entire source tree. This is useful for tasks like code refactoring, changing APIs (number or type of arguments, etc.), catching functions that should not be called, and changing existing patterns. coccinelle is driven by input scripts called `semantic patches `_ written in its own language. These scripts bear a passing resemblance to source code patches and tell coccinelle how to match and modify a piece of source code. They are stored in ``devel/coccinelle`` and each script either contains a single source transformation or several related transformations. In general, we try to keep these as simple as possible. In Pacemaker development, we use a couple targets in ``devel/Makefile.am`` to control coccinelle. The ``cocci`` target tries to apply each script to every Pacemaker source file, printing out any changes it would make to the console. The ``cocci-inplace`` target does the same but also makes those changes to the source files. A variety of warnings might also be printed. If you aren't working on a new script, these can usually be ignored. If you are working on a new coccinelle script, it can be useful (and faster) to skip everything else and only run the new script. The ``COCCI_FILES`` variable can be used for this: .. code-block:: none $ make -C devel COCCI_FILES=coccinelle/new-file.cocci cocci This variable is also used for preventing some coccinelle scripts in the Pacemaker source tree from running. Some scripts are disabled because they are not currently fully working or because they are there as templates. When adding a new script, remember to add it to this variable if it should always be run. One complication when writing coccinelle scripts is that certain Pacemaker source files may not use private functions (those whose name starts with ``pcmk__``). Handling this requires work in both the Makefile and in the coccinelle scripts. The Makefile deals with this by maintaining two lists of source files: those that may use private functions and those that may not. For those that may, a special argument (``-D internal``) is added to the coccinelle command line. This creates a virtual dependency named ``internal``. In the coccinelle scripts, those transformations that modify source code to use a private function also have a dependency on ``internal``. If that dependency was given on the command line, the transformation will be run. Otherwise, it will be skipped. This means that not all instances of an older style of code will be changed after running a given transformation. Some developer intervention is still necessary to know whether a source code block should have been changed or not. Probably the easiest way to learn how to use coccinelle is by following other people's scripts. In addition to the ones in the Pacemaker source directory, there's several others on the `coccinelle website `_. Sanitizers ########## gcc supports a variety of run-time checks called sanitizers. These can be used to catch programming errors with memory, race conditions, various undefined behavior conditions, and more. Because these are run-time checks, they should only be used during development and not in compiled packages or production code. Certain sanitizers cannot be combined with others because their run-time checks cause interfere. Instead of trying to figure out which combinations work, it is simplest to just enable one at a time. Each supported sanitizer requires an installed libray. In addition to just enabling the sanitizer, their use can be configured with environment variables. For example: .. code-block:: none $ ASAN_OPTIONS=verbosity=1:replace_str=true crm_mon -1R Pacemaker supports the following subset of gcc's sanitizers: +--------------------+-------------------------+----------+----------------------+ | Sanitizer | Configure Option | Library | Environment Variable | +====================+=========================+==========+======================+ | Address | --with-sanitizers=asan | libasan | ASAN_OPTIONS | +--------------------+-------------------------+----------+----------------------+ | Threads | --with-sanitizers=tsan | libtsan | TSAN_OPTIONS | +--------------------+-------------------------+----------+----------------------+ | Undefined behavior | --with-sanitizers=ubsan | libubsan | UBSAN_OPTIONS | +--------------------+-------------------------+----------+----------------------+ The undefined behavior sanitizer further supports suboptions that need to be given as CFLAGS when configuring pacemaker: .. code-block:: none $ CFLAGS=-fsanitize=integer-divide-by-zero ./configure --with-sanitizers=ubsan For more information, see the `gcc documentation `_ which also provides links to more information on each sanitizer. Unit Testing ############ Where possible, changes to the C side of Pacemaker should be accompanied by unit tests. Much of Pacemaker cannot effectively be unit tested (and there are other testing systems used for those parts), but the ``lib`` subdirectory is pretty easy to write tests for. Pacemaker uses the `cmocka unit testing framework `_ which looks a lot like other unit testing frameworks for C and should be fairly familiar. In addition to regular unit tests, cmocka also gives us the ability to use `mock functions `_ for unit testing functions that would otherwise be difficult to test. Organization ____________ Pay close attention to the organization and naming of test cases to ensure the unit tests continue to work as they should. Tests are spread throughout the source tree, alongside the source code they test. For instance, all the tests for the source code in ``lib/common/`` are in the ``lib/common/tests`` directory. If there is no ``tests`` subdirectory, there are no tests for that library yet. Under that directory, there is a ``Makefile.am`` and additional subdirectories. Each subdirectory contains the tests for a single library source file. For instance, all the tests for ``lib/common/strings.c`` are in the ``lib/common/tests/strings`` directory. Note that the test subdirectory does not have a ``.c`` suffix. If there is no test subdirectory, there are no tests for that file yet. Finally, under that directory, there is a ``Makefile.am`` and then various source files. Each of these source files tests the single function that it is named after. For instance, ``lib/common/tests/strings/pcmk__btoa_test.c`` tests the ``pcmk__btoa()`` function in ``lib/common/strings.c``. If there is no test source file, there are no tests for that function yet. The ``_test`` suffix on the test source file is important. All tests have this suffix, which means all the compiled test cases will also end with this suffix. That lets us ignore all the compiled tests with a single line in ``.gitignore``: .. code-block:: none /lib/*/tests/*/*_test Adding a test _____________ Testing a new function in an already testable source file ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Follow these steps if you want to test a function in a source file where there are already other tested functions. For the purposes of this example, we will add a test for the ``pcmk__scan_port()`` function in ``lib/common/strings.c``. As you can see, there are already tests for other functions in this same file in the ``lib/common/tests/strings`` directory. * cd into ``lib/common/tests/strings`` * Add the new file to the the ``check_PROGRAMS`` variable in ``Makefile.am``, making it something like this: .. code-block:: none check_PROGRAMS = \ pcmk__add_word_test \ pcmk__btoa_test \ pcmk__scan_port_test * Create a new ``pcmk__scan_port_test.c`` file, copying the copyright and include boilerplate from another file in the same directory. * Continue with the steps in `Writing the test`_. Testing a function in a source file without tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Follow these steps if you want to test a function in a source file where there are not already other tested functions, but there are tests for other files in the same library. For the purposes of this example, we will add a test for the ``pcmk_acl_required()`` function in ``lib/common/acls.c``. At the time of this documentation being written, no tests existed for that source file, so there is no ``lib/common/tests/acls`` directory. * Add to ``AC_CONFIG_FILES`` in the top-level ``configure.ac`` file so the build process knows to use directory we're about to create. That variable would now look something like: .. code-block:: none dnl Other files we output AC_CONFIG_FILES(Makefile \ ... lib/common/tests/Makefile \ lib/common/tests/acls/Makefile \ lib/common/tests/agents/Makefile \ ... ) * cd into ``lib/common/tests`` * Add to the ``SUBDIRS`` variable in ``Makefile.am``, making it something like: .. code-block:: none SUBDIRS = agents acls cmdline flags operations strings utils xpath results * Create a new ``acls`` directory, copying the ``Makefile.am`` from some other directory. At this time, each ``Makefile.am`` is largely boilerplate with very little that needs to change from directory to directory. * cd into ``acls`` * Get rid of any existing values for ``check_PROGRAMS`` and set it to ``pcmk_acl_required_test`` like so: .. code-block:: none check_PROGRAMS = pcmk_acl_required_test -* Double check that ``-I$(top_srcdir)/lib/common`` is present in ``AM_CPPFLAGS``. - -* Double check the settings of variables at the top of ``Makefile.am``. The - following block should be present: +* Double check that ``$(top_srcdir)/mk/tap.mk`` and ``$(top_srcdir)/mk/unittest.mk`` + are included in the ``Makefile.am``. These files contain all the flags necessary + for most unit tests. If necessary, individual settings can be overridden like so: .. code-block:: none - LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka - AM_CFLAGS = -DPCMK__UNIT_TESTING - AM_LDFLAGS = $(LDFLAGS_WRAP) + AM_CPPFLAGS += -I$(top_srcdir) + LDADD += $(top_builddir)/lib/pengine/libpe_status_test.la * Follow the steps in `Testing a new function in an already testable source file`_ to create the new ``pcmk_acl_required_test.c`` file. Testing a function in a library without tests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Adding a test case for a function in a library that doesn't have any test cases to begin with is only slightly more complicated. In general, the steps are the same as for the previous section, except with an additional layer of directory creation. For the purposes of this example, we will add a test case for the ``lrmd_send_resource_alert()`` function in ``lib/lrmd/lrmd_alerts.c``. Note that this may not be a very good function or even library to write actual unit tests for. * Add to ``AC_CONFIG_FILES`` in the top-level ``configure.ac`` file so the build process knows to use directory we're about to create. That variable would now look something like: .. code-block:: none dnl Other files we output AC_CONFIG_FILES(Makefile \ ... lib/lrmd/Makefile \ lib/lrmd/tests/Makefile \ lib/services/Makefile \ ... ) * cd into ``lib/lrmd`` * Create a ``SUBDIRS`` variable in ``Makefile.am`` if it doesn't already exist. Most libraries should not have this variable already. .. code-block:: none SUBDIRS = tests * Create a new ``tests`` directory and add a ``Makefile.am`` with the following contents: .. code-block:: none SUBDIRS = lrmd_alerts * Follow the steps in `Testing a function in a source file without tests`_ to create the rest of the new directory structure. * Follow the steps in `Testing a new function in an already testable source file`_ to create the new ``lrmd_send_resource_alert_test.c`` file. Adding to an existing test case ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If all you need to do is add additional test cases to an existing file, none of the above work is necessary. All you need to do is find the test source file with the name matching your function and add to it and then follow the instructions in `Writing the test`_. Writing the test ________________ A test case file contains a fair amount of boilerplate. For this reason, it's usually easiest to just copy an existing file and adapt it to your needs. However, here's the basic structure: .. code-block:: c /* * Copyright 2021 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 #include /* Put your test-specific includes here */ /* Put your test functions here */ - int - main(int argc, char **argv) - { - /* Register your test functions here */ - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); - } + PCMK__UNIT_TEST(NULL, NULL, + /* Register your test functions here */) Each test-specific function should test one aspect of the library function, though it can include many assertions if there are many ways of testing that one aspect. For instance, there might be multiple ways of testing regular expression matching: .. code-block:: c static void regex(void **state) { const char *s1 = "abcd"; const char *s2 = "ABCD"; assert_true(pcmk__strcmp(NULL, "a..d", pcmk__str_regex) < 0); assert_true(pcmk__strcmp(s1, NULL, pcmk__str_regex) > 0); assert_int_equal(pcmk__strcmp(s1, "a..d", pcmk__str_regex), 0); } Each test-specific function must also be registered or it will not be called. -This is done with ``cmocka_unit_test()`` in the ``main`` function: +This is done with ``cmocka_unit_test()`` in the ``PCMK__UNIT_TEST`` macro: .. code-block:: c - const struct CMUnitTest tests[] = { - cmocka_unit_test(regex), - }; + PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(regex)) + +Most unit tests do not require a setup and teardown function to be executed +around the entire group of tests. On occassion, this may be necessary. Simply +pass those functions in as the first two parameters to ``PCMK__UNIT_TEST`` +instead of using NULL. Assertions __________ In addition to the `assertions provided by `_, ``unittest_internal.h`` also provides ``pcmk__assert_asserts``. This macro takes an expression and verifies that the expression aborts due to a failed call to ``CRM_ASSERT`` or some other similar function. It can be used like so: .. code-block:: c static void null_input_variables(void **state) { long long start, end; pcmk__assert_asserts(pcmk__parse_ll_range("1234", NULL, &end)); pcmk__assert_asserts(pcmk__parse_ll_range("1234", &start, NULL)); } Here, ``pcmk__parse_ll_range`` expects non-NULL for its second and third arguments. If one of those arguments is NULL, ``CRM_ASSERT`` will fail and the program will abort. ``pcmk__assert_asserts`` checks that the code would abort and the test passes. If the code does not abort, the test fails. Running _______ If you had to create any new files or directories, you will first need to run ``./configure`` from the top level of the source directory. This will regenerate the Makefiles throughout the tree. If you skip this step, your changes will be skipped and you'll be left wondering why the output doesn't match what you expected. To run the tests, simply run ``make check`` after previously building the source with ``make``. The test cases in each directory will be built and then run. This should not take long. If all the tests succeed, you will be back at the prompt. Scrolling back through the history, you should see lines like the following: .. code-block:: none PASS: pcmk__strcmp_test 1 - same_pointer PASS: pcmk__strcmp_test 2 - one_is_null PASS: pcmk__strcmp_test 3 - case_matters PASS: pcmk__strcmp_test 4 - case_insensitive PASS: pcmk__strcmp_test 5 - regex ============================================================================ Testsuite summary for pacemaker 2.1.0 ============================================================================ # TOTAL: 33 # PASS: 33 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ============================================================================ make[7]: Leaving directory '/home/clumens/src/pacemaker/lib/common/tests/strings' The testing process will quit on the first failed test, and you will see lines like these: .. code-block:: none PASS: pcmk__scan_double_test 3 - trailing_chars FAIL: pcmk__scan_double_test 4 - typical_case PASS: pcmk__scan_double_test 5 - double_overflow PASS: pcmk__scan_double_test 6 - double_underflow ERROR: pcmk__scan_double_test - exited with status 1 PASS: pcmk__starts_with_test 1 - bad_input ============================================================================ Testsuite summary for pacemaker 2.1.0 ============================================================================ # TOTAL: 56 # PASS: 54 # SKIP: 0 # XFAIL: 0 # FAIL: 1 # XPASS: 0 # ERROR: 1 ============================================================================ See lib/common/tests/strings/test-suite.log Please report to users@clusterlabs.org ============================================================================ make[7]: *** [Makefile:1218: test-suite.log] Error 1 make[7]: Leaving directory '/home/clumens/src/pacemaker/lib/common/tests/strings' The failure is in ``lib/common/tests/strings/test-suite.log``: .. code-block:: none ERROR: pcmk__scan_double_test ============================= 1..6 ok 1 - empty_input_string PASS: pcmk__scan_double_test 1 - empty_input_string ok 2 - bad_input_string PASS: pcmk__scan_double_test 2 - bad_input_string ok 3 - trailing_chars PASS: pcmk__scan_double_test 3 - trailing_chars not ok 4 - typical_case FAIL: pcmk__scan_double_test 4 - typical_case # 0.000000 != 3.000000 # pcmk__scan_double_test.c:80: error: Failure! ok 5 - double_overflow PASS: pcmk__scan_double_test 5 - double_overflow ok 6 - double_underflow PASS: pcmk__scan_double_test 6 - double_underflow # not ok - tests ERROR: pcmk__scan_double_test - exited with status 1 At this point, you need to determine whether your test case is incorrect or whether the code being tested is incorrect. Fix whichever is wrong and continue. +Code Coverage +############# + +Figuring out what needs unit tests written is the purpose of a code coverage tool. +The Pacemaker build process uses ``lcov`` and special make targets to generate +an HTML coverage report that can be inspected with any web browser. + +To start, you'll need to install the ``lcov`` package which is included in most +distributions. Next, reconfigure and rebuild the source tree: + +.. code-block:: none + + $ ./configure --with-coverage + $ make + +Then simply run ``make coverage``. This will do the same thing as ``make check``, +but will generate a bunch of intermediate files as part of the compiler's output. +Essentially, the coverage tools run all the unit tests and make a note if a given +line if code is executed as a part of some test program. This will include not +just things run as part of the tests but anything in the setup and teardown +functions as well. + +Afterwards, the HTML report will be in ``coverage/index.html``. You can drill down +into individual source files to see exactly which lines are covered and which are +not, which makes it easy to target new unit tests. Note that sometimes, it is +impossible to achieve 100% coverage for a source file. For instance, how do you +test a function with a return type of void that simply returns on some condition? + +Note that Pacemaker's overall code coverage numbers are very low at the moment. +One reason for this is the large amount of code in the ``daemons`` directory that +will be very difficult to write unit tests for. For now, it is best to focus +efforts on increasing the coverage on individual libraries. + +Additionally, there is a ``coverage-cts`` target that does the same thing but +instead of testing ``make check``, it tests ``cts/cts-cli``. The idea behind this +target is to see what parts of our command line tools are covered by our regression +tests. It is probably best to clean and rebuild the source tree when switching +between these various targets. + + Debugging ######### gdb ___ If you use ``gdb`` for debugging, some helper functions are defined in ``devel/gdbhelpers``, which can be given to ``gdb`` using the ``-x`` option. From within the debugger, you can then invoke the ``pcmk`` command that will describe the helper functions available. diff --git a/include/crm/common/unittest_internal.h b/include/crm/common/unittest_internal.h index 4070539530..b8f78cf411 100644 --- a/include/crm/common/unittest_internal.h +++ b/include/crm/common/unittest_internal.h @@ -1,68 +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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include #include #include #include #include #include #include #include #ifndef CRM_COMMON_UNITTEST_INTERNAL__H #define CRM_COMMON_UNITTEST_INTERNAL__H /* internal unit testing related utilities */ /*! * \internal * \brief Assert that a statement aborts through CRM_ASSERT(). * * \param[in] stmt Statement to execute; can be an expression. * * A cmocka-like assert macro for use in unit testing. This one verifies that a * statement aborts through CRM_ASSERT(), erroring out if that is not the case. * * This macro works by running the statement in a forked child process with core * dumps disabled (CRM_ASSERT() calls \c abort(), which will write out a core * dump). The parent waits for the child to exit and checks why. If the child * received a \c SIGABRT, the test passes. For all other cases, the test fails. * * \note If cmocka's expect_*() or will_return() macros are called along with * pcmk__assert_asserts(), they must be called within a block that is * passed as the \c stmt argument. That way, the values are added only to * the child's queue. Otherwise, values added to the parent's queue will * never be popped, and the test will fail. */ #define pcmk__assert_asserts(stmt) \ do { \ pid_t p = fork(); \ if (p == 0) { \ struct rlimit cores = { 0, 0 }; \ setrlimit(RLIMIT_CORE, &cores); \ stmt; \ _exit(0); \ } else if (p > 0) { \ int wstatus = 0; \ if (waitpid(p, &wstatus, 0) == -1) { \ fail_msg("waitpid failed"); \ } \ if (!(WIFSIGNALED(wstatus) && WTERMSIG(wstatus) == SIGABRT)) { \ fail_msg("statement terminated in child without asserting"); \ } \ } else { \ fail_msg("unable to fork for assert test"); \ } \ } while (0); +/* Generate the main function of most unit test files. Typically, group_setup + * and group_teardown will be NULL. The rest of the arguments are a list of + * calls to cmocka_unit_test or cmocka_unit_test_setup_teardown to run the + * individual unit tests. + */ +#define PCMK__UNIT_TEST(group_setup, group_teardown, ...) \ +int \ +main(int argc, char **argv) \ +{ \ + const struct CMUnitTest t[] = { \ + __VA_ARGS__ \ + }; \ + cmocka_set_message_output(CM_OUTPUT_TAP); \ + return cmocka_run_group_tests(t, group_setup, group_teardown); \ +} + #endif /* CRM_COMMON_UNITTEST_INTERNAL__H */ diff --git a/lib/common/tests/acl/Makefile.am b/lib/common/tests/acl/Makefile.am index 96460e8d8e..50408f9671 100644 --- a/lib/common/tests/acl/Makefile.am +++ b/lib/common/tests/acl/Makefile.am @@ -1,28 +1,21 @@ # # 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. # -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/lib/common -LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka -AM_CFLAGS = -DPCMK__UNIT_TESTING -AM_LDFLAGS = $(LDFLAGS_WRAP) - 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__is_user_in_group_test \ pcmk_acl_required_test \ xml_acl_denied_test \ xml_acl_enabled_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/acl/pcmk__is_user_in_group_test.c b/lib/common/tests/acl/pcmk__is_user_in_group_test.c index 75fe85c4e2..537449bca9 100644 --- a/lib/common/tests/acl/pcmk__is_user_in_group_test.c +++ b/lib/common/tests/acl/pcmk__is_user_in_group_test.c @@ -1,46 +1,38 @@ /* * Copyright 2020-2022 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 #include #include #include "../../crmcommon_private.h" #include "mock_private.h" static void is_pcmk__is_user_in_group(void **state) { pcmk__mock_grent = true; // null user assert_false(pcmk__is_user_in_group(NULL, "grp0")); // null group assert_false(pcmk__is_user_in_group("user0", NULL)); // nonexistent group assert_false(pcmk__is_user_in_group("user0", "nonexistent_group")); // user is in group assert_true(pcmk__is_user_in_group("user0", "grp0")); // user is not in group assert_false(pcmk__is_user_in_group("user2", "grp0")); pcmk__mock_grent = false; } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(is_pcmk__is_user_in_group) - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(is_pcmk__is_user_in_group)) diff --git a/lib/common/tests/acl/pcmk_acl_required_test.c b/lib/common/tests/acl/pcmk_acl_required_test.c index 4e9cf31cc2..6c425a0ce8 100644 --- a/lib/common/tests/acl/pcmk_acl_required_test.c +++ b/lib/common/tests/acl/pcmk_acl_required_test.c @@ -1,34 +1,26 @@ /* * Copyright 2020-2021 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 #include #include static void is_pcmk_acl_required(void **state) { assert_false(pcmk_acl_required(NULL)); assert_false(pcmk_acl_required("")); assert_true(pcmk_acl_required("123")); assert_false(pcmk_acl_required(CRM_DAEMON_USER)); assert_false(pcmk_acl_required("root")); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(is_pcmk_acl_required), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(is_pcmk_acl_required)) diff --git a/lib/common/tests/acl/xml_acl_denied_test.c b/lib/common/tests/acl/xml_acl_denied_test.c index 72ac1a6964..dad5e685d9 100644 --- a/lib/common/tests/acl/xml_acl_denied_test.c +++ b/lib/common/tests/acl/xml_acl_denied_test.c @@ -1,69 +1,61 @@ /* * Copyright 2020-2021 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 #include #include #include "../../crmcommon_private.h" static void is_xml_acl_denied_without_node(void **state) { xmlNode *test_xml = create_xml_node(NULL, "test_xml"); assert_false(xml_acl_denied(test_xml)); test_xml->doc->_private = NULL; assert_false(xml_acl_denied(test_xml)); test_xml->doc = NULL; assert_false(xml_acl_denied(test_xml)); test_xml = NULL; assert_false(xml_acl_denied(test_xml)); } static void is_xml_acl_denied_with_node(void **state) { xml_private_t *p; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); // allocate memory for _private, which is NULL by default test_xml->doc->_private = calloc(1, sizeof(xml_private_t)); assert_false(xml_acl_denied(test_xml)); // cast _private from void* to xml_private_t* p = test_xml->doc->_private; // enable an irrelevant flag p->flags |= pcmk__xf_acl_enabled; assert_false(xml_acl_denied(test_xml)); // enable pcmk__xf_acl_denied p->flags |= pcmk__xf_acl_denied; assert_true(xml_acl_denied(test_xml)); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(is_xml_acl_denied_without_node), - cmocka_unit_test(is_xml_acl_denied_with_node), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(is_xml_acl_denied_without_node), + cmocka_unit_test(is_xml_acl_denied_with_node)) diff --git a/lib/common/tests/acl/xml_acl_enabled_test.c b/lib/common/tests/acl/xml_acl_enabled_test.c index 4cf76e5cf2..db9768d133 100644 --- a/lib/common/tests/acl/xml_acl_enabled_test.c +++ b/lib/common/tests/acl/xml_acl_enabled_test.c @@ -1,69 +1,61 @@ /* * Copyright 2020-2021 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 #include #include #include "../../crmcommon_private.h" static void is_xml_acl_enabled_without_node(void **state) { xmlNode *test_xml = create_xml_node(NULL, "test_xml"); assert_false(xml_acl_enabled(test_xml)); test_xml->doc->_private = NULL; assert_false(xml_acl_enabled(test_xml)); test_xml->doc = NULL; assert_false(xml_acl_enabled(test_xml)); test_xml = NULL; assert_false(xml_acl_enabled(test_xml)); } static void is_xml_acl_enabled_with_node(void **state) { xml_private_t *p; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); // allocate memory for _private, which is NULL by default test_xml->doc->_private = calloc(1, sizeof(xml_private_t)); assert_false(xml_acl_enabled(test_xml)); // cast _private from void* to xml_private_t* p = test_xml->doc->_private; // enable an irrelevant flag p->flags |= pcmk__xf_acl_denied; assert_false(xml_acl_enabled(test_xml)); // enable pcmk__xf_acl_enabled p->flags |= pcmk__xf_acl_enabled; assert_true(xml_acl_enabled(test_xml)); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(is_xml_acl_enabled_without_node), - cmocka_unit_test(is_xml_acl_enabled_with_node), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(is_xml_acl_enabled_without_node), + cmocka_unit_test(is_xml_acl_enabled_with_node)) diff --git a/lib/common/tests/agents/Makefile.am b/lib/common/tests/agents/Makefile.am index 7e7368fecf..7a54b7deff 100644 --- a/lib/common/tests/agents/Makefile.am +++ b/lib/common/tests/agents/Makefile.am @@ -1,27 +1,20 @@ # # Copyright 2020-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. # -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/lib/common -LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka -AM_CFLAGS = -DPCMK__UNIT_TESTING -AM_LDFLAGS = $(LDFLAGS_WRAP) - 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 = crm_generate_ra_key_test \ crm_parse_agent_spec_test \ pcmk__effective_rc_test \ pcmk_get_ra_caps_test \ pcmk_stonith_param_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/agents/crm_generate_ra_key_test.c b/lib/common/tests/agents/crm_generate_ra_key_test.c index 3f5b2582dd..4d85502cd7 100644 --- a/lib/common/tests/agents/crm_generate_ra_key_test.c +++ b/lib/common/tests/agents/crm_generate_ra_key_test.c @@ -1,56 +1,48 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include static void all_params_null(void **state) { assert_null(crm_generate_ra_key(NULL, NULL, NULL)); } static void some_params_null(void **state) { char *retval; assert_null(crm_generate_ra_key("std", "prov", NULL)); retval = crm_generate_ra_key("std", NULL, "ty"); assert_string_equal(retval, "std:ty"); free(retval); assert_null(crm_generate_ra_key(NULL, "prov", "ty")); assert_null(crm_generate_ra_key("std", NULL, NULL)); assert_null(crm_generate_ra_key(NULL, "prov", NULL)); assert_null(crm_generate_ra_key(NULL, NULL, "ty")); } static void no_params_null(void **state) { char *retval; retval = crm_generate_ra_key("std", "prov", "ty"); assert_string_equal(retval, "std:prov:ty"); free(retval); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(all_params_null), - cmocka_unit_test(some_params_null), - cmocka_unit_test(no_params_null), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(all_params_null), + cmocka_unit_test(some_params_null), + cmocka_unit_test(no_params_null)) diff --git a/lib/common/tests/agents/crm_parse_agent_spec_test.c b/lib/common/tests/agents/crm_parse_agent_spec_test.c index 19b73c5b65..67f7ef5e2b 100644 --- a/lib/common/tests/agents/crm_parse_agent_spec_test.c +++ b/lib/common/tests/agents/crm_parse_agent_spec_test.c @@ -1,95 +1,87 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include static void all_params_null(void **state) { assert_int_equal(crm_parse_agent_spec(NULL, NULL, NULL, NULL), -EINVAL); assert_int_equal(crm_parse_agent_spec("", NULL, NULL, NULL), -EINVAL); assert_int_equal(crm_parse_agent_spec(":", NULL, NULL, NULL), -EINVAL); assert_int_equal(crm_parse_agent_spec("::", NULL, NULL, NULL), -EINVAL); } static void no_prov_or_type(void **state) { assert_int_equal(crm_parse_agent_spec("ocf", NULL, NULL, NULL), -EINVAL); assert_int_equal(crm_parse_agent_spec("ocf:", NULL, NULL, NULL), -EINVAL); assert_int_equal(crm_parse_agent_spec("ocf::", NULL, NULL, NULL), -EINVAL); } static void no_type(void **state) { assert_int_equal(crm_parse_agent_spec("ocf:pacemaker:", NULL, NULL, NULL), -EINVAL); } static void get_std_and_ty(void **state) { char *std = NULL; char *prov = NULL; char *ty = NULL; assert_int_equal(crm_parse_agent_spec("stonith:fence_xvm", &std, &prov, &ty), pcmk_ok); assert_string_equal(std, "stonith"); assert_null(prov); assert_string_equal(ty, "fence_xvm"); free(std); free(ty); } static void get_all_values(void **state) { char *std = NULL; char *prov = NULL; char *ty = NULL; assert_int_equal(crm_parse_agent_spec("ocf:pacemaker:ping", &std, &prov, &ty), pcmk_ok); assert_string_equal(std, "ocf"); assert_string_equal(prov, "pacemaker"); assert_string_equal(ty, "ping"); free(std); free(prov); free(ty); } static void get_systemd_values(void **state) { char *std = NULL; char *prov = NULL; char *ty = NULL; assert_int_equal(crm_parse_agent_spec("systemd:UNIT@A:B", &std, &prov, &ty), pcmk_ok); assert_string_equal(std, "systemd"); assert_null(prov); assert_string_equal(ty, "UNIT@A:B"); free(std); free(ty); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(all_params_null), - cmocka_unit_test(no_prov_or_type), - cmocka_unit_test(no_type), - cmocka_unit_test(get_std_and_ty), - cmocka_unit_test(get_all_values), - cmocka_unit_test(get_systemd_values), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(all_params_null), + cmocka_unit_test(no_prov_or_type), + cmocka_unit_test(no_type), + cmocka_unit_test(get_std_and_ty), + cmocka_unit_test(get_all_values), + cmocka_unit_test(get_systemd_values)) diff --git a/lib/common/tests/agents/pcmk__effective_rc_test.c b/lib/common/tests/agents/pcmk__effective_rc_test.c index 0d94dbd577..ce9f2b3357 100644 --- a/lib/common/tests/agents/pcmk__effective_rc_test.c +++ b/lib/common/tests/agents/pcmk__effective_rc_test.c @@ -1,44 +1,36 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include static void pcmk__effective_rc_test(void **state) { /* All other PCMK_OCF_* values after UNKNOWN are deprecated and no longer used, * so probably not worth testing them. */ assert_int_equal(PCMK_OCF_OK, pcmk__effective_rc(PCMK_OCF_OK)); assert_int_equal(PCMK_OCF_OK, pcmk__effective_rc(PCMK_OCF_DEGRADED)); assert_int_equal(PCMK_OCF_RUNNING_PROMOTED, pcmk__effective_rc(PCMK_OCF_DEGRADED_PROMOTED)); assert_int_equal(PCMK_OCF_UNKNOWN, pcmk__effective_rc(PCMK_OCF_UNKNOWN)); /* There's nothing that says pcmk__effective_rc is restricted to PCMK_OCF_* * values. That's just how it's used. Let's check some values outside * that range just to be sure. */ assert_int_equal(-1, pcmk__effective_rc(-1)); assert_int_equal(255, pcmk__effective_rc(255)); assert_int_equal(INT_MAX, pcmk__effective_rc(INT_MAX)); assert_int_equal(INT_MIN, pcmk__effective_rc(INT_MIN)); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(pcmk__effective_rc_test), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(pcmk__effective_rc_test)) diff --git a/lib/common/tests/agents/pcmk_get_ra_caps_test.c b/lib/common/tests/agents/pcmk_get_ra_caps_test.c index fe7cfc36fb..833dca5047 100644 --- a/lib/common/tests/agents/pcmk_get_ra_caps_test.c +++ b/lib/common/tests/agents/pcmk_get_ra_caps_test.c @@ -1,71 +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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include static void ocf_standard(void **state) { uint32_t expected = pcmk_ra_cap_provider | pcmk_ra_cap_params | pcmk_ra_cap_unique | pcmk_ra_cap_promotable; assert_int_equal(pcmk_get_ra_caps("ocf"), expected); assert_int_equal(pcmk_get_ra_caps("OCF"), expected); } static void stonith_standard(void **state) { uint32_t expected = pcmk_ra_cap_params | pcmk_ra_cap_unique | pcmk_ra_cap_stdin | pcmk_ra_cap_fence_params; assert_int_equal(pcmk_get_ra_caps("stonith"), expected); assert_int_equal(pcmk_get_ra_caps("StOnItH"), expected); } static void service_standard(void **state) { assert_int_equal(pcmk_get_ra_caps("systemd"), pcmk_ra_cap_status); assert_int_equal(pcmk_get_ra_caps("SYSTEMD"), pcmk_ra_cap_status); assert_int_equal(pcmk_get_ra_caps("service"), pcmk_ra_cap_status); assert_int_equal(pcmk_get_ra_caps("SeRvIcE"), pcmk_ra_cap_status); assert_int_equal(pcmk_get_ra_caps("lsb"), pcmk_ra_cap_status); assert_int_equal(pcmk_get_ra_caps("LSB"), pcmk_ra_cap_status); assert_int_equal(pcmk_get_ra_caps("upstart"), pcmk_ra_cap_status); assert_int_equal(pcmk_get_ra_caps("uPsTaRt"), pcmk_ra_cap_status); } static void nagios_standard(void **state) { assert_int_equal(pcmk_get_ra_caps("nagios"), pcmk_ra_cap_params); assert_int_equal(pcmk_get_ra_caps("NAGios"), pcmk_ra_cap_params); } static void unknown_standard(void **state) { assert_int_equal(pcmk_get_ra_caps("blahblah"), pcmk_ra_cap_none); assert_int_equal(pcmk_get_ra_caps(""), pcmk_ra_cap_none); assert_int_equal(pcmk_get_ra_caps(NULL), pcmk_ra_cap_none); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(ocf_standard), - cmocka_unit_test(stonith_standard), - cmocka_unit_test(service_standard), - cmocka_unit_test(nagios_standard), - cmocka_unit_test(unknown_standard), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(ocf_standard), + cmocka_unit_test(stonith_standard), + cmocka_unit_test(service_standard), + cmocka_unit_test(nagios_standard), + cmocka_unit_test(unknown_standard)) diff --git a/lib/common/tests/agents/pcmk_stonith_param_test.c b/lib/common/tests/agents/pcmk_stonith_param_test.c index 44d7f92266..4994282fd4 100644 --- a/lib/common/tests/agents/pcmk_stonith_param_test.c +++ b/lib/common/tests/agents/pcmk_stonith_param_test.c @@ -1,58 +1,50 @@ /* * Copyright 2020-2021 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 #include #include static void is_stonith_param(void **state) { assert_false(pcmk_stonith_param(NULL)); assert_false(pcmk_stonith_param("")); assert_false(pcmk_stonith_param("unrecognized")); assert_false(pcmk_stonith_param("pcmk_unrecognized")); assert_false(pcmk_stonith_param("x" PCMK_STONITH_ACTION_LIMIT)); assert_false(pcmk_stonith_param(PCMK_STONITH_ACTION_LIMIT "x")); assert_true(pcmk_stonith_param(PCMK_STONITH_ACTION_LIMIT)); assert_true(pcmk_stonith_param(PCMK_STONITH_DELAY_BASE)); assert_true(pcmk_stonith_param(PCMK_STONITH_DELAY_MAX)); assert_true(pcmk_stonith_param(PCMK_STONITH_HOST_ARGUMENT)); assert_true(pcmk_stonith_param(PCMK_STONITH_HOST_CHECK)); assert_true(pcmk_stonith_param(PCMK_STONITH_HOST_LIST)); assert_true(pcmk_stonith_param(PCMK_STONITH_HOST_MAP)); assert_true(pcmk_stonith_param(PCMK_STONITH_PROVIDES)); assert_true(pcmk_stonith_param(PCMK_STONITH_STONITH_TIMEOUT)); } static void is_stonith_action_param(void **state) { /* Currently, the function accepts any string not containing underbars as * the action name, so we do not need to verify particular action names. */ assert_false(pcmk_stonith_param("pcmk_on_unrecognized")); assert_true(pcmk_stonith_param("pcmk_on_action")); assert_true(pcmk_stonith_param("pcmk_on_timeout")); assert_true(pcmk_stonith_param("pcmk_on_retries")); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(is_stonith_param), - cmocka_unit_test(is_stonith_action_param), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(is_stonith_param), + cmocka_unit_test(is_stonith_action_param)) diff --git a/lib/common/tests/cmdline/Makefile.am b/lib/common/tests/cmdline/Makefile.am index 907ae7474b..d781ed5e96 100644 --- a/lib/common/tests/cmdline/Makefile.am +++ b/lib/common/tests/cmdline/Makefile.am @@ -1,24 +1,17 @@ # # Copyright 2020-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. # -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/lib/common -LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka -AM_CFLAGS = -DPCMK__UNIT_TESTING -AM_LDFLAGS = $(LDFLAGS_WRAP) - 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__cmdline_preproc_test \ pcmk__quote_cmdline_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c index da2859dc22..1b20d74afa 100644 --- a/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c +++ b/lib/common/tests/cmdline/pcmk__cmdline_preproc_test.c @@ -1,163 +1,156 @@ /* * Copyright 2020-2022 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 #include #include #include +#include #define LISTS_EQ(a, b) { \ assert_int_equal(g_strv_length((gchar **) (a)), g_strv_length((gchar **) (b))); \ for (int i = 0; i < g_strv_length((a)); i++) { \ assert_string_equal((a)[i], (b)[i]); \ } \ } static void empty_input(void **state) { assert_null(pcmk__cmdline_preproc(NULL, "")); } static void no_specials(void **state) { const char *argv[] = { "crm_mon", "-a", "-b", "-c", "-d", "-1", NULL }; const gchar *expected[] = { "crm_mon", "-a", "-b", "-c", "-d", "-1", NULL }; gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL); LISTS_EQ(processed, expected); g_strfreev(processed); processed = pcmk__cmdline_preproc((char **) argv, ""); LISTS_EQ(processed, expected); g_strfreev(processed); } static void single_dash(void **state) { const char *argv[] = { "crm_mon", "-", NULL }; const gchar *expected[] = { "crm_mon", "-", NULL }; gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL); LISTS_EQ(processed, expected); g_strfreev(processed); } static void double_dash(void **state) { const char *argv[] = { "crm_mon", "-a", "--", "-bc", NULL }; const gchar *expected[] = { "crm_mon", "-a", "--", "-bc", NULL }; gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL); LISTS_EQ(processed, expected); g_strfreev(processed); } static void special_args(void **state) { const char *argv[] = { "crm_mon", "-aX", "-Fval", NULL }; const gchar *expected[] = { "crm_mon", "-a", "X", "-F", "val", NULL }; gchar **processed = pcmk__cmdline_preproc((char **) argv, "aF"); LISTS_EQ(processed, expected); g_strfreev(processed); } static void special_arg_at_end(void **state) { const char *argv[] = { "crm_mon", "-a", NULL }; const gchar *expected[] = { "crm_mon", "-a", NULL }; gchar **processed = pcmk__cmdline_preproc((char **) argv, "a"); LISTS_EQ(processed, expected); g_strfreev(processed); } static void long_arg(void **state) { const char *argv[] = { "crm_mon", "--blah=foo", NULL }; const gchar *expected[] = { "crm_mon", "--blah=foo", NULL }; gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL); LISTS_EQ(processed, expected); g_strfreev(processed); } static void negative_score(void **state) { const char *argv[] = { "crm_mon", "-v", "-1000", NULL }; const gchar *expected[] = { "crm_mon", "-v", "-1000", NULL }; gchar **processed = pcmk__cmdline_preproc((char **) argv, "v"); LISTS_EQ(processed, expected); g_strfreev(processed); } static void negative_score_2(void **state) { const char *argv[] = { "crm_mon", "-1i3", NULL }; const gchar *expected[] = { "crm_mon", "-1", "-i", "-3", NULL }; gchar **processed = pcmk__cmdline_preproc((char **) argv, NULL); LISTS_EQ(processed, expected); g_strfreev(processed); } static void string_arg_with_dash(void **state) { const char *argv[] = { "crm_mon", "-n", "crm_mon_options", "-v", "--opt1 --opt2", NULL }; const gchar *expected[] = { "crm_mon", "-n", "crm_mon_options", "-v", "--opt1 --opt2", NULL }; gchar **processed = pcmk__cmdline_preproc((char **) argv, "v"); LISTS_EQ(processed, expected); g_strfreev(processed); } static void string_arg_with_dash_2(void **state) { const char *argv[] = { "crm_mon", "-n", "crm_mon_options", "-v", "-1i3", NULL }; const gchar *expected[] = { "crm_mon", "-n", "crm_mon_options", "-v", "-1i3", NULL }; gchar **processed = pcmk__cmdline_preproc((char **) argv, "v"); LISTS_EQ(processed, expected); g_strfreev(processed); } static void string_arg_with_dash_3(void **state) { const char *argv[] = { "crm_mon", "-abc", "-1i3", NULL }; const gchar *expected[] = { "crm_mon", "-a", "-b", "-c", "-1i3", NULL }; gchar **processed = pcmk__cmdline_preproc((char **) argv, "c"); LISTS_EQ(processed, expected); g_strfreev(processed); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(empty_input), - cmocka_unit_test(no_specials), - cmocka_unit_test(single_dash), - cmocka_unit_test(double_dash), - cmocka_unit_test(special_args), - cmocka_unit_test(special_arg_at_end), - cmocka_unit_test(long_arg), - cmocka_unit_test(negative_score), - cmocka_unit_test(negative_score_2), - cmocka_unit_test(string_arg_with_dash), - cmocka_unit_test(string_arg_with_dash_2), - cmocka_unit_test(string_arg_with_dash_3), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(empty_input), + cmocka_unit_test(no_specials), + cmocka_unit_test(single_dash), + cmocka_unit_test(double_dash), + cmocka_unit_test(special_args), + cmocka_unit_test(special_arg_at_end), + cmocka_unit_test(long_arg), + cmocka_unit_test(negative_score), + cmocka_unit_test(negative_score_2), + cmocka_unit_test(string_arg_with_dash), + cmocka_unit_test(string_arg_with_dash_2), + cmocka_unit_test(string_arg_with_dash_3)) diff --git a/lib/common/tests/cmdline/pcmk__quote_cmdline_test.c b/lib/common/tests/cmdline/pcmk__quote_cmdline_test.c index 58d0cb5f75..d87b88f91b 100644 --- a/lib/common/tests/cmdline/pcmk__quote_cmdline_test.c +++ b/lib/common/tests/cmdline/pcmk__quote_cmdline_test.c @@ -1,64 +1,56 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include #include static void empty_input(void **state) { assert_null(pcmk__quote_cmdline(NULL)); } static void no_spaces(void **state) { const char *argv[] = { "crm_resource", "-r", "rsc1", "--meta", "-p", "comment", "-v", "hello", "--output-as=xml", NULL }; const gchar *expected = "crm_resource -r rsc1 --meta -p comment -v hello --output-as=xml"; gchar *processed = pcmk__quote_cmdline((gchar **) argv); assert_string_equal(processed, expected); g_free(processed); } static void spaces_no_quote(void **state) { const char *argv[] = { "crm_resource", "-r", "rsc1", "--meta", "-p", "comment", "-v", "hello world", "--output-as=xml", NULL }; const gchar *expected = "crm_resource -r rsc1 --meta -p comment -v 'hello world' --output-as=xml"; gchar *processed = pcmk__quote_cmdline((gchar **) argv); assert_string_equal(processed, expected); g_free(processed); } static void spaces_with_quote(void **state) { const char *argv[] = { "crm_resource", "-r", "rsc1", "--meta", "-p", "comment", "-v", "here's johnny", "--output-as=xml", NULL }; const gchar *expected = "crm_resource -r rsc1 --meta -p comment -v 'here\\\'s johnny' --output-as=xml"; gchar *processed = pcmk__quote_cmdline((gchar **) argv); assert_string_equal(processed, expected); g_free(processed); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(empty_input), - cmocka_unit_test(no_spaces), - cmocka_unit_test(spaces_no_quote), - cmocka_unit_test(spaces_with_quote), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(empty_input), + cmocka_unit_test(no_spaces), + cmocka_unit_test(spaces_no_quote), + cmocka_unit_test(spaces_with_quote)) diff --git a/lib/common/tests/flags/Makefile.am b/lib/common/tests/flags/Makefile.am index d50b9f7b12..16d8ffb336 100644 --- a/lib/common/tests/flags/Makefile.am +++ b/lib/common/tests/flags/Makefile.am @@ -1,27 +1,20 @@ # # Copyright 2020-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. # -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/lib/common -LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka -AM_CFLAGS = -DPCMK__UNIT_TESTING -AM_LDFLAGS = $(LDFLAGS_WRAP) - 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__clear_flags_as_test \ pcmk__set_flags_as_test \ pcmk_all_flags_set_test \ pcmk_any_flags_set_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/flags/pcmk__clear_flags_as_test.c b/lib/common/tests/flags/pcmk__clear_flags_as_test.c index ea54ed5bd8..7f3afc7ecb 100644 --- a/lib/common/tests/flags/pcmk__clear_flags_as_test.c +++ b/lib/common/tests/flags/pcmk__clear_flags_as_test.c @@ -1,49 +1,41 @@ /* * Copyright 2020-2021 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 #include static void clear_none(void **state) { assert_int_equal(pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, "Test", "test", 0x0f0, 0x00f, NULL), 0x0f0); assert_int_equal(pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, "Test", "test", 0x0f0, 0xf0f, NULL), 0x0f0); } static void clear_some(void **state) { assert_int_equal(pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, "Test", "test", 0x0f0, 0x020, NULL), 0x0d0); assert_int_equal(pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, "Test", "test", 0x0f0, 0x030, NULL), 0x0c0); } static void clear_all(void **state) { assert_int_equal(pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, "Test", "test", 0x0f0, 0x0f0, NULL), 0x000); assert_int_equal(pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, "Test", "test", 0x0f0, 0xfff, NULL), 0x000); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(clear_none), - cmocka_unit_test(clear_some), - cmocka_unit_test(clear_all), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(clear_none), + cmocka_unit_test(clear_some), + cmocka_unit_test(clear_all)) diff --git a/lib/common/tests/flags/pcmk__set_flags_as_test.c b/lib/common/tests/flags/pcmk__set_flags_as_test.c index 9a5db7535d..89df19b43a 100644 --- a/lib/common/tests/flags/pcmk__set_flags_as_test.c +++ b/lib/common/tests/flags/pcmk__set_flags_as_test.c @@ -1,33 +1,25 @@ /* * Copyright 2020-2021 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 #include static void set_flags(void **state) { assert_int_equal(pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, "Test", "test", 0x0f0, 0x00f, NULL), 0x0ff); assert_int_equal(pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, "Test", "test", 0x0f0, 0xf0f, NULL), 0xfff); assert_int_equal(pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, "Test", "test", 0x0f0, 0xfff, NULL), 0xfff); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(set_flags), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(set_flags)) diff --git a/lib/common/tests/flags/pcmk_all_flags_set_test.c b/lib/common/tests/flags/pcmk_all_flags_set_test.c index eeb70ac2ec..00d36aeba6 100644 --- a/lib/common/tests/flags/pcmk_all_flags_set_test.c +++ b/lib/common/tests/flags/pcmk_all_flags_set_test.c @@ -1,41 +1,33 @@ /* * Copyright 2020-2021 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 #include static void all_set(void **state) { assert_false(pcmk_all_flags_set(0x000, 0x003)); assert_true(pcmk_all_flags_set(0x00f, 0x003)); assert_false(pcmk_all_flags_set(0x00f, 0x010)); assert_false(pcmk_all_flags_set(0x00f, 0x011)); assert_true(pcmk_all_flags_set(0x000, 0x000)); assert_true(pcmk_all_flags_set(0x00f, 0x000)); } static void one_is_set(void **state) { // pcmk_is_set() is a simple macro alias for pcmk_all_flags_set() assert_true(pcmk_is_set(0x00f, 0x001)); assert_false(pcmk_is_set(0x00f, 0x010)); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(all_set), - cmocka_unit_test(one_is_set), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(all_set), + cmocka_unit_test(one_is_set)) diff --git a/lib/common/tests/flags/pcmk_any_flags_set_test.c b/lib/common/tests/flags/pcmk_any_flags_set_test.c index 36e48262be..de8e0bf14c 100644 --- a/lib/common/tests/flags/pcmk_any_flags_set_test.c +++ b/lib/common/tests/flags/pcmk_any_flags_set_test.c @@ -1,34 +1,26 @@ /* * Copyright 2020-2021 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 #include static void any_set(void **state) { assert_false(pcmk_any_flags_set(0x000, 0x000)); assert_false(pcmk_any_flags_set(0x000, 0x001)); assert_true(pcmk_any_flags_set(0x00f, 0x001)); assert_false(pcmk_any_flags_set(0x00f, 0x010)); assert_true(pcmk_any_flags_set(0x00f, 0x011)); assert_false(pcmk_any_flags_set(0x000, 0x000)); assert_false(pcmk_any_flags_set(0x00f, 0x000)); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(any_set), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(any_set)) diff --git a/lib/common/tests/health/Makefile.am b/lib/common/tests/health/Makefile.am index ebb51cb09c..ad2a2dad1f 100644 --- a/lib/common/tests/health/Makefile.am +++ b/lib/common/tests/health/Makefile.am @@ -1,24 +1,17 @@ # # 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. # -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/lib/common -LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka -AM_CFLAGS = -DPCMK__UNIT_TESTING -AM_LDFLAGS = $(LDFLAGS_WRAP) - 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__parse_health_strategy_test \ pcmk__validate_health_strategy_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/health/pcmk__parse_health_strategy_test.c b/lib/common/tests/health/pcmk__parse_health_strategy_test.c index a054e4966c..0e0d45b2c7 100644 --- a/lib/common/tests/health/pcmk__parse_health_strategy_test.c +++ b/lib/common/tests/health/pcmk__parse_health_strategy_test.c @@ -1,64 +1,56 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include static void valid(void **state) { assert_int_equal(pcmk__parse_health_strategy(NULL), pcmk__health_strategy_none); assert_int_equal(pcmk__parse_health_strategy("none"), pcmk__health_strategy_none); assert_int_equal(pcmk__parse_health_strategy("NONE"), pcmk__health_strategy_none); assert_int_equal(pcmk__parse_health_strategy("None"), pcmk__health_strategy_none); assert_int_equal(pcmk__parse_health_strategy("nOnE"), pcmk__health_strategy_none); assert_int_equal(pcmk__parse_health_strategy("migrate-on-red"), pcmk__health_strategy_no_red); assert_int_equal(pcmk__parse_health_strategy("only-green"), pcmk__health_strategy_only_green); assert_int_equal(pcmk__parse_health_strategy("progressive"), pcmk__health_strategy_progressive); assert_int_equal(pcmk__parse_health_strategy("custom"), pcmk__health_strategy_custom); } static void invalid(void **state) { assert_int_equal(pcmk__parse_health_strategy("foo"), pcmk__health_strategy_none); assert_int_equal(pcmk__parse_health_strategy("custom1"), pcmk__health_strategy_none); assert_int_equal(pcmk__parse_health_strategy("not-only-green-here"), pcmk__health_strategy_none); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(valid), - cmocka_unit_test(invalid), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(valid), + cmocka_unit_test(invalid)) diff --git a/lib/common/tests/health/pcmk__validate_health_strategy_test.c b/lib/common/tests/health/pcmk__validate_health_strategy_test.c index 7832efab3a..ef10589921 100644 --- a/lib/common/tests/health/pcmk__validate_health_strategy_test.c +++ b/lib/common/tests/health/pcmk__validate_health_strategy_test.c @@ -1,45 +1,38 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include // Test functions static void valid_strategy(void **state) { assert_true(pcmk__validate_health_strategy("none")); assert_true(pcmk__validate_health_strategy("None")); assert_true(pcmk__validate_health_strategy("NONE")); assert_true(pcmk__validate_health_strategy("NoNe")); assert_true(pcmk__validate_health_strategy("migrate-on-red")); assert_true(pcmk__validate_health_strategy("only-green")); assert_true(pcmk__validate_health_strategy("progressive")); assert_true(pcmk__validate_health_strategy("custom")); } static void invalid_strategy(void **state) { assert_false(pcmk__validate_health_strategy(NULL)); assert_false(pcmk__validate_health_strategy("")); assert_false(pcmk__validate_health_strategy("none to speak of")); assert_false(pcmk__validate_health_strategy("customized")); } -int -main(int argc, char **argv) { - const struct CMUnitTest tests[] = { - cmocka_unit_test(valid_strategy), - cmocka_unit_test(invalid_strategy), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(valid_strategy), + cmocka_unit_test(invalid_strategy)) diff --git a/lib/common/tests/io/Makefile.am b/lib/common/tests/io/Makefile.am index cb56c8683a..c26482c488 100644 --- a/lib/common/tests/io/Makefile.am +++ b/lib/common/tests/io/Makefile.am @@ -1,25 +1,18 @@ # # Copyright 2020-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. # -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/lib/common -LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka -AM_CFLAGS = -DPCMK__UNIT_TESTING -AM_LDFLAGS = $(LDFLAGS_WRAP) - 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__full_path_test \ pcmk__get_tmpdir_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/io/pcmk__full_path_test.c b/lib/common/tests/io/pcmk__full_path_test.c index 2ae9cc3b3f..6cfb691858 100644 --- a/lib/common/tests/io/pcmk__full_path_test.c +++ b/lib/common/tests/io/pcmk__full_path_test.c @@ -1,60 +1,52 @@ /* * Copyright 2020-2022 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 #include #include "mock_private.h" static void function_asserts(void **state) { pcmk__assert_asserts(pcmk__full_path(NULL, "/dir")); pcmk__assert_asserts(pcmk__full_path("file", NULL)); pcmk__assert_asserts( { pcmk__mock_strdup = true; // strdup() will return NULL expect_string(__wrap_strdup, s, "/full/path"); pcmk__full_path("/full/path", "/dir"); pcmk__mock_strdup = false; // Use real strdup() } ); } static void full_path(void **state) { char *path = NULL; path = pcmk__full_path("file", "/dir"); assert_int_equal(strcmp(path, "/dir/file"), 0); free(path); path = pcmk__full_path("/full/path", "/dir"); assert_int_equal(strcmp(path, "/full/path"), 0); free(path); path = pcmk__full_path("../relative/path", "/dir"); assert_int_equal(strcmp(path, "/dir/../relative/path"), 0); free(path); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(function_asserts), - cmocka_unit_test(full_path), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(function_asserts), + cmocka_unit_test(full_path)) diff --git a/lib/common/tests/io/pcmk__get_tmpdir_test.c b/lib/common/tests/io/pcmk__get_tmpdir_test.c index 71941b0ce5..f79051f090 100644 --- a/lib/common/tests/io/pcmk__get_tmpdir_test.c +++ b/lib/common/tests/io/pcmk__get_tmpdir_test.c @@ -1,76 +1,68 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include "mock_private.h" static void getenv_returns_invalid(void **state) { const char *result; pcmk__mock_getenv = true; expect_string(__wrap_getenv, name, "TMPDIR"); will_return(__wrap_getenv, NULL); // getenv("TMPDIR") return value result = pcmk__get_tmpdir(); assert_string_equal(result, "/tmp"); expect_string(__wrap_getenv, name, "TMPDIR"); will_return(__wrap_getenv, ""); // getenv("TMPDIR") return value result = pcmk__get_tmpdir(); assert_string_equal(result, "/tmp"); expect_string(__wrap_getenv, name, "TMPDIR"); will_return(__wrap_getenv, "subpath"); // getenv("TMPDIR") return value result = pcmk__get_tmpdir(); assert_string_equal(result, "/tmp"); pcmk__mock_getenv = false; } static void getenv_returns_valid(void **state) { const char *result; pcmk__mock_getenv = true; expect_string(__wrap_getenv, name, "TMPDIR"); will_return(__wrap_getenv, "/var/tmp"); // getenv("TMPDIR") return value result = pcmk__get_tmpdir(); assert_string_equal(result, "/var/tmp"); expect_string(__wrap_getenv, name, "TMPDIR"); will_return(__wrap_getenv, "/"); // getenv("TMPDIR") return value result = pcmk__get_tmpdir(); assert_string_equal(result, "/"); expect_string(__wrap_getenv, name, "TMPDIR"); will_return(__wrap_getenv, "/tmp/abcd.1234"); // getenv("TMPDIR") return value result = pcmk__get_tmpdir(); assert_string_equal(result, "/tmp/abcd.1234"); pcmk__mock_getenv = false; } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(getenv_returns_invalid), - cmocka_unit_test(getenv_returns_valid), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(getenv_returns_invalid), + cmocka_unit_test(getenv_returns_valid)) diff --git a/lib/common/tests/iso8601/Makefile.am b/lib/common/tests/iso8601/Makefile.am index ceb3085ade..5187aecb64 100644 --- a/lib/common/tests/iso8601/Makefile.am +++ b/lib/common/tests/iso8601/Makefile.am @@ -1,23 +1,16 @@ # # Copyright 2020-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. # -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/lib/common -LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka -AM_CFLAGS = -DPCMK__UNIT_TESTING -AM_LDFLAGS = $(LDFLAGS_WRAP) - 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__readable_interval_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/iso8601/pcmk__readable_interval_test.c b/lib/common/tests/iso8601/pcmk__readable_interval_test.c index b6a7cc2422..b45f3e383e 100644 --- a/lib/common/tests/iso8601/pcmk__readable_interval_test.c +++ b/lib/common/tests/iso8601/pcmk__readable_interval_test.c @@ -1,35 +1,27 @@ /* * Copyright 2021 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 #include #include static void readable_interval(void **state) { assert_string_equal(pcmk__readable_interval(0), "0s"); assert_string_equal(pcmk__readable_interval(30000), "30s"); assert_string_equal(pcmk__readable_interval(150000), "2m30s"); assert_string_equal(pcmk__readable_interval(3333), "3.333s"); assert_string_equal(pcmk__readable_interval(UINT_MAX), "49d17h2m47.295s"); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(readable_interval), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(readable_interval)) diff --git a/lib/common/tests/lists/Makefile.am b/lib/common/tests/lists/Makefile.am index 7281944344..ae0c0b69f5 100644 --- a/lib/common/tests/lists/Makefile.am +++ b/lib/common/tests/lists/Makefile.am @@ -1,27 +1,20 @@ # # 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. # -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/lib/common -LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka -AM_CFLAGS = -DPCMK__UNIT_TESTING -AM_LDFLAGS = $(LDFLAGS_WRAP) - 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__list_of_1_test \ pcmk__list_of_multiple_test \ pcmk__subtract_lists_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/lists/pcmk__list_of_1_test.c b/lib/common/tests/lists/pcmk__list_of_1_test.c index 916de82f59..ed070b9e45 100644 --- a/lib/common/tests/lists/pcmk__list_of_1_test.c +++ b/lib/common/tests/lists/pcmk__list_of_1_test.c @@ -1,53 +1,45 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include static void empty_list(void **state) { assert_false(pcmk__list_of_1(NULL)); } static void singleton_list(void **state) { GList *lst = NULL; lst = g_list_append(lst, strdup("abc")); assert_true(pcmk__list_of_1(lst)); g_list_free_full(lst, free); } static void longer_list(void **state) { GList *lst = NULL; lst = g_list_append(lst, strdup("abc")); lst = g_list_append(lst, strdup("xyz")); assert_false(pcmk__list_of_1(lst)); g_list_free_full(lst, free); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(empty_list), - cmocka_unit_test(singleton_list), - cmocka_unit_test(longer_list), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(empty_list), + cmocka_unit_test(singleton_list), + cmocka_unit_test(longer_list)) diff --git a/lib/common/tests/lists/pcmk__list_of_multiple_test.c b/lib/common/tests/lists/pcmk__list_of_multiple_test.c index cc78dac38b..e9aebfd82d 100644 --- a/lib/common/tests/lists/pcmk__list_of_multiple_test.c +++ b/lib/common/tests/lists/pcmk__list_of_multiple_test.c @@ -1,53 +1,45 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include static void empty_list(void **state) { assert_false(pcmk__list_of_multiple(NULL)); } static void singleton_list(void **state) { GList *lst = NULL; lst = g_list_append(lst, strdup("abc")); assert_false(pcmk__list_of_multiple(lst)); g_list_free_full(lst, free); } static void longer_list(void **state) { GList *lst = NULL; lst = g_list_append(lst, strdup("abc")); lst = g_list_append(lst, strdup("xyz")); assert_true(pcmk__list_of_multiple(lst)); g_list_free_full(lst, free); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(empty_list), - cmocka_unit_test(singleton_list), - cmocka_unit_test(longer_list), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(empty_list), + cmocka_unit_test(singleton_list), + cmocka_unit_test(longer_list)) diff --git a/lib/common/tests/lists/pcmk__subtract_lists_test.c b/lib/common/tests/lists/pcmk__subtract_lists_test.c index f92b840a9e..814e6b49f7 100644 --- a/lib/common/tests/lists/pcmk__subtract_lists_test.c +++ b/lib/common/tests/lists/pcmk__subtract_lists_test.c @@ -1,152 +1,144 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include #include static void different_lists(void **state) { GList *from = NULL; GList *items = NULL; GList *result = NULL; from = g_list_append(from, strdup("abc")); from = g_list_append(from, strdup("def")); from = g_list_append(from, strdup("ghi")); items = g_list_append(items, strdup("123")); items = g_list_append(items, strdup("456")); result = pcmk__subtract_lists(from, items, (GCompareFunc) strcmp); assert_int_equal(g_list_length(result), 3); assert_string_equal(g_list_nth_data(result, 0), "abc"); assert_string_equal(g_list_nth_data(result, 1), "def"); assert_string_equal(g_list_nth_data(result, 2), "ghi"); g_list_free(result); g_list_free_full(from, free); g_list_free_full(items, free); } static void remove_first_item(void **state) { GList *from = NULL; GList *items = NULL; GList *result = NULL; from = g_list_append(from, strdup("abc")); from = g_list_append(from, strdup("def")); from = g_list_append(from, strdup("ghi")); items = g_list_append(items, strdup("abc")); result = pcmk__subtract_lists(from, items, (GCompareFunc) strcmp); assert_int_equal(g_list_length(result), 2); assert_string_equal(g_list_nth_data(result, 0), "def"); assert_string_equal(g_list_nth_data(result, 1), "ghi"); g_list_free(result); g_list_free_full(from, free); g_list_free_full(items, free); } static void remove_middle_item(void **state) { GList *from = NULL; GList *items = NULL; GList *result = NULL; from = g_list_append(from, strdup("abc")); from = g_list_append(from, strdup("def")); from = g_list_append(from, strdup("ghi")); items = g_list_append(items, strdup("def")); result = pcmk__subtract_lists(from, items, (GCompareFunc) strcmp); assert_int_equal(g_list_length(result), 2); assert_string_equal(g_list_nth_data(result, 0), "abc"); assert_string_equal(g_list_nth_data(result, 1), "ghi"); g_list_free(result); g_list_free_full(from, free); g_list_free_full(items, free); } static void remove_last_item(void **state) { GList *from = NULL; GList *items = NULL; GList *result = NULL; from = g_list_append(from, strdup("abc")); from = g_list_append(from, strdup("def")); from = g_list_append(from, strdup("ghi")); items = g_list_append(items, strdup("ghi")); result = pcmk__subtract_lists(from, items, (GCompareFunc) strcmp); assert_int_equal(g_list_length(result), 2); assert_string_equal(g_list_nth_data(result, 0), "abc"); assert_string_equal(g_list_nth_data(result, 1), "def"); g_list_free(result); g_list_free_full(from, free); g_list_free_full(items, free); } static void remove_all_items(void **state) { GList *from = NULL; GList *items = NULL; GList *result = NULL; from = g_list_append(from, strdup("abc")); from = g_list_append(from, strdup("def")); from = g_list_append(from, strdup("ghi")); items = g_list_append(items, strdup("abc")); items = g_list_append(items, strdup("def")); items = g_list_append(items, strdup("ghi")); result = pcmk__subtract_lists(from, items, (GCompareFunc) strcmp); assert_int_equal(g_list_length(result), 0); g_list_free(result); g_list_free_full(from, free); g_list_free_full(items, free); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(different_lists), - cmocka_unit_test(remove_first_item), - cmocka_unit_test(remove_middle_item), - cmocka_unit_test(remove_last_item), - cmocka_unit_test(remove_all_items), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(different_lists), + cmocka_unit_test(remove_first_item), + cmocka_unit_test(remove_middle_item), + cmocka_unit_test(remove_last_item), + cmocka_unit_test(remove_all_items)) diff --git a/lib/common/tests/nvpair/Makefile.am b/lib/common/tests/nvpair/Makefile.am index 8b8866994d..7acaba3f27 100644 --- a/lib/common/tests/nvpair/Makefile.am +++ b/lib/common/tests/nvpair/Makefile.am @@ -1,25 +1,18 @@ # # 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. # -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/lib/common -LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka -AM_CFLAGS = -DPCMK__UNIT_TESTING -AM_LDFLAGS = $(LDFLAGS_WRAP) - include $(top_srcdir)/mk/tap.mk +include $(top_srcdir)/mk/unittest.mk # Add "_test" to the end of all test program names to simplify .gitignore. check_PROGRAMS = pcmk__xe_attr_is_true_test \ pcmk__xe_get_bool_attr_test \ pcmk__xe_set_bool_attr_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/nvpair/pcmk__xe_attr_is_true_test.c b/lib/common/tests/nvpair/pcmk__xe_attr_is_true_test.c index 69ec199df8..4f0dd26339 100644 --- a/lib/common/tests/nvpair/pcmk__xe_attr_is_true_test.c +++ b/lib/common/tests/nvpair/pcmk__xe_attr_is_true_test.c @@ -1,58 +1,50 @@ /* * Copyright 2021 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 #include #include static void empty_input(void **state) { xmlNode *node = string2xml(""); assert_false(pcmk__xe_attr_is_true(NULL, NULL)); assert_false(pcmk__xe_attr_is_true(NULL, "whatever")); assert_false(pcmk__xe_attr_is_true(node, NULL)); free_xml(node); } static void attr_missing(void **state) { xmlNode *node = string2xml(""); assert_false(pcmk__xe_attr_is_true(node, "c")); free_xml(node); } static void attr_present(void **state) { xmlNode *node = string2xml(""); assert_true(pcmk__xe_attr_is_true(node, "a")); assert_false(pcmk__xe_attr_is_true(node, "b")); free_xml(node); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(empty_input), - cmocka_unit_test(attr_missing), - cmocka_unit_test(attr_present), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(empty_input), + cmocka_unit_test(attr_missing), + cmocka_unit_test(attr_present)) diff --git a/lib/common/tests/nvpair/pcmk__xe_get_bool_attr_test.c b/lib/common/tests/nvpair/pcmk__xe_get_bool_attr_test.c index e3577f2847..523186ce4d 100644 --- a/lib/common/tests/nvpair/pcmk__xe_get_bool_attr_test.c +++ b/lib/common/tests/nvpair/pcmk__xe_get_bool_attr_test.c @@ -1,67 +1,59 @@ /* * Copyright 2021 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 #include #include static void empty_input(void **state) { xmlNode *node = string2xml(""); bool value; assert_int_equal(pcmk__xe_get_bool_attr(NULL, NULL, &value), ENODATA); assert_int_equal(pcmk__xe_get_bool_attr(NULL, "whatever", &value), ENODATA); assert_int_equal(pcmk__xe_get_bool_attr(node, NULL, &value), EINVAL); assert_int_equal(pcmk__xe_get_bool_attr(node, "whatever", NULL), EINVAL); free_xml(node); } static void attr_missing(void **state) { xmlNode *node = string2xml(""); bool value; assert_int_equal(pcmk__xe_get_bool_attr(node, "c", &value), ENODATA); free_xml(node); } static void attr_present(void **state) { xmlNode *node = string2xml(""); bool value; value = false; assert_int_equal(pcmk__xe_get_bool_attr(node, "a", &value), pcmk_rc_ok); assert_true(value); value = true; assert_int_equal(pcmk__xe_get_bool_attr(node, "b", &value), pcmk_rc_ok); assert_false(value); assert_int_equal(pcmk__xe_get_bool_attr(node, "c", &value), pcmk_rc_unknown_format); free_xml(node); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(empty_input), - cmocka_unit_test(attr_missing), - cmocka_unit_test(attr_present), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(empty_input), + cmocka_unit_test(attr_missing), + cmocka_unit_test(attr_present)) diff --git a/lib/common/tests/nvpair/pcmk__xe_set_bool_attr_test.c b/lib/common/tests/nvpair/pcmk__xe_set_bool_attr_test.c index 03ec0eb878..95e95e192c 100644 --- a/lib/common/tests/nvpair/pcmk__xe_set_bool_attr_test.c +++ b/lib/common/tests/nvpair/pcmk__xe_set_bool_attr_test.c @@ -1,39 +1,31 @@ /* * Copyright 2021 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 #include #include #include static void set_attr(void **state) { xmlNode *node = string2xml(""); pcmk__xe_set_bool_attr(node, "a", true); pcmk__xe_set_bool_attr(node, "b", false); assert_string_equal(crm_element_value(node, "a"), XML_BOOLEAN_TRUE); assert_string_equal(crm_element_value(node, "b"), XML_BOOLEAN_FALSE); free_xml(node); } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(set_attr), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(set_attr)) diff --git a/lib/common/tests/operations/Makefile.am b/lib/common/tests/operations/Makefile.am index aad5346a93..4687e1ba93 100644 --- a/lib/common/tests/operations/Makefile.am +++ b/lib/common/tests/operations/Makefile.am @@ -1,29 +1,22 @@ # # Copyright 2020-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. # -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/lib/common -LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka -AM_CFLAGS = -DPCMK__UNIT_TESTING -AM_LDFLAGS = $(LDFLAGS_WRAP) - 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 = copy_in_properties_test \ expand_plus_plus_test \ fix_plus_plus_recursive_test \ parse_op_key_test \ pcmk_is_probe_test \ pcmk_xe_is_probe_test \ pcmk_xe_mask_probe_failure_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/operations/copy_in_properties_test.c b/lib/common/tests/operations/copy_in_properties_test.c index c410a65621..31de7c805d 100644 --- a/lib/common/tests/operations/copy_in_properties_test.c +++ b/lib/common/tests/operations/copy_in_properties_test.c @@ -1,69 +1,62 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include static void target_is_NULL(void **state) { xmlNode *test_xml_1 = create_xml_node(NULL, "test_xml_1"); xmlNode *test_xml_2 = NULL; pcmk__xe_set_props(test_xml_1, "test_prop", "test_value", NULL); copy_in_properties(test_xml_2, test_xml_1); assert_ptr_equal(test_xml_2, NULL); } static void src_is_NULL(void **state) { xmlNode *test_xml_1 = NULL; xmlNode *test_xml_2 = create_xml_node(NULL, "test_xml_2"); copy_in_properties(test_xml_2, test_xml_1); assert_ptr_equal(test_xml_2->properties, NULL); } static void copying_is_successful(void **state) { const char *xml_1_value; const char *xml_2_value; xmlNode *test_xml_1 = create_xml_node(NULL, "test_xml_1"); xmlNode *test_xml_2 = create_xml_node(NULL, "test_xml_2"); pcmk__xe_set_props(test_xml_1, "test_prop", "test_value", NULL); copy_in_properties(test_xml_2, test_xml_1); xml_1_value = crm_element_value(test_xml_1, "test_prop"); xml_2_value = crm_element_value(test_xml_2, "test_prop"); assert_string_equal(xml_1_value, xml_2_value); } -int main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(target_is_NULL), - cmocka_unit_test(src_is_NULL), - cmocka_unit_test(copying_is_successful), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(target_is_NULL), + cmocka_unit_test(src_is_NULL), + cmocka_unit_test(copying_is_successful)) diff --git a/lib/common/tests/operations/expand_plus_plus_test.c b/lib/common/tests/operations/expand_plus_plus_test.c index 4db455089f..652c2f78c1 100644 --- a/lib/common/tests/operations/expand_plus_plus_test.c +++ b/lib/common/tests/operations/expand_plus_plus_test.c @@ -1,263 +1,256 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include static void value_is_name_plus_plus(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(test_xml, "X", "X++"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "6"); } static void value_is_name_plus_equals_integer(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(test_xml, "X", "X+=2"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "7"); } // NULL input static void target_is_NULL(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(NULL, "X", "X++"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "5"); } static void name_is_NULL(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(test_xml, NULL, "X++"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "5"); } static void value_is_NULL(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(test_xml, "X", NULL); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "5"); } // the value input doesn't start with the name input static void value_is_wrong_name(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(test_xml, "X", "Y++"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "Y++"); } static void value_is_only_an_integer(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(test_xml, "X", "2"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "2"); } // non-integers static void variable_is_initialized_to_be_NULL(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", NULL); expand_plus_plus(test_xml, "X", "X++"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "X++"); } static void variable_is_initialized_to_be_non_numeric(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "hello"); expand_plus_plus(test_xml, "X", "X++"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "1"); } static void variable_is_initialized_to_be_non_numeric_2(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "hello"); expand_plus_plus(test_xml, "X", "X+=2"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "2"); } static void variable_is_initialized_to_be_numeric_and_decimal_point_containing(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5.01"); expand_plus_plus(test_xml, "X", "X++"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "6"); } static void variable_is_initialized_to_be_numeric_and_decimal_point_containing_2(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5.50"); expand_plus_plus(test_xml, "X", "X++"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "6"); } static void variable_is_initialized_to_be_numeric_and_decimal_point_containing_3(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5.99"); expand_plus_plus(test_xml, "X", "X++"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "6"); } static void value_is_non_numeric(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(test_xml, "X", "X+=hello"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "5"); } static void value_is_numeric_and_decimal_point_containing(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(test_xml, "X", "X+=2.01"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "7"); } static void value_is_numeric_and_decimal_point_containing_2(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(test_xml, "X", "X+=1.50"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "6"); } static void value_is_numeric_and_decimal_point_containing_3(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(test_xml, "X", "X+=1.99"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "6"); } // undefined input static void name_is_undefined(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "Y", "5"); expand_plus_plus(test_xml, "X", "X++"); new_value = crm_element_value(test_xml, "X"); assert_string_equal(new_value, "X++"); } // large input static void assignment_result_is_too_large(void **state) { const char *new_value; xmlNode *test_xml = create_xml_node(NULL, "test_xml"); crm_xml_add(test_xml, "X", "5"); expand_plus_plus(test_xml, "X", "X+=100000000000"); new_value = crm_element_value(test_xml, "X"); printf("assignment result is too large %s\n", new_value); assert_string_equal(new_value, "1000000"); } -int main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(value_is_name_plus_plus), - cmocka_unit_test(value_is_name_plus_equals_integer), - cmocka_unit_test(target_is_NULL), - cmocka_unit_test(name_is_NULL), - cmocka_unit_test(value_is_NULL), - cmocka_unit_test(value_is_wrong_name), - cmocka_unit_test(value_is_only_an_integer), - cmocka_unit_test(variable_is_initialized_to_be_NULL), - cmocka_unit_test(variable_is_initialized_to_be_non_numeric), - cmocka_unit_test(variable_is_initialized_to_be_non_numeric_2), - cmocka_unit_test(variable_is_initialized_to_be_numeric_and_decimal_point_containing), - cmocka_unit_test(variable_is_initialized_to_be_numeric_and_decimal_point_containing_2), - cmocka_unit_test(variable_is_initialized_to_be_numeric_and_decimal_point_containing_3), - cmocka_unit_test(value_is_non_numeric), - cmocka_unit_test(value_is_numeric_and_decimal_point_containing), - cmocka_unit_test(value_is_numeric_and_decimal_point_containing_2), - cmocka_unit_test(value_is_numeric_and_decimal_point_containing_3), - cmocka_unit_test(name_is_undefined), - cmocka_unit_test(assignment_result_is_too_large), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(value_is_name_plus_plus), + cmocka_unit_test(value_is_name_plus_equals_integer), + cmocka_unit_test(target_is_NULL), + cmocka_unit_test(name_is_NULL), + cmocka_unit_test(value_is_NULL), + cmocka_unit_test(value_is_wrong_name), + cmocka_unit_test(value_is_only_an_integer), + cmocka_unit_test(variable_is_initialized_to_be_NULL), + cmocka_unit_test(variable_is_initialized_to_be_non_numeric), + cmocka_unit_test(variable_is_initialized_to_be_non_numeric_2), + cmocka_unit_test(variable_is_initialized_to_be_numeric_and_decimal_point_containing), + cmocka_unit_test(variable_is_initialized_to_be_numeric_and_decimal_point_containing_2), + cmocka_unit_test(variable_is_initialized_to_be_numeric_and_decimal_point_containing_3), + cmocka_unit_test(value_is_non_numeric), + cmocka_unit_test(value_is_numeric_and_decimal_point_containing), + cmocka_unit_test(value_is_numeric_and_decimal_point_containing_2), + cmocka_unit_test(value_is_numeric_and_decimal_point_containing_3), + cmocka_unit_test(name_is_undefined), + cmocka_unit_test(assignment_result_is_too_large)) diff --git a/lib/common/tests/operations/fix_plus_plus_recursive_test.c b/lib/common/tests/operations/fix_plus_plus_recursive_test.c index 8aaada5980..9c5972ca76 100644 --- a/lib/common/tests/operations/fix_plus_plus_recursive_test.c +++ b/lib/common/tests/operations/fix_plus_plus_recursive_test.c @@ -1,54 +1,47 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include static void element_nodes(void **state) { const char *new_value_root; const char *new_value_child; const char *new_value_grandchild; xmlNode *test_xml_root = create_xml_node(NULL, "test_xml_root"); xmlNode *test_xml_child = create_xml_node(test_xml_root, "test_xml_child"); xmlNode *test_xml_grandchild = create_xml_node(test_xml_child, "test_xml_grandchild"); xmlNode *test_xml_text = pcmk_create_xml_text_node(test_xml_root, "text_xml_text", "content"); xmlNode *test_xml_comment = string2xml(""); crm_xml_add(test_xml_root, "X", "5"); crm_xml_add(test_xml_child, "X", "X++"); crm_xml_add(test_xml_grandchild, "X", "X+=2"); crm_xml_add(test_xml_text, "X", "X++"); fix_plus_plus_recursive(test_xml_root); fix_plus_plus_recursive(test_xml_comment); new_value_root = crm_element_value(test_xml_root, "X"); new_value_child = crm_element_value(test_xml_child, "X"); new_value_grandchild = crm_element_value(test_xml_grandchild, "X"); assert_string_equal(new_value_root, "5"); assert_string_equal(new_value_child, "1"); assert_string_equal(new_value_grandchild, "2"); } -int main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(element_nodes), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(element_nodes)) diff --git a/lib/common/tests/operations/parse_op_key_test.c b/lib/common/tests/operations/parse_op_key_test.c index a830adf307..7486f7c208 100644 --- a/lib/common/tests/operations/parse_op_key_test.c +++ b/lib/common/tests/operations/parse_op_key_test.c @@ -1,230 +1,221 @@ /* * Copyright 2020-2021 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 #include #include static void basic(void **state) { char *rsc = NULL; char *ty = NULL; guint ms = 0; assert_true(parse_op_key("Fencing_monitor_60000", &rsc, &ty, &ms)); assert_string_equal(rsc, "Fencing"); assert_string_equal(ty, "monitor"); assert_int_equal(ms, 60000); free(rsc); free(ty); } static void colon_in_rsc(void **state) { char *rsc = NULL; char *ty = NULL; guint ms = 0; assert_true(parse_op_key("ClusterIP:0_start_0", &rsc, &ty, &ms)); assert_string_equal(rsc, "ClusterIP:0"); assert_string_equal(ty, "start"); assert_int_equal(ms, 0); free(rsc); free(ty); assert_true(parse_op_key("imagestoreclone:1_post_notify_stop_0", &rsc, &ty, &ms)); assert_string_equal(rsc, "imagestoreclone:1"); assert_string_equal(ty, "post_notify_stop"); assert_int_equal(ms, 0); free(rsc); free(ty); } static void dashes_in_rsc(void **state) { char *rsc = NULL; char *ty = NULL; guint ms = 0; assert_true(parse_op_key("httpd-bundle-0_monitor_30000", &rsc, &ty, &ms)); assert_string_equal(rsc, "httpd-bundle-0"); assert_string_equal(ty, "monitor"); assert_int_equal(ms, 30000); free(rsc); free(ty); assert_true(parse_op_key("httpd-bundle-ip-192.168.122.132_start_0", &rsc, &ty, &ms)); assert_string_equal(rsc, "httpd-bundle-ip-192.168.122.132"); assert_string_equal(ty, "start"); assert_int_equal(ms, 0); free(rsc); free(ty); } static void migrate_to_from(void **state) { char *rsc = NULL; char *ty = NULL; guint ms = 0; assert_true(parse_op_key("vm_migrate_from_0", &rsc, &ty, &ms)); assert_string_equal(rsc, "vm"); assert_string_equal(ty, "migrate_from"); assert_int_equal(ms, 0); free(rsc); free(ty); assert_true(parse_op_key("vm_migrate_to_0", &rsc, &ty, &ms)); assert_string_equal(rsc, "vm"); assert_string_equal(ty, "migrate_to"); assert_int_equal(ms, 0); free(rsc); free(ty); assert_true(parse_op_key("vm_idcc_devel_migrate_to_0", &rsc, &ty, &ms)); assert_string_equal(rsc, "vm_idcc_devel"); assert_string_equal(ty, "migrate_to"); assert_int_equal(ms, 0); free(rsc); free(ty); } static void pre_post(void **state) { char *rsc = NULL; char *ty = NULL; guint ms = 0; assert_true(parse_op_key("rsc_drbd_7788:1_post_notify_start_0", &rsc, &ty, &ms)); assert_string_equal(rsc, "rsc_drbd_7788:1"); assert_string_equal(ty, "post_notify_start"); assert_int_equal(ms, 0); free(rsc); free(ty); assert_true(parse_op_key("rabbitmq-bundle-clone_pre_notify_stop_0", &rsc, &ty, &ms)); assert_string_equal(rsc, "rabbitmq-bundle-clone"); assert_string_equal(ty, "pre_notify_stop"); assert_int_equal(ms, 0); free(rsc); free(ty); assert_true(parse_op_key("post_notify_start_0", &rsc, &ty, &ms)); assert_string_equal(rsc, "post_notify"); assert_string_equal(ty, "start"); assert_int_equal(ms, 0); free(rsc); free(ty); } static void skip_rsc(void **state) { char *ty = NULL; guint ms = 0; assert_true(parse_op_key("Fencing_monitor_60000", NULL, &ty, &ms)); assert_string_equal(ty, "monitor"); assert_int_equal(ms, 60000); free(ty); } static void skip_ty(void **state) { char *rsc = NULL; guint ms = 0; assert_true(parse_op_key("Fencing_monitor_60000", &rsc, NULL, &ms)); assert_string_equal(rsc, "Fencing"); assert_int_equal(ms, 60000); free(rsc); } static void skip_ms(void **state) { char *rsc = NULL; char *ty = NULL; assert_true(parse_op_key("Fencing_monitor_60000", &rsc, &ty, NULL)); assert_string_equal(rsc, "Fencing"); assert_string_equal(ty, "monitor"); free(rsc); free(ty); } static void empty_input(void **state) { char *rsc = NULL; char *ty = NULL; guint ms = 0; assert_false(parse_op_key("", &rsc, &ty, &ms)); assert_null(rsc); assert_null(ty); assert_int_equal(ms, 0); assert_false(parse_op_key(NULL, &rsc, &ty, &ms)); assert_null(rsc); assert_null(ty); assert_int_equal(ms, 0); } static void malformed_input(void **state) { char *rsc = NULL; char *ty = NULL; guint ms = 0; assert_false(parse_op_key("httpd-bundle-0", &rsc, &ty, &ms)); assert_null(rsc); assert_null(ty); assert_int_equal(ms, 0); assert_false(parse_op_key("httpd-bundle-0_monitor", &rsc, &ty, &ms)); assert_null(rsc); assert_null(ty); assert_int_equal(ms, 0); assert_false(parse_op_key("httpd-bundle-0_30000", &rsc, &ty, &ms)); assert_null(rsc); assert_null(ty); assert_int_equal(ms, 0); } -int main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(basic), - cmocka_unit_test(colon_in_rsc), - cmocka_unit_test(dashes_in_rsc), - cmocka_unit_test(migrate_to_from), - cmocka_unit_test(pre_post), - - cmocka_unit_test(skip_rsc), - cmocka_unit_test(skip_ty), - cmocka_unit_test(skip_ms), - - cmocka_unit_test(empty_input), - cmocka_unit_test(malformed_input), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(basic), + cmocka_unit_test(colon_in_rsc), + cmocka_unit_test(dashes_in_rsc), + cmocka_unit_test(migrate_to_from), + cmocka_unit_test(pre_post), + cmocka_unit_test(skip_rsc), + cmocka_unit_test(skip_ty), + cmocka_unit_test(skip_ms), + cmocka_unit_test(empty_input), + cmocka_unit_test(malformed_input)) diff --git a/lib/common/tests/operations/pcmk_is_probe_test.c b/lib/common/tests/operations/pcmk_is_probe_test.c index 07b2d45493..d439cf0e12 100644 --- a/lib/common/tests/operations/pcmk_is_probe_test.c +++ b/lib/common/tests/operations/pcmk_is_probe_test.c @@ -1,32 +1,25 @@ /* * Copyright 2021 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 #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)); } -int main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(is_probe_test), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(is_probe_test)) diff --git a/lib/common/tests/operations/pcmk_xe_is_probe_test.c b/lib/common/tests/operations/pcmk_xe_is_probe_test.c index 28312160a3..f8bee6f287 100644 --- a/lib/common/tests/operations/pcmk_xe_is_probe_test.c +++ b/lib/common/tests/operations/pcmk_xe_is_probe_test.c @@ -1,50 +1,43 @@ /* * Copyright 2021 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 #include static void op_is_probe_test(void **state) { xmlNode *node = NULL; assert_false(pcmk_xe_is_probe(NULL)); node = string2xml(""); assert_false(pcmk_xe_is_probe(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_is_probe(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_is_probe(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_is_probe(node)); free_xml(node); node = string2xml(""); assert_true(pcmk_xe_is_probe(node)); free_xml(node); } -int main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(op_is_probe_test), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(op_is_probe_test)) diff --git a/lib/common/tests/operations/pcmk_xe_mask_probe_failure_test.c b/lib/common/tests/operations/pcmk_xe_mask_probe_failure_test.c index 51b9a29c88..04461626f6 100644 --- a/lib/common/tests/operations/pcmk_xe_mask_probe_failure_test.c +++ b/lib/common/tests/operations/pcmk_xe_mask_probe_failure_test.c @@ -1,157 +1,150 @@ /* * Copyright 2021 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 #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 = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); } static void op_does_not_have_right_values_test(void **state) { xmlNode *node = NULL; node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); } static void check_values_test(void **state) { xmlNode *node = NULL; /* PCMK_EXEC_NOT_SUPPORTED */ node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_true(pcmk_xe_mask_probe_failure(node)); free_xml(node); /* PCMK_EXEC_DONE */ node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_true(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_true(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); /* PCMK_EXEC_NOT_INSTALLED */ node = string2xml(""); assert_true(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_true(pcmk_xe_mask_probe_failure(node)); free_xml(node); /* PCMK_EXEC_ERROR */ node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_true(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_true(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); /* PCMK_EXEC_ERROR_HARD */ node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_true(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_true(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); /* PCMK_EXEC_ERROR_FATAL */ node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_true(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_true(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); node = string2xml(""); assert_false(pcmk_xe_mask_probe_failure(node)); free_xml(node); } -int main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(op_is_not_probe_test), - cmocka_unit_test(op_does_not_have_right_values_test), - cmocka_unit_test(check_values_test), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(op_is_not_probe_test), + cmocka_unit_test(op_does_not_have_right_values_test), + cmocka_unit_test(check_values_test)) diff --git a/lib/common/tests/options/Makefile.am b/lib/common/tests/options/Makefile.am index a915661c33..9a5fa985de 100644 --- a/lib/common/tests/options/Makefile.am +++ b/lib/common/tests/options/Makefile.am @@ -1,26 +1,19 @@ # # 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. # -AM_CPPFLAGS = -I$(top_srcdir)/include \ - -I$(top_builddir)/include \ - -I$(top_srcdir)/lib/common -LDADD = $(top_builddir)/lib/common/libcrmcommon_test.la \ - -lcmocka -AM_CFLAGS = -DPCMK__UNIT_TESTING -AM_LDFLAGS = $(LDFLAGS_WRAP) - 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__env_option_test \ pcmk__set_env_option_test \ pcmk__env_option_enabled_test TESTS = $(check_PROGRAMS) diff --git a/lib/common/tests/options/pcmk__env_option_enabled_test.c b/lib/common/tests/options/pcmk__env_option_enabled_test.c index 4b1ca7102b..6c879c621e 100644 --- a/lib/common/tests/options/pcmk__env_option_enabled_test.c +++ b/lib/common/tests/options/pcmk__env_option_enabled_test.c @@ -1,109 +1,101 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include "mock_private.h" static void disabled_null_value(void **state) { // Return false if option value not found (NULL accomplishes this) assert_false(pcmk__env_option_enabled(NULL, NULL)); assert_false(pcmk__env_option_enabled("pacemaker-execd", NULL)); } static void enabled_true_value(void **state) { // Return true if option value is true, with or without daemon name pcmk__mock_getenv = true; expect_string(__wrap_getenv, name, "PCMK_env_var"); will_return(__wrap_getenv, "true"); assert_true(pcmk__env_option_enabled(NULL, "env_var")); expect_string(__wrap_getenv, name, "PCMK_env_var"); will_return(__wrap_getenv, "true"); assert_true(pcmk__env_option_enabled("pacemaker-execd", "env_var")); pcmk__mock_getenv = false; } static void disabled_false_value(void **state) { // Return false if option value is false (no daemon list) pcmk__mock_getenv = true; expect_string(__wrap_getenv, name, "PCMK_env_var"); will_return(__wrap_getenv, "false"); assert_false(pcmk__env_option_enabled(NULL, "env_var")); expect_string(__wrap_getenv, name, "PCMK_env_var"); will_return(__wrap_getenv, "false"); assert_false(pcmk__env_option_enabled("pacemaker-execd", "env_var")); pcmk__mock_getenv = false; } static void enabled_daemon_in_list(void **state) { // Return true if daemon is in the option's value pcmk__mock_getenv = true; expect_string(__wrap_getenv, name, "PCMK_env_var"); will_return(__wrap_getenv, "pacemaker-execd"); assert_true(pcmk__env_option_enabled("pacemaker-execd", "env_var")); expect_string(__wrap_getenv, name, "PCMK_env_var"); will_return(__wrap_getenv, "pacemaker-execd,pacemaker-fenced"); assert_true(pcmk__env_option_enabled("pacemaker-execd", "env_var")); expect_string(__wrap_getenv, name, "PCMK_env_var"); will_return(__wrap_getenv, "pacemaker-controld,pacemaker-execd"); assert_true(pcmk__env_option_enabled("pacemaker-execd", "env_var")); expect_string(__wrap_getenv, name, "PCMK_env_var"); will_return(__wrap_getenv, "pacemaker-controld,pacemaker-execd,pacemaker-fenced"); assert_true(pcmk__env_option_enabled("pacemaker-execd", "env_var")); pcmk__mock_getenv = false; } static void disabled_daemon_not_in_list(void **state) { // Return false if value is not true and daemon is not in the option's value pcmk__mock_getenv = true; expect_string(__wrap_getenv, name, "PCMK_env_var"); will_return(__wrap_getenv, "pacemaker-controld,pacemaker-fenced"); assert_false(pcmk__env_option_enabled("pacemaker-execd", "env_var")); pcmk__mock_getenv = false; } -int -main(int argc, char **argv) -{ - const struct CMUnitTest tests[] = { - cmocka_unit_test(disabled_null_value), - cmocka_unit_test(enabled_true_value), - cmocka_unit_test(disabled_false_value), - cmocka_unit_test(enabled_daemon_in_list), - cmocka_unit_test(disabled_daemon_not_in_list), - }; - - cmocka_set_message_output(CM_OUTPUT_TAP); - return cmocka_run_group_tests(tests, NULL, NULL); -} +PCMK__UNIT_TEST(NULL, NULL, + cmocka_unit_test(disabled_null_value), + cmocka_unit_test(enabled_true_value), + cmocka_unit_test(disabled_false_value), + cmocka_unit_test(enabled_daemon_in_list), + cmocka_unit_test(disabled_daemon_not_in_list)) diff --git a/lib/common/tests/options/pcmk__env_option_test.c b/lib/common/tests/options/pcmk__env_option_test.c index e5d9defb09..fc58e320af 100644 --- a/lib/common/tests/options/pcmk__env_option_test.c +++ b/lib/common/tests/options/pcmk__env_option_test.c @@ -1,142 +1,134 @@ /* * 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 Lesser General Public License * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY. */ #include #include #include "mock_private.h" static void empty_input_string(void **state) { pcmk__mock_getenv = true; // getenv() not called assert_null(pcmk__env_option(NULL)); assert_null(pcmk__env_option("")); pcmk__mock_getenv = false; } static void input_too_long_for_both(void **state) { /* pcmk__env_option() prepends "PCMK_" before lookup. If the option name is * too long for the buffer or isn't found in the env, then it prepends "HA_" * and tries again. A string of length (NAME_MAX - 3) will set us just over * just over the edge for both tries. */ char long_opt[NAME_MAX - 2]; for (int i = 0; i < NAME_MAX - 3; i++) { long_opt[i] = 'a'; } long_opt[NAME_MAX - 3] = '\0'; pcmk__mock_getenv = true; // getenv() not called assert_null(pcmk__env_option(long_opt)); pcmk__mock_getenv = false; } static void input_too_long_for_pcmk(void **state) { /* If an input is too long for "PCMK_