os/persistentdata/persistentstorage/store/TFILE/t_storfcomp.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200 (2014-06-10)
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1998-2010 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 "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
//
sl@0
    15
sl@0
    16
#include <s32file.h>
sl@0
    17
#include <e32test.h>
sl@0
    18
#include <e32math.h>
sl@0
    19
sl@0
    20
const TInt KTestCleanupStack=0x20;
sl@0
    21
sl@0
    22
// This is a path specification and should not be used as is
sl@0
    23
_LIT(KFileLocationSpec, "Z:\\STOR-TST\\T_COMPACT.DAT");
sl@0
    24
_LIT(KResultsFile,"RESULTS_%d.TXT");
sl@0
    25
sl@0
    26
static TFileName TheResultsFile;
sl@0
    27
static TBool AllTests=ETrue;
sl@0
    28
static TInt Iterations=10000;
sl@0
    29
static TInt DataVolume=160;
sl@0
    30
static TInt CompactFrequency=40;
sl@0
    31
sl@0
    32
class RLog
sl@0
    33
	{
sl@0
    34
public:
sl@0
    35
	void CreateL(RFs& aFs, const TDesC& aFile);
sl@0
    36
	void Close();
sl@0
    37
	void PrintL(const char* aFormat, ...);
sl@0
    38
private:
sl@0
    39
	RFileWriteStream iLog;
sl@0
    40
	};
sl@0
    41
sl@0
    42
LOCAL_D CTrapCleanup* TheTrapCleanup;
sl@0
    43
LOCAL_D RTest test(_L("t_storfcomp"));
sl@0
    44
LOCAL_D RFs TheFs;
sl@0
    45
LOCAL_D RLog TheLog;
sl@0
    46
sl@0
    47
class StopWatch
sl@0
    48
	{
sl@0
    49
public:
sl@0
    50
	void Start();
sl@0
    51
	TUint Stop();
sl@0
    52
private:
sl@0
    53
	TTime iTime;
sl@0
    54
	};
sl@0
    55
sl@0
    56
void StopWatch::Start()
sl@0
    57
	{
sl@0
    58
	iTime.UniversalTime();
sl@0
    59
	}
sl@0
    60
sl@0
    61
TUint StopWatch::Stop()
sl@0
    62
	{
sl@0
    63
 	TTime t;
sl@0
    64
 	t.UniversalTime();
sl@0
    65
 	TInt64 i = ((t.MicroSecondsFrom(iTime).Int64()) + 500)/1000;
sl@0
    66
 	return I64LOW(i);
sl@0
    67
	}
sl@0
    68
sl@0
    69
StopWatch CompactSW;
sl@0
    70
sl@0
    71
void CompactL(CFileStore& aStore)
sl@0
    72
//
sl@0
    73
// Compact the file and record the stats
sl@0
    74
//
sl@0
    75
	{
sl@0
    76
	aStore.CommitL();
sl@0
    77
	TInt startSize;
sl@0
    78
	User::LeaveIfError(aStore.File().Size(startSize));
sl@0
    79
	CompactSW.Start();
sl@0
    80
	TInt wasted = aStore.CompactL();
sl@0
    81
	aStore.CommitL();
sl@0
    82
	TUint ms = CompactSW.Stop();
sl@0
    83
	TInt endSize;
sl@0
    84
	User::LeaveIfError(aStore.File().Size(endSize));
sl@0
    85
	TheLog.PrintL("%d\t%d\t%d\t%u\n",startSize, endSize, wasted, ms);
sl@0
    86
	}
sl@0
    87
sl@0
    88
void ReclaimCompactL(CFileStore& aStore, TInt aTrigger)
sl@0
    89
//
sl@0
    90
// Reclaim the file and compact on trigger
sl@0
    91
