Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/atf/atf-c++/detail/fs_test.cpp
39563 views
1
// Copyright (c) 2007 The NetBSD Foundation, Inc.
2
// All rights reserved.
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 NETBSD FOUNDATION, INC. AND
14
// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22
// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24
// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26
#include "atf-c++/detail/fs.hpp"
27
28
extern "C" {
29
#include <sys/types.h>
30
#include <sys/stat.h>
31
}
32
33
#include <fstream>
34
#include <cerrno>
35
#include <cstdio>
36
37
#include <atf-c++.hpp>
38
39
#include "atf-c++/detail/exceptions.hpp"
40
41
// ------------------------------------------------------------------------
42
// Auxiliary functions.
43
// ------------------------------------------------------------------------
44
45
static
46
void
47
create_files(void)
48
{
49
::mkdir("files", 0755);
50
::mkdir("files/dir", 0755);
51
52
std::ofstream os("files/reg");
53
os.close();
54
55
// TODO: Should create all other file types (blk, chr, fifo, lnk, sock)
56
// and test for them... but the underlying file system may not support
57
// most of these. Specially as we are working on /tmp, which can be
58
// mounted with flags such as "nodev". See how to deal with this
59
// situation.
60
}
61
62
// ------------------------------------------------------------------------
63
// Test cases for the "path" class.
64
// ------------------------------------------------------------------------
65
66
ATF_TEST_CASE(path_normalize);
67
ATF_TEST_CASE_HEAD(path_normalize)
68
{
69
set_md_var("descr", "Tests the path's normalization");
70
}
71
ATF_TEST_CASE_BODY(path_normalize)
72
{
73
using atf::fs::path;
74
75
ATF_REQUIRE_EQ(path(".").str(), ".");
76
ATF_REQUIRE_EQ(path("..").str(), "..");
77
78
ATF_REQUIRE_EQ(path("foo").str(), "foo");
79
ATF_REQUIRE_EQ(path("foo/bar").str(), "foo/bar");
80
ATF_REQUIRE_EQ(path("foo/bar/").str(), "foo/bar");
81
82
ATF_REQUIRE_EQ(path("/foo").str(), "/foo");
83
ATF_REQUIRE_EQ(path("/foo/bar").str(), "/foo/bar");
84
ATF_REQUIRE_EQ(path("/foo/bar/").str(), "/foo/bar");
85
86
ATF_REQUIRE_EQ(path("///foo").str(), "/foo");
87
ATF_REQUIRE_EQ(path("///foo///bar").str(), "/foo/bar");
88
ATF_REQUIRE_EQ(path("///foo///bar///").str(), "/foo/bar");
89
}
90
91
ATF_TEST_CASE(path_is_absolute);
92
ATF_TEST_CASE_HEAD(path_is_absolute)
93
{
94
set_md_var("descr", "Tests the path::is_absolute function");
95
}
96
ATF_TEST_CASE_BODY(path_is_absolute)
97
{
98
using atf::fs::path;
99
100
ATF_REQUIRE( path("/").is_absolute());
101
ATF_REQUIRE( path("////").is_absolute());
102
ATF_REQUIRE( path("////a").is_absolute());
103
ATF_REQUIRE( path("//a//").is_absolute());
104
ATF_REQUIRE(!path("a////").is_absolute());
105
ATF_REQUIRE(!path("../foo").is_absolute());
106
}
107
108
ATF_TEST_CASE(path_is_root);
109
ATF_TEST_CASE_HEAD(path_is_root)
110
{
111
set_md_var("descr", "Tests the path::is_root function");
112
}
113
ATF_TEST_CASE_BODY(path_is_root)
114
{
115
using atf::fs::path;
116
117
ATF_REQUIRE( path("/").is_root());
118
ATF_REQUIRE( path("////").is_root());
119
ATF_REQUIRE(!path("////a").is_root());
120
ATF_REQUIRE(!path("//a//").is_root());
121
ATF_REQUIRE(!path("a////").is_root());
122
ATF_REQUIRE(!path("../foo").is_root());
123
}
124
125
ATF_TEST_CASE(path_branch_path);
126
ATF_TEST_CASE_HEAD(path_branch_path)
127
{
128
set_md_var("descr", "Tests the path::branch_path function");
129
}
130
ATF_TEST_CASE_BODY(path_branch_path)
131
{
132
using atf::fs::path;
133
134
ATF_REQUIRE_EQ(path(".").branch_path().str(), ".");
135
ATF_REQUIRE_EQ(path("foo").branch_path().str(), ".");
136
ATF_REQUIRE_EQ(path("foo/bar").branch_path().str(), "foo");
137
ATF_REQUIRE_EQ(path("/foo").branch_path().str(), "/");
138
ATF_REQUIRE_EQ(path("/foo/bar").branch_path().str(), "/foo");
139
}
140
141
ATF_TEST_CASE(path_leaf_name);
142
ATF_TEST_CASE_HEAD(path_leaf_name)
143
{
144
set_md_var("descr", "Tests the path::leaf_name function");
145
}
146
ATF_TEST_CASE_BODY(path_leaf_name)
147
{
148
using atf::fs::path;
149
150
ATF_REQUIRE_EQ(path(".").leaf_name(), ".");
151
ATF_REQUIRE_EQ(path("foo").leaf_name(), "foo");
152
ATF_REQUIRE_EQ(path("foo/bar").leaf_name(), "bar");
153
ATF_REQUIRE_EQ(path("/foo").leaf_name(), "foo");
154
ATF_REQUIRE_EQ(path("/foo/bar").leaf_name(), "bar");
155
}
156
157
ATF_TEST_CASE(path_compare_equal);
158
ATF_TEST_CASE_HEAD(path_compare_equal)
159
{
160
set_md_var("descr", "Tests the comparison for equality between paths");
161
}
162
ATF_TEST_CASE_BODY(path_compare_equal)
163
{
164
using atf::fs::path;
165
166
ATF_REQUIRE(path("/") == path("///"));
167
ATF_REQUIRE(path("/a") == path("///a"));
168
ATF_REQUIRE(path("/a") == path("///a///"));
169
170
ATF_REQUIRE(path("a/b/c") == path("a//b//c"));
171
ATF_REQUIRE(path("a/b/c") == path("a//b//c///"));
172
}
173
174
ATF_TEST_CASE(path_compare_different);
175
ATF_TEST_CASE_HEAD(path_compare_different)
176
{
177
set_md_var("descr", "Tests the comparison for difference between paths");
178
}
179
ATF_TEST_CASE_BODY(path_compare_different)
180
{
181
using atf::fs::path;
182
183
ATF_REQUIRE(path("/") != path("//a/"));
184
ATF_REQUIRE(path("/a") != path("a///"));
185
186
ATF_REQUIRE(path("a/b/c") != path("a/b"));
187
ATF_REQUIRE(path("a/b/c") != path("a//b"));
188
ATF_REQUIRE(path("a/b/c") != path("/a/b/c"));
189
ATF_REQUIRE(path("a/b/c") != path("/a//b//c"));
190
}
191
192
ATF_TEST_CASE(path_concat);
193
ATF_TEST_CASE_HEAD(path_concat)
194
{
195
set_md_var("descr", "Tests the concatenation of multiple paths");
196
}
197
ATF_TEST_CASE_BODY(path_concat)
198
{
199
using atf::fs::path;
200
201
ATF_REQUIRE_EQ((path("foo") / "bar").str(), "foo/bar");
202
ATF_REQUIRE_EQ((path("foo/") / "/bar").str(), "foo/bar");
203
ATF_REQUIRE_EQ((path("foo/") / "/bar/baz").str(), "foo/bar/baz");
204
ATF_REQUIRE_EQ((path("foo/") / "///bar///baz").str(), "foo/bar/baz");
205
}
206
207
ATF_TEST_CASE(path_to_absolute);
208
ATF_TEST_CASE_HEAD(path_to_absolute)
209
{
210
set_md_var("descr", "Tests the conversion of a relative path to an "
211
"absolute one");
212
}
213
ATF_TEST_CASE_BODY(path_to_absolute)
214
{
215
using atf::fs::file_info;
216
using atf::fs::path;
217
218
create_files();
219
220
{
221
const path p(".");
222
path pa = p.to_absolute();
223
ATF_REQUIRE(pa.is_absolute());
224
225
file_info fi(p);
226
file_info fia(pa);
227
ATF_REQUIRE_EQ(fi.get_device(), fia.get_device());
228
ATF_REQUIRE_EQ(fi.get_inode(), fia.get_inode());
229
}
230
231
{
232
const path p("files/reg");
233
path pa = p.to_absolute();
234
ATF_REQUIRE(pa.is_absolute());
235
236
file_info fi(p);
237
file_info fia(pa);
238
ATF_REQUIRE_EQ(fi.get_device(), fia.get_device());
239
ATF_REQUIRE_EQ(fi.get_inode(), fia.get_inode());
240
}
241
}
242
243
ATF_TEST_CASE(path_op_less);
244
ATF_TEST_CASE_HEAD(path_op_less)
245
{
246
set_md_var("descr", "Tests that the path's less-than operator works");
247
}
248
ATF_TEST_CASE_BODY(path_op_less)
249
{
250
using atf::fs::path;
251
252
create_files();
253
254
ATF_REQUIRE(!(path("aaa") < path("aaa")));
255
256
ATF_REQUIRE( path("aab") < path("abc"));
257
ATF_REQUIRE(!(path("abc") < path("aab")));
258
}
259
260
// ------------------------------------------------------------------------
261
// Test cases for the "directory" class.
262
// ------------------------------------------------------------------------
263
264
ATF_TEST_CASE(directory_read);
265
ATF_TEST_CASE_HEAD(directory_read)
266
{
267
set_md_var("descr", "Tests the directory class creation, which reads "
268
"the contents of a directory");
269
}
270
ATF_TEST_CASE_BODY(directory_read)
271
{
272
using atf::fs::directory;
273
using atf::fs::path;
274
275
create_files();
276
277
directory d(path("files"));
278
ATF_REQUIRE_EQ(d.size(), 4);
279
ATF_REQUIRE(d.find(".") != d.end());
280
ATF_REQUIRE(d.find("..") != d.end());
281
ATF_REQUIRE(d.find("dir") != d.end());
282
ATF_REQUIRE(d.find("reg") != d.end());
283
}
284
285
ATF_TEST_CASE(directory_file_info);
286
ATF_TEST_CASE_HEAD(directory_file_info)
287
{
288
set_md_var("descr", "Tests that the file_info objects attached to the "
289
"directory are valid");
290
}
291
ATF_TEST_CASE_BODY(directory_file_info)
292
{
293
using atf::fs::directory;
294
using atf::fs::file_info;
295
using atf::fs::path;
296
297
create_files();
298
299
directory d(path("files"));
300
301
{
302
directory::const_iterator iter = d.find("dir");
303
ATF_REQUIRE(iter != d.end());
304
const file_info& fi = (*iter).second;
305
ATF_REQUIRE(fi.get_type() == file_info::dir_type);
306
}
307
308
{
309
directory::const_iterator iter = d.find("reg");
310
ATF_REQUIRE(iter != d.end());
311
const file_info& fi = (*iter).second;
312
ATF_REQUIRE(fi.get_type() == file_info::reg_type);
313
}
314
}
315
316
ATF_TEST_CASE(directory_names);
317
ATF_TEST_CASE_HEAD(directory_names)
318
{
319
set_md_var("descr", "Tests the directory's names method");
320
}
321
ATF_TEST_CASE_BODY(directory_names)
322
{
323
using atf::fs::directory;
324
using atf::fs::path;
325
326
create_files();
327
328
directory d(path("files"));
329
std::set< std::string > ns = d.names();
330
ATF_REQUIRE_EQ(ns.size(), 4);
331
ATF_REQUIRE(ns.find(".") != ns.end());
332
ATF_REQUIRE(ns.find("..") != ns.end());
333
ATF_REQUIRE(ns.find("dir") != ns.end());
334
ATF_REQUIRE(ns.find("reg") != ns.end());
335
}
336
337
// ------------------------------------------------------------------------
338
// Test cases for the "file_info" class.
339
// ------------------------------------------------------------------------
340
341
ATF_TEST_CASE(file_info_stat);
342
ATF_TEST_CASE_HEAD(file_info_stat)
343
{
344
set_md_var("descr", "Tests the file_info creation and its basic contents");
345
}
346
ATF_TEST_CASE_BODY(file_info_stat)
347
{
348
using atf::fs::file_info;
349
using atf::fs::path;
350
351
create_files();
352
353
{
354
path p("files/dir");
355
file_info fi(p);
356
ATF_REQUIRE(fi.get_type() == file_info::dir_type);
357
}
358
359
{
360
path p("files/reg");
361
file_info fi(p);
362
ATF_REQUIRE(fi.get_type() == file_info::reg_type);
363
}
364
}
365
366
ATF_TEST_CASE(file_info_perms);
367
ATF_TEST_CASE_HEAD(file_info_perms)
368
{
369
set_md_var("descr", "Tests the file_info methods to get the file's "
370
"permissions");
371
}
372
ATF_TEST_CASE_BODY(file_info_perms)
373
{
374
using atf::fs::file_info;
375
using atf::fs::path;
376
377
path p("file");
378
379
std::ofstream os(p.c_str());
380
os.close();
381
382
#define perms(ur, uw, ux, gr, gw, gx, othr, othw, othx) \
383
{ \
384
file_info fi(p); \
385
ATF_REQUIRE(fi.is_owner_readable() == ur); \
386
ATF_REQUIRE(fi.is_owner_writable() == uw); \
387
ATF_REQUIRE(fi.is_owner_executable() == ux); \
388
ATF_REQUIRE(fi.is_group_readable() == gr); \
389
ATF_REQUIRE(fi.is_group_writable() == gw); \
390
ATF_REQUIRE(fi.is_group_executable() == gx); \
391
ATF_REQUIRE(fi.is_other_readable() == othr); \
392
ATF_REQUIRE(fi.is_other_writable() == othw); \
393
ATF_REQUIRE(fi.is_other_executable() == othx); \
394
}
395
396
::chmod(p.c_str(), 0000);
397
perms(false, false, false, false, false, false, false, false, false);
398
399
::chmod(p.c_str(), 0001);
400
perms(false, false, false, false, false, false, false, false, true);
401
402
::chmod(p.c_str(), 0010);
403
perms(false, false, false, false, false, true, false, false, false);
404
405
::chmod(p.c_str(), 0100);
406
perms(false, false, true, false, false, false, false, false, false);
407
408
::chmod(p.c_str(), 0002);
409
perms(false, false, false, false, false, false, false, true, false);
410
411
::chmod(p.c_str(), 0020);
412
perms(false, false, false, false, true, false, false, false, false);
413
414
::chmod(p.c_str(), 0200);
415
perms(false, true, false, false, false, false, false, false, false);
416
417
::chmod(p.c_str(), 0004);
418
perms(false, false, false, false, false, false, true, false, false);
419
420
::chmod(p.c_str(), 0040);
421
perms(false, false, false, true, false, false, false, false, false);
422
423
::chmod(p.c_str(), 0400);
424
perms(true, false, false, false, false, false, false, false, false);
425
426
::chmod(p.c_str(), 0644);
427
perms(true, true, false, true, false, false, true, false, false);
428
429
::chmod(p.c_str(), 0755);
430
perms(true, true, true, true, false, true, true, false, true);
431
432
::chmod(p.c_str(), 0777);
433
perms(true, true, true, true, true, true, true, true, true);
434
435
#undef perms
436
}
437
438
// ------------------------------------------------------------------------
439
// Test cases for the free functions.
440
// ------------------------------------------------------------------------
441
442
ATF_TEST_CASE(exists);
443
ATF_TEST_CASE_HEAD(exists)
444
{
445
set_md_var("descr", "Tests the exists function");
446
}
447
ATF_TEST_CASE_BODY(exists)
448
{
449
using atf::fs::exists;
450
using atf::fs::path;
451
452
create_files();
453
454
ATF_REQUIRE( exists(path("files")));
455
ATF_REQUIRE(!exists(path("file")));
456
ATF_REQUIRE(!exists(path("files2")));
457
458
ATF_REQUIRE( exists(path("files/.")));
459
ATF_REQUIRE( exists(path("files/..")));
460
ATF_REQUIRE( exists(path("files/dir")));
461
ATF_REQUIRE( exists(path("files/reg")));
462
ATF_REQUIRE(!exists(path("files/foo")));
463
}
464
465
ATF_TEST_CASE(is_executable);
466
ATF_TEST_CASE_HEAD(is_executable)
467
{
468
set_md_var("descr", "Tests the is_executable function");
469
}
470
ATF_TEST_CASE_BODY(is_executable)
471
{
472
using atf::fs::is_executable;
473
using atf::fs::path;
474
475
create_files();
476
477
ATF_REQUIRE( is_executable(path("files")));
478
ATF_REQUIRE( is_executable(path("files/.")));
479
ATF_REQUIRE( is_executable(path("files/..")));
480
ATF_REQUIRE( is_executable(path("files/dir")));
481
482
ATF_REQUIRE(!is_executable(path("non-existent")));
483
484
ATF_REQUIRE(!is_executable(path("files/reg")));
485
ATF_REQUIRE(::chmod("files/reg", 0755) != -1);
486
ATF_REQUIRE( is_executable(path("files/reg")));
487
}
488
489
ATF_TEST_CASE(remove);
490
ATF_TEST_CASE_HEAD(remove)
491
{
492
set_md_var("descr", "Tests the remove function");
493
}
494
ATF_TEST_CASE_BODY(remove)
495
{
496
using atf::fs::exists;
497
using atf::fs::path;
498
using atf::fs::remove;
499
500
create_files();
501
502
ATF_REQUIRE( exists(path("files/reg")));
503
remove(path("files/reg"));
504
ATF_REQUIRE(!exists(path("files/reg")));
505
506
ATF_REQUIRE( exists(path("files/dir")));
507
ATF_REQUIRE_THROW(atf::system_error, remove(path("files/dir")));
508
ATF_REQUIRE( exists(path("files/dir")));
509
}
510
511
// ------------------------------------------------------------------------
512
// Main.
513
// ------------------------------------------------------------------------
514
515
ATF_INIT_TEST_CASES(tcs)
516
{
517
// Add the tests for the "path" class.
518
ATF_ADD_TEST_CASE(tcs, path_normalize);
519
ATF_ADD_TEST_CASE(tcs, path_is_absolute);
520
ATF_ADD_TEST_CASE(tcs, path_is_root);
521
ATF_ADD_TEST_CASE(tcs, path_branch_path);
522
ATF_ADD_TEST_CASE(tcs, path_leaf_name);
523
ATF_ADD_TEST_CASE(tcs, path_compare_equal);
524
ATF_ADD_TEST_CASE(tcs, path_compare_different);
525
ATF_ADD_TEST_CASE(tcs, path_concat);
526
ATF_ADD_TEST_CASE(tcs, path_to_absolute);
527
ATF_ADD_TEST_CASE(tcs, path_op_less);
528
529
// Add the tests for the "file_info" class.
530
ATF_ADD_TEST_CASE(tcs, file_info_stat);
531
ATF_ADD_TEST_CASE(tcs, file_info_perms);
532
533
// Add the tests for the "directory" class.
534
ATF_ADD_TEST_CASE(tcs, directory_read);
535
ATF_ADD_TEST_CASE(tcs, directory_names);
536
ATF_ADD_TEST_CASE(tcs, directory_file_info);
537
538
// Add the tests for the free functions.
539
ATF_ADD_TEST_CASE(tcs, exists);
540
ATF_ADD_TEST_CASE(tcs, is_executable);
541
ATF_ADD_TEST_CASE(tcs, remove);
542
}
543
544