No issues found
1 /*
2 * Copyright (C) 2008, Nokia <ivan.frade@nokia.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include <string.h>
21 #include <sys/stat.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24
25 #include <glib.h>
26 #include <glib/gstdio.h>
27 #include <gio/gio.h>
28
29 #include <libtracker-common/tracker-file-utils.h>
30 #include <libtracker-common/tracker-locale.h>
31
32 #include <tracker-test-helpers.h>
33
34 #define TEST_FILENAME "./file-utils-test.txt"
35 #define TEST_HIDDEN_FILENAME "./.hidden-file.txt"
36
37 static void
38 ensure_file_exists (const gchar *filename)
39 {
40 if (!g_file_test (filename, G_FILE_TEST_EXISTS)) {
41 g_file_set_contents (filename, "Just some stuff", -1, NULL);
42 }
43 }
44
45 static void
46 remove_file (const gchar *filename)
47 {
48 g_assert (g_file_test (filename, G_FILE_TEST_EXISTS));
49 g_remove (filename);
50 }
51
52 static GSList *
53 array_as_list (const gchar **array)
54 {
55 gint i;
56 GSList *result = NULL;
57
58 for (i = 0; array[i] != NULL; i++) {
59 result = g_slist_prepend (result, g_strdup(array[i]));
60
61 }
62
63 return result;
64 }
65
66 static gboolean
67 string_in_list (GSList *list, const gchar *string)
68 {
69 GSList *it;
70 for ( it = list; it != NULL; it = it->next) {
71 if (strcmp (it->data, string) == 0) {
72 return TRUE;
73 }
74 }
75 return FALSE;
76 }
77
78 static void
79 test_path_list_filter_duplicates (void)
80 {
81 const gchar *input_roots [] = {"/home/ivan",
82 "/home",
83 "/tmp",
84 "/usr/",
85 "/usr/share/local", NULL};
86
87 GSList *input_as_list = NULL;
88 GSList *result;
89
90 input_as_list = array_as_list (input_roots);
91
92 result = tracker_path_list_filter_duplicates (input_as_list, ".", TRUE);
93 g_assert_cmpint (3, ==, g_slist_length (result));
94
95 g_assert (string_in_list (result, "/home"));
96 g_assert (string_in_list (result, "/tmp"));
97 g_assert (string_in_list (result, "/usr"));
98
99 g_slist_foreach (input_as_list, (GFunc) g_free, NULL);
100 g_slist_foreach (result, (GFunc) g_free, NULL);
101 }
102
103 static void
104 test_path_list_filter_duplicates_with_exceptions ()
105 {
106 const gchar *input_roots [] = { "/home/user/MyDocs",
107 "/home/user/MyDocs/.sounds",
108 "/home/user/MyDocs/visible",
109 NULL};
110 GSList *input_as_list = NULL, *result = NULL;
111
112 input_as_list = array_as_list (input_roots);
113
114 result = tracker_path_list_filter_duplicates (input_as_list, "/home/user/MyDocs", FALSE);
115 g_assert_cmpint (g_slist_length (result), ==, 3);
116 g_assert (string_in_list (result, "/home/user/MyDocs"));
117 g_assert (string_in_list (result, "/home/user/MyDocs/.sounds"));
118 g_assert (string_in_list (result, "/home/user/MyDocs/visible"));
119 g_slist_foreach (result, (GFunc) g_free, NULL);
120
121
122 result = tracker_path_list_filter_duplicates (input_as_list, "/home/user/MyDocs", TRUE);
123 g_assert_cmpint (g_slist_length (result), ==, 1);
124 g_assert (string_in_list (result, "/home/user/MyDocs"));
125 g_slist_foreach (result, (GFunc) g_free, NULL);
126
127 g_slist_foreach (input_as_list, (GFunc) g_free, NULL);
128 }
129
130 static void
131 test_path_evaluate_name (void)
132 {
133 gchar *result, *expected;
134
135 const gchar *home = g_getenv ("HOME");
136 const gchar *pwd = g_getenv ("PWD");
137
138 const gchar *test = "/one/two";
139 gchar *parent_dir;
140
141 g_setenv ("TEST_TRACKER_DIR", test, TRUE);
142
143
144 result = tracker_path_evaluate_name ("/home/user/all/ok");
145 g_assert_cmpstr (result, ==, "/home/user/all/ok");
146 g_free (result);
147
148 /* The result of this test and the next one are not consistent!
149 * Must it remove the end '/' or not?
150 */
151 result = tracker_path_evaluate_name ("/home/user/all/dir/");
152 g_assert_cmpstr (result, ==, "/home/user/all/dir");
153 g_free (result);
154
155
156 /*
157 * TODO: In valgrind this test shows a memory leak
158 */
159 result = tracker_path_evaluate_name ("~/all/dir/");
160 expected = g_build_path (G_DIR_SEPARATOR_S, home, "/all/dir/", NULL);
161 g_assert_cmpstr (result, ==, expected);
162 g_free (result);
163 g_free (expected);
164
165 result = tracker_path_evaluate_name ("just-a-filename");
166 g_assert_cmpstr (result, ==, "just-a-filename");
167
168 result = tracker_path_evaluate_name ("$HOME/all/dir/");
169 expected = g_build_path (G_DIR_SEPARATOR_S, home, "/all/dir", NULL);
170 g_assert_cmpstr (result, ==, expected);
171 g_free (result);
172 g_free (expected);
173
174 result = tracker_path_evaluate_name ("${HOME}/all/dir/");
175 expected = g_build_path (G_DIR_SEPARATOR_S, home, "/all/dir", NULL);
176 g_assert_cmpstr (result, ==, expected);
177 g_free (result);
178 g_free (expected);
179
180 result = tracker_path_evaluate_name ("./test/current/dir");
181 expected = g_build_path (G_DIR_SEPARATOR_S, pwd, "/test/current/dir", NULL);
182 g_assert_cmpstr (result, ==, expected);
183 g_free (result);
184 g_free (expected);
185
186 result = tracker_path_evaluate_name ("$TEST_TRACKER_DIR/test/dir");
187 expected = g_build_path (G_DIR_SEPARATOR_S, test, "/test/dir", NULL);
188 g_assert_cmpstr (result, ==, expected);
189 g_free (result);
190 g_free (expected);
191
192 result = tracker_path_evaluate_name ("../test/dir");
193 parent_dir = g_path_get_dirname (pwd);
194 expected = g_build_path (G_DIR_SEPARATOR_S, parent_dir, "/test/dir", NULL);
195 g_assert_cmpstr (result, ==, expected);
196 g_free (result);
197 g_free (parent_dir);
198 g_free (expected);
199
200 result = tracker_path_evaluate_name ("");
201 g_assert (!result);
202
203 result = tracker_path_evaluate_name (NULL);
204 g_assert (!result);
205
206
207 g_setenv ("HOME", "", TRUE);
208 result = tracker_path_evaluate_name ("~/but-no-home.txt");
209 g_assert (!result);
210 g_setenv ("HOME", home, TRUE);
211
212 result = tracker_path_evaluate_name ("$UNDEFINED/something");
213 g_assert_cmpstr (result, ==, "/something");
214
215 result = tracker_path_evaluate_name (tracker_test_helpers_get_nonutf8 ());
216 g_assert_cmpstr (result, ==, tracker_test_helpers_get_nonutf8 ());
217
218 g_unsetenv ("TEST_TRACKER_DIR");
219 }
220
221
222 static void
223 test_file_get_mime_type (void)
224 {
225 gchar *result;
226 GFile *f;
227
228 f = g_file_new_for_path (TEST_FILENAME);
229 result = tracker_file_get_mime_type (f);
230 g_assert_cmpstr (result, ==, "text/plain");
231
232 g_object_unref (f);
233 g_free (result);
234
235 f = g_file_new_for_path ("./file-does-NOT-exist");
236 result = tracker_file_get_mime_type (f);
237 g_assert_cmpstr (result, ==, "unknown");
238
239 g_object_unref (f);
240 g_free (result);
241
242 }
243
244 #define assert_filename_match(a, b) { \
245 g_assert_cmpint (tracker_filename_casecmp_without_extension (a, b), ==, TRUE); \
246 g_assert_cmpint (tracker_filename_casecmp_without_extension (b, a), ==, TRUE); }
247
248 #define assert_no_filename_match(a, b) { \
249 g_assert_cmpint (tracker_filename_casecmp_without_extension (a, b), ==, FALSE); \
250 g_assert_cmpint (tracker_filename_casecmp_without_extension (b, a), ==, FALSE); }
251
252 static void
253 test_case_match_filename_without_extension ()
254 {
255 assert_filename_match ("test.mp3", "test.mp3");
256 assert_filename_match ("test.mp3", "test.wav");
257 assert_filename_match ("test.mp3", "test.mp");
258 assert_filename_match ("test.mp3", "test.");
259 assert_filename_match ("test.mp3", "test");
260 assert_filename_match ("01 - Song 1 (Remix).wav", "01 - Song 1 (Remix).flac");
261
262 assert_no_filename_match ("test.mp3", "bacon.mp3");
263
264 /* Pathological cases, mainly testing that nothing crashes */
265 assert_no_filename_match (".", "\n");
266 assert_no_filename_match ("as", "as..");
267 assert_no_filename_match ("...as", "...as..");
268 assert_no_filename_match (".", "test.");
269 assert_filename_match ("", ".");
270 }
271
272 static void
273 test_file_utils_open_close ()
274 {
275 FILE *f;
276
277 f = tracker_file_open (TEST_FILENAME);
278 g_assert (f);
279 tracker_file_close (f, TRUE);
280
281 f = tracker_file_open (TEST_FILENAME);
282 g_assert (f);
283 tracker_file_close (f, FALSE);
284
285 f = tracker_file_open ("./file-does-NOT-exist");
286 g_assert (!f);
287 }
288
289 static void
290 test_file_utils_get_size ()
291 {
292 goffset size;
293 struct stat st;
294
295 size = tracker_file_get_size (TEST_FILENAME);
296 g_assert_cmpint (size, >, 0);
297
298 stat (TEST_FILENAME, &st);
299 g_assert_cmpint (size, ==, st.st_size);
300
301 /* File doesn't exist */
302 size = tracker_file_get_size ("./file-does-NOT-exist");
303 g_assert_cmpint (size, ==, 0);
304 }
305
306 static void
307 test_file_utils_get_mtime ()
308 {
309 guint64 mtime;
310 struct stat st;
311 gchar *pwd, *uri;
312
313 mtime = tracker_file_get_mtime (TEST_FILENAME);
314 g_assert_cmpint (mtime, >, 0);
315
316 stat (TEST_FILENAME, &st);
317 // This comparison could lead a problem in 32/64 bits?
318 g_assert_cmpint (mtime, ==, st.st_mtime);
319
320 pwd = g_get_current_dir ();
321 uri = g_strdup_printf ("file://%s/%s", pwd, TEST_FILENAME);
322 mtime = tracker_file_get_mtime_uri (uri);
323 // This comparison could lead a problem in 32/64 bits?
324 g_assert_cmpint (mtime, ==, st.st_mtime);
325
326 g_free (pwd);
327 g_free (uri);
328
329 mtime = tracker_file_get_mtime_uri ("./file-does-NOT-exist");
330 g_assert_cmpint (mtime, ==, 0);
331 }
332
333 static void
334 test_file_system_get_remaining_space ()
335 {
336 guint64 space;
337
338 space = tracker_file_system_get_remaining_space ("/home");
339 g_assert_cmpint (space, >, 0);
340
341 // This is a critical (aborts the process)
342 //space = tracker_file_system_get_remaining_space ("/unlikely/to/have/this/folder");
343 }
344
345 static void
346 test_file_system_get_remaining_space_percentage ()
347 {
348 gdouble space;
349
350 space = tracker_file_system_get_remaining_space_percentage ("/home");
351 g_assert_cmpfloat (space, >=, 0);
352 g_assert_cmpfloat (space, <=, 100);
353
354 // This is a critical (aborts the process)
355 //space = tracker_file_system_get_remaining_space_percentage ("/unlikely/to/have/this/folder");
356 }
357
358 static void
359 test_file_system_has_enough_space ()
360 {
361 /* Hopefully we will always have 1 byte free... */
362 g_assert (tracker_file_system_has_enough_space ("/home", 1, FALSE));
363 g_assert (tracker_file_system_has_enough_space ("/home", 1, TRUE));
364
365 /* gulong goes only up to 4Gb. Cannot ask for unreasonable amount of space */
366 //g_assert (!tracker_file_system_has_enough_space ("/home", G_MAXULONG, FALSE));
367 }
368
369 static void
370 test_file_exists_and_writable ()
371 {
372 const gchar *path = "./test-dir-remove-afterwards";
373
374 if (g_file_test (path, G_FILE_TEST_EXISTS)) {
375 g_remove (path);
376 }
377
378 /* This should create the directory with write access*/
379 g_assert (tracker_path_has_write_access_or_was_created (path));
380 g_assert (g_file_test (path, G_FILE_TEST_EXISTS));
381
382 /* This time exists and has write access */
383 g_assert (tracker_path_has_write_access_or_was_created (path));
384
385 chmod (path, S_IRUSR & S_IRGRP);
386
387 /* Exists but is not writable */
388 g_assert (!tracker_path_has_write_access_or_was_created (path));
389
390 /* Doesn't exist and cannot be created */
391 g_assert (!tracker_path_has_write_access_or_was_created ("/var/log/tracker-test"));
392
393 g_remove (path);
394 }
395
396 static void
397 test_file_utils_lock ()
398 {
399 GFile *f, *no_f, *no_native_f;
400
401 f = g_file_new_for_path (TEST_FILENAME);
402 no_f = g_file_new_for_path ("./file-does-NOT-exist");
403 no_native_f = g_file_new_for_uri ("http://cgit.gnome.org/projects.tracker");
404
405 /* Nothing locked */
406 g_assert (tracker_file_unlock (f));
407
408 /* Locking a regular file */
409 g_assert (!tracker_file_is_locked (f));
410
411 g_assert (tracker_file_lock (f));
412 g_assert (tracker_file_is_locked (f));
413
414 /* Try to lock twice */
415 g_assert (tracker_file_lock (f));
416 g_assert (tracker_file_is_locked (f));
417
418 g_assert (tracker_file_unlock (f));
419 g_assert (!tracker_file_is_locked (f));
420
421 /* Unlock not-locked file */
422 g_assert (tracker_file_unlock (no_f));
423
424 /* Lock a non-existent file */
425 /* This causes a warning aborting the test */
426 //g_assert (!tracker_file_lock (no_f));
427
428 /* Lock a non-native file */
429 g_assert (!tracker_file_lock (no_native_f));
430 g_assert (!tracker_file_is_locked (no_native_f));
431
432 g_object_unref (f);
433 g_object_unref (no_f);
434 g_object_unref (no_native_f);
435 }
436
437 static void
438 test_file_utils_is_hidden ()
439 {
440 GFile *f;
441
442 ensure_file_exists ("./non-hidden-test-file");
443
444 f = g_file_new_for_path (TEST_HIDDEN_FILENAME);
445 g_assert (tracker_file_is_hidden (f));
446 g_object_unref (f);
447
448 f = g_file_new_for_path ("./non-hidden-test-file");
449 g_assert (!tracker_file_is_hidden (f));
450 g_object_unref (f);
451
452 remove_file ("./non-hidden-test-file");
453 }
454
455 static void
456 test_file_utils_cmp ()
457 {
458 GFile *one, *two, *three;
459
460 one = g_file_new_for_path (TEST_FILENAME);
461 two = g_file_new_for_path (TEST_FILENAME);
462 three = g_file_new_for_path (TEST_HIDDEN_FILENAME);
463
464 g_assert (!tracker_file_cmp (one, two));
465 g_assert (tracker_file_cmp (two, three));
466 }
467
468 int
469 main (int argc, char **argv)
470 {
471 int result;
472
473 g_test_init (&argc, &argv, NULL);
474
475 tracker_locale_init ();
476 ensure_file_exists (TEST_FILENAME);
477 ensure_file_exists (TEST_HIDDEN_FILENAME);
478
479 g_test_add_func ("/libtracker-common/file-utils/path_evaluate_name",
480 test_path_evaluate_name);
481 g_test_add_func ("/libtracker-common/file-utils/path_list_filter_duplicates",
482 test_path_list_filter_duplicates);
483 g_test_add_func ("/libtracker-common/file-utils/path_list_filter_duplicates_with_exceptions",
484 test_path_list_filter_duplicates_with_exceptions);
485 g_test_add_func ("/libtracker-common/file-utils/file_get_mime_type",
486 test_file_get_mime_type);
487 g_test_add_func ("/libtracker-common/file-utils/case_match_filename_without_extension",
488 test_case_match_filename_without_extension);
489
490 g_test_add_func ("/libtracker-common/file-utils/open_close",
491 test_file_utils_open_close);
492 g_test_add_func ("/libtracker-common/file-utils/get_size",
493 test_file_utils_get_size);
494 g_test_add_func ("/libtracker-common/file-utils/get_mtime",
495 test_file_utils_get_mtime);
496 g_test_add_func ("/libtracker-common/file-utils/get_remaining_space",
497 test_file_system_get_remaining_space);
498 g_test_add_func ("/libtracker-common/file-utils/get_remaining_space_percentage",
499 test_file_system_get_remaining_space_percentage);
500 g_test_add_func ("/libtracker-common/file-utils/has_enough_space",
501 test_file_system_has_enough_space);
502 g_test_add_func ("/libtracker-common/file-utils/has_write_access_or_was_created",
503 test_file_exists_and_writable);
504 g_test_add_func ("/libtracker-common/file-utils/lock",
505 test_file_utils_lock);
506 g_test_add_func ("/libtracker-common/file-utils/is_hidden",
507 test_file_utils_is_hidden);
508 g_test_add_func ("/libtracker-common/file-utils/cmp",
509 test_file_utils_cmp);
510
511 result = g_test_run ();
512
513 remove_file (TEST_FILENAME);
514 remove_file (TEST_HIDDEN_FILENAME);
515
516 tracker_locale_shutdown ();
517
518 return result;
519 }