//
sl@0
    92
	{
sl@0
    93
	TInt startSize;
sl@0
    94
	User::LeaveIfError(aStore.File().Size(startSize));
sl@0
    95
	CompactSW.Start();
sl@0
    96
	TBool compacted = EFalse;
sl@0
    97
	if (aTrigger == 0 || aStore.ReclaimL() * 100 > startSize * aTrigger)
sl@0
    98
		{
sl@0
    99
		aStore.CompactL();
sl@0
   100
		aStore.CommitL();
sl@0
   101
		compacted = ETrue;
sl@0
   102
		}
sl@0
   103
	TUint ms = CompactSW.Stop();
sl@0
   104
	TInt endSize;
sl@0
   105
	User::LeaveIfError(aStore.File().Size(endSize));
sl@0
   106
	TheLog.PrintL("%s\t%d\t%u\n",compacted ? "Compact" : "Reclaim", startSize - endSize, ms);
sl@0
   107
	}
sl@0
   108
sl@0
   109
void WriteBytesL(RWriteStream& s, TInt aCount)
sl@0
   110
	{
sl@0
   111
	const TInt KBufSize = 512;
sl@0
   112
	TUint8 buf[KBufSize];
sl@0
   113
	while (aCount > KBufSize)
sl@0
   114
		{
sl@0
   115
		s.WriteL(buf, KBufSize);
sl@0
   116
		aCount -= KBufSize;
sl@0
   117
		}
sl@0
   118
	s.WriteL(buf, aCount);
sl@0
   119
	s.CommitL();
sl@0
   120
	}
sl@0
   121
sl@0
   122
TStreamId CreateStreamL(CStreamStore& aStore, TInt aSize)
sl@0
   123
	{
sl@0
   124
	RStoreWriteStream s;
sl@0
   125
	TStreamId id = s.CreateLC(aStore);
sl@0
   126
	WriteBytesL(s, aSize);
sl@0
   127
	CleanupStack::PopAndDestroy(&s);
sl@0
   128
	return id;
sl@0
   129
	}
sl@0
   130
sl@0
   131
TInt Random(TUint aLimit)
sl@0
   132
	{
sl@0
   133
	return Math::Random() % aLimit;
sl@0
   134
	}
sl@0
   135
sl@0
   136
sl@0
   137
TBool AllocationFailure()
sl@0
   138
	{
sl@0
   139
	User::__DbgSetAllocFail(RHeap::EUser,RHeap::EFailNext,1);
sl@0
   140
	TAny* cell = User::Alloc(4);
sl@0
   141
	User::Free(cell);
sl@0
   142
	User::__DbgSetAllocFail(RHeap::EUser,RHeap::ENone,1);
sl@0
   143
	return cell == 0;
sl@0
   144
	}
sl@0
   145
/**
sl@0
   146
@SYMTestCaseID          SYSLIB-STORE-CT-1144
sl@0
   147
@SYMTestCaseDesc	    Tests for CFileStore::CompactL() function
sl@0
   148
@SYMTestPriority 	    High
sl@0
   149
@SYMTestActions  	    Attempt for compaction process on the store.Tests for KErrNone flag
sl@0
   150
@SYMTestExpectedResults Test must not fail
sl@0
   151
@SYMREQ                 REQ0000
sl@0
   152
*/
sl@0
   153
