]>
git.saurik.com Git - apple/copyfile.git/blob - copyfile_test/identical_test.c
11 #include <removefile.h>
12 #include <sys/fcntl.h>
14 #include <sys/xattr.h>
16 #include "../copyfile.h"
17 #include "identical_test.h"
18 #include "test_utils.h"
20 #define REGULAR_FILE_NAME "regular_file"
21 #define REGULAR_DIR_NAME "regular_dir"
22 #define DUMMY_XATTR_NAME "dummy_xattr"
23 #define DUMMY_XATTR_DATA "drell"
24 #define TEST_FILE_DATA "krogan"
26 static bool verify_src_dst_identical(const char *apfs_test_directory
, __unused
size_t block_size
) {
27 char regular_file
[BSIZE_B
] = {0}, folder
[BSIZE_B
] = {0}, file_inside_folder
[BSIZE_B
] = {0};
28 int regular_file_fd
, file_inside_folder_fd
;
31 // The idea here is to verify that copyfile(file1, file1) returns success
32 // without doing anything.
33 // There are a few wrinkles - COPYFILE_CHECK still needs to work on these files,
34 // and we need to make sure that our identity check works on filesystems without
35 // persistent object identifiers. The first we can easily verify but the second
36 // is not tested here. Nor are negative tests included (there are an infinite
37 // number of those, so we rely on the other tests to verify that behavior).
40 assert_with_errno(snprintf(regular_file
, BSIZE_B
, "%s/" REGULAR_FILE_NAME
, apfs_test_directory
) > 0);
41 assert_with_errno(snprintf(folder
, BSIZE_B
, "%s/" REGULAR_DIR_NAME
, apfs_test_directory
) > 0);
42 assert_with_errno(snprintf(file_inside_folder
, BSIZE_B
, "%s/" REGULAR_FILE_NAME
, folder
) > 0);
44 // First, verify copyfile(file1, file1),
45 // where file1 is a regular file.
47 // Create our regular file.
48 regular_file_fd
= open(regular_file
, DEFAULT_OPEN_FLAGS
, DEFAULT_OPEN_PERM
);
49 assert_with_errno(regular_file_fd
>= 0);
51 // Write some data to the test file so that we can verify it is not empty.
52 assert(write(regular_file_fd
, TEST_FILE_DATA
, sizeof(TEST_FILE_DATA
)) > 0);
54 // Verify copyfile(file1, file1) does nothing.
55 assert_no_err(copyfile(regular_file
, regular_file
, NULL
, COPYFILE_ALL
));
56 success
= success
&& verify_contents_with_buf(regular_file_fd
, 0, (const char *)TEST_FILE_DATA
, sizeof(TEST_FILE_DATA
));
58 // Verify copyfile(file1, file1, COPYFILE_EXCL) returns an error.
59 assert(copyfile(regular_file
, regular_file
, NULL
, COPYFILE_ALL
|COPYFILE_EXCL
) == -1);
60 assert(errno
== EEXIST
);
62 // Write an dummy xattr to the file to verify COPYFILE_CHECK.
63 assert_no_err(fsetxattr(regular_file_fd
, DUMMY_XATTR_NAME
, DUMMY_XATTR_DATA
, sizeof(DUMMY_XATTR_DATA
), 0, XATTR_CREATE
));
65 // Verify copyfile(file1, file1, ..., COPYFILE_CHECK) works.
66 assert_no_err(copyfile(regular_file
, regular_file
, NULL
, COPYFILE_CHECK
) == COPYFILE_XATTR
);
68 // Now, verify that copyfile(dir1, dir1, COPYFILE_RECURSIVE)
69 // also returns early. Do this by making sure the contents of a file inside the directory
70 // do not change after copyfile(COPYFILE_RECURSIVE).
72 // Create our directory.
73 assert_no_err(mkdir(folder
, DEFAULT_MKDIR_PERM
));
75 // Create a regular file inside that directory.
77 file_inside_folder_fd
= open(file_inside_folder
, DEFAULT_OPEN_FLAGS
, DEFAULT_OPEN_PERM
);
78 assert_with_errno(file_inside_folder_fd
>= 0);
80 // Write some data to the interior file so that we can verify it is not empty.
81 assert(write(file_inside_folder_fd
, (const char *)TEST_FILE_DATA
, sizeof(TEST_FILE_DATA
)) > 0);
83 // Verify copyfile(dir1, dir1, ... COPYFILE_RECURSIVE).
84 assert_no_err(copyfile(folder
, folder
, NULL
, COPYFILE_RECURSIVE
));
85 success
= success
&& verify_contents_with_buf(file_inside_folder_fd
, 0, TEST_FILE_DATA
, sizeof(TEST_FILE_DATA
));
88 assert_no_err(close(file_inside_folder_fd
));
89 assert_no_err(close(regular_file_fd
));
90 (void)removefile(folder
, NULL
, REMOVEFILE_RECURSIVE
);
91 (void)removefile(regular_file
, NULL
, 0);
96 bool do_src_dst_identical_test(const char *apfs_test_directory
, __unused
size_t block_size
) {
97 char test_dir
[BSIZE_B
] = {0};
101 printf("START [identical]\n");
103 // Get ready for the test.
104 test_folder_id
= rand() % DEFAULT_NAME_MOD
;
105 create_test_file_name(apfs_test_directory
, "identical", test_folder_id
, test_dir
);
106 assert_no_err(mkdir(test_dir
, DEFAULT_MKDIR_PERM
));
108 success
= verify_src_dst_identical(test_dir
, block_size
);
111 printf("PASS [identical]\n");
113 printf("FAIL [identical]\n");
116 (void)removefile(test_dir
, NULL
, REMOVEFILE_RECURSIVE
);
118 return success
? EXIT_SUCCESS
: EXIT_FAILURE
;