os/kernelhwsrv/kerneltest/f32test/server/t_resize.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 	}