Compare commits
6 Commits
group_by_m
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd8c7adfab | ||
|
|
ab540cbeb2 | ||
|
|
47647c0f9b | ||
|
|
7e2493cc7a | ||
|
|
ad0623b150 | ||
|
|
ede62ec4e2 |
8
.gitmodules
vendored
8
.gitmodules
vendored
@@ -0,0 +1,8 @@
|
|||||||
|
[submodule "dev-utility/CMake-Module/BuildKernelModule"]
|
||||||
|
path = dev-utility/CMake-Module/BuildKernelModule
|
||||||
|
url = ../CMake-Module-KernelModuleBuilder.git
|
||||||
|
branch = master
|
||||||
|
[submodule "lib/KUnity"]
|
||||||
|
path = lib/KUnity
|
||||||
|
url = ../KUnity-Core.git
|
||||||
|
branch = master
|
||||||
|
|||||||
7
Kbuild
Normal file
7
Kbuild
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
obj-m += kunity_test_runner_module.o
|
||||||
|
kunity_test_runner_module-objs += src/kunity_proc_test_file_handler.o
|
||||||
|
kunity_test_runner_module-objs += src/kunity_test_finder.o
|
||||||
|
kunity_test_runner_module-objs += src/runner_module.o
|
||||||
|
|
||||||
|
ccflags-y += -I${PWD}/src
|
||||||
|
ccflags-y += -I${PWD}/lib/KUnity/src
|
||||||
45
README.md
Normal file
45
README.md
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
# Kunity test runner module
|
||||||
|
The Kunity test runner runs any kunity tests (see [KUnity-Core](/kttd/KUnity-Core)) by a kernel module.
|
||||||
|
This module search for test function in the symbol table of the kernel space (https://www.linux.com/learn/kernel-newbie-corner-kernel-symbols-whats-available-your-module-what-isnt) and made them runable for the userspace (by proc files).
|
||||||
|
|
||||||
|
## proc file struce
|
||||||
|
|
||||||
|
```plain
|
||||||
|
+ /proc/kunity_test
|
||||||
|
+ <modulename>
|
||||||
|
- <modulename> -> read of this file, will be run all test case of this module
|
||||||
|
+ single_tests
|
||||||
|
- <test_name> -> read of this file, will be run the specific test case
|
||||||
|
```
|
||||||
|
|
||||||
|
## building module
|
||||||
|
|
||||||
|
### cmake
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ../
|
||||||
|
# cmake -DKERNEL_DIR=<path/to/kernel/module/build> ../
|
||||||
|
make
|
||||||
|
#load module by "insmod kunity_test_runner_module/kunity_test_runner_module.ko"
|
||||||
|
```
|
||||||
|
By default the `/lib/modules/${CMAKE_SYSTEM_VERSION}/build` path is use for the kernel build path. This path can be change by using the `KERNEL_DIR` option.
|
||||||
|
|
||||||
|
### KBuild
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make -C /lib/modules/<KernelVersion>/build M=${PWD} modules KBUILD_EXTRA_SYMBOLS=${PWD}/Module.symvers
|
||||||
|
#load module by "insmod kunity_test_runner_module.ko"
|
||||||
|
```
|
||||||
|
|
||||||
|
## execution
|
||||||
|
|
||||||
|
simple use `cat` on the proc file :) like : `cat /proc/kunity_test/my_module/single_tests/my_first_module_test`
|
||||||
|
|
||||||
|
## module parameter
|
||||||
|
|
||||||
|
* proc_test_root_folder_name - The name of the proc folder, which will contains the test proc files. (Default is "kunity_test")
|
||||||
|
* test_function_filter - a filter option for test function names, which the runner is looking for. (Default is "kunity_test_*")
|
||||||
|
* module_filter - a filter option for modules, which the runner is looking for test functions. (Default is * -> search in all modules)
|
||||||
Submodule dev-utility/CMake-Module/BuildKernelModule updated: fc86d1e5f7...0a8f42f26e
Submodule lib/KUnity updated: 30c7c93ef4...163455cd00
@@ -10,45 +10,22 @@
|
|||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
|
|
||||||
//}
|
//}
|
||||||
//{ local include region
|
|
||||||
|
//{ local function prototypes region
|
||||||
|
|
||||||
|
static int proc_test_file_open(/* in */ struct inode* inode, /* in */ struct file* file);
|
||||||
|
|
||||||
|
static int proc_test_file_show(/* in */ struct seq_file* m, /* in */ void* v);
|
||||||
|
|
||||||
|
static int proc_test_module_open(/* in */ struct inode* inode, /* in */ struct file* file);
|
||||||
|
|
||||||
|
static int proc_test_module_show(/* in */ struct seq_file* m, /* in */ void* v);
|
||||||
|
|
||||||
|
static void put_seq_char(/* in */ char letter);
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//{ local define region
|
//{ local variables region
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local enum region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local typedef region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{local struct region
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local function prototype region
|
|
||||||
|
|
||||||
static int proc_test_file_open(struct inode* inode, struct file* file);
|
|
||||||
static int proc_test_file_show(struct seq_file* m, void* v);
|
|
||||||
static int proc_test_module_open(struct inode* inode, struct file* file);
|
|
||||||
static int proc_test_module_show(struct seq_file* m, void* v);
|
|
||||||
static void put_seq_char(char letter);
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ global var implements region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local var implements region
|
|
||||||
|
|
||||||
static const struct file_operations proc_test_file_ops = {
|
static const struct file_operations proc_test_file_ops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
@@ -72,7 +49,7 @@ static struct seq_file* test_proc_file;
|
|||||||
|
|
||||||
//{ global function implements region
|
//{ global function implements region
|
||||||
|
|
||||||
result_code_e create_proc_test_structure(/* in */ struct proc_dir_entry * parent, /* in */const ptr_test_list_s test_list)
|
result_code_e create_proc_test_structure(/* in */ struct proc_dir_entry* parent, /* in */ const ptr_test_list_s test_list)
|
||||||
{
|
{
|
||||||
ptr_test_module_list_item_s module = NULL;
|
ptr_test_module_list_item_s module = NULL;
|
||||||
result_code_e result = OK;
|
result_code_e result = OK;
|
||||||
@@ -93,64 +70,61 @@ result_code_e create_proc_test_structure(/* in */ struct proc_dir_entry * parent
|
|||||||
|
|
||||||
list_for_each_entry(test_item, &module->test_list, test_head)
|
list_for_each_entry(test_item, &module->test_list, test_head)
|
||||||
{
|
{
|
||||||
pr_info("bla %s; %p", test_item->test->name, single_test_folder);
|
|
||||||
tmp_entry = proc_create_data(test_item->test->name, 0, single_test_folder, &proc_test_file_ops, test_item->test);
|
tmp_entry = proc_create_data(test_item->test->name, 0, single_test_folder, &proc_test_file_ops, test_item->test);
|
||||||
if (tmp_entry == NULL) {
|
if (tmp_entry == NULL) {
|
||||||
return ERROR_INVALID_OPERATION +1;
|
return ERROR_INVALID_OPERATION + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//{ local function implements region
|
//{ local function implements region
|
||||||
|
|
||||||
static void put_seq_char(char letter)
|
static void put_seq_char(/* in */ char letter)
|
||||||
{
|
{
|
||||||
seq_putc(test_proc_file, letter);
|
seq_putc(test_proc_file, letter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int proc_test_file_open(struct inode* inode, struct file* file)
|
static int proc_test_file_open(/* in */ struct inode* inode, /* in */ struct file* file)
|
||||||
{
|
{
|
||||||
return single_open(file, proc_test_file_show, NULL);
|
return single_open(file, proc_test_file_show, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int proc_test_module_open(struct inode* inode, struct file* file)
|
static int proc_test_module_open(/* in */ struct inode* inode, /* in */ struct file* file)
|
||||||
{
|
{
|
||||||
return single_open(file, proc_test_module_show, NULL);
|
return single_open(file, proc_test_module_show, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int proc_test_file_show(struct seq_file* m, void* v)
|
static int proc_test_file_show(/* in */ struct seq_file* seqfile, /* in */ void* data)
|
||||||
{
|
{
|
||||||
test_session_control_block_s output = { put_seq_char, 0, 0 };
|
test_session_control_block_s output = { put_seq_char, 0, 0 };
|
||||||
ptr_test_s tmp_test = PDE_DATA(file_inode(m->file));
|
ptr_test_s tmp_test = PDE_DATA(file_inode(seqfile->file));
|
||||||
if (tmp_test == NULL) {
|
if (tmp_test == NULL) {
|
||||||
return ERROR_INVALID_ARGUMENT;
|
return ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
test_proc_file = m;
|
test_proc_file = seqfile;
|
||||||
return tmp_test->test_function(&output);
|
return tmp_test->test_function(&output);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int proc_test_module_show(struct seq_file* m, void* v)
|
static int proc_test_module_show(/* in */ struct seq_file* seqfile, /* in */ void* data)
|
||||||
{
|
{
|
||||||
test_session_control_block_s output = { put_seq_char, 0, 1 };
|
test_session_control_block_s output = { put_seq_char, 0, 1 };
|
||||||
ptr_test_list_item_s tmp_test = NULL;
|
ptr_test_list_item_s tmp_test = NULL;
|
||||||
ptr_test_module_list_item_s tmp_module = PDE_DATA(file_inode(m->file));
|
ptr_test_module_list_item_s tmp_module = PDE_DATA(file_inode(seqfile->file));
|
||||||
if (tmp_module == NULL) {
|
if (tmp_module == NULL) {
|
||||||
return ERROR_INVALID_ARGUMENT;
|
return ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
test_proc_file = m;
|
test_proc_file = seqfile;
|
||||||
list_for_each_entry(tmp_test, &tmp_module->test_list, test_head)
|
list_for_each_entry(tmp_test, &tmp_module->test_list, test_head)
|
||||||
{
|
{
|
||||||
result_code_e result = OK;
|
result_code_e result = OK;
|
||||||
if(list_is_last(&tmp_test->test_head, &tmp_module->test_list)){
|
if (list_is_last(&tmp_test->test_head, &tmp_module->test_list)) {
|
||||||
output._skip_end = 0;
|
output._skip_end = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#ifndef KUNITY_PROC_TEST_FILE_HANDLER_H
|
#ifndef KUNITY_PROC_TEST_FILE_HANDLER_H
|
||||||
#define KUNITY_PROC_TEST_FILE_HANDLER_H
|
#define KUNITY_PROC_TEST_FILE_HANDLER_H
|
||||||
#include "kunity_proc_test_file_handler_t.h"
|
|
||||||
//{ global include region
|
//{ global include region
|
||||||
|
|
||||||
#include <linux/proc_fs.h>
|
#include <linux/proc_fs.h>
|
||||||
@@ -12,17 +12,10 @@
|
|||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//{ function region
|
//{ function region
|
||||||
|
|
||||||
extern result_code_e create_proc_test_structure(/* in */ struct proc_dir_entry * parent, /* in */const ptr_test_list_s test_list);
|
extern result_code_e create_proc_test_structure(/* in */ struct proc_dir_entry* parent, /* in */ const ptr_test_list_s test_list);
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // KUNITY_PROC_TEST_FILE_HANDLER_H
|
#endif // KUNITY_PROC_TEST_FILE_HANDLER_H
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
#ifndef KUNITY_PROC_TEST_FILE_HANDLER_T_H
|
|
||||||
#define KUNITY_PROC_TEST_FILE_HANDLER_T_H
|
|
||||||
|
|
||||||
//{ global include region
|
|
||||||
|
|
||||||
//}
|
|
||||||
//{ local include region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
//{ define region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
//{ enum region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
//{ typedef region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ struct region
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
#endif // KUNITY_PROC_TEST_FILE_HANDLER_T_H
|
|
||||||
@@ -9,31 +9,7 @@
|
|||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//{ local include region
|
//{ local function prototypes region
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local define region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local enum region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local typedef region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{local struct region
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local function prototype region
|
|
||||||
|
|
||||||
static result_code_e create_test(/* in */ const char* name, /* in */ const char* module_name, /* in */ const kunity_test_function_ptr test_function, /* out */ ptr_test_s* test_location);
|
static result_code_e create_test(/* in */ const char* name, /* in */ const char* module_name, /* in */ const kunity_test_function_ptr test_function, /* out */ ptr_test_s* test_location);
|
||||||
|
|
||||||
@@ -51,17 +27,13 @@ static result_code_e destroy_test_module(/* in */ const ptr_test_module_list_ite
|
|||||||
|
|
||||||
static result_code_e add_test_list_item(/* in */ ptr_test_list_item_s test_item, /* in */ ptr_test_list_s test_list, /* in */ struct module* module);
|
static result_code_e add_test_list_item(/* in */ ptr_test_list_item_s test_item, /* in */ ptr_test_list_s test_list, /* in */ struct module* module);
|
||||||
|
|
||||||
static int find_test_for_each(void* data, const char* namebuf, struct module* module, unsigned long address);
|
static int find_test_for_each(/* in */ void* data, /* in */ const char* namebuf, /* in */ struct module* module, /* in */ unsigned long address);
|
||||||
|
|
||||||
static result_code_e _add_test_list_item(/* in */ ptr_test_list_item_s test_item, /* in */ ptr_test_module_list_item_s test_module);
|
static result_code_e _add_test_list_item(/* in */ ptr_test_list_item_s test_item, /* in */ ptr_test_module_list_item_s test_module);
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//{ global variabel implements region
|
//{ local variables region
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local variabel implements region
|
|
||||||
|
|
||||||
static const size_t sizeof_test = sizeof(test_s);
|
static const size_t sizeof_test = sizeof(test_s);
|
||||||
|
|
||||||
@@ -266,7 +238,7 @@ static result_code_e add_test_list_item(/* in */ ptr_test_list_item_s test_item,
|
|||||||
return _add_test_list_item(test_item, it);
|
return _add_test_list_item(test_item, it);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int find_test_for_each(void* data, const char* namebuf, struct module* module, unsigned long address)
|
static int find_test_for_each(/* in */ void* data, /* in */ const char* namebuf, /* in */ struct module* module, /* in */ unsigned long address)
|
||||||
{
|
{
|
||||||
ptr_test_query_s query = NULL;
|
ptr_test_query_s query = NULL;
|
||||||
ptr_test_s test = NULL;
|
ptr_test_s test = NULL;
|
||||||
|
|||||||
@@ -1,16 +1,6 @@
|
|||||||
#ifndef KUNITY_TEST_FINDER_H
|
#ifndef KUNITY_TEST_FINDER_H
|
||||||
#define KUNITY_TEST_FINDER_H
|
#define KUNITY_TEST_FINDER_H
|
||||||
#include "kunity_test_finder_t.h"
|
#include "kunity_test_finder_t.h"
|
||||||
//{ global include region
|
|
||||||
|
|
||||||
//}
|
|
||||||
//{ local include region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//{ function region
|
//{ function region
|
||||||
|
|
||||||
@@ -20,7 +10,4 @@ extern result_code_e destroy_test_list(/* in */ ptr_test_list_s* test_list_locat
|
|||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // KUNITY_TEST_FINDER_H
|
#endif // KUNITY_TEST_FINDER_H
|
||||||
|
|||||||
@@ -10,10 +10,6 @@
|
|||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//{ local include region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ define region
|
//{ define region
|
||||||
#ifndef KUNITY_DEFAULT_TEST_NAME_FITER
|
#ifndef KUNITY_DEFAULT_TEST_NAME_FITER
|
||||||
#define KUNITY_DEFAULT_TEST_NAME_FITER KUNITY_DEFAULT_TEST_NAME_PREFIX*
|
#define KUNITY_DEFAULT_TEST_NAME_FITER KUNITY_DEFAULT_TEST_NAME_PREFIX*
|
||||||
@@ -26,14 +22,6 @@
|
|||||||
#endif
|
#endif
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//{ enum region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ typedef region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ struct region
|
//{ struct region
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
@@ -45,10 +33,9 @@ typedef struct test_list_item_sTag {
|
|||||||
ptr_test_s test;
|
ptr_test_s test;
|
||||||
} test_list_item_s, *ptr_test_list_item_s;
|
} test_list_item_s, *ptr_test_list_item_s;
|
||||||
|
|
||||||
|
|
||||||
typedef struct test_module_list_item_sTag {
|
typedef struct test_module_list_item_sTag {
|
||||||
struct list_head test_module_head;
|
struct list_head test_module_head;
|
||||||
const struct module * test_module;
|
const struct module* test_module;
|
||||||
struct list_head test_list;
|
struct list_head test_list;
|
||||||
} test_module_list_item_s, *ptr_test_module_list_item_s;
|
} test_module_list_item_s, *ptr_test_module_list_item_s;
|
||||||
|
|
||||||
@@ -62,9 +49,9 @@ typedef struct test_query_sTag {
|
|||||||
ptr_test_list_s result_list;
|
ptr_test_list_s result_list;
|
||||||
} test_query_s, *ptr_test_query_s;
|
} test_query_s, *ptr_test_query_s;
|
||||||
|
|
||||||
typedef result_code_e (*test_list_iterator) (/* in */ const ptr_test_list_item_s);
|
typedef result_code_e (*test_list_iterator)(/* in */ const ptr_test_list_item_s);
|
||||||
|
|
||||||
typedef result_code_e (*test_module_list_iterator) (/* in */ const ptr_test_module_list_item_s);
|
typedef result_code_e (*test_module_list_iterator)(/* in */ const ptr_test_module_list_item_s);
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <kunity_t.h>
|
#include <kunity_t.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
//}
|
//}
|
||||||
@@ -13,71 +14,101 @@
|
|||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//{ local define region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local enum region
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local typedef region
|
//{ local typedef region
|
||||||
|
|
||||||
//}
|
typedef struct runner_control_block_sTag {
|
||||||
|
const char* proc_folder_name;
|
||||||
//{local struct region
|
struct proc_dir_entry* proc_test_root;
|
||||||
|
test_query_s query;
|
||||||
#pragma pack(push, 1)
|
} runner_control_block_s, *ptr_runner_control_blocks;
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//{ local function prototype region
|
//{ local function prototypes region
|
||||||
|
|
||||||
|
static void init_tests(/* in */ struct work_struct* work);
|
||||||
|
|
||||||
|
static void clean_tests(void);
|
||||||
|
|
||||||
static void init_tests(struct work_struct* work);
|
|
||||||
static int kunity_init(void);
|
static int kunity_init(void);
|
||||||
|
|
||||||
static void kunity_exit(void);
|
static void kunity_exit(void);
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//{ global variabel implements region
|
//{ local variables region
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{ local variabel implements region
|
|
||||||
|
|
||||||
static struct workqueue_struct* queue;
|
static struct workqueue_struct* queue;
|
||||||
|
|
||||||
DECLARE_WORK(work, init_tests);
|
DECLARE_WORK(work, init_tests);
|
||||||
|
|
||||||
static test_query_s query = { KUNITY_DEFAULT_TEST_NAME_FITER_STR, "*" };
|
static char* module_filter = "*";
|
||||||
|
module_param(module_filter, charp, 0);
|
||||||
|
MODULE_PARM_DESC(module_filter, "a filter option for modules, which the runner is looking for test functions. (Default is \"*\"");
|
||||||
|
|
||||||
static struct proc_dir_entry* proc_test_root = NULL;
|
static char* test_function_filter = KUNITY_DEFAULT_TEST_NAME_FITER_STR;
|
||||||
//}
|
module_param(test_function_filter, charp, 0);
|
||||||
|
MODULE_PARM_DESC(test_function_filter, "a filter option for test function names, which the runner is looking for. (Default is \"kunity_test_*\"");
|
||||||
|
|
||||||
//{ global function implements region
|
static char* proc_test_root_folder_name = "kunity_test";
|
||||||
|
module_param(proc_test_root_folder_name, charp, 0);
|
||||||
|
MODULE_PARM_DESC(proc_test_root_folder_name, "the name of the proc folder, which will contains the test proc files. (Default is \"kunity_test\"");
|
||||||
|
|
||||||
|
static const size_t sizeof_runner_control_block = sizeof(runner_control_block_s);
|
||||||
|
|
||||||
|
static runner_control_block_s* rcb = NULL;
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//{ local function implements region
|
//{ local function implements region
|
||||||
|
|
||||||
static void init_tests(struct work_struct* work)
|
static void clean_tests()
|
||||||
{
|
{
|
||||||
pr_info("init tests");
|
destroy_test_list(&rcb->query.result_list);
|
||||||
proc_test_root = proc_mkdir("kunity_test", NULL);
|
if (rcb->proc_test_root != NULL) {
|
||||||
if (proc_test_root == NULL || find_tests(&query) != OK) {
|
proc_remove(rcb->proc_test_root);
|
||||||
|
}
|
||||||
|
|
||||||
|
kzfree(rcb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_tests(/* in */ struct work_struct* work)
|
||||||
|
{
|
||||||
|
result_code_e result = OK;
|
||||||
|
if (rcb != NULL) {
|
||||||
|
clean_tests();
|
||||||
|
}
|
||||||
|
|
||||||
|
rcb = kzalloc(sizeof(runner_control_block_s), GFP_KERNEL);
|
||||||
|
rcb->query.test_function_filter = test_function_filter;
|
||||||
|
rcb->query.module_filter = module_filter;
|
||||||
|
rcb->proc_folder_name = proc_test_root_folder_name;
|
||||||
|
rcb->proc_test_root = proc_mkdir(rcb->proc_folder_name, NULL);
|
||||||
|
if (rcb->proc_test_root == NULL) {
|
||||||
|
pr_warning("cant create proc folder %s", rcb->proc_folder_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
create_proc_test_structure(proc_test_root, query.result_list);
|
result = find_tests(&rcb->query);
|
||||||
|
if (result == OK) {
|
||||||
|
result = create_proc_test_structure(rcb->proc_test_root, rcb->query.result_list);
|
||||||
|
if (result == OK) {
|
||||||
|
pr_info("successful created tests with following options:");
|
||||||
|
} else {
|
||||||
|
pr_info("test creation failed with error code %u, following options was used:", result);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pr_info("could not find any test with follwing options:");
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_info("\tmodule_filter = \"%s\"", rcb->query.module_filter);
|
||||||
|
pr_info("\ttest_function_filter = \"%s\"", rcb->query.test_function_filter);
|
||||||
|
pr_info("\tproc_folder_name = \"%s\"", rcb->proc_folder_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kunity_init()
|
static int kunity_init()
|
||||||
{
|
{
|
||||||
pr_info("init kunity_test_runner_module");
|
pr_info("init %s", THIS_MODULE->name);
|
||||||
queue = create_workqueue("test_runner_work_queue");
|
queue = create_workqueue("test_runner_work_queue");
|
||||||
if (queue == NULL) {
|
if (queue == NULL) {
|
||||||
return -ERROR_INVALID_OPERATION;
|
return -ERROR_INVALID_OPERATION;
|
||||||
@@ -88,14 +119,17 @@ static int kunity_init()
|
|||||||
|
|
||||||
static void kunity_exit()
|
static void kunity_exit()
|
||||||
{
|
{
|
||||||
pr_info("exit kunity_test_runner_module");
|
pr_info("exit %s", THIS_MODULE->name);
|
||||||
if (queue == NULL) {
|
if (queue == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy_workqueue(queue);
|
destroy_workqueue(queue);
|
||||||
destroy_test_list(&query.result_list);
|
if (rcb == NULL) {
|
||||||
proc_remove(proc_test_root);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clean_tests();
|
||||||
}
|
}
|
||||||
|
|
||||||
//}
|
//}
|
||||||
@@ -104,4 +138,4 @@ module_init(kunity_init);
|
|||||||
module_exit(kunity_exit);
|
module_exit(kunity_exit);
|
||||||
MODULE_AUTHOR("Felix Stubbe");
|
MODULE_AUTHOR("Felix Stubbe");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_DESCRIPTION("run tests");
|
MODULE_DESCRIPTION("run kunity tests");
|
||||||
|
|||||||
Reference in New Issue
Block a user