2 TestCacheBlockFiles.cpp
13 #include <Resources.h>
18 #include "nsDirectoryServiceDefs.h"
20 #include "nsIComponentManager.h"
21 #include "nsIComponentRegistrar.h"
23 #include "nsILocalFile.h"
24 #include "nsIFileStreams.h"
26 #include "nsIComponentRegistrar.h"
27 #include "nsANSIFileStreams.h"
28 #include "nsDiskCacheBlockFile.h"
36 typedef struct Allocation
{
42 StressTest(nsILocalFile
* localFile
, PRInt32 testNumber
, PRBool readWrite
)
46 #define ITERATIONS 1024
47 #define MAX_ALLOCATIONS 256
48 Allocation block
[MAX_ALLOCATIONS
];
49 PRInt32 currentAllocations
= 0;
54 char readBuf
[256 * 4];
58 for (i
= 0; i
< 4; i
++) {
59 writeBuf
[i
] = new char[256 * i
];
61 printf("Test %d: failed - out of memory\n", testNumber
);
62 rv
= NS_ERROR_OUT_OF_MEMORY
;
66 memset(writeBuf
[i
], i
, 256 * i
);
70 nsDiskCacheBlockFile
* blockFile
= new nsDiskCacheBlockFile
;
72 printf("Test %d failed (unable to allocate nsDiskCacheBlockFile", testNumber
);
73 rv
= NS_ERROR_OUT_OF_MEMORY
;
77 rv
= blockFile
->Open(localFile
, 256);
79 printf("Test %d: failed (Open returned: 0x%.8x)\n", testNumber
, rv
);
85 if ((currentAllocations
>= MAX_ALLOCATIONS
) ||
86 ((currentAllocations
> 0) && (rand() % 4 == 0))) {
87 // deallocate if we've reached the limit, or 25% of the time we have allocations
88 a
= rand() % currentAllocations
;
91 // read verify deallocation
92 rv
= blockFile
->ReadBlocks(readBuf
, block
[a
].start
, block
[a
].count
);
94 printf("Test %d: failed (ReadBlocks() returned 0x%.8x)\n", testNumber
, rv
);
99 for (i
= 0; i
< 256 * block
[a
].count
; i
++) {
100 if (readBuf
[i
] != block
[a
].count
) {
101 printf("Test %d: failed (verifying buffer 1)\n", testNumber
);
102 rv
= NS_ERROR_FAILURE
;
108 rv
= blockFile
->DeallocateBlocks(block
[a
].start
, block
[a
].count
);
110 printf("Test %d: failed (DeallocateBlocks() returned %d)\n", testNumber
, rv
);
114 --currentAllocations
;
115 if (currentAllocations
> 0)
116 block
[a
] = block
[currentAllocations
];
121 a
= currentAllocations
++;
122 block
[a
].count
= rand() % 4 + 1; // allocate 1 to 4 blocks
123 block
[a
].start
= blockFile
->AllocateBlocks(block
[a
].count
);
124 if (block
[a
].start
< 0) {
125 printf("Test %d: failed (AllocateBlocks() failed.)\n", testNumber
);
131 rv
= blockFile
->WriteBlocks(writeBuf
[block
[a
].count
], block
[a
].start
, block
[a
].count
);
133 printf("Test %d: failed (WriteBlocks() returned 0x%.8x)\n",testNumber
, rv
);
140 // now deallocate remaining allocations
141 i
= currentAllocations
;
145 // read verify deallocation
146 rv
= blockFile
->ReadBlocks(readBuf
, block
[a
].start
, block
[a
].count
);
148 printf("Test %d: failed (ReadBlocks(1) returned 0x%.8x)\n", testNumber
, rv
);
153 for (i
= 0; i
< 256 * block
[a
].count
; i
++) {
154 if (readBuf
[i
] != block
[a
].count
) {
155 printf("Test %d: failed (verifying buffer 1)\n", testNumber
);
156 rv
= NS_ERROR_FAILURE
;
162 rv
= blockFile
->DeallocateBlocks(block
[i
].start
, block
[i
].count
);
164 printf("Test %d: failed (DeallocateBlocks() returned %d)\n", testNumber
, rv
);
172 nsresult rv2
= blockFile
->Close();
173 if (NS_FAILED(rv2
)) {
174 printf("Test %d: failed (Close returned: 0x%.8x)\n", testNumber
, rv2
);
177 return rv
? rv
: rv2
;
188 printf("hello world\n");
190 unsigned long now
= time(0);
193 nsCOMPtr
<nsIFile
> file
;
194 nsCOMPtr
<nsILocalFile
> localFile
;
198 nsCOMPtr
<nsIServiceManager
> servMan
;
199 NS_InitXPCOM2(getter_AddRefs(servMan
), nsnull
, nsnull
);
200 nsCOMPtr
<nsIComponentRegistrar
> registrar
= do_QueryInterface(servMan
);
201 NS_ASSERTION(registrar
, "Null nsIComponentRegistrar");
203 registrar
->AutoRegister(nsnull
);
205 // Get default directory
206 rv
= NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR
,
207 getter_AddRefs(file
));
209 printf("NS_GetSpecialDirectory() failed : 0x%.8x\n", rv
);
212 char * currentDirPath
;
213 rv
= file
->GetPath(¤tDirPath
);
215 printf("currentProcessDir->GetPath() failed : 0x%.8x\n", rv
);
219 printf("Current Process Directory: %s\n", currentDirPath
);
222 // Generate name for cache block file
223 rv
= file
->Append("_CACHE_001_");
224 if (NS_FAILED(rv
)) goto exit
;
226 // Delete existing file
227 rv
= file
->Delete(PR_FALSE
);
228 if (NS_FAILED(rv
) && rv
!= NS_ERROR_FILE_NOT_FOUND
) goto exit
;
230 // Need nsILocalFile to open
231 localFile
= do_QueryInterface(file
, &rv
);
233 printf("do_QueryInterface(file) failed : 0x%.8x\n", rv
);
237 nsDiskCacheBlockFile
* blockFile
= new nsDiskCacheBlockFile
;
239 rv
= NS_ERROR_OUT_OF_MEMORY
;
243 //----------------------------------------------------------------
244 // local variables used in tests
245 //----------------------------------------------------------------
246 PRUint32 bytesWritten
= 0;
251 //----------------------------------------------------------------
252 // Test 1: Open non-existing file
253 //----------------------------------------------------------------
254 rv
= blockFile
->Open(localFile
, 256);
256 printf("Test 1: failed (Open returned: 0x%.8x)\n", rv
);
260 rv
= blockFile
->Close();
262 printf("Test 1: failed (Close returned: 0x%.8x)\n", rv
);
266 printf("Test 1: passed\n");
269 //----------------------------------------------------------------
270 // Test 2: Open existing file (with no allocation)
271 //----------------------------------------------------------------
272 rv
= blockFile
->Open(localFile
, 256);
274 printf("Test 2: failed (Open returned: 0x%.8x)\n", rv
);
278 rv
= blockFile
->Close();
280 printf("Test 2: failed (Close returned: 0x%.8x)\n", rv
);
284 printf("Test 2: passed\n");
287 //----------------------------------------------------------------
288 // Test 3: Open existing file (bad format) size < kBitMapBytes
289 //----------------------------------------------------------------
291 // Delete existing file
292 rv
= localFile
->Delete(PR_FALSE
);
294 printf("Test 3 failed (Delete returned: 0x%.8x)\n", rv
);
298 // write < kBitMapBytes to file
299 nsANSIFileStream
* stream
= new nsANSIFileStream
;
301 printf("Test 3 failed (unable to allocate stream\n", rv
);
305 rv
= stream
->Open(localFile
);
308 printf("Test 3 failed (stream->Open returned: 0x%.8x)\n", rv
);
313 rv
= stream
->Write("Tell me something good.\n", 24, &bytesWritten
);
316 printf("Test 3 failed (stream->Write returned: 0x%.8x)\n", rv
);
320 rv
= stream
->Close();
323 printf("Test 3 failed (stream->Close returned: 0x%.8x)\n", rv
);
328 rv
= blockFile
->Open(localFile
, 256);
329 if (NS_SUCCEEDED(rv
)) {
330 printf("Test 3: failed (Open erroneously succeeded)\n", rv
);
332 (void) blockFile
->Close();
336 printf("Test 3: passed\n");
339 //----------------------------------------------------------------
340 // Test 4: Open non-existing file (again)
341 //----------------------------------------------------------------
343 // Delete existing file
344 rv
= localFile
->Delete(PR_FALSE
);
346 printf("Test 4 failed (Delete returned: 0x%.8x)\n", rv
);
350 rv
= blockFile
->Open(localFile
, 256);
352 printf("Test 4: failed (Open returned: 0x%.8x)\n", rv
);
356 printf("Test 4: passed\n");
359 //----------------------------------------------------------------
360 // Test 5: AllocateBlocks: invalid block count (0, 5)
361 //----------------------------------------------------------------
364 startBlock
= blockFile
->AllocateBlocks(0);
365 if (startBlock
> -1) {
366 printf("Test 5: failed (AllocateBlocks(0) erroneously succeeded)\n");
370 startBlock
= blockFile
->AllocateBlocks(5);
371 if (startBlock
> -1) {
372 printf("Test 5: failed (AllocateBlocks(5) erroneously succeeded)\n");
375 printf("Test 5: passed\n");
378 //----------------------------------------------------------------
379 // Test 6: AllocateBlocks: valid block count (1, 2, 3, 4)
380 //----------------------------------------------------------------
381 startBlock
= blockFile
->AllocateBlocks(1);
382 if (startBlock
!= 0) {
383 printf("Test 6: failed (AllocateBlocks(1) failed)\n");
387 startBlock
= blockFile
->AllocateBlocks(2);
388 if (startBlock
!= 1) {
389 printf("Test 6: failed (AllocateBlocks(2) failed)\n");
393 startBlock
= blockFile
->AllocateBlocks(3);
394 if (startBlock
!= 4) {
395 printf("Test 6: failed (AllocateBlocks(3) failed)\n");
399 startBlock
= blockFile
->AllocateBlocks(4);
400 if (startBlock
!= 8) {
401 printf("Test 6: failed (AllocateBlocks(4) failed)\n");
405 // blocks allocated should be 1220 3330 4444
406 printf("Test 6: passed\n"); // but bits could be mis-allocated
410 //----------------------------------------------------------------
411 // Test 7: VerifyAllocation
412 //----------------------------------------------------------------
413 rv
= blockFile
->VerifyAllocation(0,1);
415 printf("Test 7: failed (VerifyAllocation(0,1) returned: 0x%.8x)\n", rv
);
419 rv
= blockFile
->VerifyAllocation(1,2);
421 printf("Test 7: failed (VerifyAllocation(1,2) returned: 0x%.8x)\n", rv
);
425 rv
= blockFile
->VerifyAllocation(4,3);
427 printf("Test 7: failed (VerifyAllocation(4,3) returned: 0x%.8x)\n", rv
);
431 rv
= blockFile
->VerifyAllocation(8,4);
433 printf("Test 7: failed (VerifyAllocation(8,4) returned: 0x%.8x)\n", rv
);
436 printf("Test 7: passed\n");
439 //----------------------------------------------------------------
441 //----------------------------------------------------------------
442 PRInt32 lastBlock
= blockFile
->LastBlock();
443 if (lastBlock
!= 11) {
444 printf("Test 8: failed (LastBlock() returned: %d)\n", lastBlock
);
447 printf("Test 8: passed\n");
450 //----------------------------------------------------------------
451 // Test 9: DeallocateBlocks: bad startBlock ( < 0)
452 //----------------------------------------------------------------
453 rv
= blockFile
->DeallocateBlocks(-1, 4);
454 if (NS_SUCCEEDED(rv
)) {
455 printf("Test 9: failed (DeallocateBlocks(-1, 4) erroneously succeeded)\n");
458 printf("Test 9: passed\n");
461 //----------------------------------------------------------------
462 // Test 10: DeallocateBlocks: bad numBlocks (0, 5)
463 //----------------------------------------------------------------
464 rv
= blockFile
->DeallocateBlocks(0, 0);
465 if (NS_SUCCEEDED(rv
)) {
466 printf("Test 10: failed (DeallocateBlocks(0, 0) erroneously succeeded)\n");
470 rv
= blockFile
->DeallocateBlocks(0, 5);
471 if (NS_SUCCEEDED(rv
)) {
472 printf("Test 10: failed (DeallocateBlocks(0, 5) erroneously succeeded)\n");
476 printf("Test 10: passed\n");
479 //----------------------------------------------------------------
480 // Test 11: DeallocateBlocks: unallocated blocks
481 //----------------------------------------------------------------
482 rv
= blockFile
->DeallocateBlocks(12, 1);
483 if (NS_SUCCEEDED(rv
)) {
484 printf("Test 11: failed (DeallocateBlocks(12, 1) erroneously succeeded)\n");
488 printf("Test 11: passed\n");
491 //----------------------------------------------------------------
492 // Test 12: DeallocateBlocks: 1, 2, 3, 4 (allocated in Test 6)
493 //----------------------------------------------------------------
494 rv
= blockFile
->DeallocateBlocks(0, 1);
496 printf("Test 12: failed (DeallocateBlocks(12, 1) returned: 0x%.8x)\n", rv
);
500 rv
= blockFile
->DeallocateBlocks(1, 2);
502 printf("Test 12: failed (DeallocateBlocks(1, 2) returned: 0x%.8x)\n", rv
);
506 rv
= blockFile
->DeallocateBlocks(4, 3);
508 printf("Test 12: failed (DeallocateBlocks(4, 3) returned: 0x%.8x)\n", rv
);
512 rv
= blockFile
->DeallocateBlocks(8, 4);
514 printf("Test 12: failed (DeallocateBlocks(8, 4) returned: 0x%.8x)\n", rv
);
518 // zero blocks should be allocated
519 rv
= blockFile
->Close();
521 printf("Test 12: failed (Close returned: 0x%.8x)\n", rv
);
525 printf("Test 12: passed\n");
528 //----------------------------------------------------------------
529 // Test 13: Allocate/Deallocate boundary test
530 //----------------------------------------------------------------
532 rv
= blockFile
->Open(localFile
, 256);
534 printf("Test 13: failed (Open returned: 0x%.8x)\n", rv
);
538 // fully allocate, 1 block at a time
539 for (i
=0; i
< kBitMapBytes
* 8; ++i
) {
540 startBlock
= blockFile
->AllocateBlocks(1);
541 if (startBlock
< 0) {
542 printf("Test 13: failed (AllocateBlocks(1) failed on i=%d)\n", i
);
547 // attempt allocation with full bit map
548 startBlock
= blockFile
->AllocateBlocks(1);
549 if (startBlock
>= 0) {
550 printf("Test 13: failed (AllocateBlocks(1) erroneously succeeded i=%d)\n", i
);
554 // deallocate all the bits
555 for (i
=0; i
< kBitMapBytes
* 8; ++i
) {
556 rv
= blockFile
->DeallocateBlocks(i
,1);
558 printf("Test 13: failed (DeallocateBlocks(%d,1) returned: 0x%.8x)\n", i
,rv
);
563 // attempt deallocation beyond end of bit map
564 rv
= blockFile
->DeallocateBlocks(i
,1);
565 if (NS_SUCCEEDED(rv
)) {
566 printf("Test 13: failed (DeallocateBlocks(%d,1) erroneously succeeded)\n", i
);
570 // bit map should be empty
572 // fully allocate, 2 block at a time
573 for (i
=0; i
< kBitMapBytes
* 8; i
+=2) {
574 startBlock
= blockFile
->AllocateBlocks(2);
575 if (startBlock
< 0) {
576 printf("Test 13: failed (AllocateBlocks(2) failed on i=%d)\n", i
);
581 // attempt allocation with full bit map
582 startBlock
= blockFile
->AllocateBlocks(2);
583 if (startBlock
>= 0) {
584 printf("Test 13: failed (AllocateBlocks(2) erroneously succeeded i=%d)\n", i
);
588 // deallocate all the bits
589 for (i
=0; i
< kBitMapBytes
* 8; i
+=2) {
590 rv
= blockFile
->DeallocateBlocks(i
,2);
592 printf("Test 13: failed (DeallocateBlocks(%d,2) returned: 0x%.8x)\n", i
,rv
);
597 // bit map should be empty
599 // fully allocate, 4 block at a time
600 for (i
=0; i
< kBitMapBytes
* 8; i
+=4) {
601 startBlock
= blockFile
->AllocateBlocks(4);
602 if (startBlock
< 0) {
603 printf("Test 13: failed (AllocateBlocks(4) failed on i=%d)\n", i
);
608 // attempt allocation with full bit map
609 startBlock
= blockFile
->AllocateBlocks(4);
610 if (startBlock
>= 0) {
611 printf("Test 13: failed (AllocateBlocks(4) erroneously succeeded i=%d)\n", i
);
615 // deallocate all the bits
616 for (i
=0; i
< kBitMapBytes
* 8; i
+=4) {
617 rv
= blockFile
->DeallocateBlocks(i
,4);
619 printf("Test 13: failed (DeallocateBlocks(%d,4) returned: 0x%.8x)\n", i
,rv
);
624 // bit map should be empty
626 // allocate as many triple-blocks as possible
627 for (i
=0; i
< kBitMapBytes
* 8; i
+=4) {
628 startBlock
= blockFile
->AllocateBlocks(3);
629 if (startBlock
< 0) {
630 printf("Test 13: failed (AllocateBlocks(3) failed on i=%d)\n", i
);
635 // attempt allocation with "full" bit map
636 startBlock
= blockFile
->AllocateBlocks(3);
637 if (startBlock
>= 0) {
638 printf("Test 13: failed (AllocateBlocks(3) erroneously succeeded i=%d)\n", i
);
642 // leave some blocks allocated
644 rv
= blockFile
->Close();
646 printf("Test 13: failed (Close returned: 0x%.8x)\n", rv
);
650 printf("Test 13: passed\n");
653 //----------------------------------------------------------------
654 // Test 14: ValidateFile (open existing file w/size < allocated blocks
655 //----------------------------------------------------------------
656 rv
= blockFile
->Open(localFile
, 256);
657 if (NS_SUCCEEDED(rv
)) {
658 printf("Test 14: failed (Open erroneously succeeded)\n");
662 // Delete existing file
663 rv
= localFile
->Delete(PR_FALSE
);
665 printf("Test 14 failed (Delete returned: 0x%.8x)\n", rv
);
668 printf("Test 14: passed\n");
671 //----------------------------------------------------------------
672 // Test 15: Allocate/Deallocate stress test
673 //----------------------------------------------------------------
675 rv
= StressTest(localFile
, 15, PR_FALSE
);
679 printf("Test 15: passed\n");
682 //----------------------------------------------------------------
683 // Test 16: WriteBlocks
684 //----------------------------------------------------------------
686 rv
= blockFile
->Open(localFile
, 256);
688 printf("Test 16: failed (Open returned: 0x%.8x)\n", rv
);
692 char * one
= new char[256 * 1];
693 char * two
= new char[256 * 2];
694 char * three
= new char[256 * 3];
695 char * four
= new char[256 * 4];
696 if (!one
|| !two
|| !three
|| !four
) {
697 printf("Test 16: failed - out of memory\n");
698 rv
= NS_ERROR_OUT_OF_MEMORY
;
703 memset(two
, 2, 256 * 2);
704 memset(three
, 3, 256 * 3);
705 memset(four
, 4, 256 * 4);
707 startBlock
= blockFile
->AllocateBlocks(1);
708 if (startBlock
!= 0) {
709 printf("Test 16: failed (AllocateBlocks(1) failed)\n");
713 rv
= blockFile
->WriteBlocks(one
, startBlock
, 1);
715 printf("Test 16: failed (WriteBlocks(1) returned 0x%.8x)\n", rv
);
719 startBlock
= blockFile
->AllocateBlocks(2);
720 if (startBlock
!= 1) { // starting with empy map, this allocation should begin at block 1
721 printf("Test 16: failed (AllocateBlocks(2) failed)\n");
725 rv
= blockFile
->WriteBlocks(two
, startBlock
, 2);
727 printf("Test 16: failed (WriteBlocks(2) returned 0x%.8x)\n", rv
);
731 startBlock
= blockFile
->AllocateBlocks(3);
732 if (startBlock
!= 4) { // starting with empy map, this allocation should begin at block 4
733 printf("Test 16: failed (AllocateBlocks(3) failed)\n");
737 rv
= blockFile
->WriteBlocks(three
, startBlock
, 3);
739 printf("Test 16: failed (WriteBlocks(3) returned 0x%.8x)\n", rv
);
743 startBlock
= blockFile
->AllocateBlocks(4);
744 if (startBlock
!= 8) { // starting with empy map, this allocation should begin at block 8
745 printf("Test 16: failed (AllocateBlocks(4) failed)\n");
749 rv
= blockFile
->WriteBlocks(four
, startBlock
, 4);
751 printf("Test 16: failed (WriteBlocks(4) returned 0x%.8x)\n", rv
);
755 printf("Test 16: passed\n");
758 //----------------------------------------------------------------
759 // Test 17: ReadBlocks
760 //----------------------------------------------------------------
762 rv
= blockFile
->ReadBlocks(one
, 0, 1);
764 printf("Test 17: failed (ReadBlocks(1) returned 0x%.8x)\n", rv
);
769 for (i
= 0; i
< 256; i
++) {
771 printf("Test 17: failed (verifying buffer 1)\n");
772 rv
= NS_ERROR_FAILURE
;
777 rv
= blockFile
->ReadBlocks(two
, 1, 2);
779 printf("Test 17: failed (ReadBlocks(2) returned 0x%.8x)\n", rv
);
784 for (i
= 0; i
< 256 * 2; i
++) {
786 printf("Test 17: failed (verifying buffer 2)\n");
787 rv
= NS_ERROR_FAILURE
;
792 rv
= blockFile
->ReadBlocks(three
, 4, 3);
794 printf("Test 17: failed (ReadBlocks(3) returned 0x%.8x)\n", rv
);
799 for (i
= 0; i
< 256 * 3; i
++) {
801 printf("Test 17: failed (verifying buffer 3)\n");
802 rv
= NS_ERROR_FAILURE
;
807 rv
= blockFile
->ReadBlocks(four
, 8, 4);
809 printf("Test 17: failed (ReadBlocks(4) returned 0x%.8x)\n", rv
);
814 for (i
= 0; i
< 256 * 4; i
++) {
816 printf("Test 17: failed (verifying buffer 4)\n");
817 rv
= NS_ERROR_FAILURE
;
822 rv
= blockFile
->Close();
824 printf("Test 17: failed (Close returned: 0x%.8x)\n", rv
);
828 printf("Test 17: passed\n");
831 //----------------------------------------------------------------
832 // Test 18: ValidateFile (open existing file with blocks allocated)
833 //----------------------------------------------------------------
834 rv
= blockFile
->Open(localFile
, 256);
836 printf("Test 18: failed (Open returned: 0x%.8x)\n", rv
);
840 rv
= blockFile
->Close();
842 printf("Test 18: failed (Close returned: 0x%.8x)\n", rv
);
846 printf("Test 18: passed\n");
848 //----------------------------------------------------------------
849 // Test 19: WriteBlocks/ReadBlocks stress
850 //----------------------------------------------------------------
852 rv
= StressTest(localFile
, 19, PR_FALSE
);
856 printf("Test 19: passed\n");
862 nsMemory::Free(currentDirPath
);
863 } // this scopes the nsCOMPtrs
864 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
866 printf("Test failed: 0x%.8x\n", rv
);
868 rv
= NS_ShutdownXPCOM(nsnull
);
869 NS_ASSERTION(NS_SUCCEEDED(rv
), "NS_ShutdownXPCOM failed");
871 printf("XPCOM shut down.\n\n");