void BasicCompactionTestsL()
sl@0
   154
	{
sl@0
   155
	const TInt KTestCount = 40;
sl@0
   156
	const TInt KTestSize = 50;
sl@0
   157
	TParsePtrC parse(KFileLocationSpec);
sl@0
   158
//
sl@0
   159
	test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1144 "));
sl@0
   160
	CFileStore* store = CPermanentFileStore::ReplaceLC(TheFs, parse.NameAndExt(), EFileRead|EFileWrite);
sl@0
   161
sl@0
   162
	store->SetTypeL(store->Layout());
sl@0
   163
//
sl@0
   164
	TheLog.PrintL("Compact uncommitted empty store\n");
sl@0
   165
	TRAPD(r, store->CompactL());
sl@0
   166
	test (r == KErrNone);
sl@0
   167
//
sl@0
   168
	TheLog.PrintL("Compact committed empty store\n");
sl@0
   169
	r = store->Commit();
sl@0
   170
	test (r == KErrNone);
sl@0
   171
	TRAP(r, store->CompactL());
sl@0
   172
	test (r == KErrNone);
sl@0
   173
//
sl@0
   174
	TheLog.PrintL("Compact empty store with full TOC\n");
sl@0
   175
	TStreamId streams[KTestCount];
sl@0
   176
	TInt i;
sl@0
   177
	for (i = 0; i < KTestCount; ++i)
sl@0
   178
		streams[i] = CreateStreamL(*store, KTestSize);
sl@0
   179
	store->CommitL();
sl@0
   180
	for (i = 0; i < KTestCount; ++i)
sl@0
   181
		store->DeleteL(streams[i]);
sl@0
   182
	store->CommitL();
sl@0
   183
	TRAP(r, store->CompactL());
sl@0
   184
	test (r == KErrNone);
sl@0
   185
//
sl@0
   186
	TheLog.PrintL("Compact empty store with delta TOC\n");
sl@0
   187
	streams[0] = CreateStreamL(*store, KTestSize);
sl@0
   188
	store->CommitL();
sl@0
   189
	store->DeleteL(streams[0]);
sl@0
   190
	store->CommitL();
sl@0
   191
	TRAP(r, store->CompactL());
sl@0
   192
	test (r == KErrNone);
sl@0
   193
//
sl@0
   194
	CleanupStack::PopAndDestroy(store);
sl@0
   195
	}
sl@0
   196
sl@0
   197
/**
sl@0
   198
@SYMTestCaseID          SYSLIB-STORE-CT-1145
sl@0
   199
@SYMTestCaseDesc	    Testing fallback compaction algorithm
sl@0
   200
@SYMTestPriority 	    High
sl@0
   201
@SYMTestActions  	    Tests for compaction process on the store,
sl@0
   202
                        If we have allocation failure we can test that the fallback algorithm is in place
sl@0
   203
@SYMTestExpectedResults Test must not fail
sl@0
   204
@SYMREQ                 REQ0000
sl@0
   205
*/
sl@0
   206
void CompactionAlgorithmTestL()
sl@0
   207
	{
sl@0
   208
	const TInt KTestCount = 200;
sl@0
   209
	const TInt KTestSize = 50;
sl@0
   210
	const TInt KBeyondSuccess = 2;
sl@0
   211
	TInt stopat = KMaxTInt;
sl@0
   212
	TInt bestTime = -1;
sl@0
   213
	TParsePtrC parse(KFileLocationSpec);
sl@0
   214
//
sl@0
   215
	test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1145 "));
sl@0
   216
	TheLog.PrintL("Testing fallback compaction algorithm\n");
sl@0
   217
//
sl@0
   218
	for (TInt failat = 1; failat <= stopat; ++failat)
sl@0
   219
		{
sl@0
   220
		TheLog.PrintL("Fail allocation #%d: ", failat);
sl@0
   221
//
sl@0
   222
		// prepare the store. Leave a single hole at the beginning
sl@0
   223
		CFileStore* store = CPermanentFileStore::ReplaceLC(TheFs, parse.NameAndExt(), EFileRead|EFileWrite);
sl@0
   224
		store->SetTypeL(store->Layout());
sl@0
   225
		TStreamId first = CreateStreamL(*store, KTestSize);
sl@0
   226
		for (TInt i = 1; i < KTestCount; ++i)
sl@0
   227
			CreateStreamL(*store, KTestSize);
sl@0
   228
		store->CommitL();
sl@0
   229
		store->DeleteL(first);
sl@0
   230
		store->CommitL();
sl@0
   231
		//
sl@0
   232
		User::__DbgSetAllocFail(RHeap::EUser,RHeap::EFailNext,failat);
sl@0
   233
		CompactSW.Start();
sl@0
   234
		TRAPD(r, store->CompactL();	store->CommitL();)
sl@0
   235
		TInt ms = CompactSW.Stop();
sl@0
   236
		User::__DbgSetAllocFail(RHeap::EUser,RHeap::ENone,1);
sl@0
   237
		//
sl@0
   238
		if (r != KErrNone)
sl@0
   239
			{
sl@0
   240
			test (bestTime == -1);
sl@0
   241
			TheLog.PrintL("compaction failed\n");
sl@0
   242
			}
sl@0
   243
		else
sl@0
   244
			{
sl@0
   245
			TheLog.PrintL("compaction succeeded in %u ms\n", ms);
sl@0
   246
			if (bestTime == -1)
sl@0
   247
				{
sl@0
   248
				bestTime = ms;
sl@0
   249
				stopat = failat + KBeyondSuccess;		//stop after a few passes after sucsss
sl@0
   250
				}
sl@0
   251
			else if (ms < bestTime)
sl@0
   252
				{
sl@0
   253
				if (ms < bestTime/2)
sl@0
   254
					stopat = failat + KBeyondSuccess;	// new algorithm has kicked in
sl@0
   255
				bestTime = ms;
sl@0
   256
				}
sl@0
   257
			}
sl@0
   258
sl@0
   259
		CleanupStack::PopAndDestroy(store);
sl@0
   260
		}
sl@0
   261
	}
