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/src/args.c | 134 +++++++++++++++++++++++++++++++++++++ userspace/src/exec.c | 90 +++++++++++++++++++++++++ userspace/src/io.c | 105 +++++++++++++++++++++++++++++ userspace/src/module.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++ userspace/src/nvgpu.c | 78 ++++++++++++++++++++++ userspace/src/results.c | 128 +++++++++++++++++++++++++++++++++++ userspace/src/unit_main.c | 76 +++++++++++++++++++++ 7 files changed, 778 insertions(+) create mode 100644 userspace/src/args.c create mode 100644 userspace/src/exec.c create mode 100644 userspace/src/io.c create mode 100644 userspace/src/module.c create mode 100644 userspace/src/nvgpu.c create mode 100644 userspace/src/results.c create mode 100644 userspace/src/unit_main.c (limited to 'userspace/src') diff --git a/userspace/src/args.c b/userspace/src/args.c new file mode 100644 index 00000000..d91c6f6e --- /dev/null +++ b/userspace/src/args.c @@ -0,0 +1,134 @@ +/* + * 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. + */ + +#include +#include +#include +#include + +#include +#include +#include + +static struct option core_opts[] = { + { "help", 0, NULL, 'h' }, + { "verbose", 0, NULL, 'v' }, + { "quiet", 0, NULL, 'q' }, + { "no-color", 0, NULL, 'C' }, + + { "unit-load-path", 1, NULL, 'L' }, + + { NULL, 0, NULL, 0 } +}; + +static const char *core_opts_str = "hvqCL:"; + +void core_print_help(struct unit_fw *fw) +{ + const char **line, *help_msg[] = { +"NvGpu Unit Testing FW. Basic usage\n", +"\n", +" $ nvgpu_unit [options] \n", +"\n", +"Basic usage consists of one or more options and a particular unit test to\n", +"execute.\n", +"\n", +"Available options are as follows:\n", +"\n", +" -h, --help Print this help message and exit.\n", +" -v, --verbose Increment the verbosity level. Can be specified\n", +" multiple times.\n", +" -q, --quiet Set the verbose level back to 0.\n", +" -C, --no-color Disable color printing; for example, if writing\n", +" output to a file the color escape sequences will\n", +" corrupt that file.\n", +" -L, --unit-load-path \n", +" Path to where the unit test libraries reside.\n", +"\n", +"Note: mandatory arguments to long arguments are mandatory for short\n", +"arguments as well.\n", +NULL + }; + + line = help_msg; + while (*line != NULL) { + core_msg(fw, "%s", *line); + line++; + } +} + +static void set_arg_defaults(struct unit_fw_args *args) +{ + args->unit_load_path = DEFAULT_ARG_UNIT_LOAD_PATH; +} + +/* + * Parse command line arguments. + */ +int core_parse_args(struct unit_fw *fw, int argc, char **argv) +{ + int c, opt_index; + struct unit_fw_args *args; + + args = malloc(sizeof(*args)); + if (!args) + return -1; + + memset(args, 0, sizeof(*args)); + set_arg_defaults(args); + + fw->args = args; + + while (1) { + c = getopt_long(argc, argv, + core_opts_str, core_opts, &opt_index); + + if (c == -1) + break; + + switch (c) { + case 'h': + args->help = true; + break; + case 'v': + args->verbose_lvl += 1; + break; + case 'q': + args->verbose_lvl = 0; + break; + case 'C': + args->no_color = true; + break; + case 'L': + args->unit_load_path = optarg; + break; + case '?': + args->help = true; + return -1; + default: + core_err(fw, "bug?!\n"); + return -1; + } + } + + return 0; +} diff --git a/userspace/src/exec.c b/userspace/src/exec.c new file mode 100644 index 00000000..b9ba1336 --- /dev/null +++ b/userspace/src/exec.c @@ -0,0 +1,90 @@ +/* + * 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. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +/* + * Execute a module and all its subtests. This function builds a gk20a for the + * test to use by executing nvgpu_posix_probe() and nvgpu_posix_cleanup(); + */ +static int core_exec_module(struct unit_fw *fw, + struct unit_module *module) +{ + unsigned int i; + struct gk20a *g = fw->nvgpu.nvgpu_posix_probe(); + + if (!g) + return -1; + + core_vbs(fw, 1, "Execing module: %s\n", module->name); + + /* + * Execute each test within the module. No reinit is done between tests. + * Thats up to the module itself to handle. Any setup/teardown between + * unit tests must be handled within the module. + */ + for (i = 0; i < module->nr_tests; i++) { + struct unit_module_test *t = module->tests + i; + int test_status; + + core_msg(fw, "Running %s.%s\n", module->name, t->name); + test_status = t->fn(module, g, t->args); + + if (test_status != UNIT_SUCCESS) + core_msg_color(fw, C_RED, + " Unit error! Test %s.%s FAILED!\n", + module->name, t->name); + + core_add_test_record(fw, module, t, + test_status == UNIT_SUCCESS); + } + + fw->nvgpu.nvgpu_posix_cleanup(g); + + return 0; +} + +/* + * Execute all modules loaded by the unit test framework. + */ +int core_exec(struct unit_fw *fw) +{ + int ret; + struct unit_module **modules; + + for (modules = fw->modules; *modules != NULL; modules++) { + ret = core_exec_module(fw, *modules); + + if (ret != 0) + return ret; + } + + return 0; +} diff --git a/userspace/src/io.c b/userspace/src/io.c new file mode 100644 index 00000000..21ac54da --- /dev/null +++ b/userspace/src/io.c @@ -0,0 +1,105 @@ +/* + * 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. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#define MAX_LOG_LINE_LENGTH 4096 + +static void __core_print_file(struct unit_fw *fw, FILE *filp, + const char *prefix, const char *msg, + const char *color) +{ + if (color == NULL || args(fw)->no_color) + color = ""; + + fprintf(filp, "[%s%s%s] %s%s%s", + color, prefix, C_RESET, + color, msg, C_RESET); +} + +__attribute__((format (printf, 3, 4))) +void __core_print_stdout(struct unit_fw *fw, const char *color, + const char *fmt, ...) +{ + va_list args; + char buf[MAX_LOG_LINE_LENGTH]; + + va_start(args, fmt); + vsnprintf(buf, MAX_LOG_LINE_LENGTH, fmt, args); + va_end(args); + + buf[MAX_LOG_LINE_LENGTH - 1] = 0; + + __core_print_file(fw, stdout, "C", buf, color); +} + +__attribute__((format (printf, 2, 3))) +void __core_print_stderr(struct unit_fw *fw, const char *fmt, ...) +{ + va_list args; + char buf[MAX_LOG_LINE_LENGTH]; + + va_start(args, fmt); + vsnprintf(buf, MAX_LOG_LINE_LENGTH, fmt, args); + va_end(args); + + buf[MAX_LOG_LINE_LENGTH - 1] = 0; + + __core_print_file(fw, stdout, "E", buf, C_RED); +} + +__attribute__((format (printf, 3, 4))) +void __unit_info_color(struct unit_module *unit, const char *color, + const char *fmt, ...) +{ + va_list args; + char buf[MAX_LOG_LINE_LENGTH]; + char *msg_start; + int written; + + /* + * Default color for module prints is blue. Users can still turn this + * off with '-C'. + */ + if (color == NULL) + color = C_BLUE; + + /* + * First prepend the unit name to the print. + */ + written = snprintf(buf, MAX_LOG_LINE_LENGTH, " [%s] ", unit->name); + + msg_start = buf + written; + + va_start(args, fmt); + vsnprintf(msg_start, MAX_LOG_LINE_LENGTH - written, fmt, args); + va_end(args); + + __core_print_file(unit->fw, stdout, "T", buf, color); +} diff --git a/userspace/src/module.c b/userspace/src/module.c new file mode 100644 index 00000000..c111c6cb --- /dev/null +++ b/userspace/src/module.c @@ -0,0 +1,167 @@ +/* + * 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. + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +static int check_module(struct unit_fw *fw, struct unit_module *mod) +{ + unsigned int i; + + /* + * Make sure this module has reasonable data. + */ + if (mod->name == NULL) { + core_err(fw, "Unnamed module!"); + return -1; + } + + if (mod->tests == NULL || mod->nr_tests == 0) { + core_err(fw, "%s: Empty module!\n", mod->name); + return -1; + } + + for (i = 0; i < mod->nr_tests; i++) { + struct unit_module_test *test = &mod->tests[i]; + + if (test->name == NULL) { + core_err(fw, "%s: Unnamed test\n", mod->name); + return -1; + } + + if (test->fn == NULL) { + core_err(fw, "%s: Test %s missing function \n", + mod->name, test->name); + return -1; + } + } + + return 0; +} + +static struct unit_module *load_one_module(struct unit_fw *fw, + struct dirent *dent) +{ + void *lib_handle; + struct unit_module *mod; + + core_vbs(fw, 1, "Loading: %s\n", dent->d_name); + + lib_handle = dlopen(dent->d_name, RTLD_NOW); + if (lib_handle == NULL) { + core_err(fw, "Failed to load %s: %s\n", + dent->d_name, dlerror()); + return NULL; + } + + mod = dlsym(lib_handle, "__unit_module__"); + if (mod == NULL) { + core_vbs(fw, 1, + "Failed to resolve __unit_module__ in %s: %s\n", + dent->d_name, dlerror()); + return NULL; + } + + mod->lib_handle = lib_handle; + mod->fw = fw; + + core_vbs(fw, 1, " '%s' contains %lu tests\n", mod->name, mod->nr_tests); + + return mod; +} + +/* + * Load all the modules we can from the module load path. Return the list of + * loaded module as an array of pointers to modules. The returned list of + * modules is NULL terminated. + */ +struct unit_module **core_load_modules(struct unit_fw *fw) +{ + int nr_modules = 0, i; + DIR *load_dir; + struct dirent *ent; + const char *load_path = args(fw)->unit_load_path; + struct unit_module **modules, *mod; + + core_vbs(fw, 1, "Loading modules from %s\n", load_path); + + /* + * Open and count the number of files in the dir. + */ + load_dir = opendir(load_path); + if (!load_dir) { + core_err(fw, "%s: Unable to open dir (%s)\n", + load_path, strerror(errno)); + return NULL; + } + + while (readdir(load_dir) != NULL) + nr_modules += 1; + + /* '.' and '..' should be skipped. */ + nr_modules -= 2; + + /* + * Now allocate necessary space for storing pointers to the modules and + * load the modules. +1 for the last NULL entry. + */ + modules = malloc(sizeof(*modules) * (nr_modules + 1)); + if (!modules) { + core_err(fw, "Out of mem! (huh?)\n"); + goto err; + } + + rewinddir(load_dir); + i = 0; + while ((ent = readdir(load_dir)) != NULL) { + if (strcmp(".", ent->d_name) == 0 || + strcmp("..", ent->d_name) == 0) + continue; + + mod = load_one_module(fw, ent); + if (mod == NULL) + continue; + + if (check_module(fw, mod) != 0) + continue; + + modules[i] = mod; + i++; + } + + modules[i] = NULL; + return modules; + +err: + closedir(load_dir); + return NULL; +} diff --git a/userspace/src/nvgpu.c b/userspace/src/nvgpu.c new file mode 100644 index 00000000..a9b7ced3 --- /dev/null +++ b/userspace/src/nvgpu.c @@ -0,0 +1,78 @@ +/* + * 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. + */ + +#include +#include + +#include +#include + +/* + * Load libnvgpu-drv.so. This is done with dlopen() since this will make + * resolving addresses into symbols easier in the future. + * + * Also, this makes people think carefully about what functions to call in + * nvgpu-drv from the unit test FW. The interaction should really be limited + * and doing explicit name lookups is a good way to prevent too much coupling. + */ +int core_load_nvgpu(struct unit_fw *fw) +{ + const char *msg; + + /* + * Specify a GLOBAL binding so that subsequently loaded unit tests see + * the nvgpu-drv library. They will of course need it (and will access + * it directly). I.e they will link against nvgpu-drv and this should + * satisfy that linkage. + */ + fw->nvgpu_so = dlopen("libnvgpu-drv.so", RTLD_NOW | RTLD_GLOBAL); + + if (fw->nvgpu_so == NULL) { + msg = dlerror(); + core_err(fw, "Failed to load nvgpu-drv: %s\n", msg); + return -1; + } + + /* + * We directly check the value of the returned symbol for these + * functions against NULL because if it is NULL then something is + * terribly wrong. + */ + + fw->nvgpu.nvgpu_posix_probe = dlsym(fw->nvgpu_so, + "nvgpu_posix_probe"); + if (fw->nvgpu.nvgpu_posix_probe == NULL) { + msg = dlerror(); + core_err(fw, "Failed to resolve nvgpu_posix_probe: %s\n", msg); + return -1; + } + + fw->nvgpu.nvgpu_posix_cleanup = dlsym(fw->nvgpu_so, + "nvgpu_posix_cleanup"); + if (fw->nvgpu.nvgpu_posix_cleanup == NULL) { + msg = dlerror(); + core_err(fw, "Failed to resolve nvgpu_posix_cleanup: %s\n", msg); + return -1; + } + + return 0; +} diff --git a/userspace/src/results.c b/userspace/src/results.c new file mode 100644 index 00000000..ae077b82 --- /dev/null +++ b/userspace/src/results.c @@ -0,0 +1,128 @@ +/* + * 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. + */ + +#include +#include + +#include +#include +#include +#include + +static int __init_results(struct unit_fw *fw) +{ + struct unit_results *results; + + if (fw->results != NULL) + return 0; + + results = malloc(sizeof(*results)); + if (results == NULL) + return -1; + + memset(results, 0, sizeof(*results)); + + fw->results = results; + + return 0; +} + +static void add_record(struct unit_test_list *list, + struct unit_test_record *tr) +{ + /* + * First entry. + */ + if (list->head == NULL) { + list->head = tr; + list->last = tr; + return; + } + + /* + * Add to the end of the list and update the pointer to the last entry + * in the list. This gives us O(1) add time. + */ + list->last->next = tr; + list->last = tr; +} + +int core_add_test_record(struct unit_fw *fw, + struct unit_module *mod, + struct unit_module_test *test, + bool success) +{ + struct unit_test_record *tr; + + /* + * Dones nothing if results are already inited. + */ + if (__init_results(fw) != 0) + return -1; + + tr = malloc(sizeof(*tr)); + if (tr == NULL) + return -1; + + tr->mod = mod; + tr->test = test; + tr->status = success; + tr->next = NULL; + + if (success) + add_record(&fw->results->passing, tr); + else + add_record(&fw->results->failing, tr); + + fw->results->nr_tests += 1; + if (success) + fw->results->nr_passing += 1; + + return 0; +} + +void core_print_test_status(struct unit_fw *fw) +{ + struct unit_test_list *failing_tests = &fw->results->failing; + struct unit_test_record *rec; + + /* + * Print stats for the tests. + */ + core_msg(fw, "\n"); + core_msg(fw, "Test results:\n"); + core_msg(fw, "-------------\n"); + core_msg(fw, "\n"); + core_msg(fw, " Passing: %d\n", fw->results->nr_passing); + core_msg(fw, " Failing: %d\n", + fw->results->nr_tests - fw->results->nr_passing); + core_msg(fw, " Total: %d\n", fw->results->nr_tests); + core_msg(fw, "\n"); + core_msg(fw, "Failing tests:\n"); + core_msg(fw, "\n"); + + for_record_in_test_list(failing_tests, rec) { + core_msg(fw, " %s.%s\n", + rec->mod->name, + rec->test->name); + } +} diff --git a/userspace/src/unit_main.c b/userspace/src/unit_main.c new file mode 100644 index 00000000..31c31d50 --- /dev/null +++ b/userspace/src/unit_main.c @@ -0,0 +1,76 @@ +/* + * 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. + */ + +/** + * NvGpu unit testing framework! + */ + +#include +#include + +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + struct unit_fw *fw; + int ret; + + fw = malloc(sizeof(*fw)); + if (!fw) + return 1; + + memset(fw, 0, sizeof(*fw)); + + ret = core_parse_args(fw, argc, argv); + if (ret) { + core_err(fw, "Enable to parse args.\n"); + core_err(fw, "Exiting!\n"); + return 1; + } + + core_vbs(fw, 1, "Welcome to the nvgpu unit testing framework!\n"); + + if (args(fw)->help) { + core_print_help(fw); + return 1; + } + + ret = core_load_nvgpu(fw); + if (ret != 0) + return ret; + + fw->modules = core_load_modules(fw); + if (fw->modules == NULL) + return -1; + + ret = core_exec(fw); + if (ret != 0) + return ret; + + core_print_test_status(fw); + + return 0; +} -- cgit v1.2.2