]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tests/sys/kern/module_test.c
Import device-tree files from Linux 5.17
[FreeBSD/FreeBSD.git] / tests / sys / kern / module_test.c
1 /*-
2  * Copyright (c) 2022 University of Cambridge
3  *
4  * This software was developed by Ararat River Consulting, LLC under
5  * sponsorship from the University of Cambridge Computer Laboratory
6  * (Department of Computer Science and Technology) and Google, Inc.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/param.h>
31 #include <sys/module.h>
32 #include <errno.h>
33 #include <atf-c.h>
34
35 ATF_TC_WITHOUT_HEAD(modfind);
36 ATF_TC_BODY(modfind, tc)
37 {
38         int modid;
39
40         /* This module is present in sys/kern/subr_bus.c. */
41         modid = modfind("rootbus");
42         ATF_REQUIRE(modid > 0);
43
44         modid = modfind("nonexistent_module");
45         ATF_REQUIRE(modid == -1);
46         ATF_REQUIRE(errno == ENOENT);
47 }
48
49 ATF_TC_WITHOUT_HEAD(modnext);
50 ATF_TC_BODY(modnext, tc)
51 {
52         int modid;
53
54         /* This assumes -1 is never used as a valid module id. */
55         modid = modnext(-1);
56         ATF_REQUIRE(modid == -1);
57         ATF_REQUIRE(errno == ENOENT);
58
59         modid = modnext(0);
60         ATF_REQUIRE(modid > 0);
61
62         for (;;) {
63                 modid = modnext(modid);
64                 ATF_REQUIRE(modid >= 0);
65                 if (modid == 0)
66                         break;
67         }
68 }
69
70 ATF_TC_WITHOUT_HEAD(modfnext);
71 ATF_TC_BODY(modfnext, tc)
72 {
73         int modid;
74
75         /* This assumes -1 is never used as a valid module id. */
76         modid = modfnext(-1);
77         ATF_REQUIRE(modid == -1);
78         ATF_REQUIRE(errno == ENOENT);
79
80         modid = modfnext(0);
81         ATF_REQUIRE(modid == -1);
82         ATF_REQUIRE(errno == ENOENT);
83
84         modid = modnext(0);
85         ATF_REQUIRE(modid > 0);
86
87         for (;;) {
88                 modid = modfnext(modid);
89                 ATF_REQUIRE(modid >= 0);
90                 if (modid == 0)
91                         break;
92         }
93 }
94
95 ATF_TC_WITHOUT_HEAD(modstat);
96 ATF_TC_BODY(modstat, tc)
97 {
98         struct module_stat ms;
99         int modid;
100
101         ms.version = sizeof(ms);
102         ATF_REQUIRE(modstat(0, &ms) == -1);
103         ATF_REQUIRE(errno == ENOENT);
104
105         modid = modnext(0);
106         ATF_REQUIRE(modid > 0);
107
108         ATF_REQUIRE(modstat(modid, NULL) == -1);
109         ATF_REQUIRE(errno == EFAULT);
110
111         ms.version = 0;
112         ATF_REQUIRE(modstat(modid, &ms) == -1);
113         ATF_REQUIRE(errno == EINVAL);
114
115         ms.version = sizeof(ms);
116         ATF_REQUIRE(modstat(modid, &ms) == 0);
117         ATF_REQUIRE(ms.id == modid);
118         if (strnlen(ms.name, sizeof(ms.name)) < sizeof(ms.name))
119                 ATF_REQUIRE(modfind(ms.name) == modid);
120 }
121
122 ATF_TC_WITHOUT_HEAD(modstat_v1);
123 ATF_TC_BODY(modstat_v1, tc)
124 {
125         struct module_stat_v1 {
126                 int     version;
127                 char    name[32];
128                 int     refs;
129                 int     id;
130         } ms;
131         int modid;
132
133         ms.version = sizeof(ms);
134         ATF_REQUIRE(modstat(0, (struct module_stat *)&ms) == -1);
135         ATF_REQUIRE(errno == ENOENT);
136
137         modid = modnext(0);
138         ATF_REQUIRE(modid > 0);
139
140         ATF_REQUIRE(modstat(modid, NULL) == -1);
141         ATF_REQUIRE(errno == EFAULT);
142
143         ms.version = 0;
144         ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == -1);
145         ATF_REQUIRE(errno == EINVAL);
146
147         ms.version = sizeof(ms);
148         ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == 0);
149         ATF_REQUIRE(ms.id == modid);
150         if (strnlen(ms.name, sizeof(ms.name)) < sizeof(ms.name))
151                 ATF_REQUIRE(modfind(ms.name) == modid);
152 }
153
154 ATF_TC_WITHOUT_HEAD(modstat_v2);
155 ATF_TC_BODY(modstat_v2, tc)
156 {
157         struct module_stat_v2 {
158                 int     version;
159                 char    name[32];
160                 int     refs;
161                 int     id;
162                 modspecific_t data;
163         } ms;
164         int modid;
165
166         ms.version = sizeof(ms);
167         ATF_REQUIRE(modstat(0, (struct module_stat *)&ms) == -1);
168         ATF_REQUIRE(errno == ENOENT);
169
170         modid = modnext(0);
171         ATF_REQUIRE(modid > 0);
172
173         ATF_REQUIRE(modstat(modid, NULL) == -1);
174         ATF_REQUIRE(errno == EFAULT);
175
176         ms.version = 0;
177         ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == -1);
178         ATF_REQUIRE(errno == EINVAL);
179
180         ms.version = sizeof(ms);
181         ATF_REQUIRE(modstat(modid, (struct module_stat *)&ms) == 0);
182         ATF_REQUIRE(ms.id == modid);
183         if (strnlen(ms.name, sizeof(ms.name)) < sizeof(ms.name))
184                 ATF_REQUIRE(modfind(ms.name) == modid);
185 }
186
187 ATF_TP_ADD_TCS(tp)
188 {
189         ATF_TP_ADD_TC(tp, modfind);
190         ATF_TP_ADD_TC(tp, modnext);
191         ATF_TP_ADD_TC(tp, modfnext);
192         ATF_TP_ADD_TC(tp, modstat);
193         ATF_TP_ADD_TC(tp, modstat_v1);
194         ATF_TP_ADD_TC(tp, modstat_v2);
195
196         return (atf_no_error());
197 }