1 #include <stic.h>
2
3 #include <sys/stat.h> /* stat chmod() */
4 #include <sys/types.h> /* stat */
5 #include <unistd.h> /* F_OK access() */
6
7 #include "../../src/compat/os.h"
8 #include "../../src/io/iop.h"
9 #include "../../src/io/ior.h"
10 #include "../../src/utils/fs.h"
11
12 #include "utils.h"
13
TEST(file_is_copied)14 TEST(file_is_copied)
15 {
16 {
17 io_args_t args = {
18 .arg1.src = TEST_DATA_PATH "/read/binary-data",
19 .arg2.dst = SANDBOX_PATH "/binary-data",
20 };
21 ioe_errlst_init(&args.result.errors);
22
23 assert_success(ior_cp(&args));
24 assert_int_equal(0, args.result.errors.error_count);
25 }
26
27 {
28 io_args_t args = {
29 .arg1.path = SANDBOX_PATH "/binary-data",
30 };
31 ioe_errlst_init(&args.result.errors);
32
33 assert_success(iop_rmfile(&args));
34 assert_int_equal(0, args.result.errors.error_count);
35 }
36 }
37
TEST(empty_directory_is_copied)38 TEST(empty_directory_is_copied)
39 {
40 create_empty_dir(SANDBOX_PATH "/empty-dir");
41
42 {
43 io_args_t args = {
44 .arg1.src = SANDBOX_PATH "/empty-dir",
45 .arg2.dst = SANDBOX_PATH "/empty-dir-copy",
46 };
47 ioe_errlst_init(&args.result.errors);
48
49 assert_success(ior_cp(&args));
50 assert_int_equal(0, args.result.errors.error_count);
51 }
52
53 {
54 io_args_t args = {
55 .arg1.path = SANDBOX_PATH "/empty-dir",
56 };
57 ioe_errlst_init(&args.result.errors);
58
59 assert_success(iop_rmdir(&args));
60 assert_int_equal(0, args.result.errors.error_count);
61 }
62
63 {
64 io_args_t args = {
65 .arg1.path = SANDBOX_PATH "/empty-dir-copy",
66 };
67 ioe_errlst_init(&args.result.errors);
68
69 assert_success(iop_rmdir(&args));
70 assert_int_equal(0, args.result.errors.error_count);
71 }
72 }
73
TEST(non_empty_directory_is_copied)74 TEST(non_empty_directory_is_copied)
75 {
76 create_non_empty_dir(SANDBOX_PATH "/non-empty-dir", "a-file");
77
78 {
79 io_args_t args = {
80 .arg1.src = SANDBOX_PATH "/non-empty-dir",
81 .arg2.dst = SANDBOX_PATH "/non-empty-dir-copy",
82 };
83 ioe_errlst_init(&args.result.errors);
84
85 assert_success(ior_cp(&args));
86 assert_int_equal(0, args.result.errors.error_count);
87 }
88
89 assert_success(access(SANDBOX_PATH "/non-empty-dir-copy/a-file", F_OK));
90
91 {
92 io_args_t args = {
93 .arg1.path = SANDBOX_PATH "/non-empty-dir",
94 };
95 ioe_errlst_init(&args.result.errors);
96
97 assert_success(ior_rm(&args));
98 assert_int_equal(0, args.result.errors.error_count);
99 }
100
101 {
102 io_args_t args = {
103 .arg1.path = SANDBOX_PATH "/non-empty-dir-copy",
104 };
105 ioe_errlst_init(&args.result.errors);
106
107 assert_success(ior_rm(&args));
108 assert_int_equal(0, args.result.errors.error_count);
109 }
110 }
111
TEST(empty_nested_directory_is_copied)112 TEST(empty_nested_directory_is_copied)
113 {
114 create_empty_nested_dir(SANDBOX_PATH "/non-empty-dir", "empty-nested-dir");
115
116 {
117 io_args_t args = {
118 .arg1.src = SANDBOX_PATH "/non-empty-dir",
119 .arg2.dst = SANDBOX_PATH "/non-empty-dir-copy",
120 };
121 ioe_errlst_init(&args.result.errors);
122
123 assert_success(ior_cp(&args));
124 assert_int_equal(0, args.result.errors.error_count);
125 }
126
127 assert_success(access(SANDBOX_PATH "/non-empty-dir-copy/empty-nested-dir",
128 F_OK));
129
130 {
131 io_args_t args = {
132 .arg1.path = SANDBOX_PATH "/non-empty-dir",
133 };
134 ioe_errlst_init(&args.result.errors);
135
136 assert_success(ior_rm(&args));
137 assert_int_equal(0, args.result.errors.error_count);
138 }
139
140 {
141 io_args_t args = {
142 .arg1.path = SANDBOX_PATH "/non-empty-dir-copy",
143 };
144 ioe_errlst_init(&args.result.errors);
145
146 assert_success(ior_rm(&args));
147 assert_int_equal(0, args.result.errors.error_count);
148 }
149 }
150
TEST(non_empty_nested_directory_is_copied)151 TEST(non_empty_nested_directory_is_copied)
152 {
153 create_non_empty_nested_dir(SANDBOX_PATH "/non-empty-dir", "nested-dir",
154 "a-file");
155
156 {
157 io_args_t args = {
158 .arg1.src = SANDBOX_PATH "/non-empty-dir",
159 .arg2.dst = SANDBOX_PATH "/non-empty-dir-copy",
160 };
161 ioe_errlst_init(&args.result.errors);
162
163 assert_success(ior_cp(&args));
164 assert_int_equal(0, args.result.errors.error_count);
165 }
166
167 assert_success(access(SANDBOX_PATH "/non-empty-dir-copy/nested-dir/a-file",
168 F_OK));
169
170 {
171 io_args_t args = {
172 .arg1.path = SANDBOX_PATH "/non-empty-dir",
173 };
174 ioe_errlst_init(&args.result.errors);
175
176 assert_success(ior_rm(&args));
177 assert_int_equal(0, args.result.errors.error_count);
178 }
179
180 {
181 io_args_t args = {
182 .arg1.path = SANDBOX_PATH "/non-empty-dir-copy",
183 };
184 ioe_errlst_init(&args.result.errors);
185
186 assert_success(ior_rm(&args));
187 assert_int_equal(0, args.result.errors.error_count);
188 }
189 }
190
TEST(fails_to_overwrite_file_by_default)191 TEST(fails_to_overwrite_file_by_default)
192 {
193 create_empty_file(SANDBOX_PATH "/a-file");
194
195 {
196 io_args_t args = {
197 .arg1.src = TEST_DATA_PATH "/read/two-lines",
198 .arg2.dst = SANDBOX_PATH "/a-file",
199 };
200 ioe_errlst_init(&args.result.errors);
201
202 assert_failure(ior_cp(&args));
203
204 assert_true(args.result.errors.error_count != 0);
205 ioe_errlst_free(&args.result.errors);
206 }
207
208 {
209 io_args_t args = {
210 .arg1.path = SANDBOX_PATH "/a-file",
211 };
212 ioe_errlst_init(&args.result.errors);
213
214 assert_success(iop_rmfile(&args));
215 assert_int_equal(0, args.result.errors.error_count);
216 }
217 }
218
TEST(fails_to_overwrite_dir_by_default)219 TEST(fails_to_overwrite_dir_by_default)
220 {
221 create_empty_dir(SANDBOX_PATH "/empty-dir");
222
223 {
224 io_args_t args = {
225 .arg1.src = TEST_DATA_PATH "/read",
226 .arg2.dst = SANDBOX_PATH "/empty-dir",
227 };
228 ioe_errlst_init(&args.result.errors);
229
230 assert_failure(ior_cp(&args));
231
232 assert_true(args.result.errors.error_count != 0);
233 ioe_errlst_free(&args.result.errors);
234 }
235
236 {
237 io_args_t args = {
238 .arg1.path = SANDBOX_PATH "/empty-dir",
239 };
240 ioe_errlst_init(&args.result.errors);
241
242 assert_success(iop_rmdir(&args));
243 assert_int_equal(0, args.result.errors.error_count);
244 }
245 }
246
TEST(overwrites_file_when_asked)247 TEST(overwrites_file_when_asked)
248 {
249 create_empty_file(SANDBOX_PATH "/a-file");
250
251 {
252 io_args_t args = {
253 .arg1.src = TEST_DATA_PATH "/read/two-lines",
254 .arg2.dst = SANDBOX_PATH "/a-file",
255 .arg3.crs = IO_CRS_REPLACE_FILES,
256 };
257 ioe_errlst_init(&args.result.errors);
258
259 assert_success(ior_cp(&args));
260 assert_int_equal(0, args.result.errors.error_count);
261 }
262
263 {
264 io_args_t args = {
265 .arg1.path = SANDBOX_PATH "/a-file",
266 };
267 ioe_errlst_init(&args.result.errors);
268
269 assert_success(iop_rmfile(&args));
270 assert_int_equal(0, args.result.errors.error_count);
271 }
272 }
273
TEST(overwrites_dir_when_asked)274 TEST(overwrites_dir_when_asked)
275 {
276 create_empty_dir(SANDBOX_PATH "/dir");
277
278 {
279 io_args_t args = {
280 .arg1.src = TEST_DATA_PATH "/read",
281 .arg2.dst = SANDBOX_PATH "/dir",
282 .arg3.crs = IO_CRS_REPLACE_ALL,
283 };
284 ioe_errlst_init(&args.result.errors);
285
286 assert_success(ior_cp(&args));
287 assert_int_equal(0, args.result.errors.error_count);
288 }
289
290 {
291 io_args_t args = {
292 .arg1.path = SANDBOX_PATH "/dir",
293 };
294 ioe_errlst_init(&args.result.errors);
295
296 assert_failure(iop_rmdir(&args));
297
298 assert_true(args.result.errors.error_count != 0);
299 ioe_errlst_free(&args.result.errors);
300 }
301
302 assert_success(chmod(SANDBOX_PATH "/dir", 0700));
303
304 {
305 io_args_t args = {
306 .arg1.path = SANDBOX_PATH "/dir",
307 };
308 ioe_errlst_init(&args.result.errors);
309
310 assert_success(ior_rm(&args));
311 assert_int_equal(0, args.result.errors.error_count);
312 }
313 }
314
TEST(directories_can_be_merged)315 TEST(directories_can_be_merged)
316 {
317 create_empty_dir(SANDBOX_PATH "/first");
318 create_empty_file(SANDBOX_PATH "/first/first-file");
319
320 create_empty_dir(SANDBOX_PATH "/second");
321 create_empty_file(SANDBOX_PATH "/second/second-file");
322
323 {
324 io_args_t args = {
325 .arg1.src = SANDBOX_PATH "/first",
326 .arg2.dst = SANDBOX_PATH "/second",
327 .arg3.crs = IO_CRS_REPLACE_FILES,
328 };
329 ioe_errlst_init(&args.result.errors);
330
331 assert_success(ior_cp(&args));
332 assert_int_equal(0, args.result.errors.error_count);
333 }
334
335 assert_success(access(SANDBOX_PATH "/second/second-file", F_OK));
336 assert_success(access(SANDBOX_PATH "/second/first-file", F_OK));
337
338 {
339 io_args_t args = {
340 .arg1.path = SANDBOX_PATH "/first",
341 };
342 ioe_errlst_init(&args.result.errors);
343
344 assert_success(ior_rm(&args));
345 assert_int_equal(0, args.result.errors.error_count);
346 }
347
348 {
349 io_args_t args = {
350 .arg1.path = SANDBOX_PATH "/second",
351 };
352 ioe_errlst_init(&args.result.errors);
353
354 assert_success(ior_rm(&args));
355 assert_int_equal(0, args.result.errors.error_count);
356 }
357 }
358
TEST(fails_to_copy_directory_inside_itself)359 TEST(fails_to_copy_directory_inside_itself)
360 {
361 create_empty_dir(SANDBOX_PATH "/empty-dir");
362
363 {
364 io_args_t args = {
365 .arg1.src = SANDBOX_PATH "/empty-dir",
366 .arg2.dst = SANDBOX_PATH "/empty-dir/empty-dir-copy",
367 };
368 ioe_errlst_init(&args.result.errors);
369
370 assert_failure(ior_cp(&args));
371
372 assert_true(args.result.errors.error_count != 0);
373 ioe_errlst_free(&args.result.errors);
374 }
375
376 {
377 io_args_t args = {
378 .arg1.path = SANDBOX_PATH "/empty-dir",
379 };
380 ioe_errlst_init(&args.result.errors);
381
382 assert_success(iop_rmdir(&args));
383 assert_int_equal(0, args.result.errors.error_count);
384 }
385 }
386
TEST(dir_permissions_are_preserved)387 TEST(dir_permissions_are_preserved)
388 {
389 struct stat src;
390 struct stat dst;
391
392 {
393 io_args_t args = {
394 .arg1.path = SANDBOX_PATH "/dir",
395 .arg3.mode = 0711,
396 };
397 ioe_errlst_init(&args.result.errors);
398
399 assert_success(iop_mkdir(&args));
400 assert_int_equal(0, args.result.errors.error_count);
401 }
402
403 {
404 io_args_t args = {
405 .arg1.src = SANDBOX_PATH "/dir",
406 .arg2.dst = SANDBOX_PATH "/dir-copy",
407 };
408 ioe_errlst_init(&args.result.errors);
409
410 assert_success(ior_cp(&args));
411 assert_int_equal(0, args.result.errors.error_count);
412 }
413
414 assert_success(os_stat(SANDBOX_PATH "/dir", &src));
415 assert_success(os_stat(SANDBOX_PATH "/dir-copy", &dst));
416 assert_int_equal(src.st_mode & 0777, dst.st_mode & 0777);
417
418 {
419 io_args_t args = {
420 .arg1.path = SANDBOX_PATH "/dir",
421 };
422 ioe_errlst_init(&args.result.errors);
423
424 assert_success(iop_rmdir(&args));
425 assert_int_equal(0, args.result.errors.error_count);
426 }
427
428 {
429 io_args_t args = {
430 .arg1.path = SANDBOX_PATH "/dir-copy",
431 };
432 ioe_errlst_init(&args.result.errors);
433
434 assert_success(iop_rmdir(&args));
435 assert_int_equal(0, args.result.errors.error_count);
436 }
437 }
438
TEST(permissions_are_set_in_correct_order)439 TEST(permissions_are_set_in_correct_order)
440 {
441 struct stat src;
442 struct stat dst;
443
444 {
445 io_args_t args = {
446 .arg1.path = SANDBOX_PATH "/dir/nested-dir",
447 .arg2.process_parents = 1,
448 .arg3.mode = 0600,
449 };
450 ioe_errlst_init(&args.result.errors);
451
452 assert_success(iop_mkdir(&args));
453 assert_int_equal(0, args.result.errors.error_count);
454 }
455
456 assert_success(chmod(SANDBOX_PATH "/dir", 0500));
457
458 {
459 io_args_t args = {
460 .arg1.src = SANDBOX_PATH "/dir",
461 .arg2.dst = SANDBOX_PATH "/dir-copy",
462 };
463 ioe_errlst_init(&args.result.errors);
464
465 assert_success(ior_cp(&args));
466 assert_int_equal(0, args.result.errors.error_count);
467 }
468
469 assert_success(os_stat(SANDBOX_PATH "/dir", &src));
470 assert_success(os_stat(SANDBOX_PATH "/dir-copy", &dst));
471 assert_int_equal(src.st_mode & 0777, dst.st_mode & 0777);
472
473 assert_success(chmod(SANDBOX_PATH "/dir", 0700));
474 assert_success(chmod(SANDBOX_PATH "/dir-copy", 0700));
475
476 {
477 io_args_t args = {
478 .arg1.path = SANDBOX_PATH "/dir",
479 };
480 ioe_errlst_init(&args.result.errors);
481
482 assert_success(ior_rm(&args));
483 assert_int_equal(0, args.result.errors.error_count);
484 }
485
486 {
487 io_args_t args = {
488 .arg1.path = SANDBOX_PATH "/dir-copy",
489 };
490 ioe_errlst_init(&args.result.errors);
491
492 assert_success(ior_rm(&args));
493 assert_int_equal(0, args.result.errors.error_count);
494 }
495 }
496
497 /* Creating symbolic links on Windows requires administrator rights. */
TEST(symlink_to_file_is_symlink_after_copy,IF (not_windows))498 TEST(symlink_to_file_is_symlink_after_copy, IF(not_windows))
499 {
500 {
501 io_args_t args = {
502 .arg1.path = TEST_DATA_PATH "/read/two-lines",
503 .arg2.target = SANDBOX_PATH "/sym-link",
504 };
505 ioe_errlst_init(&args.result.errors);
506
507 assert_success(iop_ln(&args));
508 assert_int_equal(0, args.result.errors.error_count);
509 }
510
511 assert_true(is_symlink(SANDBOX_PATH "/sym-link"));
512
513 {
514 io_args_t args = {
515 .arg1.src = SANDBOX_PATH "/sym-link",
516 .arg2.dst = SANDBOX_PATH "/sym-link-copy",
517 };
518 ioe_errlst_init(&args.result.errors);
519
520 assert_success(ior_cp(&args));
521 assert_int_equal(0, args.result.errors.error_count);
522 }
523
524 assert_true(is_symlink(SANDBOX_PATH "/sym-link"));
525 assert_true(is_symlink(SANDBOX_PATH "/sym-link-copy"));
526
527 {
528 io_args_t args = {
529 .arg1.path = SANDBOX_PATH "/sym-link",
530 };
531 ioe_errlst_init(&args.result.errors);
532
533 assert_success(iop_rmfile(&args));
534 assert_int_equal(0, args.result.errors.error_count);
535 }
536
537 {
538 io_args_t args = {
539 .arg1.path = SANDBOX_PATH "/sym-link-copy",
540 };
541 ioe_errlst_init(&args.result.errors);
542
543 assert_success(iop_rmfile(&args));
544 assert_int_equal(0, args.result.errors.error_count);
545 }
546 }
547
548 /* Creating symbolic links on Windows requires administrator rights. */
TEST(symlink_to_dir_is_symlink_after_copy,IF (not_windows))549 TEST(symlink_to_dir_is_symlink_after_copy, IF(not_windows))
550 {
551 {
552 io_args_t args = {
553 .arg1.path = TEST_DATA_PATH "/read",
554 .arg2.target = SANDBOX_PATH "/sym-link",
555 };
556 ioe_errlst_init(&args.result.errors);
557
558 assert_success(iop_ln(&args));
559 assert_int_equal(0, args.result.errors.error_count);
560 }
561
562 assert_true(is_symlink(SANDBOX_PATH "/sym-link"));
563
564 {
565 io_args_t args = {
566 .arg1.src = SANDBOX_PATH "/sym-link",
567 .arg2.dst = SANDBOX_PATH "/sym-link-copy",
568 };
569 ioe_errlst_init(&args.result.errors);
570
571 assert_success(ior_cp(&args));
572 assert_int_equal(0, args.result.errors.error_count);
573 }
574
575 assert_true(is_symlink(SANDBOX_PATH "/sym-link"));
576 assert_true(is_symlink(SANDBOX_PATH "/sym-link-copy"));
577
578 {
579 io_args_t args = {
580 .arg1.path = SANDBOX_PATH "/sym-link",
581 };
582 ioe_errlst_init(&args.result.errors);
583
584 assert_success(iop_rmfile(&args));
585 assert_int_equal(0, args.result.errors.error_count);
586 }
587
588 {
589 io_args_t args = {
590 .arg1.path = SANDBOX_PATH "/sym-link-copy",
591 };
592 ioe_errlst_init(&args.result.errors);
593
594 assert_success(iop_rmfile(&args));
595 assert_int_equal(0, args.result.errors.error_count);
596 }
597 }
598
599 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
600 /* vim: set cinoptions+=t0 filetype=c : */
601