xref: /haiku/src/tests/kits/storage/SymLinkTest.cpp (revision 268f99dd7dc4bd7474a8bd2742d3f1ec1de6752a)
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*
Suite()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
CreateRONodes(TestNodes & testEntries)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
CreateRWNodes(TestNodes & testEntries)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
CreateUninitializedNodes(TestNodes & testEntries)71 SymLinkTest::CreateUninitializedNodes(TestNodes& testEntries)
72 {
73 	testEntries.clear();
74 	testEntries.add(new BSymLink, "");
75 }
76 
77 // setUp
setUp()78 void SymLinkTest::setUp()
79 {
80 	NodeTest::setUp();
81 }
82 
83 // tearDown
tearDown()84 void SymLinkTest::tearDown()
85 {
86 	NodeTest::tearDown();
87 }
88 
89 // InitTest1
90 void
InitTest1()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_ENTRY_NOT_FOUND);
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
InitTest2()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_ENTRY_NOT_FOUND);
471 	CPPUNIT_ASSERT(link.InitCheck() == B_ENTRY_NOT_FOUND);
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
ReadLinkTest()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 	// Haiku: ... so do we
556 	NextSubTest();
557 	char smallBuffer[2];
558 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
559 	ssize_t linkLength = link.ReadLink(smallBuffer, sizeof(smallBuffer));
560 	CPPUNIT_ASSERT(linkLength == static_cast<ssize_t>(strlen(existingDir)));
561 	CPPUNIT_ASSERT_EQUAL('/', smallBuffer[0]);
562 	CPPUNIT_ASSERT_EQUAL('\0', smallBuffer[1]);
563 
564 	// Invoke with one extra byte of length to ensure that the result is NULL
565 	// terminated.
566 	NextSubTest();
567 	buffer[17] = 'x';
568 	CPPUNIT_ASSERT(link.ReadLink(buffer, 18));
569 	CPPUNIT_ASSERT_EQUAL('\0', buffer[17]);
570 	CPPUNIT_ASSERT_EQUAL(strcmp(buffer, "/tmp/existing-dir"), 0);
571 
572 	// bad args
573 	NextSubTest();
574 	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
575 	CPPUNIT_ASSERT( equals(link.ReadLink(NULL, sizeof(buffer)), B_BAD_ADDRESS,
576 						   B_BAD_VALUE) );
577 }
578 
579 // MakeLinkedPathTest
580 void
MakeLinkedPathTest()581 SymLinkTest::MakeLinkedPathTest()
582 {
583 	const char *dirLink = dirLinkname;
584 	const char *fileLink = fileLinkname;
585 	const char *relDirLink = relDirLinkname;
586 	const char *relFileLink = relFileLinkname;
587 	const char *cyclicLink1 = cyclicLinkname1;
588 	const char *cyclicLink2 = cyclicLinkname2;
589 	const char *existingDir = existingDirname;
590 	const char *existingSuperDir = existingSuperDirname;
591 	const char *existingFile = existingFilename;
592 	const char *existingSuperFile = existingSuperFilename;
593 	const char *nonExisting = nonExistingDirname;
594 	BSymLink link;
595 	BPath path;
596 	// 1. MakeLinkedPath(const char*, BPath*)
597 	// uninitialized
598 	NextSubTest();
599 	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
600 	CPPUNIT_ASSERT( equals(link.MakeLinkedPath("/boot", &path), B_BAD_ADDRESS,
601 						   B_FILE_ERROR) );
602 	link.Unset();
603 	path.Unset();
604 	// existing absolute dir link
605 	NextSubTest();
606 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
607 	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
608 					== (ssize_t)strlen(existingDir) );
609 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
610 	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
611 	link.Unset();
612 	path.Unset();
613 	// existing absolute file link
614 	NextSubTest();
615 	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
616 	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
617 					== (ssize_t)strlen(existingFile) );
618 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
619 	CPPUNIT_ASSERT( string(existingFile) == path.Path() );
620 	link.Unset();
621 	path.Unset();
622 	// existing absolute cyclic link
623 	NextSubTest();
624 	CPPUNIT_ASSERT( link.SetTo(cyclicLink1) == B_OK );
625 	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
626 					== (ssize_t)strlen(cyclicLink2) );
627 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
628 	CPPUNIT_ASSERT( string(cyclicLink2) == path.Path() );
629 	link.Unset();
630 	path.Unset();
631 	// existing relative dir link
632 	NextSubTest();
633 	BEntry entry;
634 	BPath entryPath;
635 	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
636 	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
637 	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
638 	CPPUNIT_ASSERT( link.MakeLinkedPath(existingSuperDir, &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 	// existing relative file link
647 	NextSubTest();
648 	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
649 	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
650 	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
651 	CPPUNIT_ASSERT( link.MakeLinkedPath(existingSuperFile, &path)
652 					== (ssize_t)strlen(entryPath.Path()) );
653 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
654 	CPPUNIT_ASSERT( entryPath == path );
655 	link.Unset();
656 	path.Unset();
657 	entry.Unset();
658 	entryPath.Unset();
659 	// bad args
660 	NextSubTest();
661 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
662 // R5: crashs, when passing a NULL path
663 #if !TEST_R5
664 	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", NULL) == B_BAD_VALUE );
665 #endif
666 	CPPUNIT_ASSERT( link.MakeLinkedPath((const char*)NULL, &path)
667 					== B_BAD_VALUE );
668 // R5: crashs, when passing a NULL path
669 #if !TEST_R5
670 	CPPUNIT_ASSERT( link.MakeLinkedPath((const char*)NULL, NULL)
671 					== B_BAD_VALUE );
672 #endif
673 	link.Unset();
674 	path.Unset();
675 
676 	// 2. MakeLinkedPath(const BDirectory*, BPath*)
677 	// uninitialized
678 	NextSubTest();
679 	link.Unset();
680 	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
681 	BDirectory dir;
682 	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
683 	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_BAD_ADDRESS,
684 						   B_FILE_ERROR) );
685 	link.Unset();
686 	path.Unset();
687 	dir.Unset();
688 	// existing absolute dir link
689 	NextSubTest();
690 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
691 	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
692 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
693 					== (ssize_t)strlen(existingDir) );
694 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
695 	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
696 	link.Unset();
697 	path.Unset();
698 	dir.Unset();
699 	// existing absolute file link
700 	NextSubTest();
701 	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
702 	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
703 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
704 					== (ssize_t)strlen(existingFile) );
705 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
706 	CPPUNIT_ASSERT( string(existingFile) == path.Path() );
707 	link.Unset();
708 	path.Unset();
709 	dir.Unset();
710 	// existing absolute cyclic link
711 	NextSubTest();
712 	CPPUNIT_ASSERT( link.SetTo(cyclicLink1) == B_OK );
713 	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
714 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
715 					== (ssize_t)strlen(cyclicLink2) );
716 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
717 	CPPUNIT_ASSERT( string(cyclicLink2) == path.Path() );
718 	link.Unset();
719 	path.Unset();
720 	dir.Unset();
721 	// existing relative dir link
722 	NextSubTest();
723 	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
724 	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
725 	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
726 	CPPUNIT_ASSERT( dir.SetTo(existingSuperDir) == B_OK);
727 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
728 					== (ssize_t)strlen(entryPath.Path()) );
729 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
730 	CPPUNIT_ASSERT( entryPath == path );
731 	link.Unset();
732 	path.Unset();
733 	dir.Unset();
734 	entry.Unset();
735 	entryPath.Unset();
736 	// existing relative file link
737 	NextSubTest();
738 	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
739 	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
740 	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
741 	CPPUNIT_ASSERT( dir.SetTo(existingSuperFile) == B_OK);
742 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
743 					== (ssize_t)strlen(entryPath.Path()) );
744 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
745 	CPPUNIT_ASSERT( entryPath == path );
746 	link.Unset();
747 	path.Unset();
748 	dir.Unset();
749 	entry.Unset();
750 	entryPath.Unset();
751 	// absolute link, uninitialized dir
752 	NextSubTest();
753 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
754 	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT);
755 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
756 					== (ssize_t)strlen(existingDir) );
757 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
758 	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
759 	// absolute link, badly initialized dir
760 	NextSubTest();
761 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
762 	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND);
763 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
764 					== (ssize_t)strlen(existingDir) );
765 	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
766 	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
767 	link.Unset();
768 	path.Unset();
769 	dir.Unset();
770 	// relative link, uninitialized dir
771 	NextSubTest();
772 	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
773 	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT);
774 	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_NO_INIT,
775 						   B_BAD_VALUE) );
776 	link.Unset();
777 	// relative link, badly initialized dir
778 	NextSubTest();
779 	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
780 	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND);
781 	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_NO_INIT,
782 						   B_BAD_VALUE) );
783 	link.Unset();
784 	path.Unset();
785 	dir.Unset();
786 	// bad args
787 	NextSubTest();
788 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
789 	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
790 // R5: crashs, when passing a NULL path
791 #if !TEST_R5
792 	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, NULL) == B_BAD_VALUE );
793 #endif
794 
795 	CPPUNIT_ASSERT( link.MakeLinkedPath((const BDirectory*)NULL, &path)
796 					== B_BAD_VALUE );
797 // R5: crashs, when passing a NULL path
798 #if !TEST_R5
799 	CPPUNIT_ASSERT( link.MakeLinkedPath((const BDirectory*)NULL, NULL)
800 					== B_BAD_VALUE );
801 #endif
802 	link.Unset();
803 	path.Unset();
804 	dir.Unset();
805 }
806 
807 // IsAbsoluteTest
808 void
IsAbsoluteTest()809 SymLinkTest::IsAbsoluteTest()
810 {
811 	const char *dirLink = dirLinkname;
812 	const char *relFileLink = relFileLinkname;
813 	const char *existingDir = existingDirname;
814 	const char *existingFile = existingFilename;
815 	const char *nonExisting = nonExistingDirname;
816 	BSymLink link;
817 	// uninitialized
818 	NextSubTest();
819 	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
820 	CPPUNIT_ASSERT( link.IsAbsolute() == false );
821 	link.Unset();
822 	// existing absolute dir link
823 	NextSubTest();
824 	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
825 	CPPUNIT_ASSERT( link.IsAbsolute() == true );
826 	link.Unset();
827 	// existing relative file link
828 	NextSubTest();
829 	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
830 	CPPUNIT_ASSERT( link.IsAbsolute() == false );
831 	link.Unset();
832 	// non-existing link
833 	NextSubTest();
834 	CPPUNIT_ASSERT( link.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
835 	CPPUNIT_ASSERT( link.IsAbsolute() == false );
836 	link.Unset();
837 	// dir
838 	NextSubTest();
839 	CPPUNIT_ASSERT( link.SetTo(existingDir) == B_OK );
840 	CPPUNIT_ASSERT( link.IsAbsolute() == false );
841 	link.Unset();
842 	// file
843 	NextSubTest();
844 	CPPUNIT_ASSERT( link.SetTo(existingFile) == B_OK );
845 	CPPUNIT_ASSERT( link.IsAbsolute() == false );
846 	link.Unset();
847 }
848 
849 // AssignmentTest
850 void
AssignmentTest()851 SymLinkTest::AssignmentTest()
852 {
853 	const char *dirLink = dirLinkname;
854 	const char *fileLink = fileLinkname;
855 	// 1. copy constructor
856 	// uninitialized
857 	NextSubTest();
858 	{
859 		BSymLink link;
860 		CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
861 		BSymLink link2(link);
862 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
863 		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
864 	}
865 	// existing dir link
866 	NextSubTest();
867 	{
868 		BSymLink link(dirLink);
869 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
870 		BSymLink link2(link);
871 		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
872 	}
873 	// existing file link
874 	NextSubTest();
875 	{
876 		BSymLink link(fileLink);
877 		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
878 		BSymLink link2(link);
879 		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
880 	}
881 
882 	// 2. assignment operator
883 	// uninitialized
884 	NextSubTest();
885 	{
886 		BSymLink link;
887 		BSymLink link2;
888 		link2 = link;
889 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
890 		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
891 	}
892 	NextSubTest();
893 	{
894 		BSymLink link;
895 		BSymLink link2(dirLink);
896 		link2 = link;
897 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
898 		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
899 	}
900 	// existing dir link
901 	NextSubTest();
902 	{
903 		BSymLink link(dirLink);
904 		BSymLink link2;
905 		link2 = link;
906 		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
907 	}
908 	// existing file link
909 	NextSubTest();
910 	{
911 		BSymLink link(fileLink);
912 		BSymLink link2;
913 		link2 = link;
914 		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
915 	}
916 }
917 
918