/* * * (C) COPYRIGHT 2014, 2017 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the * GNU General Public License version 2 as published by the Free Software * Foundation, and any use by you of this program is subject to the terms * of such GNU licence. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you can access it online at * http://www.gnu.org/licenses/gpl-2.0.html. * * SPDX-License-Identifier: GPL-2.0 * */ #ifndef _KERNEL_UTF_SUITE_H_ #define _KERNEL_UTF_SUITE_H_ /* kutf_suite.h * Functions for management of test suites. * * This collection of data structures, macros, and functions are used to * create Test Suites, Tests within those Test Suites, and Fixture variants * of each test. */ #include #include #include #include #include /* Arbitrary maximum size to prevent user space allocating too much kernel * memory */ #define KUTF_MAX_LINE_LENGTH (1024u) /** * Pseudo-flag indicating an absence of any specified test class. Note that * tests should not be annotated with this constant as it is simply a zero * value; tests without a more specific class must be marked with the flag * KUTF_F_TEST_GENERIC. */ #define KUTF_F_TEST_NONE ((unsigned int)(0)) /** * Class indicating this test is a smoke test. * A given set of smoke tests should be quick to run, enabling rapid turn-around * of "regress-on-commit" test runs. */ #define KUTF_F_TEST_SMOKETEST ((unsigned int)(1 << 1)) /** * Class indicating this test is a performance test. * These tests typically produce a performance metric, such as "time to run" or * "frames per second", */ #define KUTF_F_TEST_PERFORMANCE ((unsigned int)(1 << 2)) /** * Class indicating that this test is a deprecated test. * These tests have typically been replaced by an alternative test which is * more efficient, or has better coverage. */ #define KUTF_F_TEST_DEPRECATED ((unsigned int)(1 << 3)) /** * Class indicating that this test is a known failure. * These tests have typically been run and failed, but marking them as a known * failure means it is easier to triage results. * * It is typically more convenient to triage known failures using the * results database and web UI, as this means there is no need to modify the * test code. */ #define KUTF_F_TEST_EXPECTED_FAILURE ((unsigned int)(1 << 4)) /** * Class indicating that this test is a generic test, which is not a member of * a more specific test class. Tests which are not created with a specific set * of filter flags by the user are assigned this test class by default. */ #define KUTF_F_TEST_GENERIC ((unsigned int)(1 << 5)) /** * Class indicating this test is a resource allocation failure test. * A resource allocation failure test will test that an error code is * correctly propagated when an allocation fails. */ #define KUTF_F_TEST_RESFAIL ((unsigned int)(1 << 6)) /** * Additional flag indicating that this test is an expected failure when * run in resource failure mode. These tests are never run when running * the low resource mode. */ #define KUTF_F_TEST_EXPECTED_FAILURE_RF ((unsigned int)(1 << 7)) /** * Flag reserved for user-defined filter zero. */ #define KUTF_F_TEST_USER_0 ((unsigned int)(1 << 24)) /** * Flag reserved for user-defined filter one. */ #define KUTF_F_TEST_USER_1 ((unsigned int)(1 << 25)) /** * Flag reserved for user-defined filter two. */ #define KUTF_F_TEST_USER_2 ((unsigned int)(1 << 26)) /** * Flag reserved for user-defined filter three. */ #define KUTF_F_TEST_USER_3 ((unsigned int)(1 << 27)) /** * Flag reserved for user-defined filter four. */ #define KUTF_F_TEST_USER_4 ((unsigned int)(1 << 28)) /** * Flag reserved for user-defined filter five. */ #define KUTF_F_TEST_USER_5 ((unsigned int)(1 << 29)) /** * Flag reserved for user-defined filter six. */ #define KUTF_F_TEST_USER_6 ((unsigned int)(1 << 30)) /** * Flag reserved for user-defined filter seven. */ #define KUTF_F_TEST_USER_7 ((unsigned int)(1 << 31)) /** * Pseudo-flag indicating that all test classes should be executed. */ #define KUTF_F_TEST_ALL ((unsigned int)(0xFFFFFFFFU)) /** * union kutf_callback_data - Union used to store test callback data * @ptr_value: pointer to the location where test callback data * are stored * @u32_value: a number which represents test callback data */ union kutf_callback_data { void *ptr_value; u32 u32_value; }; /** * struct kutf_userdata_line - A line of user data to be returned to the user * @node: struct list_head to link this into a list * @str: The line of user data to return to user space * @size: The number of bytes within @str */ struct kutf_userdata_line { struct list_head node; char *str; size_t size; }; /** * KUTF_USERDATA_WARNING_OUTPUT - Flag specifying that a warning has been output * * If user space reads the "run" file while the test is waiting for user data, * then the framework will output a warning message and set this flag within * struct kutf_userdata. A subsequent read will then simply return an end of * file condition rather than outputting the warning again. The upshot of this * is that simply running 'cat' on a test which requires user data will produce * the warning followed by 'cat' exiting due to EOF - which is much more user * friendly than blocking indefinitely waiting for user data. */ #define KUTF_USERDATA_WARNING_OUTPUT 1 /** * struct kutf_userdata - Structure holding user data * @flags: See %KUTF_USERDATA_WARNING_OUTPUT * @input_head: List of struct kutf_userdata_line containing user data * to be read by the kernel space test. * @input_waitq: Wait queue signalled when there is new user data to be * read by the kernel space test. */ struct kutf_userdata { unsigned long flags; struct list_head input_head; wait_queue_head_t input_waitq; }; /** * struct kutf_context - Structure representing a kernel test context * @kref: Refcount for number of users of this context * @suite: Convenience pointer to the suite this context * is running * @test_fix: The fixture that is being run in this context * @fixture_pool: The memory pool used for the duration of * the fixture/text context. * @fixture: The user provided fixture structure. * @fixture_index: The index (id) of the current fixture. * @fixture_name: The name of the current fixture (or NULL if unnamed). * @test_data: Any user private data associated with this test * @result_set: All the results logged by this test context * @status: The status of the currently running fixture. * @expected_status: The expected status on exist of the currently * running fixture. * @work: Work item to enqueue onto the work queue to run the test * @userdata: Structure containing the user data for the test to read */ struct kutf_context { struct kref kref; struct kutf_suite *suite; struct kutf_test_fixture *test_fix; struct kutf_mempool fixture_pool; void *fixture; unsigned int fixture_index; const char *fixture_name; union kutf_callback_data test_data; struct kutf_result_set *result_set; enum kutf_result_status status; enum kutf_result_status expected_status; struct work_struct work; struct kutf_userdata userdata; }; /** * struct kutf_suite - Structure representing a kernel test suite * @app: The application this suite belongs to. * @name: The name of this suite. * @suite_data: Any user private data associated with this * suite. * @create_fixture: Function used to create a new fixture instance * @remove_fixture: Function used to destroy a new fixture instance * @fixture_variants: The number of variants (must be at least 1). * @suite_default_flags: Suite global filter flags which are set on * all tests. * @node: List node for suite_list * @dir: The debugfs directory for this suite * @test_list: List head to store all the tests which are * part of this suite */ struct kutf_suite { struct kutf_application *app; const char *name; union kutf_callback_data suite_data; void *(*create_fixture)(struct kutf_context *context); void (*remove_fixture)(struct kutf_context *context); unsigned int fixture_variants; unsigned int suite_default_flags; struct list_head node; struct dentry *dir; struct list_head test_list; }; /* ============================================================================ Application functions ============================================================================ */ /** * kutf_create_application() - Create an in kernel test application. * @name: The name of the test application. * * Return: pointer to the kutf_application on success or NULL * on failure */ struct kutf_application *kutf_create_application(const char *name); /** * kutf_destroy_application() - Destroy an in kernel test application. * * @app: The test application to destroy. */ void kutf_destroy_application(struct kutf_application *app); /* ============================================================================ Suite functions ============================================================================ */ /** * kutf_create_suite() - Create a kernel test suite. * @app: The test application to create the suite in. * @name: The name of the suite. * @fixture_count: The number of fixtures to run over the test * functions in this suite * @create_fixture: Callback used to create a fixture. The returned value * is stored in the fixture pointer in the context for * use in the test functions. * @remove_fixture: Callback used to remove a previously created fixture. * * Suite names must be unique. Should two suites with the same name be * registered with the same application then this function will fail, if they * are registered with different applications then the function will not detect * this and the call will succeed. * * Return: pointer to the created kutf_suite on success or NULL * on failure */ struct kutf_suite *kutf_create_suite( struct kutf_application *app, const char *name, unsigned int fixture_count, void *(*create_fixture)(struct kutf_context *context), void (*remove_fixture)(struct kutf_context *context)); /** * kutf_create_suite_with_filters() - Create a kernel test suite with user * defined default filters. * @app: The test application to create the suite in. * @name: The name of the suite. * @fixture_count: The number of fixtures to run over the test * functions in this suite * @create_fixture: Callback used to create a fixture. The returned value * is stored in the fixture pointer in the context for * use in the test functions. * @remove_fixture: Callback used to remove a previously created fixture. * @filters: Filters to apply to a test if it doesn't provide its own * * Suite names must be unique. Should two suites with the same name be * registered with the same application then this function will fail, if they * are registered with different applications then the function will not detect * this and the call will succeed. * * Return: pointer to the created kutf_suite on success or NULL on failure */ struct kutf_suite *kutf_create_suite_with_filters( struct kutf_application *app, const char *name, unsigned int fixture_count, void *(*create_fixture)(struct kutf_context *context), void (*remove_fixture)(struct kutf_context *context), unsigned int filters); /** * kutf_create_suite_with_filters_and_data() - Create a kernel test suite with * user defined default filters. * @app: The test application to create the suite in. * @name: The name of the suite. * @fixture_count: The number of fixtures to run over the test * functions in this suite * @create_fixture: Callback used to create a fixture. The returned value * is stored in the fixture pointer in the context for * use in the test functions. * @remove_fixture: Callback used to remove a previously created fixture. * @filters: Filters to apply to a test if it doesn't provide its own * @suite_data: Suite specific callback data, provided during the * running of the test in the kutf_context * * Return: pointer to the created kutf_suite on success or NULL * on failure */ struct kutf_suite *kutf_create_suite_with_filters_and_data( struct kutf_application *app, const char *name, unsigned int fixture_count, void *(*create_fixture)(struct kutf_context *context), void (*remove_fixture)(struct kutf_context *context), unsigned int filters, union kutf_callback_data suite_data); /** * kutf_add_test() - Add a test to a kernel test suite. * @suite: The suite to add the test to. * @id: The ID of the test. * @name: The name of the test. * @execute: Callback to the test function to run. * * Note: As no filters are provided the test will use the suite filters instead */ void kutf_add_test(struct kutf_suite *suite, unsigned int id, const char *name, void (*execute)(struct kutf_context *context)); /** * kutf_add_test_with_filters() - Add a test to a kernel test suite with filters * @suite: The suite to add the test to. * @id: The ID of the test. * @name: The name of the test. * @execute: Callback to the test function to run. * @filters: A set of filtering flags, assigning test categories. */ void kutf_add_test_with_filters(struct kutf_suite *suite, unsigned int id, const char *name, void (*execute)(struct kutf_context *context), unsigned int filters); /** * kutf_add_test_with_filters_and_data() - Add a test to a kernel test suite * with filters. * @suite: The suite to add the test to. * @id: The ID of the test. * @name: The name of the test. * @execute: Callback to the test function to run. * @filters: A set of filtering flags, assigning test categories. * @test_data: Test specific callback data, provided during the * running of the test in the kutf_context */ void kutf_add_test_with_filters_and_data( struct kutf_suite *suite, unsigned int id, const char *name, void (*execute)(struct kutf_context *context), unsigned int filters, union kutf_callback_data test_data); /* ============================================================================ Test functions ============================================================================ */ /** * kutf_test_log_result_external() - Log a result which has been created * externally into a in a standard form * recognized by the log parser. * @context: The test context the test is running in * @message: The message for this result * @new_status: The result status of this log message */ void kutf_test_log_result_external( struct kutf_context *context, const char *message, enum kutf_result_status new_status); /** * kutf_test_expect_abort() - Tell the kernel that you expect the current * fixture to produce an abort. * @context: The test context this test is running in. */ void kutf_test_expect_abort(struct kutf_context *context); /** * kutf_test_expect_fatal() - Tell the kernel that you expect the current * fixture to produce a fatal error. * @context: The test context this test is running in. */ void kutf_test_expect_fatal(struct kutf_context *context); /** * kutf_test_expect_fail() - Tell the kernel that you expect the current * fixture to fail. * @context: The test context this test is running in. */ void kutf_test_expect_fail(struct kutf_context *context); /** * kutf_test_expect_warn() - Tell the kernel that you expect the current * fixture to produce a warning. * @context: The test context this test is running in. */ void kutf_test_expect_warn(struct kutf_context *context); /** * kutf_test_expect_pass() - Tell the kernel that you expect the current * fixture to pass. * @context: The test context this test is running in. */ void kutf_test_expect_pass(struct kutf_context *context); /** * kutf_test_skip() - Tell the kernel that the test should be skipped. * @context: The test context this test is running in. */ void kutf_test_skip(struct kutf_context *context); /** * kutf_test_skip_msg() - Tell the kernel that this test has been skipped, * supplying a reason string. * @context: The test context this test is running in. * @message: A message string containing the reason for the skip. * * Note: The message must not be freed during the lifetime of the test run. * This means it should either be a prebaked string, or if a dynamic string * is required it must be created with kutf_dsprintf which will store * the resultant string in a buffer who's lifetime is the same as the test run. */ void kutf_test_skip_msg(struct kutf_context *context, const char *message); /** * kutf_test_pass() - Tell the kernel that this test has passed. * @context: The test context this test is running in. * @message: A message string containing the reason for the pass. * * Note: The message must not be freed during the lifetime of the test run. * This means it should either be a pre-baked string, or if a dynamic string * is required it must be created with kutf_dsprintf which will store * the resultant string in a buffer who's lifetime is the same as the test run. */ void kutf_test_pass(struct kutf_context *context, char const *message); /** * kutf_test_debug() - Send a debug message * @context: The test context this test is running in. * @message: A message string containing the debug information. * * Note: The message must not be freed during the lifetime of the test run. * This means it should either be a pre-baked string, or if a dynamic string * is required it must be created with kutf_dsprintf which will store * the resultant string in a buffer who's lifetime is the same as the test run. */ void kutf_test_debug(struct kutf_context *context, char const *message); /** * kutf_test_info() - Send an information message * @context: The test context this test is running in. * @message: A message string containing the information message. * * Note: The message must not be freed during the lifetime of the test run. * This means it should either be a pre-baked string, or if a dynamic string * is required it must be created with kutf_dsprintf which will store * the resultant string in a buffer who's lifetime is the same as the test run. */ void kutf_test_info(struct kutf_context *context, char const *message); /** * kutf_test_warn() - Send a warning message * @context: The test context this test is running in. * @message: A message string containing the warning message. * * Note: The message must not be freed during the lifetime of the test run. * This means it should either be a pre-baked string, or if a dynamic string * is required it must be created with kutf_dsprintf which will store * the resultant string in a buffer who's lifetime is the same as the test run. */ void kutf_test_warn(struct kutf_context *context, char const *message); /** * kutf_test_fail() - Tell the kernel that a test has failed * @context: The test context this test is running in. * @message: A message string containing the failure message. * * Note: The message must not be freed during the lifetime of the test run. * This means it should either be a pre-baked string, or if a dynamic string * is required it must be created with kutf_dsprintf which will store * the resultant string in a buffer who's lifetime is the same as the test run. */ void kutf_test_fail(struct kutf_context *context, char const *message); /** * kutf_test_fatal() - Tell the kernel that a test has triggered a fatal error * @context: The test context this test is running in. * @message: A message string containing the fatal error message. * * Note: The message must not be freed during the lifetime of the test run. * This means it should either be a pre-baked string, or if a dynamic string * is required it must be created with kutf_dsprintf which will store * the resultant string in a buffer who's lifetime is the same as the test run. */ void kutf_test_fatal(struct kutf_context *context, char const *message); /** * kutf_test_abort() - Tell the kernel that a test triggered an abort in the test * * @context: The test context this test is running in. */ void kutf_test_abort(struct kutf_context *context); #endif /* _KERNEL_UTF_SUITE_H_ */