summaryrefslogtreecommitdiffstats
path: root/userspace/src
diff options
context:
space:
mode:
authorAlex Waterman <alexw@nvidia.com>2018-06-27 17:45:07 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-08-10 02:11:06 -0400
commit691bf904451bfe2e4c44ea05319149996abbbbf1 (patch)
tree0fe66bd37989f9d619234b7f4d2be1df6ed61c85 /userspace/src
parent6e746a97cc7ee2bc5a3adee04dd9c65b3921eee5 (diff)
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 <alexw@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1683915 GVS: Gerrit_Virtual_Submit Reviewed-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'userspace/src')
-rw-r--r--userspace/src/args.c134
-rw-r--r--userspace/src/exec.c90
-rw-r--r--userspace/src/io.c105
-rw-r--r--userspace/src/module.c167
-rw-r--r--userspace/src/nvgpu.c78
-rw-r--r--userspace/src/results.c128
-rw-r--r--userspace/src/unit_main.c76
7 files changed, 778 insertions, 0 deletions
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 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <stdio.h>
24#include <getopt.h>
25#include <stdlib.h>
26#include <string.h>
27
28#include <unit/core.h>
29#include <unit/args.h>
30#include <unit/io.h>
31
32static struct option core_opts[] = {
33 { "help", 0, NULL, 'h' },
34 { "verbose", 0, NULL, 'v' },
35 { "quiet", 0, NULL, 'q' },
36 { "no-color", 0, NULL, 'C' },
37
38 { "unit-load-path", 1, NULL, 'L' },
39
40 { NULL, 0, NULL, 0 }
41};
42
43static const char *core_opts_str = "hvqCL:";
44
45void core_print_help(struct unit_fw *fw)
46{
47 const char **line, *help_msg[] = {
48"NvGpu Unit Testing FW. Basic usage\n",
49"\n",
50" $ nvgpu_unit [options] <unit>\n",
51"\n",
52"Basic usage consists of one or more options and a particular unit test to\n",
53"execute.\n",
54"\n",
55"Available options are as follows:\n",
56"\n",
57" -h, --help Print this help message and exit.\n",
58" -v, --verbose Increment the verbosity level. Can be specified\n",
59" multiple times.\n",
60" -q, --quiet Set the verbose level back to 0.\n",
61" -C, --no-color Disable color printing; for example, if writing\n",
62" output to a file the color escape sequences will\n",
63" corrupt that file.\n",
64" -L, --unit-load-path <PATH>\n",
65" Path to where the unit test libraries reside.\n",
66"\n",
67"Note: mandatory arguments to long arguments are mandatory for short\n",
68"arguments as well.\n",
69NULL
70 };
71
72 line = help_msg;
73 while (*line != NULL) {
74 core_msg(fw, "%s", *line);
75 line++;
76 }
77}
78
79static void set_arg_defaults(struct unit_fw_args *args)
80{
81 args->unit_load_path = DEFAULT_ARG_UNIT_LOAD_PATH;
82}
83
84/*
85 * Parse command line arguments.
86 */
87int core_parse_args(struct unit_fw *fw, int argc, char **argv)
88{
89 int c, opt_index;
90 struct unit_fw_args *args;
91
92 args = malloc(sizeof(*args));
93 if (!args)
94 return -1;
95
96 memset(args, 0, sizeof(*args));
97 set_arg_defaults(args);
98
99 fw->args = args;
100
101 while (1) {
102 c = getopt_long(argc, argv,
103 core_opts_str, core_opts, &opt_index);
104
105 if (c == -1)
106 break;
107
108 switch (c) {
109 case 'h':
110 args->help = true;
111 break;
112 case 'v':
113 args->verbose_lvl += 1;
114 break;
115 case 'q':
116 args->verbose_lvl = 0;
117 break;
118 case 'C':
119 args->no_color = true;
120 break;
121 case 'L':
122 args->unit_load_path = optarg;
123 break;
124 case '?':
125 args->help = true;
126 return -1;
127 default:
128 core_err(fw, "bug?!\n");
129 return -1;
130 }
131 }
132
133 return 0;
134}
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 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <stdlib.h>
24
25#include <unit/io.h>
26#include <unit/core.h>
27#include <unit/unit.h>
28#include <unit/module.h>
29#include <unit/results.h>
30
31#include <nvgpu/posix/probe.h>
32
33/*
34 * Execute a module and all its subtests. This function builds a gk20a for the
35 * test to use by executing nvgpu_posix_probe() and nvgpu_posix_cleanup();
36 */
37static int core_exec_module(struct unit_fw *fw,
38 struct unit_module *module)
39{
40 unsigned int i;
41 struct gk20a *g = fw->nvgpu.nvgpu_posix_probe();
42
43 if (!g)
44 return -1;
45
46 core_vbs(fw, 1, "Execing module: %s\n", module->name);
47
48 /*
49 * Execute each test within the module. No reinit is done between tests.
50 * Thats up to the module itself to handle. Any setup/teardown between
51 * unit tests must be handled within the module.
52 */
53 for (i = 0; i < module->nr_tests; i++) {
54 struct unit_module_test *t = module->tests + i;
55 int test_status;
56
57 core_msg(fw, "Running %s.%s\n", module->name, t->name);
58 test_status = t->fn(module, g, t->args);
59
60 if (test_status != UNIT_SUCCESS)
61 core_msg_color(fw, C_RED,
62 " Unit error! Test %s.%s FAILED!\n",
63 module->name, t->name);
64
65 core_add_test_record(fw, module, t,
66 test_status == UNIT_SUCCESS);
67 }
68
69 fw->nvgpu.nvgpu_posix_cleanup(g);
70
71 return 0;
72}
73
74/*
75 * Execute all modules loaded by the unit test framework.
76 */
77int core_exec(struct unit_fw *fw)
78{
79 int ret;
80 struct unit_module **modules;
81
82 for (modules = fw->modules; *modules != NULL; modules++) {
83 ret = core_exec_module(fw, *modules);
84
85 if (ret != 0)
86 return ret;
87 }
88
89 return 0;
90}
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 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <stdio.h>
24#include <stdarg.h>
25#include <string.h>
26
27#include <unit/io.h>
28#include <unit/args.h>
29#include <unit/core.h>
30#include <unit/unit.h>
31
32#define MAX_LOG_LINE_LENGTH 4096
33
34static void __core_print_file(struct unit_fw *fw, FILE *filp,
35 const char *prefix, const char *msg,
36 const char *color)
37{
38 if (color == NULL || args(fw)->no_color)
39 color = "";
40
41 fprintf(filp, "[%s%s%s] %s%s%s",
42 color, prefix, C_RESET,
43 color, msg, C_RESET);
44}
45
46__attribute__((format (printf, 3, 4)))
47void __core_print_stdout(struct unit_fw *fw, const char *color,
48 const char *fmt, ...)
49{
50 va_list args;
51 char buf[MAX_LOG_LINE_LENGTH];
52
53 va_start(args, fmt);
54 vsnprintf(buf, MAX_LOG_LINE_LENGTH, fmt, args);
55 va_end(args);
56
57 buf[MAX_LOG_LINE_LENGTH - 1] = 0;
58
59 __core_print_file(fw, stdout, "C", buf, color);
60}
61
62__attribute__((format (printf, 2, 3)))
63void __core_print_stderr(struct unit_fw *fw, const char *fmt, ...)
64{
65 va_list args;
66 char buf[MAX_LOG_LINE_LENGTH];
67
68 va_start(args, fmt);
69 vsnprintf(buf, MAX_LOG_LINE_LENGTH, fmt, args);
70 va_end(args);
71
72 buf[MAX_LOG_LINE_LENGTH - 1] = 0;
73
74 __core_print_file(fw, stdout, "E", buf, C_RED);
75}
76
77__attribute__((format (printf, 3, 4)))
78void __unit_info_color(struct unit_module *unit, const char *color,
79 const char *fmt, ...)
80{
81 va_list args;
82 char buf[MAX_LOG_LINE_LENGTH];
83 char *msg_start;
84 int written;
85
86 /*
87 * Default color for module prints is blue. Users can still turn this
88 * off with '-C'.
89 */
90 if (color == NULL)
91 color = C_BLUE;
92
93 /*
94 * First prepend the unit name to the print.
95 */
96 written = snprintf(buf, MAX_LOG_LINE_LENGTH, " [%s] ", unit->name);
97
98 msg_start = buf + written;
99
100 va_start(args, fmt);
101 vsnprintf(msg_start, MAX_LOG_LINE_LENGTH - written, fmt, args);
102 va_end(args);
103
104 __core_print_file(unit->fw, stdout, "T", buf, color);
105}
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 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <errno.h>
24#include <dlfcn.h>
25#include <dirent.h>
26#include <string.h>
27#include <stdlib.h>
28
29#include <sys/types.h>
30
31#include <unit/core.h>
32#include <unit/io.h>
33#include <unit/args.h>
34#include <unit/unit.h>
35
36static int check_module(struct unit_fw *fw, struct unit_module *mod)
37{
38 unsigned int i;
39
40 /*
41 * Make sure this module has reasonable data.
42 */
43 if (mod->name == NULL) {
44 core_err(fw, "Unnamed module!");
45 return -1;
46 }
47
48 if (mod->tests == NULL || mod->nr_tests == 0) {
49 core_err(fw, "%s: Empty module!\n", mod->name);
50 return -1;
51 }
52
53 for (i = 0; i < mod->nr_tests; i++) {
54 struct unit_module_test *test = &mod->tests[i];
55
56 if (test->name == NULL) {
57 core_err(fw, "%s: Unnamed test\n", mod->name);
58 return -1;
59 }
60
61 if (test->fn == NULL) {
62 core_err(fw, "%s: Test %s missing function \n",
63 mod->name, test->name);
64 return -1;
65 }
66 }
67
68 return 0;
69}
70
71static struct unit_module *load_one_module(struct unit_fw *fw,
72 struct dirent *dent)
73{
74 void *lib_handle;
75 struct unit_module *mod;
76
77 core_vbs(fw, 1, "Loading: %s\n", dent->d_name);
78
79 lib_handle = dlopen(dent->d_name, RTLD_NOW);
80 if (lib_handle == NULL) {
81 core_err(fw, "Failed to load %s: %s\n",
82 dent->d_name, dlerror());
83 return NULL;
84 }
85
86 mod = dlsym(lib_handle, "__unit_module__");
87 if (mod == NULL) {
88 core_vbs(fw, 1,
89 "Failed to resolve __unit_module__ in %s: %s\n",
90 dent->d_name, dlerror());
91 return NULL;
92 }
93
94 mod->lib_handle = lib_handle;
95 mod->fw = fw;
96
97 core_vbs(fw, 1, " '%s' contains %lu tests\n", mod->name, mod->nr_tests);
98
99 return mod;
100}
101
102/*
103 * Load all the modules we can from the module load path. Return the list of
104 * loaded module as an array of pointers to modules. The returned list of
105 * modules is NULL terminated.
106 */
107struct unit_module **core_load_modules(struct unit_fw *fw)
108{
109 int nr_modules = 0, i;
110 DIR *load_dir;
111 struct dirent *ent;
112 const char *load_path = args(fw)->unit_load_path;
113 struct unit_module **modules, *mod;
114
115 core_vbs(fw, 1, "Loading modules from %s\n", load_path);
116
117 /*
118 * Open and count the number of files in the dir.
119 */
120 load_dir = opendir(load_path);
121 if (!load_dir) {
122 core_err(fw, "%s: Unable to open dir (%s)\n",
123 load_path, strerror(errno));
124 return NULL;
125 }
126
127 while (readdir(load_dir) != NULL)
128 nr_modules += 1;
129
130 /* '.' and '..' should be skipped. */
131 nr_modules -= 2;
132
133 /*
134 * Now allocate necessary space for storing pointers to the modules and
135 * load the modules. +1 for the last NULL entry.
136 */
137 modules = malloc(sizeof(*modules) * (nr_modules + 1));
138 if (!modules) {
139 core_err(fw, "Out of mem! (huh?)\n");
140 goto err;
141 }
142
143 rewinddir(load_dir);
144 i = 0;
145 while ((ent = readdir(load_dir)) != NULL) {
146 if (strcmp(".", ent->d_name) == 0 ||
147 strcmp("..", ent->d_name) == 0)
148 continue;
149
150 mod = load_one_module(fw, ent);
151 if (mod == NULL)
152 continue;
153
154 if (check_module(fw, mod) != 0)
155 continue;
156
157 modules[i] = mod;
158 i++;
159 }
160
161 modules[i] = NULL;
162 return modules;
163
164err:
165 closedir(load_dir);
166 return NULL;
167}
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 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <dlfcn.h>
24#include <stdlib.h>
25
26#include <unit/io.h>
27#include <unit/core.h>
28
29/*
30 * Load libnvgpu-drv.so. This is done with dlopen() since this will make
31 * resolving addresses into symbols easier in the future.
32 *
33 * Also, this makes people think carefully about what functions to call in
34 * nvgpu-drv from the unit test FW. The interaction should really be limited
35 * and doing explicit name lookups is a good way to prevent too much coupling.
36 */
37int core_load_nvgpu(struct unit_fw *fw)
38{
39 const char *msg;
40
41 /*
42 * Specify a GLOBAL binding so that subsequently loaded unit tests see
43 * the nvgpu-drv library. They will of course need it (and will access
44 * it directly). I.e they will link against nvgpu-drv and this should
45 * satisfy that linkage.
46 */
47 fw->nvgpu_so = dlopen("libnvgpu-drv.so", RTLD_NOW | RTLD_GLOBAL);
48
49 if (fw->nvgpu_so == NULL) {
50 msg = dlerror();
51 core_err(fw, "Failed to load nvgpu-drv: %s\n", msg);
52 return -1;
53 }
54
55 /*
56 * We directly check the value of the returned symbol for these
57 * functions against NULL because if it is NULL then something is
58 * terribly wrong.
59 */
60
61 fw->nvgpu.nvgpu_posix_probe = dlsym(fw->nvgpu_so,
62 "nvgpu_posix_probe");
63 if (fw->nvgpu.nvgpu_posix_probe == NULL) {
64 msg = dlerror();
65 core_err(fw, "Failed to resolve nvgpu_posix_probe: %s\n", msg);
66 return -1;
67 }
68
69 fw->nvgpu.nvgpu_posix_cleanup = dlsym(fw->nvgpu_so,
70 "nvgpu_posix_cleanup");
71 if (fw->nvgpu.nvgpu_posix_cleanup == NULL) {
72 msg = dlerror();
73 core_err(fw, "Failed to resolve nvgpu_posix_cleanup: %s\n", msg);
74 return -1;
75 }
76
77 return 0;
78}
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 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#include <stdlib.h>
24#include <string.h>
25
26#include <unit/io.h>
27#include <unit/core.h>
28#include <unit/unit.h>
29#include <unit/results.h>
30
31static int __init_results(struct unit_fw *fw)
32{
33 struct unit_results *results;
34
35 if (fw->results != NULL)
36 return 0;
37
38 results = malloc(sizeof(*results));
39 if (results == NULL)
40 return -1;
41
42 memset(results, 0, sizeof(*results));
43
44 fw->results = results;
45
46 return 0;
47}
48
49static void add_record(struct unit_test_list *list,
50 struct unit_test_record *tr)
51{
52 /*
53 * First entry.
54 */
55 if (list->head == NULL) {
56 list->head = tr;
57 list->last = tr;
58 return;
59 }
60
61 /*
62 * Add to the end of the list and update the pointer to the last entry
63 * in the list. This gives us O(1) add time.
64 */
65 list->last->next = tr;
66 list->last = tr;
67}
68
69int core_add_test_record(struct unit_fw *fw,
70 struct unit_module *mod,
71 struct unit_module_test *test,
72 bool success)
73{
74 struct unit_test_record *tr;
75
76 /*
77 * Dones nothing if results are already inited.
78 */
79 if (__init_results(fw) != 0)
80 return -1;
81
82 tr = malloc(sizeof(*tr));
83 if (tr == NULL)
84 return -1;
85
86 tr->mod = mod;
87 tr->test = test;
88 tr->status = success;
89 tr->next = NULL;
90
91 if (success)
92 add_record(&fw->results->passing, tr);
93 else
94 add_record(&fw->results->failing, tr);
95
96 fw->results->nr_tests += 1;
97 if (success)
98 fw->results->nr_passing += 1;
99
100 return 0;
101}
102
103void core_print_test_status(struct unit_fw *fw)
104{
105 struct unit_test_list *failing_tests = &fw->results->failing;
106 struct unit_test_record *rec;
107
108 /*
109 * Print stats for the tests.
110 */
111 core_msg(fw, "\n");
112 core_msg(fw, "Test results:\n");
113 core_msg(fw, "-------------\n");
114 core_msg(fw, "\n");
115 core_msg(fw, " Passing: %d\n", fw->results->nr_passing);
116 core_msg(fw, " Failing: %d\n",
117 fw->results->nr_tests - fw->results->nr_passing);
118 core_msg(fw, " Total: %d\n", fw->results->nr_tests);
119 core_msg(fw, "\n");
120 core_msg(fw, "Failing tests:\n");
121 core_msg(fw, "\n");
122
123 for_record_in_test_list(failing_tests, rec) {
124 core_msg(fw, " %s.%s\n",
125 rec->mod->name,
126 rec->test->name);
127 }
128}
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 @@
1/*
2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23/**
24 * NvGpu unit testing framework!
25 */
26
27#include <stdlib.h>
28#include <string.h>
29
30#include <unit/io.h>
31#include <unit/core.h>
32#include <unit/args.h>
33#include <unit/module.h>
34#include <unit/results.h>
35
36int main(int argc, char **argv)
37{
38 struct unit_fw *fw;
39 int ret;
40
41 fw = malloc(sizeof(*fw));
42 if (!fw)
43 return 1;
44
45 memset(fw, 0, sizeof(*fw));
46
47 ret = core_parse_args(fw, argc, argv);
48 if (ret) {
49 core_err(fw, "Enable to parse args.\n");
50 core_err(fw, "Exiting!\n");
51 return 1;
52 }
53
54 core_vbs(fw, 1, "Welcome to the nvgpu unit testing framework!\n");
55
56 if (args(fw)->help) {
57 core_print_help(fw);
58 return 1;
59 }
60
61 ret = core_load_nvgpu(fw);
62 if (ret != 0)
63 return ret;
64
65 fw->modules = core_load_modules(fw);
66 if (fw->modules == NULL)
67 return -1;
68
69 ret = core_exec(fw);
70 if (ret != 0)
71 return ret;
72
73 core_print_test_status(fw);
74
75 return 0;
76}