sl@0
   262
sl@0
   263
sl@0
   264
struct TTracker
sl@0
   265
	{
sl@0
   266
	TStreamId iId;
sl@0
   267
	TInt iSize;
sl@0
   268
	};
sl@0
   269
sl@0
   270
CFileStore* InitialiseStoreLC(RArray<TTracker>& aStreams, TInt aDataVolume, TInt aAverageSize)
sl@0
   271
	{
sl@0
   272
	TParsePtrC parse(KFileLocationSpec);	
sl@0
   273
	CFileStore* store = CPermanentFileStore::ReplaceLC(TheFs, parse.NameAndExt(), EFileRead|EFileWrite);
sl@0
   274
	store->SetTypeL(store->Layout());
sl@0
   275
	for (TInt count = Max(1,(aDataVolume + aAverageSize/2)/aAverageSize); count > 0; --count)
sl@0
   276
		{
sl@0
   277
		TInt size;
sl@0
   278
		if (count == 1)
sl@0
   279
			size = aDataVolume;
sl@0
   280
		else
sl@0
   281
			{
sl@0
   282
			size = aDataVolume / count;
sl@0
   283
			TInt spread = Min(aAverageSize, size);
sl@0
   284
			size += Random(spread) - spread/2;
sl@0
   285
			}
sl@0
   286
		TTracker e;
sl@0
   287
		e.iSize = size;
sl@0
   288
		e.iId = CreateStreamL(*store, size);
sl@0
   289
		User::LeaveIfError(aStreams.Append(e));
sl@0
   290
		aDataVolume -= size;
sl@0
   291
		}
sl@0
   292
	store->CommitL();
sl@0
   293
	return store;
sl@0
   294
	}
sl@0
   295
/**
sl@0
   296
@SYMTestCaseID          SYSLIB-STORE-CT-1146
sl@0
   297
@SYMTestCaseDesc	    Tests for compaction on store
sl@0
   298
@SYMTestPriority 	    High
sl@0
   299
@SYMTestActions  	    Tests for CFileStore::CompactL() function
sl@0
   300
@SYMTestExpectedResults Test must not fail
sl@0
   301
@SYMREQ                 REQ0000
sl@0
   302
*/
sl@0
   303
