From 691bf904451bfe2e4c44ea05319149996abbbbf1 Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Wed, 27 Jun 2018 14:45:07 -0700 Subject: gpu: nvgpu: unit: Add unit testing FW Full documentation for this is in the unit testing confluence page. JIRA NVGPU-525 Bug 2261555 Change-Id: I463e6267eb0eb12b7313f8b275266e8faabe5ccf Signed-off-by: Alex Waterman Reviewed-on: https://git-master.nvidia.com/r/1683915 GVS: Gerrit_Virtual_Submit Reviewed-by: Konsta Holtta Reviewed-by: Terje Bergstrom Reviewed-by: mobile promotions Tested-by: mobile promotions --- userspace/include/unit/args.h | 58 +++++++++++++++++++++++ userspace/include/unit/core.h | 63 ++++++++++++++++++++++++ userspace/include/unit/io.h | 88 ++++++++++++++++++++++++++++++++++ userspace/include/unit/module.h | 31 ++++++++++++ userspace/include/unit/results.h | 70 +++++++++++++++++++++++++++ userspace/include/unit/unit.h | 100 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 410 insertions(+) create mode 100644 userspace/include/unit/args.h create mode 100644 userspace/include/unit/core.h create mode 100644 userspace/include/unit/io.h create mode 100644 userspace/include/unit/module.h create mode 100644 userspace/include/unit/results.h create mode 100644 userspace/include/unit/unit.h (limited to 'userspace/include/unit') diff --git a/userspace/include/unit/args.h b/userspace/include/unit/args.h new file mode 100644 index 00000000..def84a29 --- /dev/null +++ b/userspace/include/unit/args.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __UNIT_ARGS_H__ +#define __UNIT_ARGS_H__ + +#include + +/* + * Allow defaults to be changed at compile time. + */ +#define __stringify(x) #x +#define stringify(x) __stringify(x) + +#ifndef __DEFAULT_ARG_UNIT_LOAD_PATH +#define __DEFAULT_ARG_UNIT_LOAD_PATH build/units +#endif +#define DEFAULT_ARG_UNIT_LOAD_PATH stringify(__DEFAULT_ARG_UNIT_LOAD_PATH) + +struct unit_fw; + +struct unit_fw_args { + bool help; + int verbose_lvl; + bool no_color; + + const char *unit_name; + const char *unit_load_path; +}; + +int core_parse_args(struct unit_fw *fw, int argc, char **argv); +void core_print_help(struct unit_fw *fw); + +/* + * Convenience for getting the args struct pointer. + */ +#define args(fw) ((fw)->args) + +#endif diff --git a/userspace/include/unit/core.h b/userspace/include/unit/core.h new file mode 100644 index 00000000..d9d119db --- /dev/null +++ b/userspace/include/unit/core.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __UNIT_CORE_H__ +#define __UNIT_CORE_H__ + +struct unit_fw_args; +struct unit_modules; +struct unit_results; + +struct gk20a; + +/* + * The core unit testing framework data structure. Keeps track of global state + * for the unit test app. + */ +struct unit_fw { + struct unit_fw_args *args; + + struct unit_module **modules; + + struct unit_results *results; + + /* + * nvgpu-drv interface. Currently the only two directly referenced + * functions are: + * + * nvgpu_posix_probe() + * nvgpu_posix_cleanup() + * + * There will get populated so that we can call them before/after each + * module. + */ + void *nvgpu_so; + struct { + struct gk20a *(*nvgpu_posix_probe)(void); + void (*nvgpu_posix_cleanup)(struct gk20a *g); + } nvgpu; +}; + +int core_load_nvgpu(struct unit_fw *fw); +int core_exec(struct unit_fw *fw); + +#endif diff --git a/userspace/include/unit/io.h b/userspace/include/unit/io.h new file mode 100644 index 00000000..1fd0fa43 --- /dev/null +++ b/userspace/include/unit/io.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __UNIT_IO_H__ +#define __UNIT_IO_H__ + +struct unit_fw; +struct unit_module; + +/* + * necessary for args(fw) macro. IO will always, in general, depend on args + * since the args will specify where IO should be directed to. + */ +#include + +#define core_msg(fw, msg, ...) \ + core_vbs(fw, 0, msg, ##__VA_ARGS__) +#define core_msg_color(fw, color, msg, ...) \ + core_vbs_color(fw, color, 0, msg, ##__VA_ARGS__) + +#define core_vbs_color(fw, color, lvl, msg, ...) \ + do { \ + if ((lvl) > args(fw)->verbose_lvl) \ + continue; \ + \ + /* Print if verbosity level is high enough. */ \ + __core_print_stdout(fw, color, msg, ##__VA_ARGS__); \ + } while (0) +#define core_vbs(fw, lvl, msg, ...) \ + core_vbs_color(fw, NULL, lvl, msg, ##__VA_ARGS__) + +#define core_err(fw, msg, ...) \ + __core_print_stderr(fw, "(%s:%d) " msg, \ + __func__, __LINE__, ##__VA_ARGS__) + +/* + * Output macro for unit tests to use. + */ +#define unit_info(unit, msg, ...) \ + __unit_info_color(unit, NULL, msg, ##__VA_ARGS__) +#define unit_err(unit, msg, ...) \ + __unit_info_color(unit, C_RED, msg, ##__VA_ARGS__) + +/* + * Don't go overboard with these!!! + */ +#define C_RED "\x1B[31m" +#define C_GREEN "\x1B[32m" +#define C_YELLOW "\x1B[33m" +#define C_BLUE "\x1B[34m" +#define C_MAGENTA "\x1B[35m" +#define C_CYAN "\x1B[36m" +#define C_WHITE "\x1B[37m" +#define C_RESET "\x1B[0m" + +/* + * Printing functions. Do not use these directly. Instead use the provided + * macros. + */ +__attribute__((format (printf, 3, 4))) +void __core_print_stdout(struct unit_fw *fw, const char *color, + const char *fmt, ...); +__attribute__((format (printf, 2, 3))) +void __core_print_stderr(struct unit_fw *fw, const char *fmt, ...); +__attribute__((format (printf, 3, 4))) +void __unit_info_color(struct unit_module *unit, const char *color, + const char *fmt, ...); + +#endif diff --git a/userspace/include/unit/module.h b/userspace/include/unit/module.h new file mode 100644 index 00000000..79737d61 --- /dev/null +++ b/userspace/include/unit/module.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __UNIT_MODULE_H__ +#define __UNIT_MODULE_H__ + +struct unit_fw; +struct unit_module; + +struct unit_module **core_load_modules(struct unit_fw *fw); + +#endif diff --git a/userspace/include/unit/results.h b/userspace/include/unit/results.h new file mode 100644 index 00000000..fb88e59d --- /dev/null +++ b/userspace/include/unit/results.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __UNIT_RESULTS_H__ +#define __UNIT_RESULTS_H__ + +/* + * Keep track of the the results of a set of unit tests. This is effectively + * just a single linked list of records for each test. + */ + +struct unit_test_record { + /* + * Let's us determine the name of the test. + */ + struct unit_module *mod; + struct unit_module_test *test; + + /* + * True for pass, false for fail. + */ + bool status; + + struct unit_test_record *next; +}; + +struct unit_test_list { + struct unit_test_record *head; + struct unit_test_record *last; +}; + +struct unit_results { + struct unit_test_list passing; + struct unit_test_list failing; + + int nr_tests; + int nr_passing; +}; + +#define for_record_in_test_list(__test_list, __test) \ + for ((__test) = (__test_list)->head; \ + (__test) != NULL; \ + (__test) = (__test)->next) + +int core_add_test_record(struct unit_fw *fw, + struct unit_module *mod, + struct unit_module_test *test, + bool success); +void core_print_test_status(struct unit_fw *fw); + +#endif diff --git a/userspace/include/unit/unit.h b/userspace/include/unit/unit.h new file mode 100644 index 00000000..9438d4d9 --- /dev/null +++ b/userspace/include/unit/unit.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __UNIT_UNIT_H__ +#define __UNIT_UNIT_H__ + +struct gk20a; + +struct unit_module; +typedef int (*module_test_fn)(struct unit_module *m, + struct gk20a *g, void *args); + +#define UNIT_SUCCESS 0 +#define UNIT_FAIL -1 + +struct unit_module_test { + /* + * Name of the test. + */ + const char *name; + + /* + * Function to call to execute the test. + */ + module_test_fn fn; + + /* + * A void pointer to arbitrary arguments. Lets the same unit test + * function perform multiple tests. This gets passed into the + * module_test_fn as @args. + */ + void *args; +}; + +/* + * Interface to the unit test framework module loader. Each unit test module + * will have exactly one of these. + */ +struct unit_module { + /* + * Name of the module. + */ + const char *name; + + /* + * NULL terminated list of tests within the module. + */ + struct unit_module_test *tests; + unsigned long nr_tests; + + /* + * For the core FW to use. Not for modules!!! + */ + void *lib_handle; + struct unit_fw *fw; +}; + +#define UNIT_MODULE(__name, __tests) \ + struct unit_module __unit_module__ = { \ + .name = #__name, \ + .tests = __tests, \ + .nr_tests = (sizeof(__tests) / \ + sizeof(struct unit_module_test)), \ + .lib_handle = NULL, \ + } + +#define UNIT_TEST(__name, __fn, __args) \ + { \ + .name = #__name, \ + .fn = __fn, \ + .args = __args, \ + } + +#define unit_return_fail(m, msg, ...) \ + do { \ + unit_err(m, "%s():%d " msg, \ + __func__, __LINE__, ##__VA_ARGS__); \ + return UNIT_FAIL; \ + } while (0) + +#endif -- cgit v1.2.2