xref: /haiku/src/tests/kits/storage/FileTest.cpp (revision 5f4f455cfde9e453ecbf4d102a9577752706f431)
1 // FileTest.cpp
2 
3 #include <Directory.h>
4 #include <Entry.h>
5 #include <File.h>
6 #include <Path.h>
7 
8 #include <cppunit/TestCaller.h>
9 #include <cppunit/TestSuite.h>
10 #include <TestShell.h>
11 
12 #include "FileTest.h"
13 
14 // Suite
15 FileTest::Test*
Suite()16 FileTest::Suite()
17 {
18 	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
19 	typedef CppUnit::TestCaller<FileTest> TC;
20 
21 	NodeTest::AddBaseClassTests<FileTest>("BFile::", suite);
22 
23 	suite->addTest( new TC("BFile::Init Test 1", &FileTest::InitTest1) );
24 	suite->addTest( new TC("BFile::Init Test 2", &FileTest::InitTest2) );
25 	suite->addTest( new TC("BFile::IsRead-/IsWriteable Test",
26 						   &FileTest::RWAbleTest) );
27 	suite->addTest( new TC("BFile::Read/Write Test", &FileTest::RWTest) );
28 	suite->addTest( new TC("BFile::Position Test", &FileTest::PositionTest) );
29 	suite->addTest( new TC("BFile::Size Test", &FileTest::SizeTest) );
30 	suite->addTest( new TC("BFile::Assignment Test",
31 						   &FileTest::AssignmentTest) );
32 	return suite;
33 }
34 
35 // CreateRONodes
36 void
CreateRONodes(TestNodes & testEntries)37 FileTest::CreateRONodes(TestNodes& testEntries)
38 {
39 	testEntries.clear();
40 	const char *filename;
41 	filename = existingFilename;
42 	testEntries.add(new BFile(filename, B_READ_ONLY), filename);
43 }
44 
45 // CreateRWNodes
46 void
CreateRWNodes(TestNodes & testEntries)47 FileTest::CreateRWNodes(TestNodes& testEntries)
48 {
49 	testEntries.clear();
50 	const char *filename;
51 	filename = existingFilename;
52 	testEntries.add(new BFile(filename, B_READ_WRITE), filename);
53 }
54 
55 // CreateUninitializedNodes
56 void
CreateUninitializedNodes(TestNodes & testEntries)57 FileTest::CreateUninitializedNodes(TestNodes& testEntries)
58 {
59 	testEntries.clear();
60 	testEntries.add(new BFile, "");
61 }
62 
63 // setUp
setUp()64 void FileTest::setUp()
65 {
66 	NodeTest::setUp();
67 }
68 
69 // tearDown
tearDown()70 void FileTest::tearDown()
71 {
72 	NodeTest::tearDown();
73 }
74 
75 // InitTest1
76 void
InitTest1()77 FileTest::InitTest1()
78 {
79 	// 1. default constructor
80 	{
81 		BFile file;
82 		CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
83 	}
84 
85 	// helper class for the testing the different constructors versions
86 	struct Tester {
87 		void testAll() const
88 		{
89 			for (int32 i = 0; i < initTestCasesCount; i++) {
90 				if (BTestShell::GlobalBeVerbose()) {
91 					printf("[%" B_PRId32 "]", i);
92 					fflush(stdout);
93 				}
94 				test(initTestCases[i]);
95 			}
96 			if (BTestShell::GlobalBeVerbose())
97 				printf("\n");
98 		}
99 
100 		virtual void test(const InitTestCase& tc) const = 0;
101 
102 		static void testInit(const InitTestCase& tc, BFile& file)
103 		{
104 			CPPUNIT_ASSERT( file.InitCheck() == tc.initCheck );
105 			if (tc.removeAfterTest)
106 				execCommand(string("rm ") + tc.filename);
107 		}
108 	};
109 
110 	// 2. BFile(const char *, uint32)
111 	struct Tester1 : public Tester {
112 		virtual void test(const InitTestCase& tc) const
113 		{
114 			BFile file(tc.filename,
115 					   tc.rwmode
116 					   | (tc.createFile * B_CREATE_FILE)
117 					   | (tc.failIfExists * B_FAIL_IF_EXISTS)
118 					   | (tc.eraseFile * B_ERASE_FILE));
119 			testInit(tc, file);
120 		}
121 	};
122 
123 	// 3. BFile(entry_ref *, uint32)
124 	struct Tester2 : public Tester {
125 		virtual void test(const InitTestCase& tc) const
126 		{
127 			entry_ref ref;
128 			BEntry entry(tc.filename);
129 			entry_ref *refToPass = &ref;
130 			if (tc.filename)
131 				CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
132 			else
133 				refToPass = NULL;
134 			BFile file(refToPass,
135 					   tc.rwmode
136 					   | (tc.createFile * B_CREATE_FILE)
137 					   | (tc.failIfExists * B_FAIL_IF_EXISTS)
138 					   | (tc.eraseFile * B_ERASE_FILE));
139 			testInit(tc, file);
140 		}
141 	};
142 
143 	// 4. BFile(BEntry *, uint32)
144 	struct Tester3 : public Tester {
145 		virtual void test(const InitTestCase& tc) const
146 		{
147 			entry_ref ref;
148 			BEntry entry(tc.filename);
149 			BEntry *entryToPass = &entry;
150 			if (tc.filename)
151 				CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
152 			else
153 				entryToPass = NULL;
154 			BFile file(entryToPass,
155 					   tc.rwmode
156 					   | (tc.createFile * B_CREATE_FILE)
157 					   | (tc.failIfExists * B_FAIL_IF_EXISTS)
158 					   | (tc.eraseFile * B_ERASE_FILE));
159 			testInit(tc, file);
160 		}
161 	};
162 
163 	// 5. BFile(BEntry *, uint32)
164 	struct Tester4 : public Tester {
165 		virtual void test(const InitTestCase& tc) const
166 		{
167 			if (tc.filename) {
168 				BPath path(tc.filename);
169 				CPPUNIT_ASSERT( path.InitCheck() == B_OK );
170 				BPath dirPath;
171 				CPPUNIT_ASSERT( path.GetParent(&dirPath) == B_OK );
172 				BDirectory dir(dirPath.Path());
173 				CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
174 				BFile file(&dir, path.Leaf(),
175 						   tc.rwmode
176 						   | (tc.createFile * B_CREATE_FILE)
177 						   | (tc.failIfExists * B_FAIL_IF_EXISTS)
178 						   | (tc.eraseFile * B_ERASE_FILE));
179 				testInit(tc, file);
180 			}
181 		}
182 	};
183 
184 	Tester1().testAll();
185 	Tester2().testAll();
186 	Tester3().testAll();
187 	Tester4().testAll();
188 }
189 
190 // InitTest2
191 void
InitTest2()192 FileTest::InitTest2()
193 {
194 	// helper class for the testing the different SetTo() versions
195 	struct Tester {
196 		void testAll() const
197 		{
198 			for (int32 i = 0; i < initTestCasesCount; i++) {
199 				if (BTestShell::GlobalBeVerbose()) {
200 					printf("[%" B_PRId32 "]", i);
201 					fflush(stdout);
202 				}
203 				test(initTestCases[i]);
204 			}
205 			if (BTestShell::GlobalBeVerbose())
206 				printf("\n");
207 		}
208 
209 		virtual void test(const InitTestCase& tc) const = 0;
210 
211 		static void testInit(const InitTestCase& tc, BFile& file)
212 		{
213 			CPPUNIT_ASSERT( file.InitCheck() == tc.initCheck );
214 			file.Unset();
215 			CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
216 			if (tc.removeAfterTest)
217 				execCommand(string("rm ") + tc.filename);
218 		}
219 	};
220 
221 	// 2. BFile(const char *, uint32)
222 	struct Tester1 : public Tester {
223 		virtual void test(const InitTestCase& tc) const
224 		{
225 			BFile file;
226 			status_t result = file.SetTo(tc.filename,
227 				tc.rwmode
228 				| (tc.createFile * B_CREATE_FILE)
229 				| (tc.failIfExists * B_FAIL_IF_EXISTS)
230 				| (tc.eraseFile * B_ERASE_FILE));
231 			CPPUNIT_ASSERT( result == tc.initCheck );
232 			testInit(tc, file);
233 		}
234 	};
235 
236 	// 3. BFile(entry_ref *, uint32)
237 	struct Tester2 : public Tester {
238 		virtual void test(const InitTestCase& tc) const
239 		{
240 			entry_ref ref;
241 			BEntry entry(tc.filename);
242 			entry_ref *refToPass = &ref;
243 			if (tc.filename)
244 				CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
245 			else
246 				refToPass = NULL;
247 			BFile file;
248 			status_t result = file.SetTo(refToPass,
249 				tc.rwmode
250 				| (tc.createFile * B_CREATE_FILE)
251 				| (tc.failIfExists * B_FAIL_IF_EXISTS)
252 				| (tc.eraseFile * B_ERASE_FILE));
253 			CPPUNIT_ASSERT( result == tc.initCheck );
254 			testInit(tc, file);
255 		}
256 	};
257 
258 	// 4. BFile(BEntry *, uint32)
259 	struct Tester3 : public Tester {
260 		virtual void test(const InitTestCase& tc) const
261 		{
262 			entry_ref ref;
263 			BEntry entry(tc.filename);
264 			BEntry *entryToPass = &entry;
265 			if (tc.filename)
266 				CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
267 			else
268 				entryToPass = NULL;
269 			BFile file;
270 			status_t result = file.SetTo(entryToPass,
271 				tc.rwmode
272 				| (tc.createFile * B_CREATE_FILE)
273 				| (tc.failIfExists * B_FAIL_IF_EXISTS)
274 				| (tc.eraseFile * B_ERASE_FILE));
275 			CPPUNIT_ASSERT( result == tc.initCheck );
276 			testInit(tc, file);
277 		}
278 	};
279 
280 	// 5. BFile(BEntry *, uint32)
281 	struct Tester4 : public Tester {
282 		virtual void test(const InitTestCase& tc) const
283 		{
284 			if (tc.filename) {
285 				BPath path(tc.filename);
286 				CPPUNIT_ASSERT( path.InitCheck() == B_OK );
287 				BPath dirPath;
288 				CPPUNIT_ASSERT( path.GetParent(&dirPath) == B_OK );
289 				BDirectory dir(dirPath.Path());
290 				CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
291 				BFile file;
292 				status_t result = file.SetTo(&dir, path.Leaf(),
293 					tc.rwmode
294 					| (tc.createFile * B_CREATE_FILE)
295 					| (tc.failIfExists * B_FAIL_IF_EXISTS)
296 					| (tc.eraseFile * B_ERASE_FILE));
297 				CPPUNIT_ASSERT( result == tc.initCheck );
298 				testInit(tc, file);
299 			}
300 		}
301 	};
302 
303 	Tester1().testAll();
304 	Tester2().testAll();
305 	Tester3().testAll();
306 	Tester4().testAll();
307 }
308 
309 // RWAbleTest
310 void
RWAbleTest()311 FileTest::RWAbleTest()
312 {
313 	NextSubTest();
314 	{
315 		BFile file;
316 		CPPUNIT_ASSERT( file.IsReadable() == false );
317 		CPPUNIT_ASSERT( file.IsWritable() == false );
318 	}
319 	NextSubTest();
320 	{
321 		BFile file(existingFilename, B_READ_ONLY);
322 		CPPUNIT_ASSERT( file.IsReadable() == true );
323 		CPPUNIT_ASSERT( file.IsWritable() == false );
324 	}
325 	NextSubTest();
326 	{
327 		BFile file(existingFilename, B_WRITE_ONLY);
328 		CPPUNIT_ASSERT( file.IsReadable() == false );
329 		CPPUNIT_ASSERT( file.IsWritable() == true );
330 	}
331 	NextSubTest();
332 	{
333 		BFile file(existingFilename, B_READ_WRITE);
334 		CPPUNIT_ASSERT( file.IsReadable() == true );
335 		CPPUNIT_ASSERT( file.IsWritable() == true );
336 	}
337 	NextSubTest();
338 	{
339 		BFile file(nonExistingFilename, B_READ_WRITE);
340 		CPPUNIT_ASSERT( file.IsReadable() == false );
341 		CPPUNIT_ASSERT( file.IsWritable() == false );
342 	}
343 }
344 
345 // RWTest
346 void
RWTest()347 FileTest::RWTest()
348 {
349 	// read/write an uninitialized BFile
350 	NextSubTest();
351 	BFile file;
352 	char buffer[10];
353 	CPPUNIT_ASSERT( file.Read(buffer, sizeof(buffer)) < 0 );
354 	CPPUNIT_ASSERT( file.ReadAt(0, buffer, sizeof(buffer)) < 0 );
355 	CPPUNIT_ASSERT( file.Write(buffer, sizeof(buffer)) < 0 );
356 	CPPUNIT_ASSERT( file.WriteAt(0, buffer, sizeof(buffer)) < 0 );
357 	file.Unset();
358 	// read/write an file opened for writing/reading only
359 	NextSubTest();
360 	file.SetTo(existingFilename, B_WRITE_ONLY);
361 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
362 	CPPUNIT_ASSERT( file.Read(buffer, sizeof(buffer)) < 0 );
363 	CPPUNIT_ASSERT( file.ReadAt(0, buffer, sizeof(buffer)) < 0 );
364 	file.SetTo(existingFilename, B_READ_ONLY);
365 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
366 	CPPUNIT_ASSERT( file.Write(buffer, sizeof(buffer)) < 0 );
367 	CPPUNIT_ASSERT( file.WriteAt(0, buffer, sizeof(buffer)) < 0 );
368 	file.Unset();
369 	// read from an empty file
370 	NextSubTest();
371 	file.SetTo(existingFilename, B_READ_ONLY);
372 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
373 	CPPUNIT_ASSERT( file.Read(buffer, sizeof(buffer)) == 0 );
374 	CPPUNIT_ASSERT( file.ReadAt(0, buffer, sizeof(buffer)) == 0 );
375 	file.Unset();
376 	// read from past an empty file
377 	NextSubTest();
378 	file.SetTo(existingFilename, B_READ_ONLY);
379 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
380 	CPPUNIT_ASSERT( file.Seek(10, SEEK_SET) == 10 );
381 	CPPUNIT_ASSERT( file.Read(buffer, sizeof(buffer)) == 0 );
382 	CPPUNIT_ASSERT( file.ReadAt(10, buffer, sizeof(buffer)) == 0 );
383 	file.Unset();
384 	// create a new empty file and write some data into it, then
385 	// read the file and check the data
386 	NextSubTest();
387 	file.SetTo(testFilename1, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
388 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
389 	char writeBuffer[256];
390 	for (int32 i = 0; i < 256; i++)
391 		writeBuffer[i] = (char)i;
392 	CPPUNIT_ASSERT( file.Write(writeBuffer, 128) == 128 );
393 	CPPUNIT_ASSERT( file.Position() == 128 );
394 	CPPUNIT_ASSERT( file.Write(writeBuffer + 128, 128) == 128 );
395 	CPPUNIT_ASSERT( file.Position() == 256 );
396 	file.Unset();
397 	file.SetTo(testFilename1, B_READ_ONLY);
398 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
399 	char readBuffer[256];
400 	CPPUNIT_ASSERT( file.Read(readBuffer, 42) == 42 );
401 	CPPUNIT_ASSERT( file.Position() == 42 );
402 	CPPUNIT_ASSERT( file.Read(readBuffer + 42, 400) == 214 );
403 	CPPUNIT_ASSERT( file.Position() == 256 );
404 	for (int32 i = 0; i < 256; i++)
405 		CPPUNIT_ASSERT( readBuffer[i] == (char)i );
406 	file.Unset();
407 	execCommand(string("rm -f ") + testFilename1);
408 	// same procedure, just using ReadAt()/WriteAt()
409 	NextSubTest();
410 	file.SetTo(testFilename1, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
411 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
412 	CPPUNIT_ASSERT( file.WriteAt(80, writeBuffer + 80, 50) == 50 );
413 	CPPUNIT_ASSERT( file.Position() == 0 );
414 	CPPUNIT_ASSERT( file.WriteAt(0, writeBuffer, 80) == 80 );
415 	CPPUNIT_ASSERT( file.Position() == 0 );
416 	CPPUNIT_ASSERT( file.WriteAt(130, writeBuffer + 130, 126) == 126 );
417 	CPPUNIT_ASSERT( file.Position() == 0 );
418 	file.Unset();
419 	file.SetTo(testFilename1, B_READ_ONLY);
420 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
421 	for (int32 i = 0; i < 256; i++)
422 		readBuffer[i] = 0;
423 	CPPUNIT_ASSERT( file.ReadAt(42, readBuffer + 42, 84) == 84 );
424 	CPPUNIT_ASSERT( file.Position() == 0 );
425 	CPPUNIT_ASSERT( file.ReadAt(0, readBuffer, 42) == 42 );
426 	CPPUNIT_ASSERT( file.Position() == 0 );
427 	CPPUNIT_ASSERT( file.ReadAt(126, readBuffer + 126, 130) == 130 );
428 	CPPUNIT_ASSERT( file.Position() == 0 );
429 	for (int32 i = 0; i < 256; i++)
430 		CPPUNIT_ASSERT( readBuffer[i] == (char)i );
431 	file.Unset();
432 	execCommand(string("rm -f ") + testFilename1);
433 	// write past the end of a file
434 	NextSubTest();
435 	file.SetTo(testFilename1, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
436 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
437 	CPPUNIT_ASSERT( file.Seek(128, SEEK_SET) == 128 );
438 	CPPUNIT_ASSERT( file.Write(writeBuffer, 128) == 128 );
439 	CPPUNIT_ASSERT( file.Position() == 256 );
440 	file.Unset();
441 	// open the file with B_OPEN_AT_END flag, Write() some data to it, close
442 	// and re-open it to check the file
443 	NextSubTest();
444 	file.SetTo(testFilename1, B_WRITE_ONLY | B_OPEN_AT_END);
445 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
446 	for (int32 i = 0; i < 256; i++)
447 		writeBuffer[i] = (char)7;
448 	CPPUNIT_ASSERT( file.Write(writeBuffer, 50) == 50 );
449 	file.Seek(0, SEEK_SET);	// might fail -- don't check the return value
450 	CPPUNIT_ASSERT( file.Write(writeBuffer, 40) == 40 );
451 	file.Unset();
452 	file.SetTo(testFilename1, B_READ_ONLY);
453 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
454 	CPPUNIT_ASSERT( file.ReadAt(256, readBuffer, 90) == 90 );
455 	for (int32 i = 0; i < 90; i++)
456 		CPPUNIT_ASSERT( readBuffer[i] == 7 );
457 	file.Unset();
458 	// open the file with B_OPEN_AT_END flag, WriteAt() some data to it, close
459 	// and re-open it to check the file
460 	NextSubTest();
461 	file.SetTo(testFilename1, B_WRITE_ONLY | B_OPEN_AT_END);
462 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
463 	for (int32 i = 0; i < 256; i++)
464 		writeBuffer[i] = (char)42;
465 	CPPUNIT_ASSERT( file.WriteAt(0, writeBuffer, 30) == 30 );
466 	file.Unset();
467 	file.SetTo(testFilename1, B_READ_ONLY);
468 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
469 	CPPUNIT_ASSERT( file.ReadAt(346, readBuffer, 30) == 30 );
470 	for (int32 i = 0; i < 30; i++)
471 		CPPUNIT_ASSERT( readBuffer[i] == 42 );
472 	file.Unset();
473 	// open the file with B_OPEN_AT_END flag, ReadAt() some data
474 	NextSubTest();
475 	file.SetTo(testFilename1, B_READ_ONLY | B_OPEN_AT_END);
476 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
477 	for (int32 i = 0; i < 256; i++)
478 		readBuffer[i] = 0;
479 	CPPUNIT_ASSERT( file.ReadAt(256, readBuffer, 90) == 90 );
480 	for (int32 i = 0; i < 90; i++)
481 		CPPUNIT_ASSERT( readBuffer[i] == 7 );
482 	CPPUNIT_ASSERT( file.ReadAt(346, readBuffer, 30) == 30 );
483 	for (int32 i = 0; i < 30; i++)
484 		CPPUNIT_ASSERT( readBuffer[i] == 42 );
485 	file.Unset();
486 	// same procedure, just using Seek() and Read()
487 	NextSubTest();
488 	file.SetTo(testFilename1, B_READ_ONLY | B_OPEN_AT_END);
489 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
490 	for (int32 i = 0; i < 256; i++)
491 		readBuffer[i] = 0;
492 	file.Seek(256, SEEK_SET);	// might fail -- don't check the return value
493 	CPPUNIT_ASSERT( file.Read(readBuffer, 90) == 90 );
494 	for (int32 i = 0; i < 90; i++)
495 		CPPUNIT_ASSERT( readBuffer[i] == 7 );
496 	CPPUNIT_ASSERT( file.ReadAt(346, readBuffer, 30) == 30 );
497 	for (int32 i = 0; i < 30; i++)
498 		CPPUNIT_ASSERT( readBuffer[i] == 42 );
499 	file.Unset();
500 
501 	execCommand(string("rm -f ") + testFilename1);
502 }
503 
504 // PositionTest
505 void
PositionTest()506 FileTest::PositionTest()
507 {
508 	// unitialized file
509 	NextSubTest();
510 	BFile file;
511 	CPPUNIT_ASSERT( file.Position() == B_FILE_ERROR );
512 	CPPUNIT_ASSERT( file.Seek(10, SEEK_SET) == B_FILE_ERROR );
513 	CPPUNIT_ASSERT( file.Seek(10, SEEK_END) == B_FILE_ERROR );
514 	CPPUNIT_ASSERT( file.Seek(10, SEEK_CUR) == B_FILE_ERROR );
515 	// open new file, write some bytes to it and seek a bit around
516 	NextSubTest();
517 	file.SetTo(testFilename1, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
518 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
519 	CPPUNIT_ASSERT( file.Position() == 0 );
520 	char writeBuffer[256];
521 	CPPUNIT_ASSERT( file.Write(writeBuffer, 256) == 256 );
522 	CPPUNIT_ASSERT( file.Position() == 256 );
523 	CPPUNIT_ASSERT( file.Seek(10, SEEK_SET) == 10 );
524 	CPPUNIT_ASSERT( file.Position() == 10 );
525 	CPPUNIT_ASSERT( file.Seek(-20, SEEK_END) == 236 );
526 	CPPUNIT_ASSERT( file.Position() == 236 );
527 	CPPUNIT_ASSERT( file.Seek(-70, SEEK_CUR) == 166 );
528 	CPPUNIT_ASSERT( file.Position() == 166 );
529 	file.Unset();
530 	// re-open the file at the end and seek a bit around once more
531 	// The BeBook is a bit unspecific about the B_OPEN_AT_END flag:
532 	// It has probably the same meaning as the POSIX flag O_APPEND, which
533 	// means, that all write()s append their data at the end. The behavior
534 	// of Seek() and Position() is a bit unclear for this case.
535 /*
536 	NextSubTest();
537 	file.SetTo(testFilename1, B_READ_ONLY | B_OPEN_AT_END);
538 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
539 	CPPUNIT_ASSERT( file.Position() == 256 );
540 	CPPUNIT_ASSERT( file.Seek(10, SEEK_SET) == 10 );
541 	CPPUNIT_ASSERT( file.Position() == 10 );			// fails with R5
542 	CPPUNIT_ASSERT( file.Seek(-20, SEEK_END) == 236 );
543 	CPPUNIT_ASSERT( file.Position() == 236 );			// fails with R5
544 	CPPUNIT_ASSERT( file.Seek(-70, SEEK_CUR) == 166 );	// fails with R5
545 	CPPUNIT_ASSERT( file.Position() == 166 );			// fails with R5
546 */
547 	file.Unset();
548 	execCommand(string("rm -f ") + testFilename1);
549 }
550 
551 // SizeTest
552 void
SizeTest()553 FileTest::SizeTest()
554 {
555 	// unitialized file
556 	NextSubTest();
557 	BFile file;
558 	off_t size;
559 	CPPUNIT_ASSERT( file.GetSize(&size) != B_OK );
560 	CPPUNIT_ASSERT( file.SetSize(100) != B_OK );
561 	// read only file, SetSize will not succeed
562 	NextSubTest();
563 	file.SetTo(testFilename1, B_READ_ONLY | B_CREATE_FILE);
564 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
565 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
566 	CPPUNIT_ASSERT( size == 0 );
567 	CPPUNIT_ASSERT_EQUAL(file.SetSize(100), B_BAD_VALUE);
568 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
569 	CPPUNIT_ASSERT_EQUAL(size, 0);
570 	file.Unset();
571 	// successfully set size of file with appropriate flags
572 	NextSubTest();
573 	file.SetTo(testFilename1, B_WRITE_ONLY);
574 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
575 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
576 	CPPUNIT_ASSERT_EQUAL(size, 0);
577 	CPPUNIT_ASSERT( file.SetSize(73) == B_OK );
578 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
579 	CPPUNIT_ASSERT( size == 73 );
580 	file.Unset();
581 	// enlarge existing file
582 	NextSubTest();
583 	file.SetTo(testFilename1, B_READ_WRITE);
584 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
585 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
586 	CPPUNIT_ASSERT( size == 73 );
587 	CPPUNIT_ASSERT( file.SetSize(147) == B_OK );
588 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
589 	CPPUNIT_ASSERT( size == 147 );
590 	file.Unset();
591 	// erase existing file (write only)
592 	NextSubTest();
593 	file.SetTo(testFilename1, B_WRITE_ONLY | B_ERASE_FILE);
594 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
595 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
596 	CPPUNIT_ASSERT( size == 0 );
597 	CPPUNIT_ASSERT( file.SetSize(93) == B_OK );
598 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
599 	CPPUNIT_ASSERT( size == 93 );
600 	file.Unset();
601 	// erase existing file using SetSize()
602 	NextSubTest();
603 	file.SetTo(testFilename1, B_READ_WRITE);
604 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
605 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
606 	CPPUNIT_ASSERT( size == 93 );
607 	CPPUNIT_ASSERT( file.SetSize(0) == B_OK );
608 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
609 	CPPUNIT_ASSERT( size == 0 );
610 	file.Unset();
611 	execCommand(string("rm -f ") + testFilename1);
612 }
613 
614 // AssignmentTest
615 void
AssignmentTest()616 FileTest::AssignmentTest()
617 {
618 	// copy constructor
619 	// uninitialized
620 	NextSubTest();
621 	{
622 		BFile file;
623 		CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
624 		BFile file2(file);
625 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
626 		CPPUNIT_ASSERT( equals(file2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
627 	}
628 	// existing file, different open modes
629 	NextSubTest();
630 	{
631 		BFile file(existingFilename, B_READ_ONLY);
632 		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
633 		BFile file2(file);
634 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
635 		CPPUNIT_ASSERT( file2.IsReadable() == true );
636 		CPPUNIT_ASSERT( file2.IsWritable() == false );
637 	}
638 	NextSubTest();
639 	{
640 		BFile file(existingFilename, B_WRITE_ONLY);
641 		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
642 		BFile file2(file);
643 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
644 		CPPUNIT_ASSERT( file2.IsReadable() == false );
645 		CPPUNIT_ASSERT( file2.IsWritable() == true );
646 	}
647 	NextSubTest();
648 	{
649 		BFile file(existingFilename, B_READ_WRITE);
650 		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
651 		BFile file2(file);
652 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
653 		CPPUNIT_ASSERT( file2.IsReadable() == true );
654 		CPPUNIT_ASSERT( file2.IsWritable() == true );
655 	}
656 	// assignment operator
657 	// uninitialized
658 	NextSubTest();
659 	{
660 		BFile file;
661 		BFile file2;
662 		file2 = file;
663 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
664 		CPPUNIT_ASSERT( equals(file2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
665 	}
666 	NextSubTest();
667 	{
668 		BFile file;
669 		BFile file2(existingFilename, B_READ_ONLY);
670 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
671 		file2 = file;
672 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
673 		CPPUNIT_ASSERT( equals(file2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
674 	}
675 	// existing file, different open modes
676 	NextSubTest();
677 	{
678 		BFile file(existingFilename, B_READ_ONLY);
679 		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
680 		BFile file2;
681 		file2 = file;
682 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
683 		CPPUNIT_ASSERT( file2.IsReadable() == true );
684 		CPPUNIT_ASSERT( file2.IsWritable() == false );
685 	}
686 	NextSubTest();
687 	{
688 		BFile file(existingFilename, B_WRITE_ONLY);
689 		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
690 		BFile file2;
691 		file2 = file;
692 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
693 		CPPUNIT_ASSERT( file2.IsReadable() == false );
694 		CPPUNIT_ASSERT( file2.IsWritable() == true );
695 	}
696 	NextSubTest();
697 	{
698 		BFile file(existingFilename, B_READ_WRITE);
699 		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
700 		BFile file2;
701 		file2 = file;
702 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
703 		CPPUNIT_ASSERT( file2.IsReadable() == true );
704 		CPPUNIT_ASSERT( file2.IsWritable() == true );
705 	}
706 }
707 
708 
709 
710 // test cases for the init tests
711 const FileTest::InitTestCase FileTest::initTestCases[] = {
712 	{ existingFilename	 , B_READ_ONLY , 0, 0, 0, false, B_OK				},
713 	{ existingFilename	 , B_WRITE_ONLY, 0, 0, 0, false, B_OK				},
714 	{ existingFilename	 , B_READ_WRITE, 0, 0, 0, false, B_OK				},
715 	{ existingFilename	 , B_READ_ONLY , 1, 0, 0, false, B_OK				},
716 	{ existingFilename	 , B_WRITE_ONLY, 1, 0, 0, false, B_OK				},
717 	{ existingFilename	 , B_READ_WRITE, 1, 0, 0, false, B_OK				},
718 	{ existingFilename	 , B_READ_ONLY , 0, 1, 0, false, B_OK				},
719 	{ existingFilename	 , B_WRITE_ONLY, 0, 1, 0, false, B_OK				},
720 	{ existingFilename	 , B_READ_WRITE, 0, 1, 0, false, B_OK				},
721 	{ existingFilename	 , B_READ_ONLY , 0, 0, 1, false, B_NOT_ALLOWED		},
722 	{ existingFilename	 , B_WRITE_ONLY, 0, 0, 1, false, B_OK				},
723 	{ existingFilename	 , B_READ_WRITE, 0, 0, 1, false, B_OK				},
724 	{ existingFilename	 , B_READ_ONLY , 1, 1, 0, false, B_FILE_EXISTS		},
725 	{ existingFilename	 , B_WRITE_ONLY, 1, 1, 0, false, B_FILE_EXISTS		},
726 	{ existingFilename	 , B_READ_WRITE, 1, 1, 0, false, B_FILE_EXISTS		},
727 	{ existingFilename	 , B_READ_ONLY , 1, 0, 1, false, B_NOT_ALLOWED		},
728 	{ existingFilename	 , B_WRITE_ONLY, 1, 0, 1, false, B_OK				},
729 	{ existingFilename	 , B_READ_WRITE, 1, 0, 1, false, B_OK				},
730 	{ existingFilename	 , B_READ_ONLY , 1, 1, 1, false, B_FILE_EXISTS		},
731 	{ existingFilename	 , B_WRITE_ONLY, 1, 1, 1, false, B_FILE_EXISTS		},
732 	{ existingFilename	 , B_READ_WRITE, 1, 1, 1, false, B_FILE_EXISTS		},
733 	{ nonExistingFilename, B_READ_ONLY , 0, 0, 0, false, B_ENTRY_NOT_FOUND	},
734 	{ nonExistingFilename, B_WRITE_ONLY, 0, 0, 0, false, B_ENTRY_NOT_FOUND	},
735 	{ nonExistingFilename, B_READ_WRITE, 0, 0, 0, false, B_ENTRY_NOT_FOUND	},
736 	{ nonExistingFilename, B_READ_ONLY , 1, 0, 0, true , B_OK				},
737 	{ nonExistingFilename, B_WRITE_ONLY, 1, 0, 0, true , B_OK				},
738 	{ nonExistingFilename, B_READ_WRITE, 1, 0, 0, true , B_OK				},
739 	{ nonExistingFilename, B_READ_ONLY , 0, 1, 0, false, B_ENTRY_NOT_FOUND	},
740 	{ nonExistingFilename, B_WRITE_ONLY, 0, 1, 0, false, B_ENTRY_NOT_FOUND	},
741 	{ nonExistingFilename, B_READ_WRITE, 0, 1, 0, false, B_ENTRY_NOT_FOUND	},
742 	{ nonExistingFilename, B_READ_ONLY , 0, 0, 1, false, B_ENTRY_NOT_FOUND	},
743 	{ nonExistingFilename, B_WRITE_ONLY, 0, 0, 1, false, B_ENTRY_NOT_FOUND	},
744 	{ nonExistingFilename, B_READ_WRITE, 0, 0, 1, false, B_ENTRY_NOT_FOUND	},
745 	{ nonExistingFilename, B_READ_ONLY , 1, 1, 0, true , B_OK				},
746 	{ nonExistingFilename, B_WRITE_ONLY, 1, 1, 0, true , B_OK				},
747 	{ nonExistingFilename, B_READ_WRITE, 1, 1, 0, true , B_OK				},
748 	{ nonExistingFilename, B_READ_ONLY , 1, 0, 1, true , B_OK				},
749 	{ nonExistingFilename, B_WRITE_ONLY, 1, 0, 1, true , B_OK				},
750 	{ nonExistingFilename, B_READ_WRITE, 1, 0, 1, true , B_OK				},
751 	{ nonExistingFilename, B_READ_ONLY , 1, 1, 1, true , B_OK				},
752 	{ nonExistingFilename, B_WRITE_ONLY, 1, 1, 1, true , B_OK				},
753 	{ nonExistingFilename, B_READ_WRITE, 1, 1, 1, true , B_OK				},
754 	{ NULL,				   B_READ_ONLY , 1, 1, 1, false, B_BAD_VALUE		},
755 };
756 const int32 FileTest::initTestCasesCount
757 	= sizeof(FileTest::initTestCases) / sizeof(FileTest::InitTestCase);
758 
759 
760 
761 
762 
763 
764 
765 
766 
767 
768 
769