void CompactionTestL(const TInt aIterations, const TInt aDataVolume, const TInt aAverageSize, const TInt aCommitFrequency, const TInt aCompactionFrequency)
sl@0
   304
	{
sl@0
   305
	test.Next(_L(" @SYMTestCaseID:SYSLIB-STORE-CT-1146 "));
sl@0
   306
	TheLog.PrintL("CompactionTest : \n");
sl@0
   307
	TheLog.PrintL("\tIterations:\t%d\n",aIterations);
sl@0
   308
	TheLog.PrintL("\tDataVolume:\t%d\n",aDataVolume);
sl@0
   309
	TheLog.PrintL("\tAverageSize:\t%d\n",aAverageSize);
sl@0
   310
	TheLog.PrintL("\tCommitFrequency:\t%d\n",aCommitFrequency);
sl@0
   311
	TheLog.PrintL("\tCompactionFrequency:\t%d\n\n",aCompactionFrequency);
sl@0
   312
sl@0
   313
	RArray<TTracker> streams(8);
sl@0
   314
	CleanupClosePushL(streams);
sl@0
   315
	CFileStore* store = InitialiseStoreLC(streams, aDataVolume, aAverageSize);
sl@0
   316
	const TInt maxCount = streams.Count() + (streams.Count() / 5);
sl@0
   317
	TInt size = aDataVolume;
sl@0
   318
	const TInt span = aDataVolume / 10;		// +- 10%
sl@0
   319
	for (TInt i = aIterations ; --i >= 0; )
sl@0
   320
		{
sl@0
   321
		TInt from = Random(streams.Count());
sl@0
   322
		TInt to = Random(maxCount);
sl@0
   323
		TInt tfr = to == from ? 0 : Random(streams[from].iSize + 1);
sl@0
   324
		TInt adj = Random(span - 1) - span/2;
sl@0
   325
		if (size > aDataVolume + span/2)
sl@0
   326
			adj -= size - (aDataVolume + span/2);
sl@0
   327
		else if (size < aDataVolume - span/2)
sl@0
   328
			adj += (aDataVolume - span/2) - size;
sl@0
   329
		if (adj < 0)
sl@0
   330
			{
sl@0
   331
			if (adj < tfr - streams[from].iSize)
sl@0
   332
				adj = tfr - streams[from].iSize;
sl@0
   333
			}
sl@0
   334
		TInt fromSize = streams[from].iSize - tfr;
sl@0
   335
		if (adj < 0 || to == from)
sl@0
   336
			fromSize += adj;
sl@0
   337
		if (fromSize > 0)
sl@0
   338
			{
sl@0
   339
			RStoreWriteStream s;
sl@0
   340
			s.ReplaceLC(*store, streams[from].iId);
sl@0
   341
			WriteBytesL(s, fromSize);
sl@0
   342
			CleanupStack::PopAndDestroy(&s);
sl@0
   343
			streams[from].iSize = fromSize;
sl@0
   344
			}
sl@0
   345
sl@0
   346
		if (to != from)
sl@0
   347
			{
sl@0
   348
			if (to < streams.Count())
sl@0
   349
				{
sl@0
   350
				TInt toSize = streams[to].iSize + tfr;
sl@0
   351
				if (adj > 0)
sl@0
   352
					toSize += adj;
sl@0
   353
				RStoreWriteStream s;
sl@0
   354
				s.ReplaceLC(*store, streams[to].iId);
sl@0
   355
				WriteBytesL(s, toSize);
sl@0
   356
				CleanupStack::PopAndDestroy(&s);
sl@0
   357
				streams[to].iSize = toSize;
sl@0
   358
				}
sl@0
   359
			else
sl@0
   360
				{
sl@0
   361
				TInt toSize = tfr;
sl@0
   362
				if (adj > 0)
sl@0
   363
					toSize += adj;
sl@0
   364
				TTracker e;
sl@0
   365
				e.iSize = toSize;
sl@0
   366
				e.iId = CreateStreamL(*store, toSize);
sl@0
   367
				User::LeaveIfError(streams.Append(e));
sl@0
   368
				}
sl@0
   369
			}
sl@0
   370
		if (fromSize <= 0)
sl@0
   371
			{
sl@0
   372
			store->DeleteL(streams[from].iId);
sl@0
   373
			streams.Remove(from);
sl@0
   374
			}
sl@0
   375
		size += adj;
sl@0
   376
//
sl@0
   377
		if (Random(aCommitFrequency) == 0)
sl@0
   378
			{
sl@0
   379
			store->CommitL();
sl@0
   380
			if (aCompactionFrequency <= 0)
sl@0
   381
				ReclaimCompactL(*store, -aCompactionFrequency);
sl@0
   382
			}
sl@0
   383
		if (aCompactionFrequency > 0 && Random(aCompactionFrequency) == 0)
sl@0
   384
			CompactL(*store);
sl@0
   385
		}
sl@0
   386
	CleanupStack::PopAndDestroy(store);
sl@0
   387
	CleanupStack::PopAndDestroy(&streams);
sl@0
   388
	TheLog.PrintL("\nCompactionTestEnd\n\n");
sl@0
   389
	}
