Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libcam/tests/libcam_test.c
39476 views
1
/*-
2
* Copyright (c) 2017 Enji Cooper <[email protected]>
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
*
13
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
* SUCH DAMAGE.
24
*/
25
26
/* Tests functions in lib/libcam/camlib.c */
27
28
#include <sys/cdefs.h>
29
#include <errno.h>
30
#include <fcntl.h>
31
#include <stdio.h>
32
#include <camlib.h>
33
34
#include <atf-c.h>
35
36
static const char *
37
get_cam_test_device(const atf_tc_t *tc)
38
{
39
const char *cam_test_device;
40
41
cam_test_device = atf_tc_get_config_var(tc, "cam_test_device");
42
43
return (cam_test_device);
44
}
45
46
static void
47
cam_clear_error(void)
48
{
49
50
strcpy(cam_errbuf, "");
51
}
52
53
static bool
54
cam_has_error(void)
55
{
56
57
return (strlen(cam_errbuf) != 0);
58
}
59
60
ATF_TC_WITHOUT_HEAD(cam_get_device_negative_test_NULL_path);
61
ATF_TC_BODY(cam_get_device_negative_test_NULL_path, tc)
62
{
63
char parsed_dev_name[DEV_IDLEN + 1];
64
int parsed_unit;
65
66
ATF_REQUIRE_MSG(cam_get_device(NULL, parsed_dev_name,
67
nitems(parsed_dev_name), &parsed_unit) == -1,
68
"cam_get_device succeeded unexpectedly");
69
}
70
71
ATF_TC_WITHOUT_HEAD(cam_get_device_negative_test_bad_path);
72
ATF_TC_BODY(cam_get_device_negative_test_bad_path, tc)
73
{
74
char parsed_dev_name[DEV_IDLEN + 1];
75
int parsed_unit;
76
77
ATF_REQUIRE_MSG(cam_get_device("1ada", parsed_dev_name,
78
nitems(parsed_dev_name), &parsed_unit) == -1,
79
"cam_get_device succeeded unexpectedly");
80
}
81
82
ATF_TC_WITHOUT_HEAD(cam_get_device_negative_test_nul_path);
83
ATF_TC_BODY(cam_get_device_negative_test_nul_path, tc)
84
{
85
char parsed_dev_name[DEV_IDLEN + 1];
86
int parsed_unit;
87
88
ATF_REQUIRE_MSG(cam_get_device("", parsed_dev_name,
89
nitems(parsed_dev_name), &parsed_unit) == -1,
90
"cam_get_device succeeded unexpectedly");
91
}
92
93
ATF_TC_WITHOUT_HEAD(cam_get_device_negative_test_root);
94
ATF_TC_BODY(cam_get_device_negative_test_root, tc)
95
{
96
char parsed_dev_name[DEV_IDLEN + 1];
97
int parsed_unit;
98
99
ATF_REQUIRE_MSG(cam_get_device("/", parsed_dev_name,
100
nitems(parsed_dev_name), &parsed_unit) == -1,
101
"cam_get_device succeeded unexpectedly");
102
}
103
104
ATF_TC_WITHOUT_HEAD(cam_get_device_positive_test);
105
ATF_TC_BODY(cam_get_device_positive_test, tc)
106
{
107
char expected_dev_name[] = "foo";
108
char parsed_dev_name[DEV_IDLEN + 1];
109
int expected_unit, parsed_unit;
110
111
expected_unit = 1;
112
113
ATF_REQUIRE_MSG(cam_get_device("/dev/foo1", parsed_dev_name,
114
nitems(parsed_dev_name), &parsed_unit) == 0,
115
"cam_get_device failed");
116
ATF_REQUIRE_STREQ(parsed_dev_name, expected_dev_name);
117
ATF_REQUIRE(parsed_unit == expected_unit);
118
119
strcpy(parsed_dev_name, "");
120
parsed_unit = -1;
121
122
ATF_REQUIRE_MSG(cam_get_device("foo1", parsed_dev_name,
123
nitems(parsed_dev_name), &parsed_unit) == 0,
124
"cam_get_device failed");
125
ATF_REQUIRE_STREQ(parsed_dev_name, expected_dev_name);
126
ATF_REQUIRE(parsed_unit == expected_unit);
127
}
128
129
/*
130
* sa(4) uniquely creates nsa and esa device nodes for non-rewind operations
131
* and eject-on-close operations. cam_get_device must special case these nodes
132
* to always return the base device.
133
*/
134
ATF_TC_WITHOUT_HEAD(cam_get_device_sa_test);
135
ATF_TC_BODY(cam_get_device_sa_test, tc)
136
{
137
char parsed_dev_name[DEV_IDLEN + 1];
138
int parsed_unit;
139
140
ATF_REQUIRE_MSG(cam_get_device("nsa99", parsed_dev_name,
141
nitems(parsed_dev_name), &parsed_unit) == 0,
142
"cam_get_device failed");
143
ATF_REQUIRE_STREQ(parsed_dev_name, "sa");
144
ATF_REQUIRE(parsed_unit == 99);
145
146
strcpy(parsed_dev_name, "");
147
parsed_unit = -1;
148
149
ATF_REQUIRE_MSG(cam_get_device("esa99", parsed_dev_name,
150
nitems(parsed_dev_name), &parsed_unit) == 0,
151
"cam_get_device failed");
152
ATF_REQUIRE_STREQ(parsed_dev_name, "sa");
153
ATF_REQUIRE(parsed_unit == 99);
154
}
155
156
ATF_TC(cam_open_device_negative_test_O_RDONLY);
157
ATF_TC_HEAD(cam_open_device_negative_test_O_RDONLY, tc)
158
{
159
160
atf_tc_set_md_var(tc, "descr",
161
"test that cam_open_device(`cam_device`, O_RDONLY) fails to open "
162
"the underlying pass(4) device (bug 217649)");
163
atf_tc_set_md_var(tc, "require.config", "cam_test_device");
164
atf_tc_set_md_var(tc, "require.user", "root");
165
}
166
167
ATF_TC_BODY(cam_open_device_negative_test_O_RDONLY, tc)
168
{
169
const char *cam_test_device;
170
171
cam_test_device = get_cam_test_device(tc);
172
173
cam_clear_error();
174
ATF_CHECK(cam_open_device(cam_test_device, O_RDONLY) == NULL);
175
ATF_REQUIRE(cam_has_error());
176
}
177
178
ATF_TC(cam_open_device_negative_test_nonexistent);
179
ATF_TC_HEAD(cam_open_device_negative_test_nonexistent, tc)
180
{
181
182
atf_tc_set_md_var(tc, "require.user", "root");
183
}
184
185
ATF_TC_BODY(cam_open_device_negative_test_nonexistent, tc)
186
{
187
188
cam_clear_error();
189
ATF_REQUIRE(cam_open_device("/nonexistent", O_RDWR) == NULL);
190
ATF_REQUIRE(cam_has_error());
191
}
192
193
ATF_TC(cam_open_device_negative_test_unprivileged);
194
ATF_TC_HEAD(cam_open_device_negative_test_unprivileged, tc)
195
{
196
197
atf_tc_set_md_var(tc, "require.config", "cam_test_device");
198
atf_tc_set_md_var(tc, "require.user", "unprivileged");
199
}
200
201
ATF_TC_BODY(cam_open_device_negative_test_unprivileged, tc)
202
{
203
const char *cam_test_device;
204
205
cam_test_device = get_cam_test_device(tc);
206
207
cam_clear_error();
208
ATF_CHECK(cam_open_device(cam_test_device, O_RDONLY) == NULL);
209
ATF_REQUIRE(cam_has_error());
210
211
cam_clear_error();
212
ATF_CHECK(cam_open_device(cam_test_device, O_RDWR) == NULL);
213
ATF_REQUIRE(cam_has_error());
214
}
215
216
ATF_TC(cam_open_device_positive_test);
217
ATF_TC_HEAD(cam_open_device_positive_test, tc)
218
{
219
220
atf_tc_set_md_var(tc, "require.config", "cam_test_device");
221
atf_tc_set_md_var(tc, "require.user", "root");
222
}
223
224
ATF_TC_BODY(cam_open_device_positive_test, tc)
225
{
226
struct cam_device *cam_dev;
227
const char *cam_test_device;
228
229
cam_test_device = get_cam_test_device(tc);
230
231
cam_clear_error();
232
cam_dev = cam_open_device(cam_test_device, O_RDWR);
233
ATF_CHECK_MSG(cam_dev != NULL, "cam_open_device failed: %s",
234
cam_errbuf);
235
ATF_REQUIRE(!cam_has_error());
236
cam_close_device(cam_dev);
237
}
238
239
ATF_TC(cam_close_device_negative_test_NULL);
240
ATF_TC_HEAD(cam_close_device_negative_test_NULL, tc)
241
{
242
243
atf_tc_set_md_var(tc, "descr",
244
"test that cam_close_device(NULL) succeeds without error");
245
atf_tc_set_md_var(tc, "require.user", "root");
246
}
247
248
ATF_TC_BODY(cam_close_device_negative_test_NULL, tc)
249
{
250
251
cam_clear_error();
252
cam_close_device(NULL);
253
ATF_REQUIRE(!cam_has_error());
254
}
255
256
ATF_TC(cam_getccb_positive_test);
257
ATF_TC_HEAD(cam_getccb_positive_test, tc)
258
{
259
260
atf_tc_set_md_var(tc, "require.config", "cam_test_device");
261
atf_tc_set_md_var(tc, "require.user", "root");
262
}
263
264
ATF_TC_BODY(cam_getccb_positive_test, tc)
265
{
266
union ccb *cam_ccb;
267
struct cam_device *cam_dev;
268
const char *cam_test_device;
269
270
cam_test_device = get_cam_test_device(tc);
271
272
cam_clear_error();
273
cam_dev = cam_open_device(cam_test_device, O_RDWR);
274
ATF_CHECK_MSG(cam_dev != NULL, "cam_open_device failed: %s",
275
cam_errbuf);
276
ATF_REQUIRE(!cam_has_error());
277
cam_ccb = cam_getccb(cam_dev);
278
ATF_CHECK_MSG(cam_ccb != NULL, "get_camccb failed: %s", cam_errbuf);
279
ATF_REQUIRE(!cam_has_error());
280
cam_freeccb(cam_ccb);
281
cam_close_device(cam_dev);
282
}
283
284
ATF_TC(cam_freeccb_negative_test_NULL);
285
ATF_TC_HEAD(cam_freeccb_negative_test_NULL, tc)
286
{
287
288
atf_tc_set_md_var(tc, "descr",
289
"test that cam_freeccb(NULL) succeeds without error");
290
atf_tc_set_md_var(tc, "require.user", "root");
291
}
292
293
ATF_TC_BODY(cam_freeccb_negative_test_NULL, tc)
294
{
295
296
cam_clear_error();
297
cam_freeccb(NULL);
298
ATF_REQUIRE(!cam_has_error());
299
}
300
301
ATF_TP_ADD_TCS(tp)
302
{
303
304
ATF_TP_ADD_TC(tp, cam_get_device_negative_test_NULL_path);
305
ATF_TP_ADD_TC(tp, cam_get_device_negative_test_bad_path);
306
ATF_TP_ADD_TC(tp, cam_get_device_negative_test_nul_path);
307
ATF_TP_ADD_TC(tp, cam_get_device_negative_test_root);
308
ATF_TP_ADD_TC(tp, cam_get_device_positive_test);
309
ATF_TP_ADD_TC(tp, cam_get_device_sa_test);
310
ATF_TP_ADD_TC(tp, cam_open_device_negative_test_O_RDONLY);
311
ATF_TP_ADD_TC(tp, cam_open_device_negative_test_nonexistent);
312
ATF_TP_ADD_TC(tp, cam_open_device_negative_test_unprivileged);
313
ATF_TP_ADD_TC(tp, cam_open_device_positive_test);
314
ATF_TP_ADD_TC(tp, cam_close_device_negative_test_NULL);
315
ATF_TP_ADD_TC(tp, cam_getccb_positive_test);
316
ATF_TP_ADD_TC(tp, cam_freeccb_negative_test_NULL);
317
318
return (atf_no_error());
319
}
320
321