Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C) 2016 Intel Corporation.
3 : : * All rights reserved.
4 : : * Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
5 : : */
6 : :
7 : : #include "spdk/stdinc.h"
8 : :
9 : : #include "spdk_internal/cunit.h"
10 : :
11 : : #include "unit/lib/json_mock.c"
12 : : #include "init/subsystem.c"
13 : : #include "common/lib/test_env.c"
14 : :
15 : : static struct spdk_subsystem g_ut_subsystems[8];
16 : : static struct spdk_subsystem_depend g_ut_subsystem_deps[8];
17 : : static int global_rc;
18 : :
19 : : static void
20 : 12 : ut_event_fn(int rc, void *arg1)
21 : : {
22 : 12 : global_rc = rc;
23 : 12 : }
24 : :
25 : : static void
26 : 30 : set_up_subsystem(struct spdk_subsystem *subsystem, const char *name)
27 : : {
28 : 30 : subsystem->init = NULL;
29 : 30 : subsystem->fini = NULL;
30 : 30 : subsystem->name = name;
31 : 30 : }
32 : :
33 : : static void
34 : 30 : set_up_depends(struct spdk_subsystem_depend *depend, const char *subsystem_name,
35 : : const char *depends_on_name)
36 : : {
37 : 30 : depend->name = subsystem_name;
38 : 30 : depend->depends_on = depends_on_name;
39 : 30 : }
40 : :
41 : : static void
42 : 9 : subsystem_clear(void)
43 : : {
44 : : struct spdk_subsystem *subsystem, *subsystem_tmp;
45 : : struct spdk_subsystem_depend *subsystem_dep, *subsystem_dep_tmp;
46 : :
47 [ + + ]: 24 : TAILQ_FOREACH_SAFE(subsystem, &g_subsystems, tailq, subsystem_tmp) {
48 [ + + ]: 15 : TAILQ_REMOVE(&g_subsystems, subsystem, tailq);
49 : : }
50 : :
51 [ + + ]: 45 : TAILQ_FOREACH_SAFE(subsystem_dep, &g_subsystems_deps, tailq, subsystem_dep_tmp) {
52 [ + + ]: 36 : TAILQ_REMOVE(&g_subsystems_deps, subsystem_dep, tailq);
53 : : }
54 : 9 : }
55 : :
56 : : static void
57 : 3 : subsystem_sort_test_depends_on_single(void)
58 : : {
59 : : struct spdk_subsystem *subsystem;
60 : : int i;
61 : 3 : char subsystem_name[16];
62 : :
63 : 3 : global_rc = -1;
64 : 3 : spdk_subsystem_init(ut_event_fn, NULL);
65 : 3 : CU_ASSERT(global_rc == 0);
66 : :
67 : 3 : i = 4;
68 [ + + ]: 15 : TAILQ_FOREACH(subsystem, &g_subsystems, tailq) {
69 : 12 : snprintf(subsystem_name, sizeof(subsystem_name), "subsystem%d", i);
70 [ - + ]: 12 : SPDK_CU_ASSERT_FATAL(i > 0);
71 : 12 : i--;
72 [ - + ]: 12 : CU_ASSERT(strcmp(subsystem_name, subsystem->name) == 0);
73 : : }
74 : 3 : }
75 : :
76 : : static void
77 : 3 : subsystem_sort_test_depends_on_multiple(void)
78 : : {
79 : : int i;
80 : : struct spdk_subsystem *subsystem;
81 : :
82 : 3 : subsystem_clear();
83 : 3 : set_up_subsystem(&g_ut_subsystems[0], "iscsi");
84 : 3 : set_up_subsystem(&g_ut_subsystems[1], "nvmf");
85 : 3 : set_up_subsystem(&g_ut_subsystems[2], "sock");
86 : 3 : set_up_subsystem(&g_ut_subsystems[3], "bdev");
87 : 3 : set_up_subsystem(&g_ut_subsystems[4], "rpc");
88 : 3 : set_up_subsystem(&g_ut_subsystems[5], "scsi");
89 : 3 : set_up_subsystem(&g_ut_subsystems[6], "interface");
90 : 3 : set_up_subsystem(&g_ut_subsystems[7], "accel");
91 : :
92 [ + + ]: 27 : for (i = 0; i < 8; i++) {
93 : 24 : spdk_add_subsystem(&g_ut_subsystems[i]);
94 : : }
95 : :
96 : 3 : set_up_depends(&g_ut_subsystem_deps[0], "bdev", "accel");
97 : 3 : set_up_depends(&g_ut_subsystem_deps[1], "scsi", "bdev");
98 : 3 : set_up_depends(&g_ut_subsystem_deps[2], "rpc", "interface");
99 : 3 : set_up_depends(&g_ut_subsystem_deps[3], "sock", "interface");
100 : 3 : set_up_depends(&g_ut_subsystem_deps[4], "nvmf", "interface");
101 : 3 : set_up_depends(&g_ut_subsystem_deps[5], "iscsi", "scsi");
102 : 3 : set_up_depends(&g_ut_subsystem_deps[6], "iscsi", "sock");
103 : 3 : set_up_depends(&g_ut_subsystem_deps[7], "iscsi", "rpc");
104 : :
105 [ + + ]: 27 : for (i = 0; i < 8; i++) {
106 : 24 : spdk_add_subsystem_depend(&g_ut_subsystem_deps[i]);
107 : : }
108 : :
109 : 3 : global_rc = -1;
110 : 3 : spdk_subsystem_init(ut_event_fn, NULL);
111 : 3 : CU_ASSERT(global_rc == 0);
112 : :
113 : 3 : subsystem = TAILQ_FIRST(&g_subsystems);
114 [ - + ]: 3 : CU_ASSERT(strcmp(subsystem->name, "interface") == 0);
115 [ + - ]: 3 : TAILQ_REMOVE(&g_subsystems, subsystem, tailq);
116 : :
117 : 3 : subsystem = TAILQ_FIRST(&g_subsystems);
118 [ - + ]: 3 : CU_ASSERT(strcmp(subsystem->name, "accel") == 0);
119 [ + - ]: 3 : TAILQ_REMOVE(&g_subsystems, subsystem, tailq);
120 : :
121 : 3 : subsystem = TAILQ_FIRST(&g_subsystems);
122 [ - + ]: 3 : CU_ASSERT(strcmp(subsystem->name, "nvmf") == 0);
123 [ + - ]: 3 : TAILQ_REMOVE(&g_subsystems, subsystem, tailq);
124 : :
125 : 3 : subsystem = TAILQ_FIRST(&g_subsystems);
126 [ - + ]: 3 : CU_ASSERT(strcmp(subsystem->name, "sock") == 0);
127 [ + - ]: 3 : TAILQ_REMOVE(&g_subsystems, subsystem, tailq);
128 : :
129 : 3 : subsystem = TAILQ_FIRST(&g_subsystems);
130 [ - + ]: 3 : CU_ASSERT(strcmp(subsystem->name, "bdev") == 0);
131 [ + - ]: 3 : TAILQ_REMOVE(&g_subsystems, subsystem, tailq);
132 : :
133 : 3 : subsystem = TAILQ_FIRST(&g_subsystems);
134 [ - + ]: 3 : CU_ASSERT(strcmp(subsystem->name, "rpc") == 0);
135 [ + - ]: 3 : TAILQ_REMOVE(&g_subsystems, subsystem, tailq);
136 : :
137 : 3 : subsystem = TAILQ_FIRST(&g_subsystems);
138 [ - + ]: 3 : CU_ASSERT(strcmp(subsystem->name, "scsi") == 0);
139 [ + - ]: 3 : TAILQ_REMOVE(&g_subsystems, subsystem, tailq);
140 : :
141 : 3 : subsystem = TAILQ_FIRST(&g_subsystems);
142 [ - + ]: 3 : CU_ASSERT(strcmp(subsystem->name, "iscsi") == 0);
143 [ - + ]: 3 : TAILQ_REMOVE(&g_subsystems, subsystem, tailq);
144 : 3 : }
145 : :
146 : : struct spdk_subsystem subsystem1 = {
147 : : .name = "subsystem1",
148 : : };
149 : :
150 : : struct spdk_subsystem subsystem2 = {
151 : : .name = "subsystem2",
152 : : };
153 : : struct spdk_subsystem subsystem3 = {
154 : : .name = "subsystem3",
155 : : };
156 : :
157 : : struct spdk_subsystem subsystem4 = {
158 : : .name = "subsystem4",
159 : : };
160 : :
161 : 3 : SPDK_SUBSYSTEM_REGISTER(subsystem1);
162 : 3 : SPDK_SUBSYSTEM_REGISTER(subsystem2);
163 : 3 : SPDK_SUBSYSTEM_REGISTER(subsystem3);
164 : 3 : SPDK_SUBSYSTEM_REGISTER(subsystem4);
165 : :
166 : 3 : SPDK_SUBSYSTEM_DEPEND(subsystem1, subsystem2)
167 : 3 : SPDK_SUBSYSTEM_DEPEND(subsystem2, subsystem3)
168 : 3 : SPDK_SUBSYSTEM_DEPEND(subsystem3, subsystem4)
169 : :
170 : :
171 : : static void
172 : 3 : subsystem_sort_test_missing_dependency(void)
173 : : {
174 : : /*
175 : : * A depends on B, but B is missing
176 : : */
177 : :
178 : 3 : subsystem_clear();
179 : 3 : set_up_subsystem(&g_ut_subsystems[0], "A");
180 : 3 : spdk_add_subsystem(&g_ut_subsystems[0]);
181 : :
182 : 3 : set_up_depends(&g_ut_subsystem_deps[0], "A", "B");
183 : 3 : spdk_add_subsystem_depend(&g_ut_subsystem_deps[0]);
184 : :
185 : 3 : global_rc = -1;
186 : 3 : spdk_subsystem_init(ut_event_fn, NULL);
187 : 3 : CU_ASSERT(global_rc != 0);
188 : :
189 : : /*
190 : : * Dependency from C to A is defined, but C is missing
191 : : */
192 : :
193 : 3 : subsystem_clear();
194 : 3 : set_up_subsystem(&g_ut_subsystems[0], "A");
195 : 3 : spdk_add_subsystem(&g_ut_subsystems[0]);
196 : :
197 : 3 : set_up_depends(&g_ut_subsystem_deps[0], "C", "A");
198 : 3 : spdk_add_subsystem_depend(&g_ut_subsystem_deps[0]);
199 : :
200 : 3 : global_rc = -1;
201 : 3 : spdk_subsystem_init(ut_event_fn, NULL);
202 : 3 : CU_ASSERT(global_rc != 0);
203 : :
204 : 3 : }
205 : :
206 : : int
207 : 3 : main(int argc, char **argv)
208 : : {
209 : 3 : CU_pSuite suite = NULL;
210 : : unsigned int num_failures;
211 : : struct spdk_thread *thread;
212 : :
213 : 3 : CU_initialize_registry();
214 : :
215 : 3 : suite = CU_add_suite("subsystem_suite", NULL, NULL);
216 : :
217 : 3 : spdk_thread_lib_init(NULL, 0);
218 : 3 : thread = spdk_thread_create(NULL, NULL);
219 : 3 : spdk_set_thread(thread);
220 : :
221 : 3 : CU_ADD_TEST(suite, subsystem_sort_test_depends_on_single);
222 : 3 : CU_ADD_TEST(suite, subsystem_sort_test_depends_on_multiple);
223 : 3 : CU_ADD_TEST(suite, subsystem_sort_test_missing_dependency);
224 : :
225 : 3 : num_failures = spdk_ut_run_tests(argc, argv, NULL);
226 : 3 : CU_cleanup_registry();
227 : :
228 : 3 : return num_failures;
229 : : }
|