sl@0
   390
sl@0
   391
void RLog::CreateL(RFs& aFs, const TDesC& aFile)
sl@0
   392
	{
sl@0
   393
#ifdef __WINS__
sl@0
   394
	User::LeaveIfError(iLog.Replace(aFs, aFile, EFileWrite));
sl@0
   395
#endif
sl@0
   396
	}
sl@0
   397
sl@0
   398
void RLog::Close()
sl@0
   399
	{
sl@0
   400
	iLog.Close();
sl@0
   401
	}
sl@0
   402
sl@0
   403
void RLog::PrintL(const char* aFormat, ...)
sl@0
   404
	{
sl@0
   405
	VA_LIST list;
sl@0
   406
	VA_START(list,aFormat);
sl@0
   407
	TBuf8<256> b;
sl@0
   408
	b.FormatList(_L8(aFormat),list);
sl@0
   409
	VA_END(list);
sl@0
   410
#ifdef __WINS__
sl@0
   411
	iLog.WriteL(b);
sl@0
   412
#endif
sl@0
   413
	TBuf<256> b16;
sl@0
   414
	b16.Copy(b);
sl@0
   415
	test.Printf(_L("%S"),&b16);
sl@0
   416
	}
sl@0
   417
sl@0
   418
void GetOpt()
sl@0
   419
	{
sl@0
   420
	TBuf<256> options;
sl@0
   421
    User::CommandLine(options);
sl@0
   422
	if (options.Length() > 0)
sl@0
   423
		{
sl@0
   424
		AllTests = EFalse;
sl@0
   425
		TLex lex(options);
sl@0
   426
		lex.SkipSpace();
sl@0
   427
		if (lex.Val(DataVolume) == KErrNone)
sl@0
   428
			{
sl@0
   429
			lex.SkipSpace();
sl@0
   430
			if (lex.Val(Iterations) == KErrNone)
sl@0
   431
				{
sl@0
   432
				lex.SkipSpace();
sl@0
   433
				lex.Val(CompactFrequency);
sl@0
   434
				}
sl@0
   435
			}
sl@0
   436
		}
sl@0
   437
	TheResultsFile.Format(KResultsFile,DataVolume);
sl@0
   438
	}
sl@0
   439
sl@0
   440
void testCompactL()
sl@0
   441
	{
sl@0
   442
	GetOpt();
sl@0
   443
	TheLog.CreateL(TheFs, TheResultsFile);
sl@0
   444
	if (AllTests)
sl@0
   445
		{
sl@0
   446
		BasicCompactionTestsL();
sl@0
   447
		if (AllocationFailure())
sl@0
   448
			CompactionAlgorithmTestL();
sl@0
   449
		}
sl@0
   450
	CompactionTestL(Iterations, DataVolume<<10, 300, 5, CompactFrequency);
sl@0
   451
	TheLog.Close();
sl@0
   452
	}
sl@0
   453
