1 /*
2  * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all
7  * copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /**
20  * DOC: wlan_hdd_unit_test.c
21  *
22  * config wlan_hdd_unit_test which will be used by wext and
23  * debugfs unit_test_host
24  */
25 #include "wlan_hdd_main.h"
26 #include "qdf_delayed_work_test.h"
27 #include "qdf_hashtable_test.h"
28 #include "qdf_periodic_work_test.h"
29 #include "qdf_ptr_hash_test.h"
30 #include "qdf_slist_test.h"
31 #include "qdf_talloc_test.h"
32 #include "qdf_str.h"
33 #include "qdf_trace.h"
34 #include "qdf_tracker_test.h"
35 #include "qdf_types_test.h"
36 #include "wlan_dsc_test.h"
37 #include "wlan_hdd_unit_test.h"
38 
39 typedef uint32_t (*hdd_ut_callback)(void);
40 
41 struct hdd_ut_entry {
42 	const hdd_ut_callback callback;
43 	const char *name;
44 };
45 
46 struct hdd_ut_entry hdd_ut_entries[] = {
47 	{ .name = "dsc", .callback = dsc_unit_test },
48 	{ .name = "qdf_delayed_work", .callback = qdf_delayed_work_unit_test },
49 	{ .name = "qdf_ht", .callback = qdf_ht_unit_test },
50 	{ .name = "qdf_periodic_work",
51 	  .callback = qdf_periodic_work_unit_test },
52 	{ .name = "qdf_ptr_hash", .callback = qdf_ptr_hash_unit_test },
53 	{ .name = "qdf_slist", .callback = qdf_slist_unit_test },
54 	{ .name = "qdf_talloc", .callback = qdf_talloc_unit_test },
55 	{ .name = "qdf_tracker", .callback = qdf_tracker_unit_test },
56 	{ .name = "qdf_types", .callback = qdf_types_unit_test },
57 };
58 
59 #define hdd_for_each_ut_entry(cursor) \
60 	for (cursor = hdd_ut_entries; \
61 	     cursor < hdd_ut_entries + ARRAY_SIZE(hdd_ut_entries); \
62 	     cursor++)
63 
hdd_ut_lookup(const char * name)64 static struct hdd_ut_entry *hdd_ut_lookup(const char *name)
65 {
66 	struct hdd_ut_entry *entry;
67 
68 	hdd_for_each_ut_entry(entry) {
69 		if (qdf_str_eq(entry->name, name))
70 			return entry;
71 	}
72 
73 	return NULL;
74 }
75 
hdd_ut_single(const struct hdd_ut_entry * entry)76 static uint32_t hdd_ut_single(const struct hdd_ut_entry *entry)
77 {
78 	uint32_t errors;
79 
80 	hdd_nofl_info("START: '%s'", entry->name);
81 
82 	errors = entry->callback();
83 	if (errors)
84 		hdd_nofl_err("FAIL: '%s' with %u errors", entry->name, errors);
85 	else
86 		hdd_nofl_info("PASS: '%s'", entry->name);
87 
88 	return errors;
89 }
90 
wlan_hdd_unit_test(struct hdd_context * hdd_ctx,const char * name)91 int wlan_hdd_unit_test(struct hdd_context *hdd_ctx, const char *name)
92 {
93 	struct hdd_ut_entry *entry;
94 	uint32_t errors = 0;
95 
96 	hdd_nofl_info("Unit tests begin");
97 
98 	if (!name || !name[0] || qdf_str_eq(name, "all")) {
99 		hdd_for_each_ut_entry(entry)
100 			errors += hdd_ut_single(entry);
101 	} else {
102 		entry = hdd_ut_lookup(name);
103 		if (entry) {
104 			errors += hdd_ut_single(entry);
105 		} else {
106 			hdd_nofl_err("Unit test '%s' not found", name);
107 			return -EINVAL;
108 		}
109 	}
110 
111 	hdd_nofl_info("Unit tests complete");
112 
113 	return errors ? -EPERM : 0;
114 }
115