dd41c53c02d851a309af6fd1fd3efcd54f1ccb6f
[oweals/gnunet.git] / src / util / test_disk.c
1 /*
2      This file is part of GNUnet.
3      (C) 2001, 2002, 2003, 2005, 2006, 2009 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 2, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file util/test_disk.c
23  * @brief testcase for the storage module
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_common.h"
28 #include "gnunet_disk_lib.h"
29 #include "gnunet_scheduler_lib.h"
30
31 #define TESTSTRING "Hello World\0"
32
33 static int
34 testReadWrite ()
35 {
36   char tmp[100 + 1];
37   int ret;
38
39   if (GNUNET_OK != GNUNET_DISK_fn_write (".testfile", TESTSTRING, strlen (
40       TESTSTRING), GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE))
41     return 1;
42   if (GNUNET_OK != GNUNET_DISK_file_test (".testfile"))
43     return 1;
44   ret = GNUNET_DISK_fn_read (".testfile", tmp, sizeof (tmp) - 1);
45   if (ret < 0)
46     {
47       fprintf (stderr,
48                "Error reading file `%s' in testReadWrite\n", ".testfile");
49       return 1;
50     }
51   tmp[ret] = '\0';
52   if (0 != memcmp (tmp, TESTSTRING, strlen (TESTSTRING) + 1))
53     {
54       fprintf (stderr,
55                "Error in testReadWrite: *%s* != *%s* for file %s\n",
56                tmp, TESTSTRING, ".testfile");
57       return 1;
58     }
59   GNUNET_DISK_file_copy (".testfile", ".testfile2");
60   memset (tmp, 0, sizeof (tmp));
61   ret = GNUNET_DISK_fn_read (".testfile2", tmp, sizeof (tmp) - 1);
62   if (ret < 0)
63     {
64       fprintf (stderr,
65                "Error reading file `%s' in testReadWrite\n", ".testfile2");
66       return 1;
67     }
68   tmp[ret] = '\0';
69   if (0 != memcmp (tmp, TESTSTRING, strlen (TESTSTRING) + 1))
70     {
71       fprintf (stderr,
72                "Error in testReadWrite: *%s* != *%s* for file %s\n",
73                tmp, TESTSTRING, ".testfile2");
74       return 1;
75     }
76
77   GNUNET_break (0 == UNLINK (".testfile"));
78   GNUNET_break (0 == UNLINK (".testfile2"));
79   if (GNUNET_NO != GNUNET_DISK_file_test (".testfile"))
80     return 1;
81
82   return 0;
83 }
84
85 static int
86 testOpenClose ()
87 {
88   struct GNUNET_DISK_FileHandle *fh;
89   uint64_t size;
90   long avail;
91
92   fh = GNUNET_DISK_file_open (".testfile", GNUNET_DISK_OPEN_READWRITE
93       | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_READ
94       | GNUNET_DISK_PERM_USER_WRITE);
95   GNUNET_assert (GNUNET_NO == GNUNET_DISK_handle_invalid (fh));
96   GNUNET_break (5 == GNUNET_DISK_file_write (fh, "Hello", 5));
97   GNUNET_DISK_file_close (fh);
98   GNUNET_break (GNUNET_OK ==
99                 GNUNET_DISK_file_size (".testfile", &size, GNUNET_NO));
100   if (size != 5)
101     return 1;
102   GNUNET_break (0 == UNLINK (".testfile"));
103
104   /* test that avail goes down as we fill the disk... */
105   GNUNET_log_skip (1, GNUNET_NO);
106   avail = GNUNET_DISK_get_blocks_available (".testfile");
107   GNUNET_log_skip (0, GNUNET_NO);
108   fh = GNUNET_DISK_file_open (".testfile", GNUNET_DISK_OPEN_READWRITE
109       | GNUNET_DISK_OPEN_CREATE, GNUNET_DISK_PERM_USER_WRITE
110       | GNUNET_DISK_PERM_USER_READ);
111   GNUNET_assert (GNUNET_NO == GNUNET_DISK_handle_invalid (fh));
112   while ((avail == GNUNET_DISK_get_blocks_available (".testfile")) &&
113          (avail != -1))
114     if (16 != GNUNET_DISK_file_write (fh, "HelloWorld123456", 16))
115       {
116         GNUNET_DISK_file_close (fh);
117         GNUNET_break (0 == UNLINK (".testfile"));
118         return 1;
119       }
120   GNUNET_DISK_file_close (fh);
121   GNUNET_break (0 == UNLINK (".testfile"));
122
123   return 0;
124 }
125
126 static int ok;
127
128 static int
129 scan_callback (void *want, const char *filename)
130 {
131   if (NULL != strstr (filename, want))
132     ok++;
133   return GNUNET_OK;
134 }
135
136 static int
137 testDirScan ()
138 {
139   if (GNUNET_OK != GNUNET_DISK_directory_create ("test" DIR_SEPARATOR_STR "entry"))
140     return 1;
141   if (GNUNET_OK != GNUNET_DISK_directory_create ("test" DIR_SEPARATOR_STR "entry_more"))
142     return 1;
143   GNUNET_DISK_directory_scan ("test", &scan_callback, "test" DIR_SEPARATOR_STR "entry");
144   if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
145     return 1;
146   if (ok < 2)
147     return 1;
148   return 0;
149 }
150
151 static void
152 iter_callback (void *cls,
153                struct GNUNET_DISK_DirectoryIterator *di,
154                const char *filename, const char *dirname)
155 {
156   int *i = cls;
157   (*i)++;
158   GNUNET_DISK_directory_iterator_next (di, GNUNET_NO);
159 }
160
161 static void
162 iter_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
163 {
164   GNUNET_DISK_directory_iterator_start (tc->sched,
165                                         GNUNET_SCHEDULER_PRIORITY_DEFAULT,
166                                         "test", &iter_callback, cls);
167 }
168
169 static int
170 testDirIter ()
171 {
172   int i;
173
174   i = 0;
175   if (GNUNET_OK != GNUNET_DISK_directory_create ("test/entry"))
176     return 1;
177   if (GNUNET_OK != GNUNET_DISK_directory_create ("test/entry_many"))
178     return 1;
179   if (GNUNET_OK != GNUNET_DISK_directory_create ("test/entry_more"))
180     return 1;
181   GNUNET_SCHEDULER_run (&iter_task, &i);
182   if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
183     return 1;
184   if (i < 3)
185     return 1;
186   return 0;
187 }
188
189
190 static int
191 testGetHome ()
192 {
193   struct GNUNET_CONFIGURATION_Handle *cfg;
194   char *fn;
195   int ret;
196
197   cfg = GNUNET_CONFIGURATION_create ();
198   GNUNET_assert (cfg != NULL);
199   GNUNET_CONFIGURATION_set_value_string (cfg, "service", "HOME",
200                                          "/tmp/a/b/c");
201   fn = GNUNET_DISK_get_home_filename (cfg, "service", "d", "e", NULL);
202   GNUNET_assert (fn != NULL);
203   GNUNET_CONFIGURATION_destroy (cfg);
204   ret = strcmp ("/tmp/a/b/c/d/e", fn);
205   GNUNET_free (fn);
206   GNUNET_DISK_directory_remove ("/tmp/a");
207   return ret;
208 }
209
210 static int
211 testCanonicalize ()
212 {
213   char *fn = GNUNET_strdup ("ab?><|cd*ef:/g\"");
214   GNUNET_DISK_filename_canonicalize (fn);
215   if (0 != strcmp (fn, "ab____cd_ef__g_"))
216     {
217       GNUNET_free (fn);
218       return 1;
219     }
220   GNUNET_free (fn);
221   return 0;
222 }
223
224 static int
225 testChangeOwner ()
226 {
227   GNUNET_log_skip (1, GNUNET_NO);
228   if (GNUNET_OK == GNUNET_DISK_file_change_owner ("/dev/null", "unknownuser"))
229     return 1;
230   return 0;
231 }
232
233 static int
234 testDirMani ()
235 {
236   if (GNUNET_OK != GNUNET_DISK_directory_create_for_file ("test/ing"))
237     return 1;
238   if (GNUNET_NO != GNUNET_DISK_file_test ("test"))
239     return 1;
240   if (GNUNET_NO != GNUNET_DISK_file_test ("test/ing"))
241     return 1;
242   if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
243     return 1;
244   if (GNUNET_OK != GNUNET_DISK_directory_create ("test"))
245     return 1;
246   if (GNUNET_YES != GNUNET_DISK_directory_test ("test"))
247     return 1;
248   if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
249     return 1;
250
251
252   return 0;
253 }
254
255
256 int
257 main (int argc, char *argv[])
258 {
259   unsigned int failureCount = 0;
260
261   GNUNET_log_setup ("test-disk", "WARNING", NULL);
262   failureCount += testReadWrite ();
263   failureCount += testOpenClose ();
264   failureCount += testDirScan ();
265   failureCount += testDirIter ();
266   failureCount += testGetHome ();
267   failureCount += testCanonicalize ();
268   failureCount += testChangeOwner ();
269   failureCount += testDirMani ();
270   if (failureCount != 0)
271     {
272       fprintf (stderr, "\n%u TESTS FAILED!\n", failureCount);
273       return -1;
274     }
275   return 0;
276 }                               /* end of main */