sl@0
   454
LOCAL_C void setupTestDirectory()
sl@0
   455
//
sl@0
   456
// Prepare the test directory.
sl@0
   457
//
sl@0
   458
    {
sl@0
   459
	TInt r=TheFs.Connect();
sl@0
   460
	test(r==KErrNone);
sl@0
   461
//
sl@0
   462
	TDriveUnit drive(static_cast<TUint>(RFs::GetSystemDrive()));	
sl@0
   463
	TParse parse;
sl@0
   464
	parse.Set(drive.Name(), &KFileLocationSpec, NULL);
sl@0
   465
	
sl@0
   466
	r=TheFs.MkDir(parse.DriveAndPath());
sl@0
   467
	test(r==KErrNone||r==KErrAlreadyExists);
sl@0
   468
	r=TheFs.SetSessionPath(parse.DriveAndPath());
sl@0
   469
	test(r==KErrNone);
sl@0
   470
	}
sl@0
   471
sl@0
   472
LOCAL_C void setupCleanup()
sl@0
   473
//
sl@0
   474
// Initialise the cleanup stack.
sl@0
   475
//
sl@0
   476
    {
sl@0
   477
	TheTrapCleanup=CTrapCleanup::New();
sl@0
   478
	test(TheTrapCleanup!=NULL);
sl@0
   479
	TRAPD(r,\
sl@0
   480
		{\
sl@0
   481
		for (TInt i=KTestCleanupStack;i>0;i--)\
sl@0
   482
			CleanupStack::PushL((TAny*)0);\
sl@0
   483
		CleanupStack::Pop(KTestCleanupStack);\
sl@0
   484
		});
sl@0
   485
	test(r==KErrNone);
sl@0
   486
	}
sl@0
   487
sl@0
   488
LOCAL_C void DeleteDataFile(const TDesC& aFullName)
sl@0
   489
	{
sl@0
   490
	RFs fsSession;
sl@0
   491
	TInt err = fsSession.Connect();
sl@0
   492
	if(err == KErrNone)
sl@0
   493
		{
sl@0
   494
		TEntry entry;
sl@0
   495
		if(fsSession.Entry(aFullName, entry) == KErrNone)
sl@0
   496
			{
sl@0
   497
			RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
sl@0
   498
			err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
sl@0
   499
			if(err != KErrNone)
sl@0
   500
				{
sl@0
   501
				RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
sl@0
   502
				}
sl@0
   503
			err = fsSession.Delete(aFullName);
sl@0
   504
			if(err != KErrNone)
sl@0
   505
				{
sl@0
   506
				RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
sl@0
   507
				}
sl@0
   508
			}
sl@0
   509
		fsSession.Close();
sl@0
   510
		}
sl@0
   511
	else
sl@0
   512
		{
sl@0
   513
		RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
sl@0
   514
		}
sl@0
   515
	}
sl@0
   516
sl@0
   517
class CTestStreamStore : public CStreamStore
sl@0
   518
	{
sl@0
   519
public:
sl@0
   520
	static CTestStreamStore* NewL();
sl@0
   521
	virtual ~CTestStreamStore();
sl@0
   522
sl@0
   523
private:
sl@0
   524
	CTestStreamStore();
sl@0
   525
	virtual MStreamBuf* DoReadL(TStreamId anId) const;
sl@0
   526
	virtual MStreamBuf* DoCreateL(TStreamId& anId);
sl@0
   527
	
sl@0
   528
	};
sl@0
   529
sl@0
   530
CTestStreamStore* CTestStreamStore::NewL()
sl@0
   531
	{
sl@0
   532
	return new (ELeave) CTestStreamStore; 
sl@0
   533
	}
sl@0
   534
sl@0
   535
CTestStreamStore::~CTestStreamStore()
sl@0
   536
	{
sl@0
   537
	}
sl@0
   538
sl@0
   539
CTestStreamStore::CTestStreamStore()
sl@0
   540
	{
sl@0
   541
	}
