xref: /haiku/src/tests/kits/storage/SymLinkTest.cpp (revision 51978af14a173e7fae0563b562be5603bc652aeb)
1 // SymLinkTest.cpp
2 
3 #include <stdio.h>
4 #include <string>
5 
6 #include <Directory.h>
7 #include <Entry.h>
8 #include <Path.h>
9 #include <SymLink.h>
10 
11 #include "SymLinkTest.h"
12 
13 // Suite
14 SymLinkTest::Test*
15 SymLinkTest::Suite()
16 {
17 	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
18 	typedef CppUnit::TestCaller<SymLinkTest> TC;
19 
20 	NodeTest::AddBaseClassTests<SymLinkTest>("BSymLink::", suite);
21 
22 	suite->addTest( new TC("BSymLink::Init Test 1", &SymLinkTest::InitTest1) );
23 	suite->addTest( new TC("BSymLink::Init Test 2", &SymLinkTest::InitTest2) );
24 	suite->addTest( new TC("BSymLink::ReadLink Test",
25 						   &SymLinkTest::ReadLinkTest) );
26 	suite->addTest( new TC("BSymLink::MakeLinkedPath Test",
27 						   &SymLinkTest::MakeLinkedPathTest) );
28 	suite->addTest( new TC("BSymLink::IsAbsolute Test",
29 						   &SymLinkTest::IsAbsoluteTest) );
30 	suite->addTest( new TC("BSymLink::Assignment Test",
31 						   &SymLinkTest::AssignmentTest) );
32 
33 	return suite;
34 }
35 
36 // CreateRONodes
37 void
38 SymLinkTest::CreateRONodes(TestNodes& testEntries)
39 {
40 	testEntries.clear();
41 	const char *filename;
42 	filename = "/tmp";
43 	testEntries.add(new BSymLink(filename), filename);
44 	filename = dirLinkname;
45 	testEntries.add(new BSymLink(filename), filename);
46 	filename = fileLinkname;
47 	testEntries.add(new BSymLink(filename), filename);
48 	filename = badLinkname;
49 	testEntries.add(new BSymLink(filename), filename);
50 	filename = cyclicLinkname1;
51 	testEntries.add(new BSymLink(filename), filename);
52 }
53 
54 // CreateRWNodes
55 void
56 SymLinkTest::CreateRWNodes(TestNodes& testEntries)
57 {
58 	testEntries.clear();
59 	const char *filename;
60 	filename = dirLinkname;
61 	testEntries.add(new BSymLink(filename), filename);
62 	filename = fileLinkname;
63 	testEntries.add(new BSymLink(filename), filename);
64 }
65 
66 // CreateUninitializedNodes
67 void
68 SymLinkTest::CreateUninitializedNodes(TestNodes& testEntries)
69 {
70 	testEntries.clear();
71 	testEntries.add(new BSymLink, "");
72 }
73 
74 // setUp
75 void SymLinkTest::setUp()
76 {
77 	NodeTest::setUp();
78 }
79 
80 // tearDown
81 void SymLinkTest::tearDown()
82 {
83 	NodeTest::tearDown();
84 }
85 
86 // InitTest1
87 void
88 SymLinkTest::InitTest1()
89 {
90 	const char *dirLink = dirLinkname;
91 	const char *dirSuperLink = dirSuperLinkname;
92 	const char *dirRelLink = dirRelLinkname;
93 	const char *fileLink = fileLinkname;
94 	const char *existingDir = existingDirname;
95 	const char *existingSuperDir = existingSuperDirname;
96 	const char *existingRelDir = existingRelDirname;
97 	const char *existingFile = existingFilename;
98 	const char *existingSuperFile = existingSuperFilename;
99 	const char *existingRelFile = existingRelFilename;
100 	const char *nonExisting = nonExistingDirname;
101 	const char *nonExistingSuper = nonExistingSuperDirname;
102 	const char *nonExistingRel = nonExistingRelDirname;
103 	// 1. default constructor
104 	NextSubTest();
105 	{
106 		BSymLink link;
107 		CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
108 	}
109 
110 	// 2. BSymLink(const char*)
111 	NextSubTest();
112 	{
113 		BSymLink link(fileLink);
114 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
115 	}
116 	NextSubTest();
117 	{
118 		BSymLink link(nonExisting);
119 		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
120 	}
121 	NextSubTest();
122 	{
123 		BSymLink link((const char *)NULL);
124 		CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
125 	}
126 	NextSubTest();
127 	{
128 		BSymLink link("");
129 		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
130 	}
131 	NextSubTest();
132 	{
133 		BSymLink link(existingFile);
134 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
135 	}
136 	NextSubTest();
137 	{
138 		BSymLink link(existingDir);
139 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
140 	}
141 	NextSubTest();
142 	{
143 		BSymLink link(tooLongEntryname);
144 		CPPUNIT_ASSERT( link.InitCheck() == B_NAME_TOO_LONG );
145 	}
146 
147 	// 3. BSymLink(const BEntry*)
148 	NextSubTest();
149 	{
150 		BEntry entry(dirLink);
151 		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
152 		BSymLink link(&entry);
153 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
154 	}
155 	NextSubTest();
156 	{
157 		BEntry entry(nonExisting);
158 		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
159 		BSymLink link(&entry);
160 		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
161 	}
162 	NextSubTest();
163 	{
164 		BSymLink link((BEntry *)NULL);
165 		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
166 	}
167 	NextSubTest();
168 	{
169 		BEntry entry;
170 		BSymLink link(&entry);
171 		CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
172 	}
173 	NextSubTest();
174 	{
175 		BEntry entry(existingFile);
176 		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
177 		BSymLink link(&entry);
178 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
179 
180 	}
181 	NextSubTest();
182 	{
183 		BEntry entry(existingDir);
184 		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
185 		BSymLink link(&entry);
186 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
187 
188 	}
189 	NextSubTest();
190 	{
191 		BEntry entry(tooLongEntryname);
192 		// R5 returns E2BIG instead of B_NAME_TOO_LONG
193 		CPPUNIT_ASSERT( equals(entry.InitCheck(), E2BIG, B_NAME_TOO_LONG) );
194 		BSymLink link(&entry);
195 		CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
196 	}
197 
198 	// 4. BSymLink(const entry_ref*)
199 	NextSubTest();
200 	{
201 		BEntry entry(dirLink);
202 		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
203 		entry_ref ref;
204 		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
205 		BSymLink link(&ref);
206 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
207 	}
208 	NextSubTest();
209 	{
210 		BEntry entry(nonExisting);
211 		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
212 		entry_ref ref;
213 		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
214 		BSymLink link(&ref);
215 		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
216 	}
217 	NextSubTest();
218 	{
219 		BSymLink link((entry_ref *)NULL);
220 		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
221 	}
222 	NextSubTest();
223 	{
224 		BEntry entry(existingFile);
225 		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
226 		entry_ref ref;
227 		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
228 		BSymLink link(&ref);
229 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
230 	}
231 	NextSubTest();
232 	{
233 		BEntry entry(existingDir);
234 		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
235 		entry_ref ref;
236 		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
237 		BSymLink link(&ref);
238 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
239 	}
240 
241 	// 5. BSymLink(const BDirectory*, const char*)
242 	NextSubTest();
243 	{
244 		BDirectory pathDir(dirSuperLink);
245 		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
246 		BSymLink link(&pathDir, dirRelLink);
247 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
248 	}
249 	NextSubTest();
250 	{
251 		BDirectory pathDir(dirSuperLink);
252 		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
253 		BSymLink link(&pathDir, dirLink);
254 		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
255 	}
256 	NextSubTest();
257 	{
258 		BDirectory pathDir(nonExistingSuper);
259 		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
260 		BSymLink link(&pathDir, nonExistingRel);
261 		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
262 	}
263 	NextSubTest();
264 	{
265 		BSymLink link((BDirectory *)NULL, (const char *)NULL);
266 		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
267 	}
268 	NextSubTest();
269 	{
270 		BSymLink link((BDirectory *)NULL, dirLink);
271 		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
272 	}
273 	NextSubTest();
274 	{
275 		BDirectory pathDir(dirSuperLink);
276 		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
277 		BSymLink link(&pathDir, (const char *)NULL);
278 		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
279 	}
280 	NextSubTest();
281 	{
282 		BDirectory pathDir(dirSuperLink);
283 		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
284 		BSymLink link(&pathDir, "");
285 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
286 	}
287 	NextSubTest();
288 	{
289 		BDirectory pathDir(existingSuperFile);
290 		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
291 		BSymLink link(&pathDir, existingRelFile);
292 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
293 	}
294 	NextSubTest();
295 	{
296 		BDirectory pathDir(existingSuperDir);
297 		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
298 		BSymLink link(&pathDir, existingRelDir);
299 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
300 	}
301 	NextSubTest();
302 	{
303 		BDirectory pathDir(tooLongSuperEntryname);
304 		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
305 		BSymLink link(&pathDir, tooLongRelEntryname);
306 		CPPUNIT_ASSERT( link.InitCheck() == B_NAME_TOO_LONG );
307 	}
308 	NextSubTest();
309 	{
310 		BDirectory pathDir(fileSuperDirname);
311 		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
312 		BSymLink link(&pathDir, fileRelDirname);
313 		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
314 	}
315 }
316 
317 // InitTest2
318 void
319 SymLinkTest::InitTest2()
320 {
321 	const char *dirLink = dirLinkname;
322 	const char *dirSuperLink = dirSuperLinkname;
323 	const char *dirRelLink = dirRelLinkname;
324 	const char *fileLink = fileLinkname;
325 	const char *existingDir = existingDirname;
326 	const char *existingSuperDir = existingSuperDirname;
327 	const char *existingRelDir = existingRelDirname;
328 	const char *existingFile = existingFilename;
329 	const char *existingSuperFile = existingSuperFilename;
330 	const char *existingRelFile = existingRelFilename;
331 	const char *nonExisting = nonExistingDirname;
332 	const char *nonExistingSuper = nonExistingSuperDirname;
333 	const char *nonExistingRel = nonExistingRelDirname;
334 	BSymLink link;
335 	// 2. BSymLink(const char*)
336 	NextSubTest();
337 	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
338 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
339 	//
340 	NextSubTest();
341 	CPPUNIT_ASSERT( link.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
342 	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
343 	//
344 	NextSubTest();
345 	CPPUNIT_ASSERT( equals(link.SetTo((const char *)NULL), B_BAD_VALUE,
346 						   B_NO_INIT) );
347 	CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
348 	//
349 	NextSubTest();
350 	CPPUNIT_ASSERT( link.SetTo("") == B_ENTRY_NOT_FOUND );
351 	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
352 	//
353 	NextSubTest();
354 	CPPUNIT_ASSERT( link.SetTo(existingFile) == B_OK );
355 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
356 	//
357 	NextSubTest();
358 	CPPUNIT_ASSERT( link.SetTo(existingDir) == B_OK );
359 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
360 	//
361 	NextSubTest();
362 	CPPUNIT_ASSERT( link.SetTo(tooLongEntryname) == B_NAME_TOO_LONG );
363 	CPPUNIT_ASSERT( link.InitCheck() == B_NAME_TOO_LONG );
364 
365 	// 3. BSymLink(const BEntry*)
366 	NextSubTest();
367 	BEntry entry(dirLink);
368 	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
369 	CPPUNIT_ASSERT( link.SetTo(&entry) == B_OK );
370 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
371 	//
372 	NextSubTest();
373 	CPPUNIT_ASSERT( entry.SetTo(nonExisting) == B_OK );
374 	CPPUNIT_ASSERT( link.SetTo(&entry) == B_ENTRY_NOT_FOUND );
375 	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
376 	//
377 	NextSubTest();
378 	CPPUNIT_ASSERT( link.SetTo((BEntry *)NULL) == B_BAD_VALUE );
379 	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
380 	//
381 	NextSubTest();
382 	entry.Unset();
383 	CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
384 	CPPUNIT_ASSERT( equals(link.SetTo(&entry), B_BAD_ADDRESS, B_BAD_VALUE) );
385 	CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
386 	//
387 	NextSubTest();
388 	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
389 	CPPUNIT_ASSERT( link.SetTo(&entry) == B_OK );
390 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
391 	//
392 	NextSubTest();
393 	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
394 	CPPUNIT_ASSERT( link.SetTo(&entry) == B_OK );
395 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
396 	//
397 	NextSubTest();
398 	// R5 returns E2BIG instead of B_NAME_TOO_LONG
399 	CPPUNIT_ASSERT( equals(entry.SetTo(tooLongEntryname), E2BIG,
400 						   B_NAME_TOO_LONG) );
401 	CPPUNIT_ASSERT( equals(link.SetTo(&entry), B_BAD_ADDRESS, B_BAD_VALUE) );
402 	CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
403 
404 	// 4. BSymLink(const entry_ref*)
405 	NextSubTest();
406 	CPPUNIT_ASSERT( entry.SetTo(dirLink) == B_OK );
407 	entry_ref ref;
408 	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
409 	CPPUNIT_ASSERT( link.SetTo(&ref) == B_OK );
410 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
411 	//
412 	NextSubTest();
413 	CPPUNIT_ASSERT( entry.SetTo(nonExisting) == B_OK );
414 	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
415 	CPPUNIT_ASSERT( link.SetTo(&ref) == B_ENTRY_NOT_FOUND );
416 	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
417 	//
418 	NextSubTest();
419 	CPPUNIT_ASSERT( link.SetTo((entry_ref *)NULL) == B_BAD_VALUE );
420 	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
421 	//
422 	NextSubTest();
423 	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
424 	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
425 	CPPUNIT_ASSERT( link.SetTo(&ref) == B_OK );
426 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
427 	//
428 	NextSubTest();
429 	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
430 	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
431 	CPPUNIT_ASSERT( link.SetTo(&ref) == B_OK );
432 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
433 
434 	// 5. BSymLink(const BDirectory*, const char*)
435 	NextSubTest();
436 	BDirectory pathDir(dirSuperLink);
437 	CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
438 	CPPUNIT_ASSERT( link.SetTo(&pathDir, dirRelLink) == B_OK );
439 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
440 	//
441 	NextSubTest();
442 	CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK );
443 	CPPUNIT_ASSERT( link.SetTo(&pathDir, dirLink) == B_BAD_VALUE );
444 	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
445 	//
446 	NextSubTest();
447 	CPPUNIT_ASSERT( pathDir.SetTo(nonExistingSuper) == B_OK );
448 	CPPUNIT_ASSERT( link.SetTo(&pathDir, nonExistingRel) == B_ENTRY_NOT_FOUND );
449 	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
450 	//
451 	NextSubTest();
452 	CPPUNIT_ASSERT( link.SetTo((BDirectory *)NULL, (const char *)NULL)
453 					== B_BAD_VALUE );
454 	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
455 	//
456 	NextSubTest();
457 	CPPUNIT_ASSERT( link.SetTo((BDirectory *)NULL, dirLink) == B_BAD_VALUE );
458 	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
459 	//
460 	NextSubTest();
461 	CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK );
462 	CPPUNIT_ASSERT( link.SetTo(&pathDir, (const char *)NULL) == B_BAD_VALUE );
463 	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
464 	//
465 	NextSubTest();
466 	CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK );
467 	CPPUNIT_ASSERT( link.SetTo(&pathDir, "") == B_OK );
468 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
469 	//
470 	NextSubTest();
471 	CPPUNIT_ASSERT( pathDir.SetTo(existingSuperFile) == B_OK );
472 	CPPUNIT_ASSERT( link.SetTo(&pathDir, existingRelFile) == B_OK );
473 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
474 	//
475 	NextSubTest();
476 	CPPUNIT_ASSERT( pathDir.SetTo(existingSuperDir) == B_OK );
477 	CPPUNIT_ASSERT( link.SetTo(&pathDir, existingRelDir) == B_OK );
478 	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
479 	//
480 	NextSubTest();
481 	CPPUNIT_ASSERT( pathDir.SetTo(tooLongSuperEntryname) == B_OK );
482 	CPPUNIT_ASSERT( link.SetTo(&pathDir, tooLongRelEntryname)
483 					== B_NAME_TOO_LONG );
484 	CPPUNIT_ASSERT( link.InitCheck() == B_NAME_TOO_LONG );
485 	//
486 	NextSubTest();
487 	CPPUNIT_ASSERT( pathDir.SetTo(fileSuperDirname) == B_OK );
488 	CPPUNIT_ASSERT( link.SetTo(&pathDir, fileRelDirname) == B_ENTRY_NOT_FOUND );
489 	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
490 }
491 
492 // ReadLinkTest
493 void
494 SymLinkTest::ReadLinkTest()
495 {
496 	const char *dirLink = dirLinkname;
497 	const char *fileLink = fileLinkname;
498 	const char *badLink = badLinkname;
499 	const char *cyclicLink1 = cyclicLinkname1;
500 	const char *cyclicLink2 = cyclicLinkname2;
501 	const char *existingDir = existingDirname;
502 	const char *existingFile = existingFilename;
503 	const char *nonExisting = nonExistingDirname;
504 	BSymLink link;
505 	char buffer[B_PATH_NAME_LENGTH + 1];
506 	// uninitialized
507 	// R5: returns B_BAD_ADDRESS instead of (as doc'ed) B_FILE_ERROR
508 	NextSubTest();
509 	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
510 	CPPUNIT_ASSERT( equals(link.ReadLink(buffer, sizeof(buffer)),
511 						   B_BAD_ADDRESS, B_FILE_ERROR) );
512 	// existing dir link
513 	NextSubTest();
514 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
515 	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
516 					== (ssize_t)strlen(existingDir) );
517 	CPPUNIT_ASSERT( strcmp(buffer, existingDir) == 0 );
518 	// existing file link
519 	NextSubTest();
520 	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
521 	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
522 					== (ssize_t)strlen(existingFile) );
523 	CPPUNIT_ASSERT( strcmp(buffer, existingFile) == 0 );
524 	// existing cyclic link
525 	NextSubTest();
526 	CPPUNIT_ASSERT( link.SetTo(cyclicLink1) == B_OK );
527 	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
528 					== (ssize_t)strlen(cyclicLink2) );
529 	CPPUNIT_ASSERT( strcmp(buffer, cyclicLink2) == 0 );
530 	// existing link to non-existing entry
531 	NextSubTest();
532 	CPPUNIT_ASSERT( link.SetTo(badLink) == B_OK );
533 	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
534 					== (ssize_t)strlen(nonExisting) );
535 	CPPUNIT_ASSERT( strcmp(buffer, nonExisting) == 0 );
536 	// non-existing link
537 	// R5: returns B_BAD_ADDRESS instead of (as doc'ed) B_FILE_ERROR
538 	NextSubTest();
539 	CPPUNIT_ASSERT( link.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
540 	CPPUNIT_ASSERT( equals(link.ReadLink(buffer, sizeof(buffer)),
541 						   B_BAD_ADDRESS, B_FILE_ERROR) );
542 	// dir
543 	NextSubTest();
544 	CPPUNIT_ASSERT( link.SetTo(existingDir) == B_OK );
545 	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer)) == B_BAD_VALUE );
546 	// file
547 	NextSubTest();
548 	CPPUNIT_ASSERT( link.SetTo(existingFile) == B_OK );
549 	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer)) == B_BAD_VALUE );
550 	// small buffer
551 	// R5: returns the size of the contents, not the number of bytes copied
552 	// OBOS: ... so do we
553 	NextSubTest();
554 	char smallBuffer[2];
555 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
556 	CPPUNIT_ASSERT( link.ReadLink(smallBuffer, sizeof(smallBuffer))
557 					== (ssize_t)strlen(dirLink) );
558 	CPPUNIT_ASSERT( strncmp(smallBuffer, existingDir, sizeof(smallBuffer)) == 0 );
559 	// bad args
560 	NextSubTest();
561 	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
562 	CPPUNIT_ASSERT( equals(link.ReadLink(NULL, sizeof(buffer)), B_BAD_ADDRESS,
563 						   B_BAD_VALUE) );
564 }
565 
566 // MakeLinkedPathTest
567 void
568 SymLinkTest::MakeLinkedPathTest()
569 {
570 	const char *dirLink = dirLinkname;
571 	const char *fileLink = fileLinkname;
572 	const char *relDirLink = relDirLinkname;
573 	const char *relFileLink = relFileLinkname;
574 	const char *cyclicLink1 = cyclicLinkname1;
575 	const char *cyclicLink2 = cyclicLinkname2;
576 	const char *existingDir = existingDirname;
577 	const char *existingSuperDir = existingSuperDirname;
578 	const char *existingFile = existingFilename;
579 	const char *existingSuperFile = existingSuperFilename;
580 	const char *nonExisting = nonExistingDirname;
581 	BSymLink link;
582 	BPath path;
583 	// 1. MakeLinkedPath(const char*, BPath*)
584 	// uninitialized
585 	NextSubTest();
586 	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
587 	CPPUNIT_ASSERT( equals(link.MakeLinkedPath("/boot", &path), B_BAD_ADDRESS,
588 						   B_FILE_ERROR) );
589 	link.Unset();
590 	path.Unset();
591 	// existing absolute dir link
592 	NextSubTest();
593 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
594 	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
595 					== (ssize_t)strlen(existingDir) );
596 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
597 	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
598 	link.Unset();
599 	path.Unset();
600 	// existing absolute file link
601 	NextSubTest();
602 	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
603 	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
604 					== (ssize_t)strlen(existingFile) );
605 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
606 	CPPUNIT_ASSERT( string(existingFile) == path.Path() );
607 	link.Unset();
608 	path.Unset();
609 	// existing absolute cyclic link
610 	NextSubTest();
611 	CPPUNIT_ASSERT( link.SetTo(cyclicLink1) == B_OK );
612 	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
613 					== (ssize_t)strlen(cyclicLink2) );
614 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
615 	CPPUNIT_ASSERT( string(cyclicLink2) == path.Path() );
616 	link.Unset();
617 	path.Unset();
618 	// existing relative dir link
619 	NextSubTest();
620 	BEntry entry;
621 	BPath entryPath;
622 	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
623 	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
624 	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
625 	CPPUNIT_ASSERT( link.MakeLinkedPath(existingSuperDir, &path)
626 					== (ssize_t)strlen(entryPath.Path()) );
627 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
628 	CPPUNIT_ASSERT( entryPath == path );
629 	link.Unset();
630 	path.Unset();
631 	entry.Unset();
632 	entryPath.Unset();
633 	// existing relative file link
634 	NextSubTest();
635 	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
636 	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
637 	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
638 	CPPUNIT_ASSERT( link.MakeLinkedPath(existingSuperFile, &path)
639 					== (ssize_t)strlen(entryPath.Path()) );
640 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
641 	CPPUNIT_ASSERT( entryPath == path );
642 	link.Unset();
643 	path.Unset();
644 	entry.Unset();
645 	entryPath.Unset();
646 	// bad args
647 	NextSubTest();
648 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
649 // R5: crashs, when passing a NULL path
650 #if !TEST_R5
651 	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", NULL) == B_BAD_VALUE );
652 #endif
653 	CPPUNIT_ASSERT( link.MakeLinkedPath((const char*)NULL, &path)
654 					== B_BAD_VALUE );
655 // R5: crashs, when passing a NULL path
656 #if !TEST_R5
657 	CPPUNIT_ASSERT( link.MakeLinkedPath((const char*)NULL, NULL)
658 					== B_BAD_VALUE );
659 #endif
660 	link.Unset();
661 	path.Unset();
662 
663 	// 2. MakeLinkedPath(const BDirectory*, BPath*)
664 	// uninitialized
665 	NextSubTest();
666 	link.Unset();
667 	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
668 	BDirectory dir;
669 	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
670 	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_BAD_ADDRESS,
671 						   B_FILE_ERROR) );
672 	link.Unset();
673 	path.Unset();
674 	dir.Unset();
675 	// existing absolute dir link
676 	NextSubTest();
677 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
678 	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
679 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
680 					== (ssize_t)strlen(existingDir) );
681 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
682 	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
683 	link.Unset();
684 	path.Unset();
685 	dir.Unset();
686 	// existing absolute file link
687 	NextSubTest();
688 	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
689 	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
690 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
691 					== (ssize_t)strlen(existingFile) );
692 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
693 	CPPUNIT_ASSERT( string(existingFile) == path.Path() );
694 	link.Unset();
695 	path.Unset();
696 	dir.Unset();
697 	// existing absolute cyclic link
698 	NextSubTest();
699 	CPPUNIT_ASSERT( link.SetTo(cyclicLink1) == B_OK );
700 	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
701 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
702 					== (ssize_t)strlen(cyclicLink2) );
703 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
704 	CPPUNIT_ASSERT( string(cyclicLink2) == path.Path() );
705 	link.Unset();
706 	path.Unset();
707 	dir.Unset();
708 	// existing relative dir link
709 	NextSubTest();
710 	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
711 	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
712 	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
713 	CPPUNIT_ASSERT( dir.SetTo(existingSuperDir) == B_OK);
714 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
715 					== (ssize_t)strlen(entryPath.Path()) );
716 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
717 	CPPUNIT_ASSERT( entryPath == path );
718 	link.Unset();
719 	path.Unset();
720 	dir.Unset();
721 	entry.Unset();
722 	entryPath.Unset();
723 	// existing relative file link
724 	NextSubTest();
725 	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
726 	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
727 	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
728 	CPPUNIT_ASSERT( dir.SetTo(existingSuperFile) == B_OK);
729 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
730 					== (ssize_t)strlen(entryPath.Path()) );
731 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
732 	CPPUNIT_ASSERT( entryPath == path );
733 	link.Unset();
734 	path.Unset();
735 	dir.Unset();
736 	entry.Unset();
737 	entryPath.Unset();
738 	// absolute link, uninitialized dir
739 	NextSubTest();
740 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
741 	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT);
742 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
743 					== (ssize_t)strlen(existingDir) );
744 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
745 	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
746 	// absolute link, badly initialized dir
747 	NextSubTest();
748 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
749 	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND);
750 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
751 					== (ssize_t)strlen(existingDir) );
752 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
753 	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
754 	link.Unset();
755 	path.Unset();
756 	dir.Unset();
757 	// relative link, uninitialized dir
758 	NextSubTest();
759 	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
760 	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT);
761 	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_NO_INIT,
762 						   B_BAD_VALUE) );
763 	link.Unset();
764 	// relative link, badly initialized dir
765 	NextSubTest();
766 	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
767 	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND);
768 	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_NO_INIT,
769 						   B_BAD_VALUE) );
770 	link.Unset();
771 	path.Unset();
772 	dir.Unset();
773 	// bad args
774 	NextSubTest();
775 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
776 	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
777 // R5: crashs, when passing a NULL path
778 #if !TEST_R5
779 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, NULL) == B_BAD_VALUE );
780 #endif
781 
782 	CPPUNIT_ASSERT( link.MakeLinkedPath((const BDirectory*)NULL, &path)
783 					== B_BAD_VALUE );
784 // R5: crashs, when passing a NULL path
785 #if !TEST_R5
786 	CPPUNIT_ASSERT( link.MakeLinkedPath((const BDirectory*)NULL, NULL)
787 					== B_BAD_VALUE );
788 #endif
789 	link.Unset();
790 	path.Unset();
791 	dir.Unset();
792 }
793 
794 // IsAbsoluteTest
795 void
796 SymLinkTest::IsAbsoluteTest()
797 {
798 	const char *dirLink = dirLinkname;
799 	const char *relFileLink = relFileLinkname;
800 	const char *existingDir = existingDirname;
801 	const char *existingFile = existingFilename;
802 	const char *nonExisting = nonExistingDirname;
803 	BSymLink link;
804 	// uninitialized
805 	NextSubTest();
806 	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
807 	CPPUNIT_ASSERT( link.IsAbsolute() == false );
808 	link.Unset();
809 	// existing absolute dir link
810 	NextSubTest();
811 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
812 	CPPUNIT_ASSERT( link.IsAbsolute() == true );
813 	link.Unset();
814 	// existing relative file link
815 	NextSubTest();
816 	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
817 	CPPUNIT_ASSERT( link.IsAbsolute() == false );
818 	link.Unset();
819 	// non-existing link
820 	NextSubTest();
821 	CPPUNIT_ASSERT( link.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
822 	CPPUNIT_ASSERT( link.IsAbsolute() == false );
823 	link.Unset();
824 	// dir
825 	NextSubTest();
826 	CPPUNIT_ASSERT( link.SetTo(existingDir) == B_OK );
827 	CPPUNIT_ASSERT( link.IsAbsolute() == false );
828 	link.Unset();
829 	// file
830 	NextSubTest();
831 	CPPUNIT_ASSERT( link.SetTo(existingFile) == B_OK );
832 	CPPUNIT_ASSERT( link.IsAbsolute() == false );
833 	link.Unset();
834 }
835 
836 // AssignmentTest
837 void
838 SymLinkTest::AssignmentTest()
839 {
840 	const char *dirLink = dirLinkname;
841 	const char *fileLink = fileLinkname;
842 	// 1. copy constructor
843 	// uninitialized
844 	NextSubTest();
845 	{
846 		BSymLink link;
847 		CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
848 		BSymLink link2(link);
849 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
850 		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
851 	}
852 	// existing dir link
853 	NextSubTest();
854 	{
855 		BSymLink link(dirLink);
856 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
857 		BSymLink link2(link);
858 		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
859 	}
860 	// existing file link
861 	NextSubTest();
862 	{
863 		BSymLink link(fileLink);
864 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
865 		BSymLink link2(link);
866 		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
867 	}
868 
869 	// 2. assignment operator
870 	// uninitialized
871 	NextSubTest();
872 	{
873 		BSymLink link;
874 		BSymLink link2;
875 		link2 = link;
876 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
877 		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
878 	}
879 	NextSubTest();
880 	{
881 		BSymLink link;
882 		BSymLink link2(dirLink);
883 		link2 = link;
884 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
885 		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
886 	}
887 	// existing dir link
888 	NextSubTest();
889 	{
890 		BSymLink link(dirLink);
891 		BSymLink link2;
892 		link2 = link;
893 		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
894 	}
895 	// existing file link
896 	NextSubTest();
897 	{
898 		BSymLink link(fileLink);
899 		BSymLink link2;
900 		link2 = link;
901 		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
902 	}
903 }
904 
905