kerneltest/f32test/server/t_resize.cpp
changeset 0 a41df078684a
child 109 b3a1d9898418
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // f32test\server\t_resize.cpp
       
    15 // This program is designed to test the CFatFileCB::ResizeIndex() method,
       
    16 // especially wrt defect EDNMDON-4J2EWK, which occured when the index was
       
    17 // resized by an extreme amount.
       
    18 // This program must be run on a FAT formatted disk with at least 10Mb free.
       
    19 // RFile::SetSize(TInt aSize)
       
    20 // 
       
    21 //
       
    22 
       
    23 #include <e32test.h>
       
    24 #include <f32file.h>
       
    25 #include <hal.h>
       
    26 #include "t_server.h"
       
    27 
       
    28 GLDEF_D RTest test(_L("T_RESIZE"));
       
    29 
       
    30 // const TInt KBrutusUidValue=0x09080001;  	/* Never used */
       
    31 // const TInt KWinsUidValue=0x00000001;		/* Never used */
       
    32 const TInt K1K = 1 << 10;						// 1K
       
    33 const TInt K4K = 4 * K1K;
       
    34 const TInt K1Mb = 1 << 20;
       
    35 const TInt KBigFileSize = 10 * K1Mb;			// 10Mb
       
    36 const TInt KSmallFileSize = 10 * K1K;
       
    37 const TInt KFillBufLength = K1K;
       
    38 const TInt KNumberLength = 8;
       
    39 const TInt KNumbersPerFillBuf = KFillBufLength / KNumberLength;
       
    40 
       
    41 LOCAL_C TBool IsDiskValid(TInt aDrive);
       
    42 LOCAL_C void FillBuf(TDes8 &aBuf, TInt aStart);
       
    43 
       
    44 GLDEF_C void CallTestsL()
       
    45 	{
       
    46 //
       
    47 // Test with drive nearly full
       
    48 //
       
    49 	CTrapCleanup* cleanup;						// create cleanup stack
       
    50 	cleanup = CTrapCleanup::New();
       
    51  	__UHEAP_MARK;
       
    52 
       
    53 	test.Title();
       
    54 	test.Start(_L("Starting tests"));
       
    55 
       
    56 	test.Next(_L("Connecting to file server."));
       
    57 	TInt r;
       
    58 	r = TheFs.Connect();
       
    59 	test(r == KErrNone);
       
    60 
       
    61 	if ( !gDriveToTest.IsLower() )
       
    62 		{
       
    63 		gDriveToTest.LowerCase();
       
    64 		}
       
    65 
       
    66 	TInt gDriveNumber;	// current drive number
       
    67 	test((r = RFs::CharToDrive(gDriveToTest, gDriveNumber)) == KErrNone);
       
    68 
       
    69 	if (IsDiskValid(gDriveNumber))
       
    70 		{
       
    71 		// Overflows occur because iSeekIndex is 128 elements long.
       
    72 
       
    73 		// ASSUMES CLUSTER SIZE IS 512 BYTES
       
    74 
       
    75 		// 1: Create a 10Mb file and resize it to 10k.
       
    76 
       
    77 		// A 10Mb file will create force each member of CFatFileCB::iSeekIndex to
       
    78 		// mark the start of 2^8 blocks (512 * 128 * 2^8 = 2^9 * 2^7 * 2^8 = 2^24 = 16777216)
       
    79 		// A 10K file has an iSeekIndex with granularity 2^0 = 1 cluster.
       
    80 		// skip half-words = (1<<(iSeekIndexSize-aNewMult))-1 = (1 << (8 - 0)) - 1 = 255.
       
    81 
       
    82 		test.Next(_L("Creating file."));
       
    83 		test.Printf(_L("Writing %08x file.\n"), KBigFileSize);
       
    84 		RFile f;
       
    85 		TFileName fn;
       
    86 		fn.Format(_L("%c:\\resize.tst"), TUint(gDriveToTest));
       
    87 		test((r = f.Create(TheFs, fn, EFileShareExclusive | EFileStream | EFileWrite)) == KErrNone);
       
    88 		TInt i;								// bad for scope under VC
       
    89 		TBuf8<KFillBufLength> buf;			// don't reconstruct for each iteration
       
    90 		for (i = 0; i < KBigFileSize / KNumberLength; i += KNumbersPerFillBuf)
       
    91 			{
       
    92 			if (((i * KNumberLength) % (KBigFileSize / 32)) == 0)
       
    93 				test.Printf(_L("writing to file posn %08x.\n"), i * 8);
       
    94 
       
    95 			FillBuf(buf, i);
       
    96 			test(f.Write(buf) == KErrNone);
       
    97 			}
       
    98 
       
    99 		// Resize the file to 10k.  This should cause CFatFileCB::iSeekIndex to be filled
       
   100 		// with zeroes and not cause a Des16PanicDesIndexOutOfRange.
       
   101 		test.Next(_L("Resizing file downwards.\n"));
       
   102 		test.Printf(_L("Resizing %08x file to %08x.\n"), KBigFileSize, KSmallFileSize);
       
   103 		f.SetSize(KSmallFileSize);
       
   104 
       
   105 		// Re-read the file up to 10k to make sure it is navigated properly.
       
   106 		test.Printf(_L("Checking first %08x bytes are maintained.\n"), KSmallFileSize);
       
   107 		TInt startPos = 0;
       
   108 		f.Seek(ESeekStart, startPos);
       
   109 		TBuf8<KFillBufLength> buf2;			// don't reconstruct for each iteration
       
   110 		for (i = 0; i < KSmallFileSize / KNumberLength; i += KNumbersPerFillBuf)
       
   111 			{
       
   112 			test(f.Read(buf) == KErrNone);
       
   113 			test(buf.Length() == KFillBufLength);
       
   114 			FillBuf(buf2, i);
       
   115 			test(buf2.Compare(buf) == 0);
       
   116 			}
       
   117 
       
   118 		// 2: Resize the 10K file to 10Mb.
       
   119 		//
       
   120 		// iSeekIndex will be cleared because the resize loop is never executed.
       
   121 
       
   122 		// TUint16* newVal=(TUint16*)ptr;
       
   123 		// TInt step=1<<(aNewMult-iSeekIndexSize);	// 256
       
   124 		// ptr+=step-1;								// ptr := &(*iSeekIndex[255])
       
   125 		// while(ptr<ptrEnd && newVal<newValEnd)	// ptr > ptrEnd on first iteration
       
   126 		// 	{
       
   127 		// 	*newVal=*ptr;
       
   128 		// 	newVal++;
       
   129 		// 	ptr+=step;
       
   130 		// 	}
       
   131 		// while(newVal<ptrEnd)					// newVal == ptr on first iteration
       
   132 		// 	*newVal++=0;						// just zero entire array
       
   133 
       
   134 		test.Next(_L("Resizing file upwards.\n"));
       
   135 		test.Printf(_L("Resizing %08x file to %08x."), KSmallFileSize, KBigFileSize);
       
   136 		test(f.SetSize(KBigFileSize) == KErrNone);
       
   137 		f.Seek(ESeekStart, startPos);
       
   138 		for (i = 0; i < KBigFileSize / KNumberLength; i += KNumbersPerFillBuf)
       
   139 			{
       
   140 			if (((i * KNumberLength) % (KBigFileSize / 32)) == 0)
       
   141 				test.Printf(_L("reading from file posn %08x.\n"), i * 8);
       
   142 
       
   143 			test(f.Read(buf) == KErrNone);
       
   144 			test(buf.Length() == KFillBufLength);
       
   145 
       
   146 			if (i < (K4K / KNumberLength))
       
   147 				{
       
   148 				FillBuf(buf2, i);
       
   149 				test(buf.Compare(buf2) == 0);
       
   150 				}
       
   151 			}
       
   152 		f.Close();
       
   153 		test( TheFs.Delete(fn) == KErrNone );
       
   154 		}	// if (IsDiskValid(gDriveNumber))
       
   155 
       
   156 //	TheFs.Close();	/* TheFs is being accessed by t_main's E32MAIN() after the test is complete. */
       
   157 
       
   158 	test.End();
       
   159 	test.Close();
       
   160 
       
   161 	__UHEAP_MARKEND;
       
   162 	delete cleanup;
       
   163 	}
       
   164 
       
   165 LOCAL_C TBool IsDiskValid(TInt aDrive)
       
   166 // Returns ETrue if aDrive is a FAT formatted disk with KBigFileSize bytes free,
       
   167 // EFalse otherwise.
       
   168 	{
       
   169 	TInt r;
       
   170 
       
   171 	TInt isFat, isValid;
       
   172     TInt machUid;
       
   173     r=HAL::Get(HAL::EMachineUid,machUid);
       
   174     test(r==KErrNone);
       
   175 //	test.Printf(_L("machUid = %08x.\n"), machUid);
       
   176 
       
   177 	TBuf<16> fsName;							// _?_ length
       
   178         
       
   179     r = TheFs.FileSystemName(fsName, aDrive);
       
   180     test(r == KErrNone || r == KErrNotFound);
       
   181 	test.Printf(_L("fsName = \"%S\".\n"), &fsName);
       
   182 
       
   183 	if (machUid == HAL::EMachineUid_Brutus)
       
   184 		{
       
   185 		isFat = (fsName.CompareF(_L("Local")) == 0);
       
   186 		}
       
   187 	else
       
   188 		{
       
   189 		isFat = (fsName.CompareF(_L("Fat")) == 0);
       
   190 		}
       
   191 
       
   192 	test.Printf(_L("isFat = %x.\n"), isFat);
       
   193 	if (! isFat)
       
   194 		{
       
   195 		isValid = EFalse;
       
   196 		}
       
   197 	else
       
   198 		{
       
   199 		TVolumeInfo vi;
       
   200 		test((r = TheFs.Volume(vi, aDrive)) == KErrNone);
       
   201 		test.Printf(_L("vi.iFree = %ld\n"), vi.iFree);
       
   202 		isValid = (vi.iFree >= TInt64(KBigFileSize));
       
   203 		}
       
   204 
       
   205 	if (! isValid)
       
   206 		{
       
   207 		test.Printf(_L("IsDiskValid: Skipped because drive %d is not a valid FAT volume (with 10Mb free).\n"), aDrive);
       
   208 		}
       
   209 
       
   210 	return isValid;
       
   211 	}
       
   212 
       
   213 LOCAL_C void FillBuf(TDes8 &aBuf, TInt aStart)
       
   214 // Fills aBuf with a list of ascending 8 digit numbers.
       
   215 // Assumes aBuf.MaxLength() is divisible by 8.
       
   216 	{
       
   217 	aBuf.Zero();
       
   218 	while (aBuf.Length() < aBuf.MaxLength())
       
   219 		{
       
   220 		aBuf.AppendFormat(_L8("%08x"), aStart++);
       
   221 		}
       
   222 	}