blob: e3884d6b14e3f424fb7898abefc3cc3b26f6e6c8 [file] [log] [blame]
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* 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.
*/
#ifndef _IPA_UT_FRAMEWORK_H_
#define _IPA_UT_FRAMEWORK_H_
#include <linux/kernel.h>
#include "../ipa_common_i.h"
#include "ipa_ut_i.h"
#define IPA_UT_DRV_NAME "ipa_ut"
#define IPA_UT_DBG(fmt, args...) \
do { \
pr_debug(IPA_UT_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
IPA_UT_DRV_NAME " %s:%d " fmt, ## args); \
IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
IPA_UT_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define IPA_UT_DBG_LOW(fmt, args...) \
do { \
pr_debug(IPA_UT_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
IPA_UT_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define IPA_UT_ERR(fmt, args...) \
do { \
pr_err(IPA_UT_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
IPA_UT_DRV_NAME " %s:%d " fmt, ## args); \
IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
IPA_UT_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
#define IPA_UT_INFO(fmt, args...) \
do { \
pr_info(IPA_UT_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
IPA_IPC_LOGGING(ipa_get_ipc_logbuf(), \
IPA_UT_DRV_NAME " %s:%d " fmt, ## args); \
IPA_IPC_LOGGING(ipa_get_ipc_logbuf_low(), \
IPA_UT_DRV_NAME " %s:%d " fmt, ## args); \
} while (0)
/**
* struct ipa_ut_tst_fail_report - Information on test failure
* @valid: When a test posts a report, valid will be marked true
* @file: File name containing the failed test.
* @line: Number of line in the file where the test failed.
* @func: Function where the test failed in.
* @info: Information about the failure.
*/
struct ipa_ut_tst_fail_report {
bool valid;
const char *file;
int line;
const char *func;
const char *info;
};
/**
* Report on test failure
* To be used by tests to report a point were a test fail.
* Failures are saved in a stack manner.
* Dumping the failure info will dump the fail reports
* from all the function in the calling stack
*/
#define IPA_UT_TEST_FAIL_REPORT(__info) \
do { \
extern struct ipa_ut_tst_fail_report \
_IPA_UT_TEST_FAIL_REPORT_DATA \
[_IPA_UT_TEST_FAIL_REPORT_SIZE]; \
extern u32 _IPA_UT_TEST_FAIL_REPORT_IDX; \
struct ipa_ut_tst_fail_report *entry; \
if (_IPA_UT_TEST_FAIL_REPORT_IDX >= \
_IPA_UT_TEST_FAIL_REPORT_SIZE) \
break; \
entry = &(_IPA_UT_TEST_FAIL_REPORT_DATA \
[_IPA_UT_TEST_FAIL_REPORT_IDX]); \
entry->file = __FILENAME__; \
entry->line = __LINE__; \
entry->func = __func__; \
if (__info) \
entry->info = __info; \
else \
entry->info = ""; \
_IPA_UT_TEST_FAIL_REPORT_IDX++; \
} while (0)
/**
* To be used by tests to log progress and ongoing information
* Logs are not printed to user, but saved to a buffer.
* I/S shall print the buffer at different occasions - e.g. in test failure
*/
#define IPA_UT_LOG(fmt, args...) \
do { \
extern char *_IPA_UT_TEST_LOG_BUF_NAME; \
char __buf[512]; \
IPA_UT_DBG(fmt, ## args); \
if (!_IPA_UT_TEST_LOG_BUF_NAME) {\
pr_err(IPA_UT_DRV_NAME " %s:%d " fmt, \
__func__, __LINE__, ## args); \
break; \
} \
scnprintf(__buf, sizeof(__buf), \
" %s:%d " fmt, \
__func__, __LINE__, ## args); \
strlcat(_IPA_UT_TEST_LOG_BUF_NAME, __buf, \
_IPA_UT_TEST_LOG_BUF_SIZE); \
} while (0)
/**
* struct ipa_ut_suite_meta - Suite meta-data
* @name: Suite unique name
* @desc: Suite description
* @setup: Setup Call-back of the suite
* @teardown: Teardown Call-back of the suite
* @priv: Private pointer of the suite
*
* Setup/Teardown will be called once for the suite when running a tests of it.
* priv field is shared between the Setup/Teardown and the tests
*/
struct ipa_ut_suite_meta {
char *name;
char *desc;
int (*setup)(void **ppriv);
int (*teardown)(void *priv);
void *priv;
};
/* Test suite data structure declaration */
struct ipa_ut_suite;
/**
* struct ipa_ut_test - Test information
* @name: Test name
* @desc: Test description
* @run: Test execution call-back
* @run_in_regression: To run this test as part of regression?
* @min_ipa_hw_ver: Minimum IPA H/W version where the test is supported?
* @max_ipa_hw_ver: Maximum IPA H/W version where the test is supported?
* @suite: Pointer to suite containing this test
* @res: Test execution result. Will be updated after running a test as part
* of suite tests run
*/
struct ipa_ut_test {
char *name;
char *desc;
int (*run)(void *priv);
bool run_in_regression;
int min_ipa_hw_ver;
int max_ipa_hw_ver;
struct ipa_ut_suite *suite;
enum ipa_ut_test_result res;
};
/**
* struct ipa_ut_suite - Suite information
* @meta_data: Pointer to meta-data structure of the suite
* @tests: Pointer to array of tests belongs to the suite
* @tests_cnt: Number of tests
*/
struct ipa_ut_suite {
struct ipa_ut_suite_meta *meta_data;
struct ipa_ut_test *tests;
size_t tests_cnt;
};
/**
* Add a test to a suite.
* Will add entry to tests array and update its info with
* the given info, thus adding new test.
*/
#define IPA_UT_ADD_TEST(__name, __desc, __run, __run_in_regression, \
__min_ipa_hw_ver, __max_ipa__hw_ver) \
{ \
.name = #__name, \
.desc = __desc, \
.run = __run, \
.run_in_regression = __run_in_regression, \
.min_ipa_hw_ver = __min_ipa_hw_ver, \
.max_ipa_hw_ver = __max_ipa__hw_ver, \
.suite = NULL, \
}
/**
* Declare a suite
* Every suite need to be declared before it is registered.
*/
#define IPA_UT_DECLARE_SUITE(__name) \
extern struct ipa_ut_suite _IPA_UT_SUITE_DATA(__name)
/**
* Register a suite
* Registering a suite is mandatory so it will be considered.
*/
#define IPA_UT_REGISTER_SUITE(__name) \
(&_IPA_UT_SUITE_DATA(__name))
/**
* Start/End suite definition
* Will create the suite global structures and adds adding tests to it.
* Use IPA_UT_ADD_TEST() with these macros to add tests when defining
* a suite
*/
#define IPA_UT_DEFINE_SUITE_START(__name, __desc, __setup, __teardown) \
static struct ipa_ut_suite_meta _IPA_UT_SUITE_META_DATA(__name) = \
{ \
.name = #__name, \
.desc = __desc, \
.setup = __setup, \
.teardown = __teardown, \
}; \
static struct ipa_ut_test _IPA_UT_SUITE_TESTS(__name)[] =
#define IPA_UT_DEFINE_SUITE_END(__name) \
; \
struct ipa_ut_suite _IPA_UT_SUITE_DATA(__name) = \
{ \
.meta_data = &_IPA_UT_SUITE_META_DATA(__name), \
.tests = _IPA_UT_SUITE_TESTS(__name), \
.tests_cnt = ARRAY_SIZE(_IPA_UT_SUITE_TESTS(__name)), \
}
#endif /* _IPA_UT_FRAMEWORK_H_ */