xref: /haiku/src/tests/kits/storage/FindDirectoryTest.cpp (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
1 // FindDirectoryTest.cpp
2 
3 #include <errno.h>
4 #include <stdio.h>
5 #include <string>
6 #include <unistd.h>
7 
8 #include "FindDirectoryTest.h"
9 
10 #include <FindDirectory.h>
11 #include <fs_info.h>
12 #include <Entry.h>
13 #include <Path.h>
14 #include <Volume.h>
15 
16 
17 
18 const directory_which directories[] = {
19 	B_DESKTOP_DIRECTORY,
20 	B_TRASH_DIRECTORY,
21 	// BeOS directories.  These are mostly accessed read-only.
22 	B_BEOS_DIRECTORY,
23 	B_BEOS_SYSTEM_DIRECTORY,
24 	B_BEOS_ADDONS_DIRECTORY,
25 	B_BEOS_BOOT_DIRECTORY,
26 	B_BEOS_FONTS_DIRECTORY,
27 	B_BEOS_LIB_DIRECTORY,
28  	B_BEOS_SERVERS_DIRECTORY,
29 	B_BEOS_APPS_DIRECTORY,
30 	B_BEOS_BIN_DIRECTORY,
31 	B_BEOS_ETC_DIRECTORY,
32 	B_BEOS_DOCUMENTATION_DIRECTORY,
33 	B_BEOS_PREFERENCES_DIRECTORY,
34 	B_BEOS_TRANSLATORS_DIRECTORY,
35 	B_BEOS_MEDIA_NODES_DIRECTORY,
36 	B_BEOS_SOUNDS_DIRECTORY,
37 	// Common directories, shared among all users.
38 	B_COMMON_DIRECTORY,
39 	B_COMMON_SYSTEM_DIRECTORY,
40 	B_COMMON_ADDONS_DIRECTORY,
41 	B_COMMON_BOOT_DIRECTORY,
42 	B_COMMON_FONTS_DIRECTORY,
43 	B_COMMON_LIB_DIRECTORY,
44 	B_COMMON_SERVERS_DIRECTORY,
45 	B_COMMON_BIN_DIRECTORY,
46 	B_COMMON_ETC_DIRECTORY,
47 	B_COMMON_DOCUMENTATION_DIRECTORY,
48 	B_COMMON_SETTINGS_DIRECTORY,
49 	B_COMMON_DEVELOP_DIRECTORY,
50 	B_COMMON_LOG_DIRECTORY,
51 	B_COMMON_SPOOL_DIRECTORY,
52 	B_COMMON_TEMP_DIRECTORY,
53 	B_COMMON_VAR_DIRECTORY,
54 	B_COMMON_TRANSLATORS_DIRECTORY,
55 	B_COMMON_MEDIA_NODES_DIRECTORY,
56 	B_COMMON_SOUNDS_DIRECTORY,
57 	// User directories.  These are interpreted in the context
58 	// of the user making the find_directory call.
59 	B_USER_DIRECTORY,
60 	B_USER_CONFIG_DIRECTORY,
61 	B_USER_ADDONS_DIRECTORY,
62 	B_USER_BOOT_DIRECTORY,
63 	B_USER_FONTS_DIRECTORY,
64 	B_USER_LIB_DIRECTORY,
65 	B_USER_SETTINGS_DIRECTORY,
66 	B_USER_DESKBAR_DIRECTORY,
67 	B_USER_PRINTERS_DIRECTORY,
68 	B_USER_TRANSLATORS_DIRECTORY,
69 	B_USER_MEDIA_NODES_DIRECTORY,
70 	B_USER_SOUNDS_DIRECTORY,
71 	// Global directories.
72 	B_APPS_DIRECTORY,
73 	B_PREFERENCES_DIRECTORY,
74 	B_UTILITIES_DIRECTORY
75 };
76 
77 const int32 directoryCount = sizeof(directories) / sizeof(directory_which);
78 
79 const char *testFile		= "/tmp/testFile";
80 const char *testMountPoint	= "/non-existing-mount-point";
81 
82 
83 // Suite
84 CppUnit::Test*
85 FindDirectoryTest::Suite() {
86 	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
87 	typedef CppUnit::TestCaller<FindDirectoryTest> TC;
88 
89 	suite->addTest( new TC("find_directory() Test",
90 						   &FindDirectoryTest::Test) );
91 
92 	return suite;
93 }
94 
95 // setUp
96 void
97 FindDirectoryTest::setUp()
98 {
99 	BasicTest::setUp();
100 	createVolume(testFile, testMountPoint, 1);
101 }
102 
103 // tearDown
104 void
105 FindDirectoryTest::tearDown()
106 {
107 	deleteVolume(testFile, testMountPoint);
108 	BasicTest::tearDown();
109 }
110 
111 // print_directories
112 /*static
113 void
114 print_directories(dev_t device)
115 {
116 	printf("device id: %ld\n", device);
117 	BVolume volume;
118 	status_t error = volume.SetTo(device);
119 	if (error != B_OK)
120 		printf("Failed to init volume\n");
121 	for (int32 i = 0; error == B_OK && i < directoryCount; i++) {
122 		BPath path;
123 		error = find_directory(directories[i], &path, false, &volume);
124 		if (error == B_OK)
125 			printf("%4d: `%s'\n", directories[i], path.Path());
126 		else
127 			printf("Failed to find directory: %s\n", strerror(error));
128 	}
129 }*/
130 
131 // test_find_directory
132 static
133 status_t
134 test_find_directory(directory_which dir, BPath &path, dev_t device)
135 {
136 	status_t error = B_BAD_VALUE;
137 	switch (dir) {
138 		// volume relative dirs
139 		case B_DESKTOP_DIRECTORY:
140 		{
141 			if (device < 0)
142 				device = dev_for_path("/boot");
143 			fs_info info;
144 			if (fs_stat_dev(device, &info) == 0) {
145 				if (!strcmp(info.fsh_name, "bfs")) {
146 					entry_ref ref(device, info.root, "home");
147 					BPath homePath(&ref);
148 					error = homePath.InitCheck();
149 					if (error == B_OK)
150 						path.SetTo(homePath.Path(), "Desktop");
151 				} else
152 					error = B_ENTRY_NOT_FOUND;
153 			} else
154 				error = errno;
155 			break;
156 		}
157 		case B_TRASH_DIRECTORY:
158 		{
159 			if (device < 0)
160 				device = dev_for_path("/boot");
161 			fs_info info;
162 			if (fs_stat_dev(device, &info) == 0) {
163 				if (!strcmp(info.fsh_name, "bfs")) {
164 					entry_ref ref(device, info.root, "home");
165 					BPath homePath(&ref);
166 					error = homePath.InitCheck();
167 					if (error == B_OK)
168 						path.SetTo(homePath.Path(), "Desktop/Trash");
169 				} else if (!strcmp(info.fsh_name, "dos")) {
170 					entry_ref ref(device, info.root, "RECYCLED");
171 					BPath recycledPath(&ref);
172 					error = recycledPath.InitCheck();
173 					if (error == B_OK)
174 						path.SetTo(recycledPath.Path(), "_BEOS_");
175 				} else
176 					error = B_ENTRY_NOT_FOUND;
177 			} else
178 				error = errno;
179 			break;
180 		}
181 		// BeOS directories.  These are mostly accessed read-only.
182 		case B_BEOS_DIRECTORY:
183 			error = path.SetTo("/boot/beos");
184 			break;
185 		case B_BEOS_SYSTEM_DIRECTORY:
186 			error = path.SetTo("/boot/beos/system");
187 			break;
188 		case B_BEOS_ADDONS_DIRECTORY:
189 			error = path.SetTo("/boot/beos/system/add-ons");
190 			break;
191 		case B_BEOS_BOOT_DIRECTORY:
192 			error = path.SetTo("/boot/beos/system/boot");
193 			break;
194 		case B_BEOS_FONTS_DIRECTORY:
195 			error = path.SetTo("/boot/beos/etc/fonts");
196 			break;
197 		case B_BEOS_LIB_DIRECTORY:
198 			error = path.SetTo("/boot/beos/system/lib");
199 			break;
200  		case B_BEOS_SERVERS_DIRECTORY:
201 			error = path.SetTo("/boot/beos/system/servers");
202 			break;
203 		case B_BEOS_APPS_DIRECTORY:
204 			error = path.SetTo("/boot/beos/apps");
205 			break;
206 		case B_BEOS_BIN_DIRECTORY:
207 			error = path.SetTo("/boot/beos/bin");
208 			break;
209 		case B_BEOS_ETC_DIRECTORY:
210 			error = path.SetTo("/boot/beos/etc");
211 			break;
212 		case B_BEOS_DOCUMENTATION_DIRECTORY:
213 			error = path.SetTo("/boot/beos/documentation");
214 			break;
215 		case B_BEOS_PREFERENCES_DIRECTORY:
216 			error = path.SetTo("/boot/beos/preferences");
217 			break;
218 		case B_BEOS_TRANSLATORS_DIRECTORY:
219 			error = path.SetTo("/boot/beos/system/add-ons/Translators");
220 			break;
221 		case B_BEOS_MEDIA_NODES_DIRECTORY:
222 			error = path.SetTo("/boot/beos/system/add-ons/media");
223 			break;
224 		case B_BEOS_SOUNDS_DIRECTORY:
225 			error = path.SetTo("/boot/beos/etc/sounds");
226 			break;
227 		// Common directories, shared among all users.
228 		case B_COMMON_DIRECTORY:
229 			error = path.SetTo("/boot/home");
230 			break;
231 		case B_COMMON_SYSTEM_DIRECTORY:
232 			error = path.SetTo("/boot/home/config");
233 			break;
234 		case B_COMMON_ADDONS_DIRECTORY:
235 			error = path.SetTo("/boot/home/config/add-ons");
236 			break;
237 		case B_COMMON_BOOT_DIRECTORY:
238 			error = path.SetTo("/boot/home/config/boot");
239 			break;
240 		case B_COMMON_FONTS_DIRECTORY:
241 			error = path.SetTo("/boot/home/config/fonts");
242 			break;
243 		case B_COMMON_LIB_DIRECTORY:
244 			error = path.SetTo("/boot/home/config/lib");
245 			break;
246 		case B_COMMON_SERVERS_DIRECTORY:
247 			error = path.SetTo("/boot/home/config/servers");
248 			break;
249 		case B_COMMON_BIN_DIRECTORY:
250 			error = path.SetTo("/boot/home/config/bin");
251 			break;
252 		case B_COMMON_ETC_DIRECTORY:
253 			error = path.SetTo("/boot/home/config/etc");
254 			break;
255 		case B_COMMON_DOCUMENTATION_DIRECTORY:
256 			error = path.SetTo("/boot/home/config/documentation");
257 			break;
258 		case B_COMMON_SETTINGS_DIRECTORY:
259 			error = path.SetTo("/boot/home/config/settings");
260 			break;
261 		case B_COMMON_DEVELOP_DIRECTORY:
262 			error = path.SetTo("/boot/develop");
263 			break;
264 		case B_COMMON_LOG_DIRECTORY:
265 			error = path.SetTo("/boot/var/log");
266 			break;
267 		case B_COMMON_SPOOL_DIRECTORY:
268 			error = path.SetTo("/boot/var/spool");
269 			break;
270 		case B_COMMON_TEMP_DIRECTORY:
271 			error = path.SetTo("/boot/var/tmp");
272 			break;
273 		case B_COMMON_VAR_DIRECTORY:
274 			error = path.SetTo("/boot/var");
275 			break;
276 		case B_COMMON_TRANSLATORS_DIRECTORY:
277 			error = path.SetTo("/boot/home/config/add-ons/Translators");
278 			break;
279 		case B_COMMON_MEDIA_NODES_DIRECTORY:
280 			error = path.SetTo("/boot/home/config/add-ons/media");
281 			break;
282 		case B_COMMON_SOUNDS_DIRECTORY:
283 			error = path.SetTo("/boot/home/config/sounds");
284 			break;
285 		// User directories.  These are interpreted in the context
286 		// of the user making the find_directory call.
287 		case B_USER_DIRECTORY:
288 			error = path.SetTo("/boot/home");
289 			break;
290 		case B_USER_CONFIG_DIRECTORY:
291 			error = path.SetTo("/boot/home/config");
292 			break;
293 		case B_USER_ADDONS_DIRECTORY:
294 			error = path.SetTo("/boot/home/config/add-ons");
295 			break;
296 		case B_USER_BOOT_DIRECTORY:
297 			error = path.SetTo("/boot/home/config/boot");
298 			break;
299 		case B_USER_FONTS_DIRECTORY:
300 			error = path.SetTo("/boot/home/config/fonts");
301 			break;
302 		case B_USER_LIB_DIRECTORY:
303 			error = path.SetTo("/boot/home/config/lib");
304 			break;
305 		case B_USER_SETTINGS_DIRECTORY:
306 			error = path.SetTo("/boot/home/config/settings");
307 			break;
308 		case B_USER_DESKBAR_DIRECTORY:
309 			error = path.SetTo("/boot/home/config/be");
310 			break;
311 		case B_USER_PRINTERS_DIRECTORY:
312 			error = path.SetTo("/boot/home/config/settings/printers");
313 			break;
314 		case B_USER_TRANSLATORS_DIRECTORY:
315 			error = path.SetTo("/boot/home/config/add-ons/Translators");
316 			break;
317 		case B_USER_MEDIA_NODES_DIRECTORY:
318 			error = path.SetTo("/boot/home/config/add-ons/media");
319 			break;
320 		case B_USER_SOUNDS_DIRECTORY:
321 			error = path.SetTo("/boot/home/config/sounds");
322 			break;
323 		// Global directories.
324 		case B_APPS_DIRECTORY:
325 			error = path.SetTo("/boot/apps");
326 			break;
327 		case B_PREFERENCES_DIRECTORY:
328 			error = path.SetTo("/boot/preferences");
329 			break;
330 		case B_UTILITIES_DIRECTORY:
331 			error = path.SetTo("/boot/utilities");
332 			break;
333 	}
334 	return error;
335 }
336 
337 // TestDirectories
338 static
339 void
340 TestDirectories(dev_t device)
341 {
342 	BVolume volume;
343 	if (device >= 0)
344 		CPPUNIT_ASSERT( volume.SetTo(device) == B_OK );
345 	for (int32 i = 0; i < directoryCount; i++) {
346 		BPath path;
347 		BPath path2;
348 		char path3[B_PATH_NAME_LENGTH + 1];
349 		status_t result = test_find_directory(directories[i], path, device);
350 		status_t result2 = find_directory(directories[i], &path2, false,
351 										  &volume);
352 		status_t result3 = find_directory(directories[i], device, false,
353 										  path3, B_PATH_NAME_LENGTH + 1);
354 		CPPUNIT_ASSERT( result == result2 && result == result3 );
355 		if (result == B_OK)
356 			CPPUNIT_ASSERT( path == path2 && path == path3 );
357 	}
358 }
359 
360 // Test
361 void
362 FindDirectoryTest::Test()
363 {
364 	// /boot
365 	NextSubTest();
366 	dev_t device = dev_for_path("/boot");
367 	CPPUNIT_ASSERT( device > 0 );
368 	TestDirectories(device);
369 	// /dev
370 	NextSubTest();
371 	device = dev_for_path("/dev");
372 	CPPUNIT_ASSERT( device > 0 );
373 	TestDirectories(device);
374 	// /
375 	NextSubTest();
376 	device = dev_for_path("/");
377 	CPPUNIT_ASSERT( device > 0 );
378 	TestDirectories(device);
379 	// test image
380 	NextSubTest();
381 	device = dev_for_path(testMountPoint);
382 	CPPUNIT_ASSERT( device > 0 );
383 	TestDirectories(device);
384 	// invalid device ID
385 	NextSubTest();
386 	TestDirectories(-1);
387 	// NULL BVolume
388 	NextSubTest();
389 	for (int32 i = 0; i < directoryCount; i++) {
390 		BPath path;
391 		BPath path2;
392 		status_t result = test_find_directory(directories[i], path, -1);
393 		status_t result2 = find_directory(directories[i], &path2, false, NULL);
394 		CPPUNIT_ASSERT( result == result2 );
395 		if (result == B_OK)
396 			CPPUNIT_ASSERT( path == path2 );
397 	}
398 	// no such volume
399 	NextSubTest();
400 	device = 213;
401 	fs_info info;
402 	while (fs_stat_dev(device, &info) == 0)
403 		device++;
404 	for (int32 i = 0; i < directoryCount; i++) {
405 		BPath path;
406 		char path3[B_PATH_NAME_LENGTH + 1];
407 		status_t result = test_find_directory(directories[i], path, device);
408 		status_t result3 = find_directory(directories[i], device, false,
409 										  path3, B_PATH_NAME_LENGTH + 1);
410 		// Our test_find_directory() returns rather strange errors instead
411 		// of B_ENTRY_NOT_FOUND.
412 		CPPUNIT_ASSERT( result == B_OK && result3 == B_OK
413 						|| result != B_OK && result3 != B_OK );
414 		if (result == B_OK)
415 			CPPUNIT_ASSERT( path == path3 );
416 	}
417 	// bad args
418 	// R5: crashes
419 	NextSubTest();
420 	device = dev_for_path("/boot");
421 	CPPUNIT_ASSERT( device > 0 );
422 #if !TEST_R5
423 	CPPUNIT_ASSERT( find_directory(B_BEOS_DIRECTORY, NULL, false, NULL)
424 					== B_BAD_VALUE );
425 	CPPUNIT_ASSERT( find_directory(B_BEOS_DIRECTORY, device, false, NULL, 50)
426 					== B_BAD_VALUE );
427 #endif
428 	// small buffer
429 	NextSubTest();
430 	char path3[7];
431 	CPPUNIT_ASSERT( find_directory(B_BEOS_DIRECTORY, device, false, path3, 7)
432 					== E2BIG );
433 }
434 
435 
436 
437 
438 
439