1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/loggingservices/eventlogger/test/src/t_logutil2.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,936 @@
1.4 +// Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include <bautils.h>
1.20 +#include "t_logutil2.h"
1.21 +
1.22 +//Define "TheTest" variable used in the test cpp files
1.23 +extern RTest TheTest;
1.24 +
1.25 +_LIT(KHelperExeName, "t_LogHiCapHelper.exe");
1.26 +
1.27 +//======================================================================================================
1.28 +
1.29 +#ifdef LOGGING_ENABLED
1.30 +
1.31 +void Log::New()
1.32 + {
1.33 + _LIT(KNewLogText, "===== NEW LOG =====");
1.34 + //
1.35 + RFileLogger logger;
1.36 + TInt ret=logger.Connect();
1.37 + if (ret==KErrNone)
1.38 + {
1.39 + logger.CreateLog(KLogFolder, KLogFileName, EFileLoggingModeOverwrite);
1.40 + logger.Write(KNewLogText);
1.41 + }
1.42 + logger.Close();
1.43 + }
1.44 +
1.45 +void Log::Write(const TDesC& aText)
1.46 + {
1.47 + PruneLogFile();
1.48 +
1.49 + RFileLogger logger;
1.50 + TInt ret=logger.Connect();
1.51 + if (ret==KErrNone)
1.52 + {
1.53 + logger.SetDateAndTime(EFalse,EFalse);
1.54 + logger.CreateLog(KLogFolder, KLogFileName,EFileLoggingModeAppend);
1.55 + TBuf<KLogEngLogBufferSize> buf;
1.56 + TTime now;
1.57 + now.HomeTime();
1.58 + TDateTime dateTime;
1.59 + dateTime = now.DateTime();
1.60 + buf.Format(KTimeFormat,dateTime.Hour(),dateTime.Minute(),dateTime.Second(),dateTime.MicroSecond());
1.61 + buf.AppendFormat(KTextFormat,&aText);
1.62 +
1.63 + logger.Write(buf);
1.64 + }
1.65 +
1.66 + logger.Close();
1.67 + }
1.68 +
1.69 +void Log::WriteFormat(TRefByValue<const TDesC> aFmt, ...)
1.70 + {
1.71 + VA_LIST list;
1.72 + VA_START(list,aFmt);
1.73 +
1.74 + PruneLogFile();
1.75 +
1.76 + TBuf<2*KLogEngLogBufferSize> buf;
1.77 + buf.SetMax();
1.78 + buf.FillZ();
1.79 + TTime now;
1.80 + now.HomeTime();
1.81 + TDateTime dateTime;
1.82 + dateTime = now.DateTime();
1.83 + buf.Format(KTimeFormat,dateTime.Hour(),dateTime.Minute(),dateTime.Second(),dateTime.MicroSecond());
1.84 + buf.AppendFormatList(aFmt, list );
1.85 +
1.86 + RFileLogger logger;
1.87 + TInt ret=logger.Connect();
1.88 + if (ret==KErrNone)
1.89 + {
1.90 + logger.SetDateAndTime(EFalse,EFalse);
1.91 + logger.CreateLog(KLogFolder, KLogFileName,EFileLoggingModeAppend);
1.92 + logger.Write(buf);
1.93 + }
1.94 +
1.95 + logger.Close();
1.96 + }
1.97 +
1.98 +void Log::PruneLogFile()
1.99 + {
1.100 + const TInt KMaxLogSize = 1024 * 500;
1.101 + _LIT(KDriveLetter, "C:\\Logs\\");
1.102 + //
1.103 + TFileName fileName(KDriveLetter);
1.104 + fileName.Append(KLogFolder);
1.105 + fileName.Append(KLogFileName);
1.106 + //
1.107 + RFs fsSession;
1.108 + if (fsSession.Connect() == KErrNone)
1.109 + {
1.110 + TEntry entry;
1.111 + if (fsSession.Entry(fileName, entry) == KErrNone)
1.112 + {
1.113 + // Check size and delete if its too big
1.114 + if (entry.iSize >= KMaxLogSize)
1.115 + fsSession.Delete(fileName); // ignore error
1.116 + }
1.117 + }
1.118 + fsSession.Close();
1.119 + }
1.120 +
1.121 +#endif
1.122 +
1.123 +// Globals
1.124 +GLDEF_D CTrapCleanup* theCleanup;
1.125 +GLDEF_D CActiveScheduler *testScheduler;
1.126 +GLDEF_D RFs theFs;
1.127 +GLDEF_D TFileName theLogName;
1.128 +GLDEF_D RFile theLog;
1.129 +GLDEF_D RLogTestSession theLogServ;
1.130 +
1.131 +//**********************************
1.132 +// CTestActive
1.133 +//**********************************
1.134 +
1.135 +CTestActive::CTestActive(TInt aPriority)
1.136 +: CActive(aPriority)
1.137 + {
1.138 + CActiveScheduler::Add(this);
1.139 + iDelayTime=0;
1.140 + }
1.141 +
1.142 +CTestActive::~CTestActive()
1.143 + {
1.144 + Cancel();
1.145 + }
1.146 +
1.147 +void CTestActive::DoCancel()
1.148 + {
1.149 + TRequestStatus* s=&iStatus;
1.150 + User::RequestComplete(s, KErrNone);
1.151 + }
1.152 +
1.153 +void CTestActive::StartL()
1.154 + {
1.155 + iDelayCompletion=EFalse;
1.156 + iDelayTime=0;
1.157 + iStatus = KRequestPending;
1.158 + SetActive();
1.159 + }
1.160 +
1.161 +void CTestActive::StartL(TInt aDelay)
1.162 + {
1.163 + iDelayCompletion=ETrue;
1.164 + iDelayTime=aDelay;
1.165 + iStatus = KRequestPending;
1.166 + SetActive();
1.167 + }
1.168 +
1.169 +void CTestActive::RunL()
1.170 + {
1.171 + if(iDelayCompletion && iDelayTime)
1.172 + {
1.173 + // Wait for events in other threads to have a go....
1.174 + User::After(iDelayTime);
1.175 + iDelayTime=0;
1.176 + iStoredStatus=iStatus;
1.177 + SetActive();
1.178 + TRequestStatus* s=&iStatus;
1.179 + User::RequestComplete(s, KErrNone);
1.180 + }
1.181 + else
1.182 + {
1.183 + if(iDelayCompletion)
1.184 + iStatus=iStoredStatus;
1.185 +
1.186 + LOGTEXT("CTestActive::RunL() - Stopping the scheduler");
1.187 + CActiveScheduler::Stop();
1.188 + }
1.189 + }
1.190 +
1.191 +//**********************************
1.192 +// CTestTimer
1.193 +//**********************************
1.194 +
1.195 +CTestTimer::CTestTimer()
1.196 +: CTimer(EPriorityLow)
1.197 + {}
1.198 +
1.199 +void CTestTimer::RunL()
1.200 + {
1.201 + LOGTEXT("CTestTimer::RunL() - Stopping the scheduler");
1.202 + CActiveScheduler::Stop();
1.203 + }
1.204 +
1.205 +CTestTimer* CTestTimer::NewL()
1.206 + {
1.207 + CTestTimer* self = new(ELeave) CTestTimer();
1.208 + CleanupStack::PushL(self);
1.209 + self->ConstructL(); // CTimer
1.210 + CActiveScheduler::Add(self);
1.211 + CleanupStack::Pop();
1.212 + return self;
1.213 + }
1.214 +
1.215 +//**********************************
1.216 +// TestUtils
1.217 +//**********************************
1.218 +
1.219 +void TestUtils::Initialize(const TDesC& aName)
1.220 + {
1.221 + TheTest.Title();
1.222 + TheTest.Printf(_L("%S\r\n"), &aName);
1.223 + User::RenameThread(aName);
1.224 + }
1.225 +
1.226 +TBool TestUtils::FileExists(const TDesC& aFile)
1.227 + {
1.228 + TEntry entry;
1.229 + return theFs.Entry(aFile, entry) == KErrNone;
1.230 + }
1.231 +
1.232 +//Loads t_loghihelper process and passes for execution to t_loghihelper "aCommandLineArg" command line.
1.233 +//t_loghihelper will run, execute the command and die, returning the result of the command execution.
1.234 +//TestUtils::ExecuteRemoteL() will leave if error and return the result of the remote cmd execution to the caller.
1.235 +TInt TestUtils::ExecuteRemoteL(const TDesC& aCommandLineArg)
1.236 + {
1.237 + RProcess process;
1.238 + LEAVE_IF_ERROR(process.Create(KHelperExeName, aCommandLineArg));
1.239 +
1.240 + TRequestStatus status;
1.241 + process.Logon(status);
1.242 + process.Resume();
1.243 +
1.244 + User::WaitForRequest(status);
1.245 + TInt exitReason = process.ExitReason();
1.246 +
1.247 + process.Close();
1.248 + LEAVE_IF_ERROR(exitReason);
1.249 +
1.250 + return exitReason;
1.251 + }
1.252 +
1.253 +//Runs t_loghihelper. t_loghihelper will execute the "delete LogEng database" command.
1.254 +//The "delete LogEng database" is a complex operation. The request is sent via the backup server
1.255 +//which will send a request to the LogEng server to release the LogEng database file locks and close the file.
1.256 +//After that the database will be deleted.
1.257 +//In the same call the LogEng server will restarted and the LogEng server will re-create the database during the
1.258 +//server startup.
1.259 +//
1.260 +//If "aCloseBeforeDelete" flag is false, then the database wil be only deleted.
1.261 +//The default value of "aCloseBeforeDelete" is true: the database will be closed, deleted and re-created.
1.262 +//But some of the LogEng tests create a CBaBackupSessionWrapper object and call CloseFileL() with the logeng
1.263 +//database name as a parameter. In this case, if another process, as t_loghicaphelper for example, attempts
1.264 +//to call CloseFileL() with the same file name as a parameter, then the caller will get KErrServerBusy error.
1.265 +//See how CBaBackupSessionWrapper::CloseFileL() is implemented on the server side.
1.266 +void TestUtils::DeleteDatabaseL(TBool aCloseBeforeDelete)
1.267 + {
1.268 + _LIT(KCmdLine1, "-delete_db1");
1.269 + _LIT(KCmdLine2, "-delete_db2");
1.270 + (void)ExecuteRemoteL(aCloseBeforeDelete ? KCmdLine1 : KCmdLine2);
1.271 + }
1.272 +
1.273 +//Runs t_loghihelper. t_loghihelper will check and return whether the LogEng database is open or not.
1.274 +TBool TestUtils::IsDatabaseOpenL()
1.275 + {
1.276 + _LIT(KCmdLine, "-db_is_open");
1.277 + TInt result = ExecuteRemoteL(KCmdLine);
1.278 + return result != 0;
1.279 + }
1.280 +
1.281 +//Runs t_loghihelper. t_loghihelper will add an event type to the LogEng database.
1.282 +void TestUtils::AddEventTypeL()
1.283 + {
1.284 + _LIT(KCmdLine, "-add_event_type");
1.285 + (void)ExecuteRemoteL(KCmdLine);
1.286 + }
1.287 +
1.288 +//Runs t_loghihelper. t_loghihelper will add an event to the LogEng database.
1.289 +TInt TestUtils::AddEventL()
1.290 + {
1.291 + _LIT(KCmdLine, "-add_event");
1.292 + return ExecuteRemoteL(KCmdLine);
1.293 + }
1.294 +
1.295 +//Runs t_loghihelper. t_loghihelper will add events to the LogEng database.
1.296 +void TestUtils::AddViewTestEventsL()
1.297 + {
1.298 + _LIT(KCmdLine, "-add_view_test_events");
1.299 + (void)ExecuteRemoteL(KCmdLine);
1.300 + }
1.301 +
1.302 +//Runs t_loghihelper. t_loghihelper will return the size of the LogEng database.
1.303 +TInt TestUtils::DatabaseSizeL()
1.304 + {
1.305 + _LIT(KCmdLine, "-db_size");
1.306 + return ExecuteRemoteL(KCmdLine);
1.307 + }
1.308 +
1.309 +//Runs t_loghihelper. t_loghihelper will replace the LogEng database with a corrupted database (for testing purposes).
1.310 +//The LogEng server will be stopped before that. The function can be used only in debug mode.
1.311 +#ifdef _DEBUG
1.312 +void TestUtils::CopyCorruptDbL()
1.313 + {
1.314 +
1.315 + _LIT(KCmdLine, "-copy_corrupt");
1.316 + (void)ExecuteRemoteL(KCmdLine);
1.317 + }
1.318 +
1.319 +//Runs t_loghihelper. t_loghihelper will replace the LogEng database with a corrupted database (for testing purposes).
1.320 +//The LogEng server will be stopped before that. The function can be used only in debug mode.
1.321 +void TestUtils::CopyCorruptDamagedDbL()
1.322 + {
1.323 +
1.324 + _LIT(KCmdLine, "-copy_corrupt_damaged");
1.325 + (void)ExecuteRemoteL(KCmdLine);
1.326 + }
1.327 +
1.328 +//Runs t_loghihelper. t_loghihelper will replace the LogEng database with an old format database
1.329 +//(no SimId column, phone number length is different). The LogEng server will be stopped before that.
1.330 +//The function can be used only in debug mode.
1.331 +void TestUtils::CopyOldDbL()
1.332 + {
1.333 + _LIT(KCmdLine, "-copy_old");
1.334 + (void)ExecuteRemoteL(KCmdLine);
1.335 + }
1.336 +#else //_DEBUG
1.337 +void TestUtils::CopyCorruptDbL()
1.338 + {
1.339 + TheTest.Printf(_L("TestUtils::CopyCorruptDbL() has a meaningfull implementation in debug builds only.\n"));
1.340 + }
1.341 +
1.342 +void TestUtils::CopyCorruptDamagedDbL()
1.343 + {
1.344 + TheTest.Printf(_L("TestUtils::CopyCorruptDamagedDbL() has a meaningfull implementation in debug builds only.\n"));
1.345 + }
1.346 +
1.347 +void TestUtils::CopyOldDbL()
1.348 + {
1.349 + TheTest.Printf(_L("TestUtils::CopyOldDbL() has a meaningfull implementation in debug builds only.\n"));
1.350 + }
1.351 +
1.352 +#endif//_DEBUG
1.353 +
1.354 +//Runs t_loghihelper. t_loghihelper will re-create the LogEng database and check whether LogEng client can connect to the server.
1.355 +void TestUtils::TestInvalidSchemaL()
1.356 + {
1.357 + _LIT(KCmdLine, "-invalid_schema");
1.358 + (void)ExecuteRemoteL(KCmdLine);
1.359 + }
1.360 +
1.361 +//Runs t_loghihelper. t_loghihelper checks whether the phone number mathcing is enabled.
1.362 +TBool TestUtils::MatchingEnabledL()
1.363 + {
1.364 + _LIT(KCmdLine, "-is_matching_enabled");
1.365 + return ExecuteRemoteL(KCmdLine) != 0;
1.366 + }
1.367 +
1.368 +//Creates HBufC object and puts it on the cleanup stack.
1.369 +//The buffer will be filled with (' ' + pos) characters, where pos is the character position in the buffer.
1.370 +HBufC* TestUtils::CreateBufLC(TInt aLength)
1.371 + {
1.372 + HBufC* buf = HBufC::NewLC(aLength);
1.373 + TPtr ptr = buf->Des();
1.374 + for(TInt pos=0;pos<aLength;++pos)
1.375 + {
1.376 + ptr.Append(TChar(' ' + pos));
1.377 + }
1.378 + return buf;
1.379 + }
1.380 +
1.381 +//Returns whether the two filters are equal or not.
1.382 +TBool TestUtils::FiltersEqual(const CLogFilter& aFilter1, const CLogFilter& aFilter2)
1.383 + {
1.384 + return aFilter1.EventType() == aFilter2.EventType() &&
1.385 + aFilter1.RemoteParty() == aFilter2.RemoteParty() &&
1.386 + aFilter1.Direction() == aFilter2.Direction() &&
1.387 + aFilter1.DurationType() == aFilter2.DurationType() &&
1.388 + aFilter1.Status() == aFilter2.Status() &&
1.389 + aFilter1.Contact() == aFilter2.Contact() &&
1.390 + aFilter1.Number() == aFilter2.Number()
1.391 +#ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM
1.392 + &&
1.393 + aFilter1.SimId() == aFilter2.SimId()
1.394 +#endif
1.395 + ;
1.396 + }
1.397 +
1.398 +//Creates HBufC8 object and puts it on the cleanup stack.
1.399 +//The buffer will be filled with (' ' + pos % (0xff - 32)) characters, where pos is the character position in the buffer.
1.400 +HBufC8* TestUtils::CreateBuf8LC(TInt aLength)
1.401 + {
1.402 + HBufC8* buf = HBufC8::NewLC(aLength);
1.403 + TPtr8 ptr = buf->Des();
1.404 + for(TInt pos=0;pos<aLength;++pos)
1.405 + {
1.406 + ptr.Append(TChar(' ' + pos % (0xff - 32)));
1.407 + }
1.408 + return buf;
1.409 + }
1.410 +
1.411 +//Returns whether the two events are equal or not.
1.412 +TBool TestUtils::EventsEqual(const CLogEvent& aEvent1, const CLogEvent& aEvent2)
1.413 + {
1.414 + return aEvent1.Id() == aEvent2.Id() &&
1.415 + aEvent1.EventType() == aEvent2.EventType() &&
1.416 + aEvent1.RemoteParty() == aEvent2.RemoteParty() &&
1.417 + aEvent1.Direction() == aEvent2.Direction() &&
1.418 + aEvent1.Time() == aEvent2.Time() &&
1.419 + aEvent1.DurationType() == aEvent2.DurationType() &&
1.420 + aEvent1.Duration() == aEvent2.Duration() &&
1.421 + aEvent1.Status() == aEvent2.Status() &&
1.422 + aEvent1.Subject() == aEvent2.Subject() &&
1.423 + aEvent1.Number() == aEvent2.Number() &&
1.424 + aEvent1.Contact() == aEvent2.Contact() &&
1.425 + aEvent1.Link() == aEvent2.Link() &&
1.426 + aEvent1.Description() == aEvent2.Description() &&
1.427 + aEvent1.Data() == aEvent2.Data()
1.428 +#ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM
1.429 + &&
1.430 + aEvent1.SimId() == aEvent2.SimId()
1.431 +#endif
1.432 + ;
1.433 + }
1.434 +
1.435 +//Returns whether the two event types are equal or not.
1.436 +TBool TestUtils::TypesEqual(const CLogEventType& aType1, const CLogEventType& aType2)
1.437 + {
1.438 + return aType1.Uid() == aType2.Uid() &&
1.439 + aType1.Description() == aType2.Description() &&
1.440 + aType1.LoggingEnabled() == aType2.LoggingEnabled();
1.441 + }
1.442 +
1.443 +//Waits for a key to be pressed.
1.444 +TBool TestUtils::WaitForKeyL(TTimeIntervalMicroSeconds32 aDelay, TKeyCode& aKeyCode)
1.445 + {
1.446 + TEST(TheTest.Console() != NULL);
1.447 +
1.448 + // Create timer
1.449 + CTestTimer* timer = CTestTimer::NewL();
1.450 + CleanupStack::PushL(timer);
1.451 + timer->After(aDelay);
1.452 +
1.453 + CTestActive* wait = new(ELeave)CTestActive;
1.454 + CleanupStack::PushL(wait);
1.455 + wait->StartL();
1.456 +
1.457 + // Wait for key press
1.458 + TheTest.Console()->Read(wait->iStatus);
1.459 + CActiveScheduler::Start();
1.460 +
1.461 + // If timer still active a key was pressed
1.462 + TBool keyPressed = timer->IsActive();
1.463 +
1.464 + if (keyPressed)
1.465 + {
1.466 + // Get the key pressed
1.467 + aKeyCode = TheTest.Console()->KeyCode();
1.468 +
1.469 + // Cancel timer
1.470 + timer->Cancel();
1.471 + }
1.472 + else
1.473 + {
1.474 + // Cancel wait for character
1.475 + TheTest.Console()->ReadCancel();
1.476 + User::WaitForRequest(wait->iStatus);
1.477 + }
1.478 +
1.479 + CleanupStack::PopAndDestroy(2); // wait, timer
1.480 + return keyPressed;
1.481 + }
1.482 +
1.483 +//Used for LogEng server side heap failure testing.
1.484 +#ifdef _DEBUG
1.485 +void TestUtils::SetLogServHeapFailureL(RHeap::TAllocFail aType, TInt aRate)
1.486 + {
1.487 + //this function doesn't have any effect on UREL builds
1.488 + //get rid of warnings in release builds
1.489 + aType = aType;
1.490 + aRate = aRate;
1.491 + if (!theLogServ.Handle())
1.492 + LEAVE_IF_ERROR(theLogServ.Connect());
1.493 +
1.494 + TIpcArgs ipcArgs(aType,aRate) ;
1.495 + LEAVE_IF_ERROR(theLogServ.Send(ELogSetHeapFail, ipcArgs));
1.496 + }
1.497 +#else
1.498 +void TestUtils::SetLogServHeapFailureL(RHeap::TAllocFail, TInt)
1.499 + {
1.500 + }
1.501 +#endif//_DEBUG
1.502 +
1.503 +//**********************************
1.504 +// CLogViewChangeObserver
1.505 +//**********************************
1.506 +
1.507 +CLogViewChangeObserver* CLogViewChangeObserver::NewLC()
1.508 + {
1.509 + CLogViewChangeObserver* self = new(ELeave) CLogViewChangeObserver();
1.510 + CleanupStack::PushL(self);
1.511 + return self;
1.512 + }
1.513 +
1.514 +CLogViewChangeObserver::~CLogViewChangeObserver()
1.515 + {
1.516 + Cancel();
1.517 + delete iChanges;
1.518 + }
1.519 +
1.520 +CLogViewChangeObserver::CLogViewChangeObserver()
1.521 +: CActive(EPriorityStandard)
1.522 + {
1.523 + CActiveScheduler::Add(this);
1.524 + }
1.525 +
1.526 +
1.527 +CLogChangeDefinition* CLogViewChangeObserver::WaitForChangesLC(TStopType aType, TInt aCount)
1.528 + {
1.529 + __ASSERT_ALWAYS(!iSchedulerStarted, User::Invariant());
1.530 + Reset();
1.531 + //
1.532 + iExpectedChangeCount = aCount;
1.533 + iType = aType;
1.534 + if (aType != EStopOnChanges)
1.535 + SetActive();
1.536 + //
1.537 + iSchedulerStarted = ETrue;
1.538 + CActiveScheduler::Start();
1.539 + iSchedulerStarted = EFalse;
1.540 + //
1.541 + CLogChangeDefinition* ret = iChanges;
1.542 + TEST(iChanges != NULL);
1.543 + iChanges = NULL;
1.544 + CleanupStack::PushL(ret);
1.545 + return ret;
1.546 + }
1.547 +
1.548 +CLogChangeDefinition* CLogViewChangeObserver::WaitForChangesLC(TCallBack aCallBack, TStopType aType, TInt aCount)
1.549 + {
1.550 + iHaveCallBack = ETrue;
1.551 + iCallBack = aCallBack;
1.552 + return WaitForChangesLC(aType, aCount);
1.553 + }
1.554 +
1.555 +void CLogViewChangeObserver::HandleLogViewChangeEventAddedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
1.556 + {
1.557 + AddChangeL(ELogChangeTypeEventAdded, aId, aViewIndex);
1.558 + if (aChangeIndex == aTotalChangeCount-1)
1.559 + CheckForSchedulerStop();
1.560 + }
1.561 +
1.562 +void CLogViewChangeObserver::HandleLogViewChangeEventChangedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
1.563 + {
1.564 + AddChangeL(ELogChangeTypeEventChanged, aId, aViewIndex);
1.565 + if (aChangeIndex == aTotalChangeCount-1)
1.566 + CheckForSchedulerStop();
1.567 + }
1.568 +
1.569 +void CLogViewChangeObserver::HandleLogViewChangeEventDeletedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
1.570 + {
1.571 + AddChangeL(ELogChangeTypeEventDeleted, aId, aViewIndex);
1.572 + if (aChangeIndex == aTotalChangeCount-1)
1.573 + CheckForSchedulerStop();
1.574 + }
1.575 +
1.576 +void CLogViewChangeObserver::RunL()
1.577 + {
1.578 + __ASSERT_ALWAYS(iType == EStopOnRunL || iType == EStopOnBoth, User::Invariant());
1.579 + iHaveFinishedOperation = ETrue;
1.580 + CheckForSchedulerStop();
1.581 + }
1.582 +
1.583 +void CLogViewChangeObserver::DoCancel()
1.584 + {
1.585 + TRequestStatus* s=&iStatus;
1.586 + User::RequestComplete(s, KErrCancel);
1.587 + }
1.588 +
1.589 +void CLogViewChangeObserver::Reset()
1.590 + {
1.591 + iExpectedChangeCount = 0;
1.592 + iHaveFinishedOperation = EFalse;
1.593 + iHaveObtainedChanges = EFalse;
1.594 + iSchedulerStarted = EFalse;
1.595 + iType = EStopOnChanges;
1.596 + delete iChanges;
1.597 + iChanges = NULL;
1.598 + }
1.599 +
1.600 +void CLogViewChangeObserver::CheckForSchedulerStop()
1.601 + {
1.602 + if(iSchedulerStarted)
1.603 + {
1.604 + if (iHaveCallBack)
1.605 + {
1.606 + iCallBack.CallBack();
1.607 + iCallBack.iFunction = NULL;
1.608 + iCallBack.iPtr = NULL;
1.609 + iHaveCallBack = EFalse;
1.610 + }
1.611 + //
1.612 + TBool stopScheduler = EFalse;
1.613 + switch(iType)
1.614 + {
1.615 + case EStopOnChanges:
1.616 + stopScheduler = iHaveObtainedChanges;
1.617 + break;
1.618 + case EStopOnRunL:
1.619 + stopScheduler = iHaveFinishedOperation;
1.620 + break;
1.621 + case EStopOnBoth:
1.622 + stopScheduler = (iHaveObtainedChanges && iHaveFinishedOperation);
1.623 + break;
1.624 + case EStopOnCount:
1.625 + if (iChanges)
1.626 + {
1.627 + TEST(iChanges->Count() <= iExpectedChangeCount);
1.628 + stopScheduler = (iChanges->Count() == iExpectedChangeCount);
1.629 + }
1.630 + case EDontStopScheduler:
1.631 + break;
1.632 + }
1.633 +
1.634 + if (stopScheduler)
1.635 + {
1.636 + LOGTEXT("CLogViewChangeObserver::CheckForSchedulerStop() - Stopping the scheduler");
1.637 + CActiveScheduler::Stop();
1.638 + }
1.639 + }
1.640 + }
1.641 +
1.642 +void CLogViewChangeObserver::AddChangeL(TLogDatabaseChangeType aType, TLogId aId, TInt aViewIndex)
1.643 + {
1.644 + CLogChangeDefinition* changes;
1.645 +
1.646 + if (iChanges)
1.647 + changes = iChanges;
1.648 + else
1.649 + {
1.650 + changes = CLogChangeDefinition::NewL();
1.651 + CleanupStack::PushL(changes);
1.652 + }
1.653 + //
1.654 + changes->AddL(aId, aType, aViewIndex);
1.655 + //
1.656 + if (!iChanges)
1.657 + {
1.658 + delete iChanges;
1.659 + iChanges = changes;
1.660 + CleanupStack::Pop(changes);
1.661 + }
1.662 + //
1.663 + iHaveObtainedChanges = ETrue;
1.664 + }
1.665 +
1.666 +//**********************************
1.667 +// CLogViewChangeObserverErrorTest
1.668 +//**********************************
1.669 +CLogViewChangeObserverErrorTest* CLogViewChangeObserverErrorTest::NewLC()
1.670 + {
1.671 + CLogViewChangeObserverErrorTest* self = new(ELeave) CLogViewChangeObserverErrorTest();
1.672 + CleanupStack::PushL(self);
1.673 + return self;
1.674 + }
1.675 +
1.676 +CLogViewChangeObserverErrorTest::CLogViewChangeObserverErrorTest()
1.677 + {}
1.678 +
1.679 +void CLogViewChangeObserverErrorTest::HandleLogViewChangeEventAddedL(TLogId aId, TInt aViewIndex, TInt aChangeIndex, TInt aTotalChangeCount)
1.680 + {
1.681 + // DEF108741L - the error condition tested here is that a leave is dealt with
1.682 + // gracefully without any panics.
1.683 +
1.684 + // Add a new event to the log
1.685 + AddChangeL(ELogChangeTypeEventAdded, aId, aViewIndex);
1.686 + if (aChangeIndex == aTotalChangeCount-1)
1.687 + CheckForSchedulerStop();
1.688 +
1.689 + // In the test case for DEF108741L this method will be effectively
1.690 + // invoked 3 times. This code forces a leave on the middle event to
1.691 + // ensure that the leave is dealt with and the rest of the test
1.692 + // completes successfully.
1.693 + if (aId == 1)
1.694 + {
1.695 + LEAVE(KErrGeneral);
1.696 + }
1.697 + }
1.698 +
1.699 +//**********************************
1.700 +// CLogSchedulerTimer
1.701 +//**********************************
1.702 +
1.703 +CLogSchedulerTimer* CLogSchedulerTimer::NewLC()
1.704 + {
1.705 + CLogSchedulerTimer* self = new(ELeave) CLogSchedulerTimer();
1.706 + CleanupStack::PushL(self);
1.707 + self->ConstructL();
1.708 + return self;
1.709 + }
1.710 +
1.711 +CLogSchedulerTimer::~CLogSchedulerTimer()
1.712 + {
1.713 + Cancel();
1.714 + }
1.715 +
1.716 +CLogSchedulerTimer::CLogSchedulerTimer()
1.717 +: CTimer(0)
1.718 + {
1.719 + CActiveScheduler::Add(this);
1.720 + }
1.721 +
1.722 +void CLogSchedulerTimer::ConstructL()
1.723 + {
1.724 + CTimer::ConstructL();
1.725 + }
1.726 +
1.727 +void CLogSchedulerTimer::Wait(TTimeIntervalMicroSeconds32 aTime)
1.728 + {
1.729 + After(aTime);
1.730 + CActiveScheduler::Start();
1.731 + }
1.732 +
1.733 +void CLogSchedulerTimer::RunL()
1.734 + {
1.735 + LOGTEXT("CLogSchedulerTimer::RunL() - Stopping the scheduler");
1.736 + CActiveScheduler::Stop();
1.737 + }
1.738 +
1.739 +
1.740 +
1.741 +
1.742 +//**********************************
1.743 +// CLogChangeNotifier
1.744 +//**********************************
1.745 +
1.746 +CLogChangeNotifier* CLogChangeNotifier::NewL()
1.747 + {
1.748 + CLogChangeNotifier* self = new(ELeave)CLogChangeNotifier();
1.749 + CleanupStack::PushL(self);
1.750 + self->ConstructL();
1.751 + CleanupStack::Pop(self);
1.752 + return self;
1.753 + }
1.754 +
1.755 +CLogChangeNotifier::~CLogChangeNotifier()
1.756 + {
1.757 + Cancel();
1.758 + delete iClient;
1.759 + }
1.760 +
1.761 +CLogChangeNotifier::CLogChangeNotifier()
1.762 +: CActive(EPriorityStandard)
1.763 + {
1.764 + CActiveScheduler::Add(this);
1.765 + }
1.766 +
1.767 +void CLogChangeNotifier::ConstructL()
1.768 + {
1.769 + iClient = CLogClient::NewL(theFs);
1.770 +
1.771 + iStart.UniversalTime();
1.772 + iClient->NotifyChange(10000000, iStatus);
1.773 + SetActive();
1.774 + }
1.775 +
1.776 +void CLogChangeNotifier::RunL()
1.777 + {
1.778 + TTime now;
1.779 + now.UniversalTime();
1.780 + TTimeIntervalSeconds seconds;
1.781 + now.SecondsFrom(iStart, seconds);
1.782 +
1.783 + TBuf<256> buf;
1.784 + const TInt error = iStatus.Int();
1.785 + if (error == KErrServerTerminated)
1.786 + {
1.787 + buf.Format(_L("KErrServerTerminated"));
1.788 + User::InfoPrint(buf);
1.789 + return;
1.790 + }
1.791 +
1.792 + buf.Format(_L("%d seconds"), seconds.Int());
1.793 + User::InfoPrint(buf);
1.794 +
1.795 + iStart.UniversalTime();
1.796 + iClient->NotifyChange(10000000, iStatus);
1.797 + SetActive();
1.798 + }
1.799 +
1.800 +void CLogChangeNotifier::DoCancel()
1.801 + {
1.802 + iClient->NotifyChangeCancel();
1.803 + }
1.804 +
1.805 +//**********************************
1.806 +// Global
1.807 +//**********************************
1.808 +
1.809 +void SetupSchedulerL()
1.810 + {
1.811 + testScheduler = new (ELeave) CActiveScheduler;
1.812 + CleanupStack::PushL( testScheduler );
1.813 + CActiveScheduler::Install( testScheduler );
1.814 + }
1.815 +
1.816 +void CloseScheduler()
1.817 + {
1.818 + CleanupStack::PopAndDestroy(); // Scheduler
1.819 + testScheduler = NULL;
1.820 + }
1.821 +
1.822 +static void CreateLogL()
1.823 + {
1.824 + LEAVE_IF_ERROR(theFs.Connect());
1.825 +
1.826 + theLogName.Copy(RProcess().FileName());
1.827 + TInt start = theLogName.LocateReverse('\\');
1.828 + TInt end = theLogName.LocateReverse('.');
1.829 + theLogName = theLogName.Mid(start + 1, end - start - 1);
1.830 +
1.831 + // create the log filename
1.832 + theLogName.Insert(0, _L("C:\\"));
1.833 +#if defined(__WINS__)
1.834 + theLogName.Append(_L(".WINS."));
1.835 +#else
1.836 + theLogName.Append(_L(".MARM."));
1.837 +#endif
1.838 +#if defined(_UNICODE)
1.839 + theLogName.Append(_L("UNICODE."));
1.840 +#else
1.841 + theLogName.Append(_L("ASCII."));
1.842 +#endif
1.843 +#if defined(_DEBUG)
1.844 + theLogName.Append(_L("DEB."));
1.845 +#else
1.846 + theLogName.Append(_L("REL."));
1.847 +#endif
1.848 + theLogName.Append(_L("LOG"));
1.849 +
1.850 + // create the logfile
1.851 + LEAVE_IF_ERROR(theLog.Replace(theFs, theLogName, EFileWrite|EFileShareExclusive));
1.852 + TBuf8<256> text;
1.853 + text.Copy(theLogName);
1.854 + theLog.Write(text);
1.855 + theLog.Write(_L8("\nTest results\n"));
1.856 + }
1.857 +
1.858 +static void CloseLog()
1.859 + {
1.860 + theLog.Write(_L8("Tests completed\n"));
1.861 + TheTest.Printf(_L("Results saved in %S\n"), &theLogName);
1.862 + theLog.Close();
1.863 + theFs.Close();
1.864 + }
1.865 +
1.866 +void DeleteDataFile(const TDesC& aFullName)
1.867 + {
1.868 + RFs fsSession;
1.869 + TInt err = fsSession.Connect();
1.870 + if(err == KErrNone)
1.871 + {
1.872 + TEntry entry;
1.873 + if(fsSession.Entry(aFullName, entry) == KErrNone)
1.874 + {
1.875 + TheTest.Printf(_L("Deleting \"%S\" file.\n"), &aFullName);
1.876 + err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
1.877 + if(err != KErrNone)
1.878 + {
1.879 + TheTest.Printf(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
1.880 + }
1.881 + err = fsSession.Delete(aFullName);
1.882 + if(err != KErrNone)
1.883 + {
1.884 + TheTest.Printf(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
1.885 + }
1.886 + }
1.887 + fsSession.Close();
1.888 + }
1.889 + else
1.890 + {
1.891 + TheTest.Printf(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
1.892 + }
1.893 + }
1.894 +
1.895 +static void Cleanup(void*)
1.896 + {
1.897 + TRAP_IGNORE(TestUtils::DeleteDatabaseL());
1.898 + ::DeleteDataFile(theLogName);
1.899 + }
1.900 +
1.901 +static void DoMainL()
1.902 + {
1.903 + ::SetupSchedulerL();
1.904 + TCleanupItem cleanup(&Cleanup, NULL);
1.905 + CleanupStack::PushL(cleanup);
1.906 + CreateLogL();
1.907 + ::doTestsL();
1.908 + CloseLog();
1.909 + CleanupStack::PopAndDestroy();//cleanup
1.910 + ::CloseScheduler();
1.911 + }
1.912 +
1.913 +TInt E32Main()
1.914 + {
1.915 + __UHEAP_MARK;
1.916 +
1.917 + theCleanup = CTrapCleanup::New();
1.918 + if(!theCleanup)
1.919 + {
1.920 + _LIT(KLogHiCapHelperPanic, "LogTestPanic");
1.921 + User::Panic(KLogHiCapHelperPanic, KErrNoMemory);
1.922 + }
1.923 +
1.924 + TRAPD(err, ::DoMainL());
1.925 + TEST2(err, KErrNone);
1.926 +
1.927 + delete theCleanup;
1.928 +
1.929 + TheTest.Console()->SetPos(0, 13);
1.930 +
1.931 + TheTest.End();
1.932 + TheTest.Close();
1.933 +
1.934 + __UHEAP_MARKEND;
1.935 +
1.936 + return KErrNone;
1.937 + }
1.938 +
1.939 +