2 TestCacheBlockFiles.cpp
13 #include <Resources.h>
18 #include "nsDirectoryServiceDefs.h"
20 #include "nsIComponentManager.h"
21 #include "nsIComponentRegistrar.h"
23 #include "nsIFileStreams.h"
25 #include "nsIComponentRegistrar.h"
26 #include "nsANSIFileStreams.h"
27 #include "nsDiskCacheBlockFile.h"
35 typedef struct Allocation
{
41 StressTest(nsIFile
* localFile
, int32_t testNumber
, bool readWrite
)
45 #define ITERATIONS 1024
46 #define MAX_ALLOCATIONS 256
47 Allocation block
[MAX_ALLOCATIONS
];
48 int32_t currentAllocations
= 0;
53 char readBuf
[256 * 4];
57 for (i
= 0; i
< 4; i
++) {
58 writeBuf
[i
] = new char[256 * i
];
60 printf("Test %d: failed - out of memory\n", testNumber
);
61 rv
= NS_ERROR_OUT_OF_MEMORY
;
65 memset(writeBuf
[i
], i
, 256 * i
);
69 nsDiskCacheBlockFile
* blockFile
= new nsDiskCacheBlockFile
;
71 printf("Test %d failed (unable to allocate nsDiskCacheBlockFile", testNumber
);
72 rv
= NS_ERROR_OUT_OF_MEMORY
;
76 rv
= blockFile
->Open(localFile
, 256);
78 printf("Test %d: failed (Open returned: 0x%.8x)\n", testNumber
, rv
);
84 if ((currentAllocations
>= MAX_ALLOCATIONS
) ||
85 ((currentAllocations
> 0) && (rand() % 4 == 0))) {
86 // deallocate if we've reached the limit, or 25% of the time we have allocations
87 a
= rand() % currentAllocations
;
90 // read verify deallocation
91 rv
= blockFile
->ReadBlocks(readBuf
, block
[a
].start
, block
[a
].count
);
93 printf("Test %d: failed (ReadBlocks() returned 0x%.8x)\n", testNumber
, rv
);
98 for (i
= 0; i
< 256 * block
[a
].count
; i
++) {
99 if (readBuf
[i
] != block
[a
].count
) {
100 printf("Test %d: failed (verifying buffer 1)\n", testNumber
);
101 rv
= NS_ERROR_FAILURE
;
107 rv
= blockFile
->DeallocateBlocks(block
[a
].start
, block
[a
].count
);
109 printf("Test %d: failed (DeallocateBlocks() returned %d)\n", testNumber
, rv
);
113 --currentAllocations
;
114 if (currentAllocations
> 0)
115 block
[a
] = block
[currentAllocations
];
120 a
= currentAllocations
++;
121 block
[a
].count
= rand() % 4 + 1; // allocate 1 to 4 blocks
122 block
[a
].start
= blockFile
->AllocateBlocks(block
[a
].count
);
123 if (block
[a
].start
< 0) {
124 printf("Test %d: failed (AllocateBlocks() failed.)\n", testNumber
);
130 rv
= blockFile
->WriteBlocks(writeBuf
[block
[a
].count
], block
[a
].start
, block
[a
].count
);
132 printf("Test %d: failed (WriteBlocks() returned 0x%.8x)\n",testNumber
, rv
);
139 // now deallocate remaining allocations
140 i
= currentAllocations
;
144 // read verify deallocation
145 rv
= blockFile
->ReadBlocks(readBuf
, block
[a
].start
, block
[a
].count
);
147 printf("Test %d: failed (ReadBlocks(1) returned 0x%.8x)\n", testNumber
, rv
);
152 for (i
= 0; i
< 256 * block
[a
].count
; i
++) {
153 if (readBuf
[i
] != block
[a
].count
) {
154 printf("Test %d: failed (verifying buffer 1)\n", testNumber
);
155 rv
= NS_ERROR_FAILURE
;
161 rv
= blockFile
->DeallocateBlocks(block
[i
].start
, block
[i
].count
);
163 printf("Test %d: failed (DeallocateBlocks() returned %d)\n", testNumber
, rv
);
171 nsresult rv2
= blockFile
->Close();
172 if (NS_FAILED(rv2
)) {
173 printf("Test %d: failed (Close returned: 0x%.8x)\n", testNumber
, rv2
);
176 return rv
? rv
: rv2
;
187 printf("hello world\n");
189 unsigned long now
= time(0);
192 nsCOMPtr
<nsIFile
> file
;
193 nsCOMPtr
<nsIFile
> localFile
;
197 nsCOMPtr
<nsIServiceManager
> servMan
;
198 NS_InitXPCOM2(getter_AddRefs(servMan
), nullptr, nullptr);
199 nsCOMPtr
<nsIComponentRegistrar
> registrar
= do_QueryInterface(servMan
);
200 NS_ASSERTION(registrar
, "Null nsIComponentRegistrar");
202 registrar
->AutoRegister(nullptr);
204 // Get default directory
205 rv
= NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR
,
206 getter_AddRefs(file
));
208 printf("NS_GetSpecialDirectory() failed : 0x%.8x\n", rv
);
211 char * currentDirPath
;
212 rv
= file
->GetPath(¤tDirPath
);
214 printf("currentProcessDir->GetPath() failed : 0x%.8x\n", rv
);
218 printf("Current Process Directory: %s\n", currentDirPath
);
221 // Generate name for cache block file
222 rv
= file
->Append("_CACHE_001_");
223 if (NS_FAILED(rv
)) goto exit
;
225 // Delete existing file
226 rv
= file
->Delete(false);
227 if (NS_FAILED(rv
) && rv
!= NS_ERROR_FILE_NOT_FOUND
) goto exit
;
229 // Need nsIFile to open
230 localFile
= do_QueryInterface(file
, &rv
);
232 printf("do_QueryInterface(file) failed : 0x%.8x\n", rv
);
236 nsDiskCacheBlockFile
* blockFile
= new nsDiskCacheBlockFile
;
238 rv
= NS_ERROR_OUT_OF_MEMORY
;
242 //----------------------------------------------------------------
243 // local variables used in tests
244 //----------------------------------------------------------------
245 uint32_t bytesWritten
= 0;
250 //----------------------------------------------------------------
251 // Test 1: Open nonexistent file
252 //----------------------------------------------------------------
253 rv
= blockFile
->Open(localFile
, 256);
255 printf("Test 1: failed (Open returned: 0x%.8x)\n", rv
);
259 rv
= blockFile
->Close();
261 printf("Test 1: failed (Close returned: 0x%.8x)\n", rv
);
265 printf("Test 1: passed\n");
268 //----------------------------------------------------------------
269 // Test 2: Open existing file (with no allocation)
270 //----------------------------------------------------------------
271 rv
= blockFile
->Open(localFile
, 256);
273 printf("Test 2: failed (Open returned: 0x%.8x)\n", rv
);
277 rv
= blockFile
->Close();
279 printf("Test 2: failed (Close returned: 0x%.8x)\n", rv
);
283 printf("Test 2: passed\n");
286 //----------------------------------------------------------------
287 // Test 3: Open existing file (bad format) size < kBitMapBytes
288 //----------------------------------------------------------------
290 // Delete existing file
291 rv
= localFile
->Delete(false);
293 printf("Test 3 failed (Delete returned: 0x%.8x)\n", rv
);
297 // write < kBitMapBytes to file
298 nsANSIFileStream
* stream
= new nsANSIFileStream
;
300 printf("Test 3 failed (unable to allocate stream\n", rv
);
304 rv
= stream
->Open(localFile
);
307 printf("Test 3 failed (stream->Open returned: 0x%.8x)\n", rv
);
312 rv
= stream
->Write("Tell me something good.\n", 24, &bytesWritten
);
315 printf("Test 3 failed (stream->Write returned: 0x%.8x)\n", rv
);
319 rv
= stream
->Close();
322 printf("Test 3 failed (stream->Close returned: 0x%.8x)\n", rv
);
327 rv
= blockFile
->Open(localFile
, 256);
328 if (NS_SUCCEEDED(rv
)) {
329 printf("Test 3: failed (Open erroneously succeeded)\n", rv
);
331 (void) blockFile
->Close();
335 printf("Test 3: passed\n");
338 //----------------------------------------------------------------
339 // Test 4: Open nonexistent file (again)
340 //----------------------------------------------------------------
342 // Delete existing file
343 rv
= localFile
->Delete(false);
345 printf("Test 4 failed (Delete returned: 0x%.8x)\n", rv
);
349 rv
= blockFile
->Open(localFile
, 256);
351 printf("Test 4: failed (Open returned: 0x%.8x)\n", rv
);
355 printf("Test 4: passed\n");
358 //----------------------------------------------------------------
359 // Test 5: AllocateBlocks: invalid block count (0, 5)
360 //----------------------------------------------------------------
363 startBlock
= blockFile
->AllocateBlocks(0);
364 if (startBlock
> -1) {
365 printf("Test 5: failed (AllocateBlocks(0) erroneously succeeded)\n");
369 startBlock
= blockFile
->AllocateBlocks(5);
370 if (startBlock
> -1) {
371 printf("Test 5: failed (AllocateBlocks(5) erroneously succeeded)\n");
374 printf("Test 5: passed\n");
377 //----------------------------------------------------------------
378 // Test 6: AllocateBlocks: valid block count (1, 2, 3, 4)
379 //----------------------------------------------------------------
380 startBlock
= blockFile
->AllocateBlocks(1);
381 if (startBlock
!= 0) {
382 printf("Test 6: failed (AllocateBlocks(1) failed)\n");
386 startBlock
= blockFile
->AllocateBlocks(2);
387 if (startBlock
!= 1) {
388 printf("Test 6: failed (AllocateBlocks(2) failed)\n");
392 startBlock
= blockFile
->AllocateBlocks(3);
393 if (startBlock
!= 4) {
394 printf("Test 6: failed (AllocateBlocks(3) failed)\n");
398 startBlock
= blockFile
->AllocateBlocks(4);
399 if (startBlock
!= 8) {
400 printf("Test 6: failed (AllocateBlocks(4) failed)\n");
404 // blocks allocated should be 1220 3330 4444
405 printf("Test 6: passed\n"); // but bits could be mis-allocated
409 //----------------------------------------------------------------
410 // Test 7: VerifyAllocation
411 //----------------------------------------------------------------
412 rv
= blockFile
->VerifyAllocation(0,1);
414 printf("Test 7: failed (VerifyAllocation(0,1) returned: 0x%.8x)\n", rv
);
418 rv
= blockFile
->VerifyAllocation(1,2);
420 printf("Test 7: failed (VerifyAllocation(1,2) returned: 0x%.8x)\n", rv
);
424 rv
= blockFile
->VerifyAllocation(4,3);
426 printf("Test 7: failed (VerifyAllocation(4,3) returned: 0x%.8x)\n", rv
);
430 rv
= blockFile
->VerifyAllocation(8,4);
432 printf("Test 7: failed (VerifyAllocation(8,4) returned: 0x%.8x)\n", rv
);
435 printf("Test 7: passed\n");
438 //----------------------------------------------------------------
440 //----------------------------------------------------------------
441 int32_t lastBlock
= blockFile
->LastBlock();
442 if (lastBlock
!= 11) {
443 printf("Test 8: failed (LastBlock() returned: %d)\n", lastBlock
);
446 printf("Test 8: passed\n");
449 //----------------------------------------------------------------
450 // Test 9: DeallocateBlocks: bad startBlock ( < 0)
451 //----------------------------------------------------------------
452 rv
= blockFile
->DeallocateBlocks(-1, 4);
453 if (NS_SUCCEEDED(rv
)) {
454 printf("Test 9: failed (DeallocateBlocks(-1, 4) erroneously succeeded)\n");
457 printf("Test 9: passed\n");
460 //----------------------------------------------------------------
461 // Test 10: DeallocateBlocks: bad numBlocks (0, 5)
462 //----------------------------------------------------------------
463 rv
= blockFile
->DeallocateBlocks(0, 0);
464 if (NS_SUCCEEDED(rv
)) {
465 printf("Test 10: failed (DeallocateBlocks(0, 0) erroneously succeeded)\n");
469 rv
= blockFile
->DeallocateBlocks(0, 5);
470 if (NS_SUCCEEDED(rv
)) {
471 printf("Test 10: failed (DeallocateBlocks(0, 5) erroneously succeeded)\n");
475 printf("Test 10: passed\n");
478 //----------------------------------------------------------------
479 // Test 11: DeallocateBlocks: unallocated blocks
480 //----------------------------------------------------------------
481 rv
= blockFile
->DeallocateBlocks(12, 1);
482 if (NS_SUCCEEDED(rv
)) {
483 printf("Test 11: failed (DeallocateBlocks(12, 1) erroneously succeeded)\n");
487 printf("Test 11: passed\n");
490 //----------------------------------------------------------------
491 // Test 12: DeallocateBlocks: 1, 2, 3, 4 (allocated in Test 6)
492 //----------------------------------------------------------------
493 rv
= blockFile
->DeallocateBlocks(0, 1);
495 printf("Test 12: failed (DeallocateBlocks(12, 1) returned: 0x%.8x)\n", rv
);
499 rv
= blockFile
->DeallocateBlocks(1, 2);
501 printf("Test 12: failed (DeallocateBlocks(1, 2) returned: 0x%.8x)\n", rv
);
505 rv
= blockFile
->DeallocateBlocks(4, 3);
507 printf("Test 12: failed (DeallocateBlocks(4, 3) returned: 0x%.8x)\n", rv
);
511 rv
= blockFile
->DeallocateBlocks(8, 4);
513 printf("Test 12: failed (DeallocateBlocks(8, 4) returned: 0x%.8x)\n", rv
);
517 // zero blocks should be allocated
518 rv
= blockFile
->Close();
520 printf("Test 12: failed (Close returned: 0x%.8x)\n", rv
);
524 printf("Test 12: passed\n");
527 //----------------------------------------------------------------
528 // Test 13: Allocate/Deallocate boundary test
529 //----------------------------------------------------------------
531 rv
= blockFile
->Open(localFile
, 256);
533 printf("Test 13: failed (Open returned: 0x%.8x)\n", rv
);
537 // fully allocate, 1 block at a time
538 for (i
=0; i
< kBitMapBytes
* 8; ++i
) {
539 startBlock
= blockFile
->AllocateBlocks(1);
540 if (startBlock
< 0) {
541 printf("Test 13: failed (AllocateBlocks(1) failed on i=%d)\n", i
);
546 // attempt allocation with full bit map
547 startBlock
= blockFile
->AllocateBlocks(1);
548 if (startBlock
>= 0) {
549 printf("Test 13: failed (AllocateBlocks(1) erroneously succeeded i=%d)\n", i
);
553 // deallocate all the bits
554 for (i
=0; i
< kBitMapBytes
* 8; ++i
) {
555 rv
= blockFile
->DeallocateBlocks(i
,1);
557 printf("Test 13: failed (DeallocateBlocks(%d,1) returned: 0x%.8x)\n", i
,rv
);
562 // attempt deallocation beyond end of bit map
563 rv
= blockFile
->DeallocateBlocks(i
,1);
564 if (NS_SUCCEEDED(rv
)) {
565 printf("Test 13: failed (DeallocateBlocks(%d,1) erroneously succeeded)\n", i
);
569 // bit map should be empty
571 // fully allocate, 2 block at a time
572 for (i
=0; i
< kBitMapBytes
* 8; i
+=2) {
573 startBlock
= blockFile
->AllocateBlocks(2);
574 if (startBlock
< 0) {
575 printf("Test 13: failed (AllocateBlocks(2) failed on i=%d)\n", i
);
580 // attempt allocation with full bit map
581 startBlock
= blockFile
->AllocateBlocks(2);
582 if (startBlock
>= 0) {
583 printf("Test 13: failed (AllocateBlocks(2) erroneously succeeded i=%d)\n", i
);
587 // deallocate all the bits
588 for (i
=0; i
< kBitMapBytes
* 8; i
+=2) {
589 rv
= blockFile
->DeallocateBlocks(i
,2);
591 printf("Test 13: failed (DeallocateBlocks(%d,2) returned: 0x%.8x)\n", i
,rv
);
596 // bit map should be empty
598 // fully allocate, 4 block at a time
599 for (i
=0; i
< kBitMapBytes
* 8; i
+=4) {
600 startBlock
= blockFile
->AllocateBlocks(4);
601 if (startBlock
< 0) {
602 printf("Test 13: failed (AllocateBlocks(4) failed on i=%d)\n", i
);
607 // attempt allocation with full bit map
608 startBlock
= blockFile
->AllocateBlocks(4);
609 if (startBlock
>= 0) {
610 printf("Test 13: failed (AllocateBlocks(4) erroneously succeeded i=%d)\n", i
);
614 // deallocate all the bits
615 for (i
=0; i
< kBitMapBytes
* 8; i
+=4) {
616 rv
= blockFile
->DeallocateBlocks(i
,4);
618 printf("Test 13: failed (DeallocateBlocks(%d,4) returned: 0x%.8x)\n", i
,rv
);
623 // bit map should be empty
625 // allocate as many triple-blocks as possible
626 for (i
=0; i
< kBitMapBytes
* 8; i
+=4) {
627 startBlock
= blockFile
->AllocateBlocks(3);
628 if (startBlock
< 0) {
629 printf("Test 13: failed (AllocateBlocks(3) failed on i=%d)\n", i
);
634 // attempt allocation with "full" bit map
635 startBlock
= blockFile
->AllocateBlocks(3);
636 if (startBlock
>= 0) {
637 printf("Test 13: failed (AllocateBlocks(3) erroneously succeeded i=%d)\n", i
);
641 // leave some blocks allocated
643 rv
= blockFile
->Close();
645 printf("Test 13: failed (Close returned: 0x%.8x)\n", rv
);
649 printf("Test 13: passed\n");
652 //----------------------------------------------------------------
653 // Test 14: ValidateFile (open existing file w/size < allocated blocks
654 //----------------------------------------------------------------
655 rv
= blockFile
->Open(localFile
, 256);
656 if (NS_SUCCEEDED(rv
)) {
657 printf("Test 14: failed (Open erroneously succeeded)\n");
661 // Delete existing file
662 rv
= localFile
->Delete(false);
664 printf("Test 14 failed (Delete returned: 0x%.8x)\n", rv
);
667 printf("Test 14: passed\n");
670 //----------------------------------------------------------------
671 // Test 15: Allocate/Deallocate stress test
672 //----------------------------------------------------------------
674 rv
= StressTest(localFile
, 15, false);
678 printf("Test 15: passed\n");
681 //----------------------------------------------------------------
682 // Test 16: WriteBlocks
683 //----------------------------------------------------------------
685 rv
= blockFile
->Open(localFile
, 256);
687 printf("Test 16: failed (Open returned: 0x%.8x)\n", rv
);
691 char * one
= new char[256 * 1];
692 char * two
= new char[256 * 2];
693 char * three
= new char[256 * 3];
694 char * four
= new char[256 * 4];
695 if (!one
|| !two
|| !three
|| !four
) {
696 printf("Test 16: failed - out of memory\n");
697 rv
= NS_ERROR_OUT_OF_MEMORY
;
702 memset(two
, 2, 256 * 2);
703 memset(three
, 3, 256 * 3);
704 memset(four
, 4, 256 * 4);
706 startBlock
= blockFile
->AllocateBlocks(1);
707 if (startBlock
!= 0) {
708 printf("Test 16: failed (AllocateBlocks(1) failed)\n");
712 rv
= blockFile
->WriteBlocks(one
, startBlock
, 1);
714 printf("Test 16: failed (WriteBlocks(1) returned 0x%.8x)\n", rv
);
718 startBlock
= blockFile
->AllocateBlocks(2);
719 if (startBlock
!= 1) { // starting with empy map, this allocation should begin at block 1
720 printf("Test 16: failed (AllocateBlocks(2) failed)\n");
724 rv
= blockFile
->WriteBlocks(two
, startBlock
, 2);
726 printf("Test 16: failed (WriteBlocks(2) returned 0x%.8x)\n", rv
);
730 startBlock
= blockFile
->AllocateBlocks(3);
731 if (startBlock
!= 4) { // starting with empy map, this allocation should begin at block 4
732 printf("Test 16: failed (AllocateBlocks(3) failed)\n");
736 rv
= blockFile
->WriteBlocks(three
, startBlock
, 3);
738 printf("Test 16: failed (WriteBlocks(3) returned 0x%.8x)\n", rv
);
742 startBlock
= blockFile
->AllocateBlocks(4);
743 if (startBlock
!= 8) { // starting with empy map, this allocation should begin at block 8
744 printf("Test 16: failed (AllocateBlocks(4) failed)\n");
748 rv
= blockFile
->WriteBlocks(four
, startBlock
, 4);
750 printf("Test 16: failed (WriteBlocks(4) returned 0x%.8x)\n", rv
);
754 printf("Test 16: passed\n");
757 //----------------------------------------------------------------
758 // Test 17: ReadBlocks
759 //----------------------------------------------------------------
761 rv
= blockFile
->ReadBlocks(one
, 0, 1);
763 printf("Test 17: failed (ReadBlocks(1) returned 0x%.8x)\n", rv
);
768 for (i
= 0; i
< 256; i
++) {
770 printf("Test 17: failed (verifying buffer 1)\n");
771 rv
= NS_ERROR_FAILURE
;
776 rv
= blockFile
->ReadBlocks(two
, 1, 2);
778 printf("Test 17: failed (ReadBlocks(2) returned 0x%.8x)\n", rv
);
783 for (i
= 0; i
< 256 * 2; i
++) {
785 printf("Test 17: failed (verifying buffer 2)\n");
786 rv
= NS_ERROR_FAILURE
;
791 rv
= blockFile
->ReadBlocks(three
, 4, 3);
793 printf("Test 17: failed (ReadBlocks(3) returned 0x%.8x)\n", rv
);
798 for (i
= 0; i
< 256 * 3; i
++) {
800 printf("Test 17: failed (verifying buffer 3)\n");
801 rv
= NS_ERROR_FAILURE
;
806 rv
= blockFile
->ReadBlocks(four
, 8, 4);
808 printf("Test 17: failed (ReadBlocks(4) returned 0x%.8x)\n", rv
);
813 for (i
= 0; i
< 256 * 4; i
++) {
815 printf("Test 17: failed (verifying buffer 4)\n");
816 rv
= NS_ERROR_FAILURE
;
821 rv
= blockFile
->Close();
823 printf("Test 17: failed (Close returned: 0x%.8x)\n", rv
);
827 printf("Test 17: passed\n");
830 //----------------------------------------------------------------
831 // Test 18: ValidateFile (open existing file with blocks allocated)
832 //----------------------------------------------------------------
833 rv
= blockFile
->Open(localFile
, 256);
835 printf("Test 18: failed (Open returned: 0x%.8x)\n", rv
);
839 rv
= blockFile
->Close();
841 printf("Test 18: failed (Close returned: 0x%.8x)\n", rv
);
845 printf("Test 18: passed\n");
847 //----------------------------------------------------------------
848 // Test 19: WriteBlocks/ReadBlocks stress
849 //----------------------------------------------------------------
851 rv
= StressTest(localFile
, 19, false);
855 printf("Test 19: passed\n");
861 nsMemory::Free(currentDirPath
);
862 } // this scopes the nsCOMPtrs
863 // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
865 printf("Test failed: 0x%.8x\n", rv
);
867 rv
= NS_ShutdownXPCOM(nullptr);
868 NS_ASSERTION(NS_SUCCEEDED(rv
), "NS_ShutdownXPCOM failed");
870 printf("XPCOM shut down.\n\n");