proper shutdown
[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 3, 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 (strlen (TESTSTRING) !=
40       GNUNET_DISK_fn_write (".testfile", TESTSTRING,
41                             strlen (TESTSTRING),
42                             GNUNET_DISK_PERM_USER_READ |
43                             GNUNET_DISK_PERM_USER_WRITE))
44     return 1;
45   if (GNUNET_OK != GNUNET_DISK_file_test (".testfile"))
46     return 1;
47   ret = GNUNET_DISK_fn_read (".testfile", tmp, sizeof (tmp) - 1);
48   if (ret < 0)
49     {
50       fprintf (stderr,
51                "Error reading file `%s' in testReadWrite\n", ".testfile");
52       return 1;
53     }
54   tmp[ret] = '\0';
55   if (0 != memcmp (tmp, TESTSTRING, strlen (TESTSTRING) + 1))
56     {
57       fprintf (stderr,
58                "Error in testReadWrite: *%s* != *%s* for file %s\n",
59                tmp, TESTSTRING, ".testfile");
60       return 1;
61     }
62   GNUNET_DISK_file_copy (".testfile", ".testfile2");
63   memset (tmp, 0, sizeof (tmp));
64   ret = GNUNET_DISK_fn_read (".testfile2", tmp, sizeof (tmp) - 1);
65   if (ret < 0)
66     {
67       fprintf (stderr,
68                "Error reading file `%s' in testReadWrite\n", ".testfile2");
69       return 1;
70     }
71   tmp[ret] = '\0';
72   if (0 != memcmp (tmp, TESTSTRING, strlen (TESTSTRING) + 1))
73     {
74       fprintf (stderr,
75                "Error in testReadWrite: *%s* != *%s* for file %s\n",
76                tmp, TESTSTRING, ".testfile2");
77       return 1;
78     }
79
80   GNUNET_break (0 == UNLINK (".testfile"));
81   GNUNET_break (0 == UNLINK (".testfile2"));
82   if (GNUNET_NO != GNUNET_DISK_file_test (".testfile"))
83     return 1;
84
85   return 0;
86 }
87
88 static int
89 testOpenClose ()
90 {
91   struct GNUNET_DISK_FileHandle *fh;
92   uint64_t size;
93   long avail;
94
95   fh = GNUNET_DISK_file_open (".testfile", GNUNET_DISK_OPEN_READWRITE
96                               | GNUNET_DISK_OPEN_CREATE,
97                               GNUNET_DISK_PERM_USER_READ |
98                               GNUNET_DISK_PERM_USER_WRITE);
99   GNUNET_assert (GNUNET_NO == GNUNET_DISK_handle_invalid (fh));
100   GNUNET_break (5 == GNUNET_DISK_file_write (fh, "Hello", 5));
101   GNUNET_DISK_file_close (fh);
102   GNUNET_break (GNUNET_OK ==
103                 GNUNET_DISK_file_size (".testfile", &size, GNUNET_NO));
104   if (size != 5)
105     return 1;
106   GNUNET_break (0 == UNLINK (".testfile"));
107
108   /* test that avail goes down as we fill the disk... */
109   GNUNET_log_skip (1, GNUNET_NO);
110   avail = GNUNET_DISK_get_blocks_available (".testfile");
111   GNUNET_log_skip (0, GNUNET_NO);
112   fh = GNUNET_DISK_file_open (".testfile", GNUNET_DISK_OPEN_READWRITE
113                               | GNUNET_DISK_OPEN_CREATE,
114                               GNUNET_DISK_PERM_USER_WRITE |
115                               GNUNET_DISK_PERM_USER_READ);
116   GNUNET_assert (GNUNET_NO == GNUNET_DISK_handle_invalid (fh));
117   while ((avail == GNUNET_DISK_get_blocks_available (".testfile")) &&
118          (avail != -1))
119     if (16 != GNUNET_DISK_file_write (fh, "HelloWorld123456", 16))
120       {
121         GNUNET_DISK_file_close (fh);
122         GNUNET_break (0 == UNLINK (".testfile"));
123         return 1;
124       }
125   GNUNET_DISK_file_close (fh);
126   GNUNET_break (0 == UNLINK (".testfile"));
127
128   return 0;
129 }
130
131 static int ok;
132
133 static int
134 scan_callback (void *want, const char *filename)
135 {
136   if (NULL != strstr (filename, want))
137     ok++;
138   return GNUNET_OK;
139 }
140
141 static int
142 testDirScan ()
143 {
144   if (GNUNET_OK !=
145       GNUNET_DISK_directory_create ("test" DIR_SEPARATOR_STR "entry"))
146     return 1;
147   if (GNUNET_OK !=
148       GNUNET_DISK_directory_create ("test" DIR_SEPARATOR_STR "entry_more"))
149     return 1;
150   GNUNET_DISK_directory_scan ("test", &scan_callback,
151                               "test" DIR_SEPARATOR_STR "entry");
152   if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
153     return 1;
154   if (ok < 2)
155     return 1;
156   return 0;
157 }
158
159 static void
160 iter_callback (void *cls,
161                struct GNUNET_DISK_DirectoryIterator *di,
162                const char *filename, const char *dirname)
163 {
164   int *i = cls;
165   (*i)++;
166   GNUNET_DISK_directory_iterator_next (di, GNUNET_NO);
167 }
168
169 static void
170 iter_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
171 {
172   GNUNET_DISK_directory_iterator_start (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
173                                         "test", &iter_callback, cls);
174 }
175
176 static int
177 testDirIter ()
178 {
179   int i;
180
181   i = 0;
182   if (GNUNET_OK != GNUNET_DISK_directory_create ("test/entry"))
183     return 1;
184   if (GNUNET_OK != GNUNET_DISK_directory_create ("test/entry_many"))
185     return 1;
186   if (GNUNET_OK != GNUNET_DISK_directory_create ("test/entry_more"))
187     return 1;
188   GNUNET_SCHEDULER_run (&iter_task, &i);
189   if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
190     return 1;
191   if (i < 3)
192     return 1;
193   return 0;
194 }
195
196
197 static int
198 testGetHome ()
199 {
200   struct GNUNET_CONFIGURATION_Handle *cfg;
201   char *fn;
202   int ret;
203
204   cfg = GNUNET_CONFIGURATION_create ();
205   GNUNET_assert (cfg != NULL);
206   GNUNET_CONFIGURATION_set_value_string (cfg, "service", "HOME",
207                                          "/tmp/test-gnunet-disk-a/b/c");
208   fn = GNUNET_DISK_get_home_filename (cfg, "service", "d", "e", NULL);
209   GNUNET_assert (fn != NULL);
210   GNUNET_CONFIGURATION_destroy (cfg);
211   ret = strcmp ("/tmp/test-gnunet-disk-a/b/c/d/e", fn);
212   GNUNET_free (fn);
213   GNUNET_break (GNUNET_OK == GNUNET_DISK_directory_remove ("/tmp/test-gnunet-disk-a"));
214   return ret;
215 }
216
217 static int
218 testCanonicalize ()
219 {
220   char *fn = GNUNET_strdup ("ab?><|cd*ef:/g\"");
221   GNUNET_DISK_filename_canonicalize (fn);
222   if (0 != strcmp (fn, "ab____cd_ef__g_"))
223     {
224       GNUNET_free (fn);
225       return 1;
226     }
227   GNUNET_free (fn);
228   return 0;
229 }
230
231 static int
232 testChangeOwner ()
233 {
234   GNUNET_log_skip (1, GNUNET_NO);
235   if (GNUNET_OK == GNUNET_DISK_file_change_owner ("/dev/null", "unknownuser"))
236     return 1;
237   return 0;
238 }
239
240 static int
241 testDirMani ()
242 {
243   if (GNUNET_OK != GNUNET_DISK_directory_create_for_file ("test/ing"))
244     return 1;
245   if (GNUNET_NO != GNUNET_DISK_file_test ("test"))
246     return 1;
247   if (GNUNET_NO != GNUNET_DISK_file_test ("test/ing"))
248     return 1;
249   if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
250     return 1;
251   if (GNUNET_OK != GNUNET_DISK_directory_create ("test"))
252     return 1;
253   if (GNUNET_YES != GNUNET_DISK_directory_test ("test"))
254     return 1;
255   if (GNUNET_OK != GNUNET_DISK_directory_remove ("test"))
256     return 1;
257
258
259   return 0;
260 }
261
262
263 int
264 main (int argc, char *argv[])
265 {
266   unsigned int failureCount = 0;
267
268   GNUNET_log_setup ("test-disk", "WARNING", NULL);
269   failureCount += testReadWrite ();
270   failureCount += testOpenClose ();
271   failureCount += testDirScan ();
272   failureCount += testDirIter ();
273   failureCount += testGetHome ();
274   failureCount += testCanonicalize ();
275   failureCount += testChangeOwner ();
276   failureCount += testDirMani ();
277   if (failureCount != 0)
278     {
279       fprintf (stderr, "\n%u TESTS FAILED!\n", failureCount);
280       return -1;
281     }
282   return 0;
283 }                               /* end of main */