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