sl@0
   542
sl@0
   543
MStreamBuf* CTestStreamStore::DoReadL(TStreamId) const
sl@0
   544
	{
sl@0
   545
	return NULL;
sl@0
   546
	}
sl@0
   547
sl@0
   548
MStreamBuf* CTestStreamStore::DoCreateL(TStreamId&)
sl@0
   549
	{
sl@0
   550
	return NULL;
sl@0
   551
	}
sl@0
   552
sl@0
   553
/**
sl@0
   554
@SYMTestCaseID          PDS-STORE-CT-4063
sl@0
   555
@SYMTestCaseDesc        CStreamStore tests.
sl@0
   556
@SYMTestActions         CStreamStore provides couple of virtual methods in its private section:
sl@0
   557
                        DoExtendL(), DoDeleteL(), DoReplaceL(), DoReclaimL().
sl@0
   558
                        They are no-ops and are expected to be overriden in the class derived from
sl@0
   559
                        CStreamStore. Their implementations leave with KErrNotsupported. 
sl@0
   560
                        The test uses a class derived from CStreamStore, which class does not implement
sl@0
   561
                        virtuals mentioned above. These virtuals should leave with KErrNotSupported when called.
sl@0
   562
@SYMTestPriority        High
sl@0
   563
@SYMTestExpectedResults Test must not fail
sl@0
   564
*/
sl@0
   565
void TestStreamStoreVirtualsL()
sl@0
   566
	{
sl@0
   567
	CTestStreamStore* store = CTestStreamStore::NewL();
sl@0
   568
	TRAPD(err, store->CommitL());
sl@0
   569
	test(err == KErrNone);
sl@0
   570
	TRAP(err, store->RevertL());
sl@0
   571
	test(err == KErrNotSupported);
sl@0
   572
	TRAP(err, store->ReclaimL());
sl@0
   573
	test(err == KErrNotSupported);
sl@0
   574
	TRAP(err, store->CompactL());
sl@0
   575
	test(err == KErrNotSupported);
sl@0
   576
	TRAP(err, store->DeleteL(TStreamId(1)));
sl@0
   577
	test(err == KErrNotSupported);
sl@0
   578
	delete store;
sl@0
   579
	}
sl@0
   580
sl@0
   581
//
sl@0
   582
// Test permanent file store.
sl@0
   583
//
sl@0
   584
GLDEF_C TInt E32Main()
sl@0
   585
    {
sl@0
   586
	test.Title();
sl@0
   587
	setupTestDirectory();
sl@0
   588
	setupCleanup();
sl@0
   589
	__UHEAP_MARK;
sl@0
   590
//
sl@0
   591
	test.Start(_L("Test compaction"));
sl@0
   592
	TRAPD(r,testCompactL());
sl@0
   593
	test(r==KErrNone);
sl@0
   594
	test.Next(_L("@SYMTestCaseID:PDS-STORE-CT-4063: Test CStreamStore virtuals"));
sl@0
   595
	TRAP(r, TestStreamStoreVirtualsL())
sl@0
   596
	test(r==KErrNone);
sl@0
   597
	
sl@0
   598
	//deletion of data files must be before call to .End() - DEF047652
sl@0
   599
	TDriveUnit drive(static_cast<TUint>(RFs::GetSystemDrive()));	
sl@0
   600
	TParse parse;
sl@0
   601
	parse.Set(drive.Name(), &KFileLocationSpec, NULL);
sl@0
   602
	::DeleteDataFile(parse.FullName());
sl@0
   603
sl@0
   604
	test.End();
sl@0
   605
//
sl@0
   606
	__UHEAP_MARKEND;
sl@0
   607
sl@0
   608
	delete TheTrapCleanup;
sl@0
   609
	TheFs.Close();
sl@0
   610
	test.Close();
sl@0
   611
	return 0;
sl@0
   612
    }
sl@0
   613