michael@0: /* michael@0: TestCacheBlockFiles.cpp michael@0: */ michael@0: michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsCRT.h" michael@0: #include "nsDirectoryServiceDefs.h" michael@0: #include "nsError.h" michael@0: #include "nsIComponentManager.h" michael@0: #include "nsIComponentRegistrar.h" michael@0: #include "nsIFile.h" michael@0: #include "nsIFileStreams.h" michael@0: #include "nsMemory.h" michael@0: #include "nsIComponentRegistrar.h" michael@0: #include "nsANSIFileStreams.h" michael@0: #include "nsDiskCacheBlockFile.h" michael@0: michael@0: #include "prclist.h" michael@0: michael@0: /** michael@0: * StressTest() michael@0: */ michael@0: michael@0: typedef struct Allocation { michael@0: int32_t start; michael@0: int32_t count; michael@0: } Allocation; michael@0: michael@0: nsresult michael@0: StressTest(nsIFile * localFile, int32_t testNumber, bool readWrite) michael@0: { michael@0: nsresult rv = NS_OK; michael@0: michael@0: #define ITERATIONS 1024 michael@0: #define MAX_ALLOCATIONS 256 michael@0: Allocation block[MAX_ALLOCATIONS]; michael@0: int32_t currentAllocations = 0; michael@0: int32_t i; michael@0: uint32_t a; michael@0: michael@0: char * writeBuf[4]; michael@0: char readBuf[256 * 4]; michael@0: michael@0: michael@0: if (readWrite) { michael@0: for (i = 0; i < 4; i++) { michael@0: writeBuf[i] = new char[256 * i]; michael@0: if (!writeBuf[i]) { michael@0: printf("Test %d: failed - out of memory\n", testNumber); michael@0: rv = NS_ERROR_OUT_OF_MEMORY; michael@0: goto exit; michael@0: } michael@0: michael@0: memset(writeBuf[i], i, 256 * i); michael@0: } michael@0: } michael@0: michael@0: nsDiskCacheBlockFile * blockFile = new nsDiskCacheBlockFile; michael@0: if (!blockFile) { michael@0: printf("Test %d failed (unable to allocate nsDiskCacheBlockFile", testNumber); michael@0: rv = NS_ERROR_OUT_OF_MEMORY; michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->Open(localFile, 256); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test %d: failed (Open returned: 0x%.8x)\n", testNumber, rv); michael@0: goto exit; michael@0: } michael@0: michael@0: i = ITERATIONS; michael@0: while (i > 0) { michael@0: if ((currentAllocations >= MAX_ALLOCATIONS) || michael@0: ((currentAllocations > 0) && (rand() % 4 == 0))) { michael@0: // deallocate if we've reached the limit, or 25% of the time we have allocations michael@0: a = rand() % currentAllocations; michael@0: michael@0: if (readWrite) { michael@0: // read verify deallocation michael@0: rv = blockFile->ReadBlocks(readBuf, block[a].start, block[a].count); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test %d: failed (ReadBlocks() returned 0x%.8x)\n", testNumber, rv); michael@0: goto exit; michael@0: } michael@0: michael@0: // Verify buffer michael@0: for (i = 0; i < 256 * block[a].count; i++) { michael@0: if (readBuf[i] != block[a].count) { michael@0: printf("Test %d: failed (verifying buffer 1)\n", testNumber); michael@0: rv = NS_ERROR_FAILURE; michael@0: goto exit; michael@0: } michael@0: } michael@0: } michael@0: michael@0: rv = blockFile->DeallocateBlocks(block[a].start, block[a].count); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test %d: failed (DeallocateBlocks() returned %d)\n", testNumber, rv); michael@0: goto exit; michael@0: } michael@0: michael@0: --currentAllocations; michael@0: if (currentAllocations > 0) michael@0: block[a] = block[currentAllocations]; michael@0: michael@0: } else { michael@0: // allocate blocks michael@0: --i; michael@0: a = currentAllocations++; michael@0: block[a].count = rand() % 4 + 1; // allocate 1 to 4 blocks michael@0: block[a].start = blockFile->AllocateBlocks(block[a].count); michael@0: if (block[a].start < 0) { michael@0: printf("Test %d: failed (AllocateBlocks() failed.)\n", testNumber); michael@0: goto exit; michael@0: } michael@0: michael@0: if (readWrite) { michael@0: // write buffer michael@0: rv = blockFile->WriteBlocks(writeBuf[block[a].count], block[a].start, block[a].count); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test %d: failed (WriteBlocks() returned 0x%.8x)\n",testNumber, rv); michael@0: goto exit; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: // now deallocate remaining allocations michael@0: i = currentAllocations; michael@0: while (i--) { michael@0: michael@0: if (readWrite) { michael@0: // read verify deallocation michael@0: rv = blockFile->ReadBlocks(readBuf, block[a].start, block[a].count); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test %d: failed (ReadBlocks(1) returned 0x%.8x)\n", testNumber, rv); michael@0: goto exit; michael@0: } michael@0: michael@0: // Verify buffer michael@0: for (i = 0; i < 256 * block[a].count; i++) { michael@0: if (readBuf[i] != block[a].count) { michael@0: printf("Test %d: failed (verifying buffer 1)\n", testNumber); michael@0: rv = NS_ERROR_FAILURE; michael@0: goto exit; michael@0: } michael@0: } michael@0: } michael@0: michael@0: rv = blockFile->DeallocateBlocks(block[i].start, block[i].count); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test %d: failed (DeallocateBlocks() returned %d)\n", testNumber, rv); michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: michael@0: michael@0: exit: michael@0: nsresult rv2 = blockFile->Close(); michael@0: if (NS_FAILED(rv2)) { michael@0: printf("Test %d: failed (Close returned: 0x%.8x)\n", testNumber, rv2); michael@0: } michael@0: michael@0: return rv ? rv : rv2; michael@0: } michael@0: michael@0: /** michael@0: * main() michael@0: */ michael@0: michael@0: int michael@0: main(void) michael@0: { michael@0: // OSErr err; michael@0: printf("hello world\n"); michael@0: michael@0: unsigned long now = time(0); michael@0: srand(now); michael@0: michael@0: nsCOMPtr file; michael@0: nsCOMPtr localFile; michael@0: nsresult rv = NS_OK; michael@0: { michael@0: // Start up XPCOM michael@0: nsCOMPtr servMan; michael@0: NS_InitXPCOM2(getter_AddRefs(servMan), nullptr, nullptr); michael@0: nsCOMPtr registrar = do_QueryInterface(servMan); michael@0: NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); michael@0: if (registrar) michael@0: registrar->AutoRegister(nullptr); michael@0: michael@0: // Get default directory michael@0: rv = NS_GetSpecialDirectory(NS_XPCOM_CURRENT_PROCESS_DIR, michael@0: getter_AddRefs(file)); michael@0: if (NS_FAILED(rv)) { michael@0: printf("NS_GetSpecialDirectory() failed : 0x%.8x\n", rv); michael@0: goto exit; michael@0: } michael@0: char * currentDirPath; michael@0: rv = file->GetPath(¤tDirPath); michael@0: if (NS_FAILED(rv)) { michael@0: printf("currentProcessDir->GetPath() failed : 0x%.8x\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Current Process Directory: %s\n", currentDirPath); michael@0: michael@0: michael@0: // Generate name for cache block file michael@0: rv = file->Append("_CACHE_001_"); michael@0: if (NS_FAILED(rv)) goto exit; michael@0: michael@0: // Delete existing file michael@0: rv = file->Delete(false); michael@0: if (NS_FAILED(rv) && rv != NS_ERROR_FILE_NOT_FOUND) goto exit; michael@0: michael@0: // Need nsIFile to open michael@0: localFile = do_QueryInterface(file, &rv); michael@0: if (NS_FAILED(rv)) { michael@0: printf("do_QueryInterface(file) failed : 0x%.8x\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: nsDiskCacheBlockFile * blockFile = new nsDiskCacheBlockFile; michael@0: if (!blockFile) { michael@0: rv = NS_ERROR_OUT_OF_MEMORY; michael@0: goto exit; michael@0: } michael@0: michael@0: //---------------------------------------------------------------- michael@0: // local variables used in tests michael@0: //---------------------------------------------------------------- michael@0: uint32_t bytesWritten = 0; michael@0: int32_t startBlock; michael@0: int32_t i = 0; michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 1: Open nonexistent file michael@0: //---------------------------------------------------------------- michael@0: rv = blockFile->Open(localFile, 256); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 1: failed (Open returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->Close(); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 1: failed (Close returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Test 1: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 2: Open existing file (with no allocation) michael@0: //---------------------------------------------------------------- michael@0: rv = blockFile->Open(localFile, 256); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 2: failed (Open returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->Close(); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 2: failed (Close returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Test 2: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 3: Open existing file (bad format) size < kBitMapBytes michael@0: //---------------------------------------------------------------- michael@0: michael@0: // Delete existing file michael@0: rv = localFile->Delete(false); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 3 failed (Delete returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: // write < kBitMapBytes to file michael@0: nsANSIFileStream * stream = new nsANSIFileStream; michael@0: if (!stream) { michael@0: printf("Test 3 failed (unable to allocate stream\n", rv); michael@0: goto exit; michael@0: } michael@0: NS_ADDREF(stream); michael@0: rv = stream->Open(localFile); michael@0: if (NS_FAILED(rv)) { michael@0: NS_RELEASE(stream); michael@0: printf("Test 3 failed (stream->Open returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: bytesWritten = 0; michael@0: rv = stream->Write("Tell me something good.\n", 24, &bytesWritten); michael@0: if (NS_FAILED(rv)) { michael@0: NS_RELEASE(stream); michael@0: printf("Test 3 failed (stream->Write returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = stream->Close(); michael@0: if (NS_FAILED(rv)) { michael@0: NS_RELEASE(stream); michael@0: printf("Test 3 failed (stream->Close returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: NS_RELEASE(stream); michael@0: michael@0: rv = blockFile->Open(localFile, 256); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: printf("Test 3: failed (Open erroneously succeeded)\n", rv); michael@0: michael@0: (void) blockFile->Close(); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Test 3: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 4: Open nonexistent file (again) michael@0: //---------------------------------------------------------------- michael@0: michael@0: // Delete existing file michael@0: rv = localFile->Delete(false); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 4 failed (Delete returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->Open(localFile, 256); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 4: failed (Open returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Test 4: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 5: AllocateBlocks: invalid block count (0, 5) michael@0: //---------------------------------------------------------------- michael@0: michael@0: michael@0: startBlock = blockFile->AllocateBlocks(0); michael@0: if (startBlock > -1) { michael@0: printf("Test 5: failed (AllocateBlocks(0) erroneously succeeded)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: startBlock = blockFile->AllocateBlocks(5); michael@0: if (startBlock > -1) { michael@0: printf("Test 5: failed (AllocateBlocks(5) erroneously succeeded)\n"); michael@0: goto exit; michael@0: } michael@0: printf("Test 5: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 6: AllocateBlocks: valid block count (1, 2, 3, 4) michael@0: //---------------------------------------------------------------- michael@0: startBlock = blockFile->AllocateBlocks(1); michael@0: if (startBlock != 0) { michael@0: printf("Test 6: failed (AllocateBlocks(1) failed)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: startBlock = blockFile->AllocateBlocks(2); michael@0: if (startBlock != 1) { michael@0: printf("Test 6: failed (AllocateBlocks(2) failed)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: startBlock = blockFile->AllocateBlocks(3); michael@0: if (startBlock != 4) { michael@0: printf("Test 6: failed (AllocateBlocks(3) failed)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: startBlock = blockFile->AllocateBlocks(4); michael@0: if (startBlock != 8) { michael@0: printf("Test 6: failed (AllocateBlocks(4) failed)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: // blocks allocated should be 1220 3330 4444 michael@0: printf("Test 6: passed\n"); // but bits could be mis-allocated michael@0: michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 7: VerifyAllocation michael@0: //---------------------------------------------------------------- michael@0: rv = blockFile->VerifyAllocation(0,1); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 7: failed (VerifyAllocation(0,1) returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->VerifyAllocation(1,2); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 7: failed (VerifyAllocation(1,2) returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->VerifyAllocation(4,3); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 7: failed (VerifyAllocation(4,3) returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->VerifyAllocation(8,4); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 7: failed (VerifyAllocation(8,4) returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: printf("Test 7: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 8: LastBlock michael@0: //---------------------------------------------------------------- michael@0: int32_t lastBlock = blockFile->LastBlock(); michael@0: if (lastBlock != 11) { michael@0: printf("Test 8: failed (LastBlock() returned: %d)\n", lastBlock); michael@0: goto exit; michael@0: } michael@0: printf("Test 8: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 9: DeallocateBlocks: bad startBlock ( < 0) michael@0: //---------------------------------------------------------------- michael@0: rv = blockFile->DeallocateBlocks(-1, 4); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: printf("Test 9: failed (DeallocateBlocks(-1, 4) erroneously succeeded)\n"); michael@0: goto exit; michael@0: } michael@0: printf("Test 9: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 10: DeallocateBlocks: bad numBlocks (0, 5) michael@0: //---------------------------------------------------------------- michael@0: rv = blockFile->DeallocateBlocks(0, 0); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: printf("Test 10: failed (DeallocateBlocks(0, 0) erroneously succeeded)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->DeallocateBlocks(0, 5); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: printf("Test 10: failed (DeallocateBlocks(0, 5) erroneously succeeded)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Test 10: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 11: DeallocateBlocks: unallocated blocks michael@0: //---------------------------------------------------------------- michael@0: rv = blockFile->DeallocateBlocks(12, 1); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: printf("Test 11: failed (DeallocateBlocks(12, 1) erroneously succeeded)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Test 11: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 12: DeallocateBlocks: 1, 2, 3, 4 (allocated in Test 6) michael@0: //---------------------------------------------------------------- michael@0: rv = blockFile->DeallocateBlocks(0, 1); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 12: failed (DeallocateBlocks(12, 1) returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->DeallocateBlocks(1, 2); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 12: failed (DeallocateBlocks(1, 2) returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->DeallocateBlocks(4, 3); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 12: failed (DeallocateBlocks(4, 3) returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->DeallocateBlocks(8, 4); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 12: failed (DeallocateBlocks(8, 4) returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: // zero blocks should be allocated michael@0: rv = blockFile->Close(); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 12: failed (Close returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Test 12: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 13: Allocate/Deallocate boundary test michael@0: //---------------------------------------------------------------- michael@0: michael@0: rv = blockFile->Open(localFile, 256); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 13: failed (Open returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: // fully allocate, 1 block at a time michael@0: for (i=0; i< kBitMapBytes * 8; ++i) { michael@0: startBlock = blockFile->AllocateBlocks(1); michael@0: if (startBlock < 0) { michael@0: printf("Test 13: failed (AllocateBlocks(1) failed on i=%d)\n", i); michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: // attempt allocation with full bit map michael@0: startBlock = blockFile->AllocateBlocks(1); michael@0: if (startBlock >= 0) { michael@0: printf("Test 13: failed (AllocateBlocks(1) erroneously succeeded i=%d)\n", i); michael@0: goto exit; michael@0: } michael@0: michael@0: // deallocate all the bits michael@0: for (i=0; i< kBitMapBytes * 8; ++i) { michael@0: rv = blockFile->DeallocateBlocks(i,1); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 13: failed (DeallocateBlocks(%d,1) returned: 0x%.8x)\n", i,rv); michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: // attempt deallocation beyond end of bit map michael@0: rv = blockFile->DeallocateBlocks(i,1); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: printf("Test 13: failed (DeallocateBlocks(%d,1) erroneously succeeded)\n", i); michael@0: goto exit; michael@0: } michael@0: michael@0: // bit map should be empty michael@0: michael@0: // fully allocate, 2 block at a time michael@0: for (i=0; i< kBitMapBytes * 8; i+=2) { michael@0: startBlock = blockFile->AllocateBlocks(2); michael@0: if (startBlock < 0) { michael@0: printf("Test 13: failed (AllocateBlocks(2) failed on i=%d)\n", i); michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: // attempt allocation with full bit map michael@0: startBlock = blockFile->AllocateBlocks(2); michael@0: if (startBlock >= 0) { michael@0: printf("Test 13: failed (AllocateBlocks(2) erroneously succeeded i=%d)\n", i); michael@0: goto exit; michael@0: } michael@0: michael@0: // deallocate all the bits michael@0: for (i=0; i< kBitMapBytes * 8; i+=2) { michael@0: rv = blockFile->DeallocateBlocks(i,2); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 13: failed (DeallocateBlocks(%d,2) returned: 0x%.8x)\n", i,rv); michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: // bit map should be empty michael@0: michael@0: // fully allocate, 4 block at a time michael@0: for (i=0; i< kBitMapBytes * 8; i+=4) { michael@0: startBlock = blockFile->AllocateBlocks(4); michael@0: if (startBlock < 0) { michael@0: printf("Test 13: failed (AllocateBlocks(4) failed on i=%d)\n", i); michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: // attempt allocation with full bit map michael@0: startBlock = blockFile->AllocateBlocks(4); michael@0: if (startBlock >= 0) { michael@0: printf("Test 13: failed (AllocateBlocks(4) erroneously succeeded i=%d)\n", i); michael@0: goto exit; michael@0: } michael@0: michael@0: // deallocate all the bits michael@0: for (i=0; i< kBitMapBytes * 8; i+=4) { michael@0: rv = blockFile->DeallocateBlocks(i,4); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 13: failed (DeallocateBlocks(%d,4) returned: 0x%.8x)\n", i,rv); michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: // bit map should be empty michael@0: michael@0: // allocate as many triple-blocks as possible michael@0: for (i=0; i< kBitMapBytes * 8; i+=4) { michael@0: startBlock = blockFile->AllocateBlocks(3); michael@0: if (startBlock < 0) { michael@0: printf("Test 13: failed (AllocateBlocks(3) failed on i=%d)\n", i); michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: // attempt allocation with "full" bit map michael@0: startBlock = blockFile->AllocateBlocks(3); michael@0: if (startBlock >= 0) { michael@0: printf("Test 13: failed (AllocateBlocks(3) erroneously succeeded i=%d)\n", i); michael@0: goto exit; michael@0: } michael@0: michael@0: // leave some blocks allocated michael@0: michael@0: rv = blockFile->Close(); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 13: failed (Close returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Test 13: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 14: ValidateFile (open existing file w/size < allocated blocks michael@0: //---------------------------------------------------------------- michael@0: rv = blockFile->Open(localFile, 256); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: printf("Test 14: failed (Open erroneously succeeded)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: // Delete existing file michael@0: rv = localFile->Delete(false); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 14 failed (Delete returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: printf("Test 14: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 15: Allocate/Deallocate stress test michael@0: //---------------------------------------------------------------- michael@0: michael@0: rv = StressTest(localFile, 15, false); michael@0: if (NS_FAILED(rv)) michael@0: goto exit; michael@0: michael@0: printf("Test 15: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 16: WriteBlocks michael@0: //---------------------------------------------------------------- michael@0: michael@0: rv = blockFile->Open(localFile, 256); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 16: failed (Open returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: char * one = new char[256 * 1]; michael@0: char * two = new char[256 * 2]; michael@0: char * three = new char[256 * 3]; michael@0: char * four = new char[256 * 4]; michael@0: if (!one || !two || !three || !four) { michael@0: printf("Test 16: failed - out of memory\n"); michael@0: rv = NS_ERROR_OUT_OF_MEMORY; michael@0: goto exit; michael@0: } michael@0: michael@0: memset(one, 1, 256); michael@0: memset(two, 2, 256 * 2); michael@0: memset(three, 3, 256 * 3); michael@0: memset(four, 4, 256 * 4); michael@0: michael@0: startBlock = blockFile->AllocateBlocks(1); michael@0: if (startBlock != 0) { michael@0: printf("Test 16: failed (AllocateBlocks(1) failed)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->WriteBlocks(one, startBlock, 1); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 16: failed (WriteBlocks(1) returned 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: startBlock = blockFile->AllocateBlocks(2); michael@0: if (startBlock != 1) { // starting with empy map, this allocation should begin at block 1 michael@0: printf("Test 16: failed (AllocateBlocks(2) failed)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->WriteBlocks(two, startBlock, 2); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 16: failed (WriteBlocks(2) returned 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: startBlock = blockFile->AllocateBlocks(3); michael@0: if (startBlock != 4) { // starting with empy map, this allocation should begin at block 4 michael@0: printf("Test 16: failed (AllocateBlocks(3) failed)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->WriteBlocks(three, startBlock, 3); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 16: failed (WriteBlocks(3) returned 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: startBlock = blockFile->AllocateBlocks(4); michael@0: if (startBlock != 8) { // starting with empy map, this allocation should begin at block 8 michael@0: printf("Test 16: failed (AllocateBlocks(4) failed)\n"); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->WriteBlocks(four, startBlock, 4); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 16: failed (WriteBlocks(4) returned 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Test 16: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 17: ReadBlocks michael@0: //---------------------------------------------------------------- michael@0: michael@0: rv = blockFile->ReadBlocks(one, 0, 1); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 17: failed (ReadBlocks(1) returned 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: // Verify buffer michael@0: for (i = 0; i < 256; i++) { michael@0: if (one[i] != 1) { michael@0: printf("Test 17: failed (verifying buffer 1)\n"); michael@0: rv = NS_ERROR_FAILURE; michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: rv = blockFile->ReadBlocks(two, 1, 2); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 17: failed (ReadBlocks(2) returned 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: // Verify buffer michael@0: for (i = 0; i < 256 * 2; i++) { michael@0: if (two[i] != 2) { michael@0: printf("Test 17: failed (verifying buffer 2)\n"); michael@0: rv = NS_ERROR_FAILURE; michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: rv = blockFile->ReadBlocks(three, 4, 3); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 17: failed (ReadBlocks(3) returned 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: // Verify buffer michael@0: for (i = 0; i < 256 * 3; i++) { michael@0: if (three[i] != 3) { michael@0: printf("Test 17: failed (verifying buffer 3)\n"); michael@0: rv = NS_ERROR_FAILURE; michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: rv = blockFile->ReadBlocks(four, 8, 4); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 17: failed (ReadBlocks(4) returned 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: // Verify buffer michael@0: for (i = 0; i < 256 * 4; i++) { michael@0: if (four[i] != 4) { michael@0: printf("Test 17: failed (verifying buffer 4)\n"); michael@0: rv = NS_ERROR_FAILURE; michael@0: goto exit; michael@0: } michael@0: } michael@0: michael@0: rv = blockFile->Close(); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 17: failed (Close returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Test 17: passed\n"); michael@0: michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 18: ValidateFile (open existing file with blocks allocated) michael@0: //---------------------------------------------------------------- michael@0: rv = blockFile->Open(localFile, 256); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 18: failed (Open returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: rv = blockFile->Close(); michael@0: if (NS_FAILED(rv)) { michael@0: printf("Test 18: failed (Close returned: 0x%.8x)\n", rv); michael@0: goto exit; michael@0: } michael@0: michael@0: printf("Test 18: passed\n"); michael@0: michael@0: //---------------------------------------------------------------- michael@0: // Test 19: WriteBlocks/ReadBlocks stress michael@0: //---------------------------------------------------------------- michael@0: michael@0: rv = StressTest(localFile, 19, false); michael@0: if (NS_FAILED(rv)) michael@0: goto exit; michael@0: michael@0: printf("Test 19: passed\n"); michael@0: michael@0: michael@0: exit: michael@0: michael@0: if (currentDirPath) michael@0: nsMemory::Free(currentDirPath); michael@0: } // this scopes the nsCOMPtrs michael@0: // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM michael@0: if (NS_FAILED(rv)) michael@0: printf("Test failed: 0x%.8x\n", rv); michael@0: michael@0: rv = NS_ShutdownXPCOM(nullptr); michael@0: NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed"); michael@0: michael@0: printf("XPCOM shut down.\n\n"); michael@0: return 0; michael@0: } michael@0: