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