blob: 8d75f506f9eb8462dc32689bb1b2f78783431df4 [file] [log] [blame]
/*
*
* (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 <linux/kref.h>
#include <linux/workqueue.h>
#include <linux/wait.h>
#include <kutf/kutf_mem.h>
#include <kutf/kutf_resultset.h>
/* 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_ */