sl@0: /* sl@0: * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * Test program exercises the swi observer UPS API. sl@0: * See individual test functions for more information. sl@0: * sl@0: */ sl@0: sl@0: sl@0: /** sl@0: @file sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: #include "rtestwrapper.h" sl@0: sl@0: #include sl@0: #include "f32file.h" sl@0: sl@0: using namespace UserPromptService; sl@0: sl@0: /** Top-level test object renders stages and confirms conditions. */ sl@0: static RTestWrapper test(_L("UPSTESTOBSIFOOM")); sl@0: sl@0: static RUpsManagement sMngmntSession; sl@0: sl@0: void PopulateDatabaseL() sl@0: { sl@0: //test.Start(_L("Populate database")); sl@0: RUpsSession session; sl@0: User::LeaveIfError(session.Connect()); sl@0: CleanupClosePushL(session); sl@0: sl@0: RThread thd; sl@0: RUpsSubsession clientSubsession; sl@0: TInt r = clientSubsession.Initialise(session, thd); sl@0: test(r == KErrNone); sl@0: CleanupClosePushL(clientSubsession); sl@0: sl@0: RBuf destination; sl@0: destination.CreateL(100); sl@0: CleanupClosePushL(destination); sl@0: sl@0: for(TInt i=0 ; i<10; ++i) sl@0: { sl@0: TServiceId serviceId = {42}; sl@0: if( i & 1) serviceId.iUid = 43; sl@0: destination.Zero(); sl@0: destination.AppendFormat(_L("destination %x"), i); sl@0: sl@0: TUpsDecision dec = EUpsDecNo; sl@0: TRequestStatus rs; sl@0: clientSubsession.Authorise(EFalse, serviceId, destination, _L8("Opaque data"), dec, rs); sl@0: User::WaitForRequest(rs); sl@0: test((rs == KErrNone) || (rs == KErrNoMemory)); sl@0: if(rs == KErrNone) sl@0: { sl@0: if(serviceId.iUid == 42) sl@0: { sl@0: test(dec == EUpsDecYes); sl@0: } sl@0: else sl@0: { sl@0: test(dec == EUpsDecNo); sl@0: } sl@0: } sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(&destination); sl@0: CleanupStack::PopAndDestroy(&clientSubsession); sl@0: CleanupStack::PopAndDestroy(&session); sl@0: //test.End(); sl@0: } sl@0: sl@0: #if 1 sl@0: class CTestSwiIf; sl@0: NONSHARABLE_CLASS(CRequest) : public CActive sl@0: { sl@0: public: sl@0: static CRequest *NewL(RUpsSession &aSession, CTestSwiIf &aParent, TInt aId, TUpsDecision aExpected); sl@0: ~CRequest(); sl@0: private: sl@0: CRequest(CTestSwiIf &aParent, TUpsDecision aExpected); sl@0: void ConstructL(RUpsSession &aSession, TInt aId); sl@0: sl@0: virtual void RunL(); sl@0: virtual void DoCancel(); sl@0: virtual TInt RunError(TInt aError); sl@0: sl@0: CTestSwiIf &iParent; sl@0: sl@0: RUpsSubsession iSubSession; sl@0: sl@0: TUpsDecision iDec; sl@0: TUpsDecision iExpected; sl@0: }; sl@0: sl@0: sl@0: NONSHARABLE_CLASS(CTestSwiIf) : public CActive sl@0: { sl@0: public: sl@0: static CTestSwiIf *NewL(); sl@0: sl@0: ~CTestSwiIf(); sl@0: sl@0: void IncUsers(); sl@0: void DecUsers(); sl@0: sl@0: TInt Result(); sl@0: private: sl@0: CTestSwiIf(); sl@0: void ConstructL(); sl@0: sl@0: enum EState sl@0: { sl@0: EPrePolicyChange, sl@0: EPostPolicyChange, sl@0: ERevertPolicyChange, sl@0: ETestingComplete sl@0: }; sl@0: sl@0: virtual void RunL(); sl@0: virtual void DoCancel(); sl@0: virtual TInt RunError(TInt aError); sl@0: sl@0: TInt iUsers; sl@0: sl@0: RFs iFs; sl@0: EState iState; sl@0: RUpsSession iUpsSession; sl@0: RUpsManagement iManagementSession; sl@0: sl@0: TInt iResult; sl@0: }; sl@0: sl@0: CTestSwiIf *CTestSwiIf::NewL() sl@0: { sl@0: CTestSwiIf *self = new(ELeave) CTestSwiIf; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CTestSwiIf::CTestSwiIf() sl@0: : CActive(CActive::EPriorityStandard), iState(EPrePolicyChange) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: } sl@0: sl@0: _LIT(KCheckIfFailed, "z:\\private\\10283558\\policies\\ups_102836c3_0000002b_checkiffailed.rsc"); sl@0: _LIT(KResourceFileDirC, "c:\\private\\10283558\\policies\\"); sl@0: _LIT(KResourceFileOnC, "c:\\private\\10283558\\policies\\ups_102836c3_0000002b.rsc"); sl@0: sl@0: void CTestSwiIf::ConstructL() sl@0: { sl@0: User::LeaveIfError(iFs.Connect()); sl@0: sl@0: sl@0: User::LeaveIfError(iUpsSession.Connect()); sl@0: User::LeaveIfError(iManagementSession.Connect()); sl@0: sl@0: sl@0: TRequestStatus *rs = &iStatus; sl@0: *rs = KRequestPending; sl@0: User::RequestComplete(rs, KErrNone); sl@0: SetActive(); sl@0: } sl@0: sl@0: sl@0: CTestSwiIf::~CTestSwiIf() sl@0: { sl@0: Cancel(); sl@0: iManagementSession.Close(); sl@0: iUpsSession.Close(); sl@0: iFs.Close(); sl@0: } sl@0: sl@0: TInt CTestSwiIf::Result() sl@0: { sl@0: return iResult; sl@0: } sl@0: sl@0: void CTestSwiIf::IncUsers() sl@0: { sl@0: ++iUsers; sl@0: } sl@0: sl@0: void CTestSwiIf::DecUsers() sl@0: { sl@0: --iUsers; sl@0: if((iUsers <= 0) && sl@0: ((iState == ETestingComplete) || (iResult != KErrNone))) sl@0: { sl@0: CActiveScheduler::Stop(); sl@0: } sl@0: } sl@0: void CTestSwiIf::RunL() sl@0: { sl@0: User::LeaveIfError(iStatus.Int()); sl@0: switch(iState) sl@0: { sl@0: case EPrePolicyChange: sl@0: { sl@0: PopulateDatabaseL(); sl@0: sl@0: (void)CRequest::NewL(iUpsSession, *this, 8, EUpsDecYes); sl@0: (void)CRequest::NewL(iUpsSession, *this, 4, EUpsDecYes); sl@0: (void)CRequest::NewL(iUpsSession, *this, 5, EUpsDecNo); sl@0: (void)CRequest::NewL(iUpsSession, *this, 2, EUpsDecYes); sl@0: (void)CRequest::NewL(iUpsSession, *this, 7, EUpsDecNo); sl@0: sl@0: (void)iFs.MkDirAll(KResourceFileDirC); sl@0: sl@0: CFileMan *fileman = CFileMan::NewL(iFs); sl@0: CleanupStack::PushL(fileman); sl@0: TInt r = fileman->Copy(KCheckIfFailed, KResourceFileOnC); sl@0: User::LeaveIfError(r); sl@0: CleanupStack::PopAndDestroy(fileman); sl@0: sl@0: TRequestStatus rs; sl@0: iManagementSession.NotifyPolicyFilesChanged(rs); sl@0: iManagementSession.CancelNotifyPolicyFilesChanged(); sl@0: User::WaitForRequest(rs); sl@0: if(rs.Int() != KErrCancel) User::Leave(rs.Int()); sl@0: sl@0: iState = EPostPolicyChange; sl@0: iManagementSession.NotifyPolicyFilesChanged(iStatus); sl@0: SetActive(); sl@0: break; sl@0: } sl@0: case EPostPolicyChange: sl@0: // Notify complete, do some more queries sl@0: (void)CRequest::NewL(iUpsSession, *this, 2, EUpsDecYes); sl@0: (void)CRequest::NewL(iUpsSession, *this, 8, EUpsDecYes); sl@0: (void)CRequest::NewL(iUpsSession, *this, 5, EUpsDecYes); sl@0: (void)CRequest::NewL(iUpsSession, *this, 4, EUpsDecYes); sl@0: (void)CRequest::NewL(iUpsSession, *this, 3, EUpsDecYes); sl@0: sl@0: // Revert change sl@0: User::LeaveIfError(iFs.Delete(KResourceFileOnC)); sl@0: sl@0: iState = ERevertPolicyChange; sl@0: iManagementSession.NotifyPolicyFilesChanged(iStatus); sl@0: SetActive(); sl@0: break; sl@0: sl@0: case ERevertPolicyChange: sl@0: iState = ETestingComplete; sl@0: if(iUsers <= 0) sl@0: { sl@0: CActiveScheduler::Stop(); sl@0: } sl@0: break; sl@0: sl@0: case ETestingComplete: sl@0: break; sl@0: } sl@0: } sl@0: sl@0: void CTestSwiIf::DoCancel() sl@0: { sl@0: switch(iState) sl@0: { sl@0: case EPrePolicyChange: sl@0: { sl@0: TRequestStatus *rs = &iStatus; sl@0: if(*rs == KRequestPending) sl@0: { sl@0: User::RequestComplete(rs, KErrCancel); sl@0: } sl@0: break; sl@0: } sl@0: sl@0: case EPostPolicyChange: sl@0: iManagementSession.CancelNotifyPolicyFilesChanged(); sl@0: break; sl@0: sl@0: case ERevertPolicyChange: sl@0: iManagementSession.CancelNotifyPolicyFilesChanged(); sl@0: break; sl@0: sl@0: case ETestingComplete: sl@0: break; sl@0: default: sl@0: ASSERT(0); // Unknown state sl@0: } sl@0: sl@0: } sl@0: sl@0: TInt CTestSwiIf::RunError(TInt aError) sl@0: { sl@0: iResult = aError; sl@0: if(iUsers <= 0) sl@0: { sl@0: CActiveScheduler::Stop(); sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: CRequest *CRequest::NewL(RUpsSession &aSession, CTestSwiIf &aParent, TInt aId, TUpsDecision aExpected) sl@0: { sl@0: CRequest *self = new(ELeave) CRequest(aParent, aExpected); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aSession, aId); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CRequest::CRequest(CTestSwiIf &aParent, TUpsDecision aExpected) sl@0: : CActive(CActive::EPriorityStandard-1), sl@0: iParent(aParent), sl@0: iExpected(aExpected) sl@0: { sl@0: CActiveScheduler::Add(this); sl@0: iParent.IncUsers(); sl@0: } sl@0: sl@0: void CRequest::ConstructL(RUpsSession &aSession, TInt aId) sl@0: { sl@0: RThread thd; sl@0: User::LeaveIfError(iSubSession.Initialise(aSession, thd)); sl@0: TServiceId serviceId = {42}; sl@0: if( aId & 1) serviceId.iUid = 43; sl@0: RBuf destination; sl@0: destination.CreateL(100); sl@0: CleanupClosePushL(destination); sl@0: destination.AppendFormat(_L("destination %x"), aId); sl@0: sl@0: iDec = EUpsDecNo; sl@0: iSubSession.Authorise(EFalse, serviceId, destination, _L8("Opaque data"), iDec, iStatus); sl@0: SetActive(); sl@0: sl@0: CleanupStack::PopAndDestroy(&destination); sl@0: } sl@0: sl@0: CRequest::~CRequest() sl@0: { sl@0: iSubSession.Close(); sl@0: iParent.DecUsers(); sl@0: } sl@0: sl@0: void CRequest::RunL() sl@0: { sl@0: test((iStatus.Int() == KErrNone) || (iStatus.Int() == KErrNoMemory)); sl@0: if(iStatus.Int() == KErrNone) sl@0: { sl@0: // Some OOM situations appear to cause us to return NO. sl@0: test((iDec == iExpected) || (iDec == EUpsDecNo)); sl@0: } sl@0: delete this; sl@0: } sl@0: sl@0: void CRequest::DoCancel() sl@0: { sl@0: } sl@0: sl@0: TInt CRequest::RunError(TInt aError) sl@0: { sl@0: User::Panic(_L("CRequest::RunError"), aError); sl@0: /*lint -unreachable*/ sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: #endif sl@0: void TestSwiObserverL() sl@0: { sl@0: RUpsManagement session; sl@0: User::LeaveIfError(session.Connect()); sl@0: CleanupClosePushL(session); sl@0: sl@0: session.NotifyPluginsMayHaveChangedL(); sl@0: sl@0: TRequestStatus rs; sl@0: session.NotifyPolicyFilesChanged(rs); sl@0: User::WaitForRequest(rs); sl@0: sl@0: test((rs.Int() == KErrNone) || (rs.Int() == KErrNoMemory)); sl@0: if(rs.Int() == KErrNone) sl@0: { sl@0: session.CancelNotifyPolicyFilesChanged(); sl@0: } sl@0: sl@0: TSecureId ourSid(0x10283559); sl@0: session.DeleteDecisionsForExeL(ourSid); sl@0: sl@0: sl@0: CleanupStack::PopAndDestroy(&session); sl@0: } sl@0: sl@0: sl@0: // -------- entrypoint -------- sl@0: void MainL() sl@0: { sl@0: // We need to increase the priority of the thread running the test code to make sure sl@0: // that asynchronous ups management calls, for example CreateView() , won't finish sl@0: // before following synchronous cancellation or termination calls, for example: sl@0: // DeleteDatabaseL() or CancelAndCloseView(). sl@0: RThread thread; sl@0: TThreadPriority currentPri = thread.Priority(); sl@0: currentPri = (TThreadPriority)((TInt)currentPri+10); sl@0: thread.SetPriority(currentPri); sl@0: sl@0: CActiveScheduler *scheduler = new(ELeave) CActiveScheduler; sl@0: CActiveScheduler::Install(scheduler); sl@0: CleanupStack::PushL(scheduler); sl@0: sl@0: test.Title(_L("c:\\upstestobsifoom.log")); sl@0: test.Start(_L(" @SYMTestCaseID:SEC-UPS-OBSIF_OOM-0001 Testing RUpsSession SWI observer IF ")); sl@0: sl@0: RFs fs; sl@0: User::LeaveIfError(fs.Connect()); sl@0: CleanupClosePushL(fs); sl@0: sl@0: User::LeaveIfError(sMngmntSession.Connect()); sl@0: sMngmntSession.ShutdownServer(); sl@0: sMngmntSession.Close(); sl@0: sl@0: TBuf<21> notifierConfig(_L("!:\\upsrefnotifier.txt")); sl@0: notifierConfig[0] = fs.GetSystemDriveChar(); sl@0: sl@0: TInt lineLength = User::CommandLineLength(); sl@0: switch(lineLength) sl@0: { sl@0: default: sl@0: // fall through - extra command line arguments are ignored sl@0: case 2: sl@0: // 2 char arg - Delete DB and run interactive sl@0: (void) fs.Delete(_L("c:\\Private\\10283558\\database\\ups.db")); sl@0: // Fall through to also delete notifier config file sl@0: case 1: sl@0: // 1 char arg - Run interactive, without deleting DB sl@0: (void) fs.Delete(notifierConfig); sl@0: break; sl@0: case 0: sl@0: { sl@0: // No args - delete DB and run in silent mode sl@0: (void) fs.Delete(_L("c:\\Private\\10283558\\database\\ups.db")); sl@0: sl@0: (void) fs.Delete(notifierConfig); sl@0: RFile file; sl@0: User::LeaveIfError(file.Create(fs, notifierConfig, EFileShareExclusive | EFileWrite)); sl@0: User::LeaveIfError(file.Write(_L8("Always"))); sl@0: file.Close(); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: User::LeaveIfError(sMngmntSession.Connect()); sl@0: CleanupClosePushL(sMngmntSession); sl@0: sl@0: sl@0: TInt err = KErrNone; sl@0: TInt errTmp = KErrNone; sl@0: TInt run = 0; sl@0: TInt passingRuns = 0; sl@0: static const TInt maxRun = 1000; sl@0: static const TInt passThreshold = 5; sl@0: sl@0: for(run=1; run<=maxRun; ++run) sl@0: { sl@0: test.Printf(_L("\n\nOBSIF OOM -- Run %d\n"), run); sl@0: sl@0: // Make sure the C: policy is deleted. sl@0: (void)fs.Delete(KResourceFileOnC); sl@0: sl@0: // Make sure server is not holding cached values for the C: policy sl@0: // We could stop/restart the server, but that is very slow... sl@0: TRequestStatus rs; sl@0: sMngmntSession.NotifyPolicyFilesChanged(rs); sl@0: User::WaitForRequest(rs); sl@0: sl@0: err = sMngmntSession.SetServerHeapFail(run); sl@0: if(err == KErrNoMemory) sl@0: { sl@0: // Reinitialisation failed sl@0: test.Printf(_L("\tReinitialisation failed\n")); sl@0: sMngmntSession.ResetServerHeapFail(); sl@0: continue; sl@0: } sl@0: if(err != KErrNone) sl@0: { sl@0: // Failed to set heap fail, maybe the previous loop crashed the server?? sl@0: test.Printf(_L("Failed to set heap fail with error code %d"), err); sl@0: test(EFalse); sl@0: break; sl@0: } sl@0: sl@0: // Run the test sl@0: #if 1 sl@0: CTestSwiIf *t = 0; sl@0: TRAP(err, t = CTestSwiIf::NewL()); sl@0: if(err == KErrNone) sl@0: { sl@0: CActiveScheduler::Start(); sl@0: err = t->Result(); sl@0: delete t; sl@0: } sl@0: #else sl@0: err = KErrNone; sl@0: #endif sl@0: sl@0: #if 1 sl@0: if(err == KErrNone) sl@0: { sl@0: TRAP(err, TestSwiObserverL()); sl@0: } sl@0: #endif sl@0: sl@0: // Clear the heap fail sl@0: test.Printf(_L("Reseting heap failure\n")); sl@0: errTmp = sMngmntSession.ResetServerHeapFail(); sl@0: if((err == KErrServerTerminated) || (errTmp == KErrServerTerminated)) sl@0: { sl@0: test.Printf(_L("\tUPS server died")); sl@0: test(EFalse); sl@0: break; sl@0: } sl@0: if((err == KErrNone) && (errTmp != KErrNone)) sl@0: { sl@0: err = errTmp; sl@0: } sl@0: sl@0: // Did it work? sl@0: if(err == KErrNone) sl@0: { sl@0: ++passingRuns; sl@0: } sl@0: else sl@0: { sl@0: passingRuns = 0; sl@0: } sl@0: sl@0: if(passingRuns > passThreshold) break; sl@0: } // End of OOM loop sl@0: sl@0: if(run > maxRun) sl@0: { sl@0: User::Leave(err); sl@0: } sl@0: sl@0: sMngmntSession.ShutdownServer(); sl@0: sl@0: // Close top level session (low level session was closed by sl@0: // ShutdownServer, but we still need to do the RUpsManagement sl@0: // cleanup). sl@0: CleanupStack::PopAndDestroy(&sMngmntSession); sl@0: sl@0: (void) fs.Delete(notifierConfig); sl@0: CleanupStack::PopAndDestroy(&fs); sl@0: sl@0: test.End(); sl@0: test.Close(); sl@0: sl@0: CleanupStack::PopAndDestroy(scheduler); sl@0: } sl@0: sl@0: void PanicIfError(TInt r) sl@0: { sl@0: if(r != KErrNone) sl@0: { sl@0: User::Panic(_L("upstest failed: "), r); sl@0: } sl@0: } sl@0: sl@0: sl@0: TInt E32Main() sl@0: /** sl@0: Executable entrypoint establishes connection with UPS server sl@0: and then invokes tests for each functional area. sl@0: sl@0: @return Symbian OS error code where KErrNone indicates sl@0: success and any other value indicates failure. sl@0: */ sl@0: { sl@0: // disable lazy DLL unloading so kernel heap balances at end sl@0: RLoader l; sl@0: PanicIfError(l.Connect()); sl@0: PanicIfError(l.CancelLazyDllUnload()); sl@0: l.Close(); sl@0: sl@0: __UHEAP_MARK; sl@0: //__KHEAP_MARK; sl@0: sl@0: // allocating a cleanup stack also installs it sl@0: CTrapCleanup* tc = CTrapCleanup::New(); sl@0: if (tc == 0) sl@0: return KErrNoMemory; sl@0: sl@0: sl@0: TRAPD(err, MainL()); sl@0: if(err != KErrNone) sl@0: { sl@0: User::Panic(_L("upstest failed: "), err); sl@0: } sl@0: delete tc; sl@0: sl@0: //__KHEAP_MARKEND; sl@0: __UHEAP_MARKEND; sl@0: sl@0: sl@0: return KErrNone; sl@0: } sl@0: