diff options
author | Luca Muscariello <lumuscar+fdio@cisco.com> | 2017-02-23 17:01:02 +0100 |
---|---|---|
committer | Luca Muscariello <lumuscar+fdio@cisco.com> | 2017-02-23 17:21:02 +0100 |
commit | ec688b4723a041044226358bcd4dd6e2da39da49 (patch) | |
tree | 3a244c48d1eb9e4d90f9050fd1a61ae5c0327526 /longbow/src/LongBow/unit-test.h | |
parent | 9b30fc10fb1cbebe651e5a107e8ca5b24de54675 (diff) |
Initial commit: cframework. Longbow and Libparc
Change-Id: I90378dbd30da6033b20fb1f829b3b822cf366c59
Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com>
Diffstat (limited to 'longbow/src/LongBow/unit-test.h')
-rw-r--r-- | longbow/src/LongBow/unit-test.h | 413 |
1 files changed, 413 insertions, 0 deletions
diff --git a/longbow/src/LongBow/unit-test.h b/longbow/src/LongBow/unit-test.h new file mode 100644 index 00000000..3f282671 --- /dev/null +++ b/longbow/src/LongBow/unit-test.h @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file unit-test.h + * @ingroup testing + * @brief LongBow Unit Test Support. + * + * Every LongBow Test module must include this file as the first included file <em>after</em> + * including the files necessary for the functions under test. + * + */ +#ifndef UNIT_TEST_H_ +#define UNIT_TEST_H_ + +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> +#include <setjmp.h> +#include <unistd.h> + +#include <LongBow/runtime.h> + +#include <LongBow/longBow_Compiler.h> +#include <LongBow/longBow_UnitTest.h> +#include <LongBow/longBow_Status.h> +#include <LongBow/longBow_Config.h> +#include <LongBow/longBow_UnitTesting.h> +#include <LongBow/longBow_Runtime.h> +#include <LongBow/longBow_Main.h> +#include <LongBow/longBow_TestRunner.h> +#include <LongBow/longBow_TestFixture.h> +#include <LongBow/longBow_TestCase.h> +#include <LongBow/longBow_SubProcess.h> +#include <LongBow/longBow_TestCaseMetaData.h> +#include <LongBow/Reporting/longBowReport_Testing.h> + +#define longBowUnused(declaration) declaration __attribute__((unused)) + +/** + * Test Runner setup function called before the invocation of the Test Fixtures associated with this Test Runner. + * + * Every Test Runner has a set-up and tear-down function that are invoked + * just before and just after the execution of each test case function. + * This function performs setup common for all fixtures to use. + * If this function must return a valid `LongBowStatus` value. + * + * @param [in] runnerName A valid identifier for the Test Runner. + * + * @return A LongBowStatus indicating the status of the setup. + * + * Example: + * @code + * // An example of a minimal Test Runner Setup function. + * + * LONGBOW_TEST_RUNNER_SETUP(LongBow) + * { + * return LONGBOW_STATUS_SUCCEEDED; + * } + * @endcode + * + * @see LONGBOW_TEST_RUNNER_TEARDOWN + */ +#define LONGBOW_TEST_RUNNER_SETUP(runnerName) \ + LongBowStatus longBowUnitTest_RunnerSetupName(runnerName) (LongBowTestRunner * testRunner); \ + LongBowStatus longBowUnitTest_RunnerSetupName(runnerName) (longBowUnused(LongBowTestRunner * testRunner)) + +/** + * @brief The post-processing for a Test Runner called after all fixtures have been run. + * + * The Test Runner calls this function once after all the Test Fixtures are run. + * + * This function is responsible for resetting or restoring external resources previously setup by the + * Test Runner Setup function and which may have been modified by any test fixture or test case. + * If this function must return a valid LongBowStatus value. + * + * @see LONGBOW_TEST_RUNNER_SETUP + * @param [in] longBowRunnerName A valid identifier for the Test Runner. + */ +#define LONGBOW_TEST_RUNNER_TEARDOWN(longBowRunnerName) \ + LongBowStatus longBowUnitTest_RunnerTearDownName(longBowRunnerName) (LongBowTestRunner * testRunner); \ + LongBowStatus longBowUnitTest_RunnerTearDownName(longBowRunnerName) (longBowUnused(LongBowTestRunner * testRunner)) + +/** + * @brief Define a Test Case Runner with the given name. + * The name must be valid syntax for a C identifier and will be used to compose a longer C function name. + * + * The resulting function that this macro defines specifies the parameter `LongBowTestRunner *testRunner` + * which is a pointer to a LongBowTestRunner instance for the Test Runner. + * + * @param [in] testRunnerName A valid identifier for the Test Runner. + */ +#define LONGBOW_TEST_RUNNER(testRunnerName) \ + void longBowUnitTest_RunnerName(testRunnerName) (const LongBowTestRunner * testRunner); \ + void longBowUnitTest_RunnerName(testRunnerName) (const LongBowTestRunner * testRunner) + +/** + * @brief Create an allocated instance of a LongBowTestRunner that must be destroyed via `longBowTestRunner_Destroy` + * + * @param [in] testRunnerName A valid identifier for the Test Runner. (see LONGBOW_TEST_RUNNER) + * @return The return value from longBowTestRunner_Create + */ +#define LONGBOW_TEST_RUNNER_CREATE(testRunnerName) \ + longBowTestRunner_Create(#testRunnerName, \ + longBowUnitTest_RunnerSetupName(testRunnerName), \ + (LongBowTestRunnerRun *) longBowUnitTest_RunnerName(testRunnerName), \ + longBowUnitTest_RunnerTearDownName(testRunnerName)) + +#define LongBowTestRunner_Create(_runnerName_) \ + longBowTestRunner_Create(#_runnerName_, longBowUnitTest_RunnerSetupName(_runnerName_), \ + longBowUnitTest_RunnerName(_runnerName_), longBowUnitTest_RunnerTearDownName(_runnerName_)) + +/** + * @brief Run the LongBow test fixture with the specified `fixtureName`. + * + * @param [in] LongBowTestFixtureName A valid C identifier + * @see LONGBOW_TEST_FIXTURE(fixtureName) + */ +#define LONGBOW_RUN_TEST_FIXTURE(LongBowTestFixtureName) \ + do { \ + extern LONGBOW_TEST_FIXTURE_SETUP(LongBowTestFixtureName); \ + extern LONGBOW_TEST_FIXTURE_TEARDOWN(LongBowTestFixtureName); \ + extern LongBowUnitTest_FixtureDeclaration(LongBowTestFixtureName); \ + extern LongBowTestFixtureConfig longBowUnitTest_FixtureConfigName(LongBowTestFixtureName); \ + longBowTestFixture_Run(testRunner, \ + #LongBowTestFixtureName, \ + &longBowUnitTest_FixtureConfigName(LongBowTestFixtureName), \ + longBowUnitTest_FixtureSetupName(LongBowTestFixtureName), \ + longBowUnitTest_FixtureName(LongBowTestFixtureName), \ + longBowUnitTest_FixtureTearDownName(LongBowTestFixtureName)); \ + } while (0) + + + +/** + * @brief Define a test fixture with the given `fixtureName`. + * + * The value for `fixtureName` must be a valid syntax for a C identifier. + * + * @param [in] fixtureName A valid syntax for a C identifier. + */ +#define LongBowUnitTest_FixtureDeclaration(_fixtureName_) \ + void longBowUnitTest_FixtureName(_fixtureName_)(longBowUnused(const LongBowTestRunner * testRunner), longBowUnused(const LongBowTestFixture * testFixture)) + +/** + * @brief The default value for the expected result of a LongBow Fixture. + */ +#define LONGBOW_TEST_FIXTURE_CONFIG_DEFAULT .enabled = true + +/** + * @brief Define a test fixture with the given `fixtureName`. + * + * The value for `fixtureName` must be valid syntax for a C identifier. + * + * The resulting function that this macro defines specifies the parameter `LongBowTestFixture *LongBowTestFixture` + * which is a pointer to a `LongBowTestFixture` instance for the Test Fixture. + * + * @param [in] fixtureName + */ +#define LONGBOW_TEST_FIXTURE(fixtureName) \ + LONGBOW_TEST_FIXTURE_OPTIONS(fixtureName, LONGBOW_TEST_FIXTURE_CONFIG_DEFAULT) + +#define LONGBOW_TEST_FIXTURE_OPTIONS(fixtureName, ...) \ + LongBowCompiler_IgnoreInitializerOverrides \ + LongBowTestFixtureConfig longBowUnitTest_FixtureConfigName(fixtureName) = { LONGBOW_TEST_FIXTURE_CONFIG_DEFAULT, __VA_ARGS__ }; \ + LongBowCompiler_WarnInitializerOverrides \ + extern LONGBOW_TEST_FIXTURE_SETUP(fixtureName); \ + extern LONGBOW_TEST_FIXTURE_TEARDOWN(fixtureName); \ + LongBowUnitTest_FixtureDeclaration(fixtureName); \ + LongBowUnitTest_FixtureDeclaration(fixtureName) + + +/** + * The pre-processing for a test fixture called before each invocation of a test case in the same fixture. + * + * This function is responsible for setting up the common programmatic state for each test case in the same fixture. + * If this function returns `false` the corresponding test case is skipped. + * + * The resulting function that this macro defines specifies the parameters + * `LongBowTestFixture *testFixture` and `LongBowTestCase *testCase` + * + * @param [in] fixtureName + * + * @see LONGBOW_TEST_FIXTURE_TEARDOWN + */ +#define LONGBOW_TEST_FIXTURE_SETUP(fixtureName) \ + LongBowStatus longBowUnitTest_FixtureSetupName(fixtureName) (longBowUnused(const LongBowTestRunner * testRunner), longBowUnused(const LongBowTestFixture * testFixture), longBowUnused(const LongBowTestCase * testCase), longBowUnused(LongBowClipBoard * testClipBoard)) + +/** + * The post-processing for a test fixture called after each invocation of a test case in the same fixture. + * + * This function is responsible for resetting the common programmatic state for each test case in the same fixture. + * If this function returns `false` the corresponding test case is considered passed, but warned. + * + * The resulting function that this macro defines specifies the parameters + * `LongBowTestFixture *testFixture` and `LongBowTestCase *testCase` + * + * @param [in] fixtureName + * + * @see `LONGBOW_TEST_FIXTURE_SETUP` + */ +#define LONGBOW_TEST_FIXTURE_TEARDOWN(fixtureName) \ + LongBowStatus longBowUnitTest_FixtureTearDownName(fixtureName) (longBowUnused(const LongBowTestRunner * testRunner), longBowUnused(const LongBowTestFixture * testFixture), longBowUnused(const LongBowTestCase * testCase), longBowUnused(LongBowClipBoard * testClipBoard)) + +/** + * @brief Defines the canonical name of a LongBow Test Case meta data. + * + * @param fixtureName The name of the Test Fixture that the Test Case belongs to. + * @param testCaseName The name of the Test Case. + */ +#define longBowTestCase_MetaDataDeclaration(_testFixtureName_, _testCaseName_) \ + TestCase ## _testFixtureName_ ## _testCaseName_ ## MetaData + +/** + * @brief Forward declare a LongBow Test Case. + * + * @param fixtureName The name of the Test Fixture that the Test Case belongs to. + * @param testCaseName The name of the Test Case. + */ +#define longBowUnitTest_TestCaseDeclaration(fixtureName, testCaseName) \ + void longBowUnitTest_CaseName(fixtureName, testCaseName) (longBowUnused(const LongBowTestRunner * testRunner), longBowUnused(const LongBowTestFixture * testFixture), longBowUnused(const LongBowTestCase * testCase), longBowUnused(const LongBowClipBoard * testClipBoard), longBowUnused(jmp_buf longBowTestCaseAbort)) + +/** + * @brief The default value for the expected result of a LongBow Test Case. + */ +#define LongBowUnitTest_TestCaseDefaultExpectedResult .event = NULL, .status = LongBowStatus_DONTCARE + +/** + * Define a test case with the given `fixtureName` and `testCaseName`. + * + * The `fixtureName` must be the name of a defined fixture, see `LONGBOW_TEST_FIXTURE`. + * The `testCaseName` must be valid syntax for a C identifier. + * + * @param fixtureName + * @param testCaseName + * + * @code + * LONGBOW_TEST_CASE(MyFixture, MyTestCase) + * { + * assertTrue(true, "It lied to me!"); + * } + */ +#define LONGBOW_TEST_CASE(fixtureName, testCaseName) \ + LONGBOW_TEST_CASE_EXPECTS(fixtureName, testCaseName, LongBowUnitTest_TestCaseDefaultExpectedResult) + +/** + * Define a test case with the given `fixtureName` and `testCaseName` with an explictly specified status. + * + * The `fixtureName` must be the name of a defined fixture, see `LONGBOW_TEST_FIXTURE`. + * The `testCaseName` is the name of the Test Case and must be valid syntax for a C identifier. + * The variable number of subsequent arguments are a comma separated list of structure initialisers for the + * LongBowRuntimeResult structure. + * + * For example, the construct + * @code + * LONGBOW_TEST_CASE_EXPECTS(MyFixture, alwaysWarn, .event = &LongBowAssertEvent) + * @endcode + * defines the Long Bow Test case `alwaysWarn` that is within the Test Fixture named `MyFixture`. + * The expected termination is expected to be a `LongBowAssertEvent`, which means an assertion was triggered. + * + * If the termination status of the test must is equal to the specified status, + * the test will be signaled as `LONGBOW_STATUS_SUCCESS, otherwise it will be LONGBOW_STATUS_FAILED. + * + * @param fixtureName + * @param testCaseName + */ +#define LONGBOW_TEST_CASE_EXPECTS(fixtureName, testCaseName, ...) \ + LongBowCompiler_IgnoreInitializerOverrides \ + LongBowTestCaseMetaData longBowTestCase_MetaDataDeclaration(fixtureName, testCaseName) = \ + { .fileName = __FILE__, .functionName = #testCaseName, .lineNumber = __LINE__, \ + .expectedResult = { LongBowUnitTest_TestCaseDefaultExpectedResult, __VA_ARGS__ } }; \ + LongBowCompiler_WarnInitializerOverrides \ + longBowUnitTest_TestCaseDeclaration(fixtureName, testCaseName); \ + longBowUnitTest_TestCaseDeclaration(fixtureName, testCaseName) + + +/** + * @brief Run a test case defined for the named <code>fixtureName</code> and <code>testCaseName</code>. + * + * This is executed within a LongBow test fixture function and references the function's + * <code>LongBowTestFixture</code> parameter. + * + * @param [in] fixtureName + * @param [in] testCaseName + * + * @see LONGBOW_TEST_CASE + */ +#define LONGBOW_RUN_TEST_CASE(fixtureName, testCaseName) \ + extern longBowUnitTest_TestCaseDeclaration(fixtureName, testCaseName); \ + extern LongBowTestCaseMetaData longBowTestCase_MetaDataDeclaration(fixtureName, testCaseName); \ + longBowTestCase_Run(#testCaseName, testFixture, longBowUnitTest_CaseName(fixtureName, testCaseName), \ + &longBowTestCase_MetaDataDeclaration(fixtureName, testCaseName)) + +/** + * @brief Configure and run a set of LongBowTestRunner instances + * + * @param [in] argc The number of elements in the @p argv array. + * @param [in] argv An array of nul-terminated C-strings. + * + * Example Usage: + * @code + * int + * main(int argc, char *argv[argc]) + * { + * LongBowTestRunner *testRunner1 = LONGBOW_TEST_RUNNER_CREATE(MyTestRunner); + * LongBowTestRunner *testRunner2 = LONGBOW_TEST_RUNNER_CREATE(MyOtherTestRunner); + * + * int exitStatus = longBowMain(argc, argv, testRunner, testRunner2); + * + * longBowTestRunner_Destroy(&testRunner1); + * longBowTestRunner_Destroy(&testRunner2); + * exit(exitStatus); + * } + * @endcode + */ +#ifdef LongBow_DISABLE_ASSERTIONS +/* 77 is the exit status for a skipped test when run with automake generated Makefiles */ +# define longBowMain(argc, argv, ...) \ + 77 +#else +# define longBowMain(argc, argv, ...) \ + longBowMain_Impl(argc, argv, __VA_ARGS__, NULL) +#endif + +/** + * @brief Configure and run a set of `LongBowTestRunner` instances + * + * @param [in] argc The number of elements in the @p argv array. + * @param [in] argv An NULL terminated list of pointers to `LongBowTestRunner` instances. + * + * Example Usage: + * @code + * int + * main(int argc, char *argv[argc]) + * { + * LongBowTestRunner *testRunner1 = LONGBOW_TEST_RUNNER_CREATE(MyTestRunner); + * LongBowTestRunner *testRunner2 = LONGBOW_TEST_RUNNER_CREATE(MyOtherTestRunner); + * + * int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner, testRunner2); + * + * longBowTestRunner_Destroy(&testRunner1); + * longBowTestRunner_Destroy(&testRunner2); + * exit(exitStatus); + * } + * @endcode + */ +#define LONGBOW_TEST_MAIN(argc, argv, ...) \ + longBowMain(argc, argv, __VA_ARGS__, NULL) + +/** + * @brief Skip this test case + * + * @param [in] ... A printf format string followed by a variable number of parameters corresponding to the format string. + */ +#define testSkip(...) do { \ + longBowTest(&LongBowTestSkippedEvent, "Skipped " __VA_ARGS__); \ +} while (0) + +/** + * @brief Terminate the test indicating that the test is unimplemented. + * + * @param [in] ... A printf format string followed by a variable number of parameters corresponding to the format string. + */ +#define testUnimplemented(...) do { \ + longBowTest(&LongBowTestUnimplementedEvent, "Unimplemented test " __VA_ARGS__); \ +} while (0) + +/** + * @brief Issue a warning and terminate with the `LONGBOW_TESTCASE_WARNED` code. + * + * @param [in] ... A printf format string followed by a variable number of parameters corresponding to the format string. + */ +#define testWarn(...) \ + do { longBowTest(&LongBowTestEvent, "Warning " __VA_ARGS__); } while (0) + +/** + * @brief assert the Equals Contract for the given function. + * + * @param [in] function The function under test. + * @param [in] x The pivotal value which must not be NULL. + * @param [in] y A value that must be perfectly equal to x and z, but neither x nor z. + * @param [in] z A value that must be perfectly equal to x and y, but neither x nor y. + * @param [in] ... A variable number of values that are unequal to x. + */ +#define assertEqualsContract(function, x, y, z, ...) \ + assertTrue(longBowUnitTesting_AssertEqualsContract((bool (*)(void *, void *))function, x, y, z, __VA_ARGS__, NULL), "Failed Equals Contract"); + +/** + * @brief assert the Compare To Contract for the given function. + * + * @param [in] function The function under test. + * @param [in] value The pivotal value under test. + * @param [in] equality A NULL terminated array of values that are all equivalent to `value`. + * @param [in] lesser A NULL terminated array of values that are all less than `value`. + * @param [in] greater A NULL terminated array of values that are all greater than `value`. + * @return `true` if the evalutation is successful. + * @see assertCompareToContract() + */ +#define assertCompareToContract(function, value, equality, lesser, greater) \ + assertTrue(longBowUnitTesting_AssertCompareToContract((int (*)(const void *, const void *))function, value, (void *) equality, (void *) lesser, (void *) greater), "Failed CompareTo Contract"); +#endif // UNIT_TEST_H_ |