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