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