Branch data Line data Source code
1 : : /*
2 : : * Authors:
3 : : * Jakub Hrozek <jhrozek@redhat.com>
4 : : *
5 : : * Copyright (C) 2008 Red Hat
6 : : * see file 'COPYING' for use and warranty information
7 : : *
8 : : * This program is free software; you can redistribute it and/or
9 : : * modify it under the terms of the GNU General Public License as
10 : : * published by the Free Software Foundation; version 3 or (at
11 : : * your option) any later version.
12 : : *
13 : : * This program is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : : * GNU General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU General Public License
19 : : * along with this program; if not, write to the Free Software
20 : : * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 : : */
22 : :
23 : : #include <stdlib.h>
24 : : #include <check.h>
25 : : #include <unistd.h>
26 : : #include <sys/types.h>
27 : : #include <sys/stat.h>
28 : : #include <fcntl.h>
29 : : #include <limits.h>
30 : : #include <errno.h>
31 : : #include <talloc.h>
32 : : #include <popt.h>
33 : :
34 : : #include "config.h"
35 : : #include "tools/tools_util.h"
36 : : #include "util/util.h"
37 : : #include "tests/common.h"
38 : :
39 : : static char tpl_dir[] = "file-tests-dir-XXXXXX";
40 : : static char *dir_path;
41 : : static char *dst_path;
42 : : static uid_t uid;
43 : : static gid_t gid;
44 : : static TALLOC_CTX *test_ctx = NULL;
45 : :
46 : 4 : static void setup_files_test(void)
47 : : {
48 : : /* create a temporary directory that we fill with stuff later on */
49 : 4 : test_ctx = talloc_new(NULL);
50 : 4 : dir_path = mkdtemp(talloc_strdup(test_ctx, tpl_dir));
51 : 4 : dst_path = mkdtemp(talloc_strdup(test_ctx, tpl_dir));
52 : :
53 : 4 : uid = getuid();
54 : 4 : gid = getgid();
55 : 4 : }
56 : :
57 : 4 : static void teardown_files_test(void)
58 : : {
59 : 4 : char *cmd = NULL;
60 : : int ret;
61 : :
62 : : /* OK this is crude but since the functions to remove tree are under test.. */
63 [ + - ][ + - ]: 4 : if (dir_path && test_ctx) {
64 : 4 : cmd = talloc_asprintf(test_ctx, "/bin/rm -rf %s\n", dir_path);
65 : 4 : ret = system(cmd);
66 [ - + ]: 4 : if (ret == -1) {
67 [ # # ][ # # ]: 0 : DEBUG(1, ("Removing [%s] failed.\n", dir_path));
[ # # ][ # # ]
[ # # ]
68 : : }
69 : : }
70 [ + - ][ + - ]: 4 : if (dst_path && test_ctx) {
71 : 4 : cmd = talloc_asprintf(test_ctx, "/bin/rm -rf %s\n", dst_path);
72 : 4 : ret = system(cmd);
73 [ - + ]: 4 : if (ret == -1) {
74 [ # # ][ # # ]: 0 : DEBUG(1, ("Removing [%s] failed.\n", dst_path));
[ # # ][ # # ]
[ # # ]
75 : : }
76 : : }
77 : :
78 : : /* clean up */
79 : 4 : talloc_zfree(test_ctx);
80 : 4 : }
81 : :
82 : 5 : static int create_simple_file(const char *name, const char *content)
83 : : {
84 : : int fd;
85 : : ssize_t size;
86 : : int ret;
87 : :
88 : 5 : fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0700);
89 : 5 : fail_if(fd == -1, "Cannot create simple file\n");
90 : :
91 : 5 : size = write(fd, "abc", 3);
92 : 5 : fail_if(size == -1, "Cannot write to file\n");
93 : :
94 : 5 : ret = fsync(fd);
95 : 5 : fail_if(ret == -1, "Cannot sync file\n");
96 : :
97 : 5 : ret = close(fd);
98 : 5 : fail_if(ret == -1, "Cannot close file\n");
99 : :
100 : 5 : return ret;
101 : : }
102 : :
103 : 1 : START_TEST(test_remove_tree)
104 : : {
105 : : int ret;
106 : : char origpath[PATH_MAX+1];
107 : :
108 : 1 : errno = 0;
109 : 1 : fail_unless(getcwd(origpath, PATH_MAX) == origpath, "Cannot getcwd\n");
110 : 1 : fail_unless(errno == 0, "Cannot getcwd\n");
111 : :
112 [ + - ][ - + ]: 1 : DEBUG(5, ("About to delete %s\n", dir_path));
[ # # ][ # # ]
[ # # ]
113 : :
114 : : /* create a file */
115 : 1 : ret = chdir(dir_path);
116 : 1 : fail_if(ret == -1, "Cannot chdir1\n");
117 : :
118 : 1 : ret = create_simple_file("bar", "bar");
119 : 1 : fail_if(ret == -1, "Cannot create file1\n");
120 : :
121 : : /* create a subdir and file inside it */
122 : 1 : ret = mkdir("subdir", 0700);
123 : 1 : fail_if(ret == -1, "Cannot create subdir\n");
124 : :
125 : 1 : ret = chdir("subdir");
126 : 1 : fail_if(ret == -1, "Cannot chdir\n");
127 : :
128 : 1 : ret = create_simple_file("foo", "foo");
129 : 1 : fail_if(ret == -1, "Cannot create file\n");
130 : :
131 : : /* create another subdir, empty this time */
132 : 1 : ret = mkdir("subdir2", 0700);
133 : 1 : fail_if(ret == -1, "Cannot create subdir\n");
134 : :
135 : 1 : ret = chdir(origpath);
136 : 1 : fail_if(ret == -1, "Cannot chdir2\n");
137 : :
138 : : /* go back */
139 : 1 : ret = chdir(origpath);
140 : 1 : fail_if(ret == -1, "Cannot chdir\n");
141 : :
142 : : /* and finally wipe it out.. */
143 : 1 : ret = remove_tree(dir_path);
144 : 1 : fail_unless(ret == EOK, "remove_tree failed\n");
145 : :
146 : : /* check if really gone */
147 : 1 : ret = access(dir_path, F_OK);
148 : 1 : fail_unless(ret == -1, "directory still there after remove_tree\n");
149 : : }
150 : 1 : END_TEST
151 : :
152 : 1 : START_TEST(test_simple_copy)
153 : : {
154 : : int ret;
155 : : char origpath[PATH_MAX+1];
156 : : char *tmp;
157 : 1 : int fd = -1;
158 : :
159 : 1 : errno = 0;
160 : 1 : fail_unless(getcwd(origpath, PATH_MAX) == origpath, "Cannot getcwd\n");
161 : 1 : fail_unless(errno == 0, "Cannot getcwd\n");
162 : :
163 : : /* create a file */
164 : 1 : ret = chdir(dir_path);
165 : 1 : fail_if(ret == -1, "Cannot chdir1\n");
166 : :
167 : 1 : ret = create_simple_file("bar", "bar");
168 : 1 : fail_if(ret == -1, "Cannot create file1\n");
169 : :
170 : : /* create a subdir and file inside it */
171 : 1 : ret = mkdir("subdir", 0700);
172 : 1 : fail_if(ret == -1, "Cannot create subdir\n");
173 : :
174 : 1 : ret = chdir("subdir");
175 : 1 : fail_if(ret == -1, "Cannot chdir\n");
176 : :
177 : 1 : ret = create_simple_file("foo", "foo");
178 : 1 : fail_if(ret == -1, "Cannot create file\n");
179 : :
180 : : /* go back */
181 : 1 : ret = chdir(origpath);
182 : 1 : fail_if(ret == -1, "Cannot chdir\n");
183 : :
184 : : /* and finally copy.. */
185 [ + - ][ - + ]: 1 : DEBUG(5, ("Will copy from '%s' to '%s'\n", dir_path, dst_path));
[ # # ][ # # ]
[ # # ]
186 : 1 : ret = copy_tree(dir_path, dst_path, uid, gid);
187 : 1 : fail_unless(ret == EOK, "copy_tree failed\n");
188 : :
189 : : /* check if really copied */
190 : 1 : ret = access(dst_path, F_OK);
191 : 1 : fail_unless(ret == 0, "destination directory not there\n");
192 : :
193 : 1 : tmp = talloc_asprintf(test_ctx, "%s/bar", dst_path);
194 : 1 : ret = check_and_open_readonly(tmp, &fd, uid, gid, 0700, CHECK_REG);
195 : 1 : fail_unless(ret == EOK, "Cannot open %s\n");
196 : 1 : close(fd);
197 : 1 : talloc_free(tmp);
198 : : }
199 : 1 : END_TEST
200 : :
201 : 1 : START_TEST(test_copy_symlink)
202 : : {
203 : : int ret;
204 : : char origpath[PATH_MAX+1];
205 : : char *tmp;
206 : : struct stat statbuf;
207 : :
208 : 1 : errno = 0;
209 : 1 : fail_unless(getcwd(origpath, PATH_MAX) == origpath, "Cannot getcwd\n");
210 : 1 : fail_unless(errno == 0, "Cannot getcwd\n");
211 : :
212 : : /* create a subdir */
213 : 1 : ret = chdir(dir_path);
214 : 1 : fail_if(ret == -1, "Cannot chdir\n");
215 : :
216 : 1 : ret = create_simple_file("footarget", "foo");
217 : 1 : fail_if(ret == -1, "Cannot create file\n");
218 : :
219 : 1 : ret = symlink("footarget", "foolink");
220 : 1 : fail_if(ret == -1, "Cannot create symlink\n");
221 : :
222 : : /* go back */
223 : 1 : ret = chdir(origpath);
224 : 1 : fail_if(ret == -1, "Cannot chdir\n");
225 : :
226 : : /* and finally copy.. */
227 [ + - ][ - + ]: 1 : DEBUG(5, ("Will copy from '%s' to '%s'\n", dir_path, dst_path));
[ # # ][ # # ]
[ # # ]
228 : 1 : ret = copy_tree(dir_path, dst_path, uid, gid);
229 : 1 : fail_unless(ret == EOK, "copy_tree failed\n");
230 : :
231 : : /* check if really copied */
232 : 1 : ret = access(dst_path, F_OK);
233 : 1 : fail_unless(ret == 0, "destination directory not there\n");
234 : :
235 : 1 : tmp = talloc_asprintf(test_ctx, "%s/foolink", dst_path);
236 : 1 : ret = lstat(tmp, &statbuf);
237 : 1 : fail_unless(ret == 0, "cannot stat the symlink %s\n", tmp);
238 : 1 : fail_unless(S_ISLNK(statbuf.st_mode), "%s not a symlink?\n", tmp);
239 : 1 : talloc_free(tmp);
240 : : }
241 : 1 : END_TEST
242 : :
243 : 1 : START_TEST(test_copy_node)
244 : : {
245 : : int ret;
246 : : char origpath[PATH_MAX+1];
247 : : char *tmp;
248 : : struct stat statbuf;
249 : :
250 : 1 : errno = 0;
251 : 1 : fail_unless(getcwd(origpath, PATH_MAX) == origpath, "Cannot getcwd\n");
252 : 1 : fail_unless(errno == 0, "Cannot getcwd\n");
253 : :
254 : : /* create a node */
255 : 1 : ret = chdir(dir_path);
256 : 1 : fail_if(ret == -1, "Cannot chdir\n");
257 : :
258 : 1 : ret = mknod("testnode", S_IFIFO | S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, 0);
259 : 1 : fail_unless(ret == 0, "cannot stat /dev/null: %s", strerror(errno));
260 : :
261 : : /* go back */
262 : 1 : ret = chdir(origpath);
263 : 1 : fail_if(ret == -1, "Cannot chdir\n");
264 : :
265 : : /* and finally copy.. */
266 [ + - ][ - + ]: 1 : DEBUG(5, ("Will copy from '%s' to '%s'\n", dir_path, dst_path));
[ # # ][ # # ]
[ # # ]
267 : 1 : ret = copy_tree(dir_path, dst_path, uid, gid);
268 : 1 : fail_unless(ret == EOK, "copy_tree failed\n");
269 : :
270 : : /* check if really copied */
271 : 1 : ret = access(dst_path, F_OK);
272 : 1 : fail_unless(ret == 0, "destination directory not there\n");
273 : :
274 : 1 : tmp = talloc_asprintf(test_ctx, "%s/testnode", dst_path);
275 : 1 : ret = lstat(tmp, &statbuf);
276 : 1 : fail_unless(ret == 0, "cannot stat the node %s\n", tmp);
277 : 1 : fail_unless(S_ISFIFO(statbuf.st_mode), "%s not a char device??\n", tmp);
278 : 1 : talloc_free(tmp);
279 : : }
280 : 1 : END_TEST
281 : :
282 : 5 : static Suite *files_suite(void)
283 : : {
284 : 5 : Suite *s = suite_create("files_suite");
285 : :
286 : 5 : TCase *tc_files = tcase_create("files");
287 : 5 : tcase_add_checked_fixture(tc_files,
288 : : setup_files_test,
289 : : teardown_files_test);
290 : :
291 : 5 : tcase_add_test(tc_files, test_remove_tree);
292 : 5 : tcase_add_test(tc_files, test_simple_copy);
293 : 5 : tcase_add_test(tc_files, test_copy_symlink);
294 : 5 : tcase_add_test(tc_files, test_copy_node);
295 : 5 : suite_add_tcase(s, tc_files);
296 : :
297 : 5 : return s;
298 : : }
299 : :
300 : 5 : int main(int argc, const char *argv[])
301 : : {
302 : : int number_failed;
303 : : int opt;
304 : : poptContext pc;
305 : 5 : int debug = 0;
306 : :
307 : 5 : struct poptOption long_options[] = {
308 : : POPT_AUTOHELP
309 : : { "debug-level", 'd', POPT_ARG_INT, &debug, 0, "Set debug level", NULL },
310 : : POPT_TABLEEND
311 : : };
312 : :
313 : : /* Set debug level to invalid value so we can deside if -d 0 was used. */
314 : 5 : debug_level = SSSDBG_INVALID;
315 : :
316 : 5 : pc = poptGetContext(argv[0], argc, (const char **) argv, long_options, 0);
317 [ - + ]: 5 : while((opt = poptGetNextOpt(pc)) != -1) {
318 : 0 : fprintf(stderr, "\nInvalid option %s: %s\n\n",
319 : : poptBadOption(pc, 0), poptStrerror(opt));
320 : 0 : poptPrintUsage(pc, stderr, 0);
321 : : return 1;
322 : : }
323 : 5 : poptFreeContext(pc);
324 : :
325 [ + - ]: 5 : DEBUG_INIT(debug);
326 : :
327 : 5 : tests_set_cwd();
328 : :
329 : 5 : Suite *s = files_suite();
330 : 5 : SRunner *sr = srunner_create(s);
331 : : /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
332 : 5 : srunner_run_all(sr, CK_ENV);
333 : 1 : number_failed = srunner_ntests_failed(sr);
334 : 1 : srunner_free(sr);
335 : 1 : return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
336 : : }
337 : :
|