os/security/authorisation/userpromptservice/server/test/upstest/upstestobsifoom.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /*
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     3 * All rights reserved.
     4 * This component and the accompanying materials are made available
     5 * under the terms of the License "Eclipse Public License v1.0"
     6 * which accompanies this distribution, and is available
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
     8 *
     9 * Initial Contributors:
    10 * Nokia Corporation - initial contribution.
    11 *
    12 * Contributors:
    13 *
    14 * Description: 
    15 * Test program exercises the swi observer UPS API.
    16 * See individual test functions for more information.
    17 *
    18 */
    19 
    20 
    21 /**
    22  @file
    23 */
    24 
    25 #include <e32ldr.h>
    26 #include <e32ldr_private.h>
    27 #include "rtestwrapper.h"
    28 
    29 #include <ups/upsclient.h>
    30 #include "f32file.h"
    31 
    32 using namespace UserPromptService;
    33 
    34 /** Top-level test object renders stages and confirms conditions. */
    35 static RTestWrapper test(_L("UPSTESTOBSIFOOM"));
    36 
    37 static RUpsManagement sMngmntSession;
    38 
    39 void PopulateDatabaseL()
    40 	{
    41 	//test.Start(_L("Populate database"));
    42 	RUpsSession session;
    43 	User::LeaveIfError(session.Connect());
    44 	CleanupClosePushL(session);
    45 
    46 	RThread thd;
    47 	RUpsSubsession clientSubsession;
    48 	TInt r = clientSubsession.Initialise(session, thd);
    49 	test(r == KErrNone);
    50 	CleanupClosePushL(clientSubsession);
    51 
    52 	RBuf destination;
    53 	destination.CreateL(100);
    54 	CleanupClosePushL(destination);
    55 
    56 	for(TInt i=0 ; i<10; ++i)
    57 		{
    58 		TServiceId serviceId = {42};
    59 		if( i & 1) serviceId.iUid = 43;
    60 		destination.Zero();
    61 		destination.AppendFormat(_L("destination %x"), i);
    62 		
    63 		TUpsDecision dec = EUpsDecNo;
    64 		TRequestStatus rs;
    65 		clientSubsession.Authorise(EFalse, serviceId, destination, _L8("Opaque data"), dec, rs);
    66 		User::WaitForRequest(rs);
    67 		test((rs == KErrNone) || (rs == KErrNoMemory));
    68 		if(rs == KErrNone)
    69 			{
    70 			if(serviceId.iUid == 42)
    71 				{
    72 				test(dec == EUpsDecYes);
    73 				}
    74 			else
    75 				{
    76 				test(dec == EUpsDecNo);
    77 				}
    78 			}
    79 		}
    80 
    81 	CleanupStack::PopAndDestroy(&destination);
    82 	CleanupStack::PopAndDestroy(&clientSubsession);
    83 	CleanupStack::PopAndDestroy(&session);
    84 	//test.End();
    85 	}
    86 	
    87 #if 1
    88 class CTestSwiIf;
    89 NONSHARABLE_CLASS(CRequest) : public CActive
    90 	{
    91 public:
    92 	static CRequest *NewL(RUpsSession &aSession, CTestSwiIf &aParent, TInt aId, TUpsDecision aExpected);
    93 	~CRequest();
    94 private:
    95 	CRequest(CTestSwiIf &aParent, TUpsDecision aExpected);
    96 	void ConstructL(RUpsSession &aSession, TInt aId);
    97 
    98 	virtual void RunL();
    99 	virtual void DoCancel();
   100 	virtual TInt RunError(TInt aError);
   101 
   102 	CTestSwiIf &iParent;
   103 
   104 	RUpsSubsession iSubSession;
   105 
   106 	TUpsDecision iDec;
   107 	TUpsDecision iExpected;
   108 	};
   109 
   110 
   111 NONSHARABLE_CLASS(CTestSwiIf) : public CActive
   112 	{
   113 public:
   114 	static CTestSwiIf *NewL();
   115 
   116 	~CTestSwiIf();
   117 
   118 	void IncUsers();
   119 	void DecUsers();
   120 
   121 	TInt Result();
   122 private:
   123 	CTestSwiIf();
   124 	void ConstructL();
   125 
   126 	enum EState
   127 		{
   128 		EPrePolicyChange,
   129 		EPostPolicyChange,
   130 		ERevertPolicyChange,
   131 		ETestingComplete
   132 		};
   133 	
   134 	virtual void RunL();
   135 	virtual void DoCancel();
   136 	virtual TInt RunError(TInt aError);
   137 
   138 	TInt iUsers;
   139 
   140 	RFs iFs;
   141 	EState iState;
   142 	RUpsSession iUpsSession;
   143 	RUpsManagement iManagementSession;
   144 
   145 	TInt iResult;
   146 	};
   147 
   148 CTestSwiIf *CTestSwiIf::NewL()
   149 	{
   150 	CTestSwiIf *self = new(ELeave) CTestSwiIf;
   151 	CleanupStack::PushL(self);
   152 	self->ConstructL();
   153 	CleanupStack::Pop(self);
   154 	return self;
   155 	}
   156 
   157 CTestSwiIf::CTestSwiIf()
   158 	:	CActive(CActive::EPriorityStandard), iState(EPrePolicyChange)
   159 	{
   160 	CActiveScheduler::Add(this);
   161 	}
   162 
   163 _LIT(KCheckIfFailed, "z:\\private\\10283558\\policies\\ups_102836c3_0000002b_checkiffailed.rsc");
   164 _LIT(KResourceFileDirC, "c:\\private\\10283558\\policies\\");
   165 _LIT(KResourceFileOnC, "c:\\private\\10283558\\policies\\ups_102836c3_0000002b.rsc");
   166 
   167 void CTestSwiIf::ConstructL()
   168 	{
   169 	User::LeaveIfError(iFs.Connect());
   170 
   171 
   172 	User::LeaveIfError(iUpsSession.Connect());
   173 	User::LeaveIfError(iManagementSession.Connect());
   174 
   175 
   176 	TRequestStatus *rs = &iStatus;
   177 	*rs = KRequestPending;
   178 	User::RequestComplete(rs, KErrNone);
   179 	SetActive();
   180 	}
   181 
   182 
   183 CTestSwiIf::~CTestSwiIf()
   184 	{
   185 	Cancel();
   186 	iManagementSession.Close();
   187 	iUpsSession.Close();
   188 	iFs.Close();
   189 	}
   190 
   191 TInt CTestSwiIf::Result()
   192 	{
   193 	return iResult;
   194 	}
   195 
   196 void CTestSwiIf::IncUsers()
   197 	{
   198 	++iUsers;
   199 	}
   200 
   201 void CTestSwiIf::DecUsers()
   202 	{
   203 	--iUsers;
   204 	if((iUsers <= 0) && 
   205 		((iState == ETestingComplete) || (iResult != KErrNone)))
   206 		{
   207 		CActiveScheduler::Stop();
   208 		}
   209 	}
   210 void CTestSwiIf::RunL()
   211 	{
   212 	User::LeaveIfError(iStatus.Int());
   213 	switch(iState)
   214 		{
   215 		case EPrePolicyChange:
   216 			{
   217 			PopulateDatabaseL();
   218 
   219 			(void)CRequest::NewL(iUpsSession, *this, 8, EUpsDecYes);
   220 			(void)CRequest::NewL(iUpsSession, *this, 4, EUpsDecYes);
   221 			(void)CRequest::NewL(iUpsSession, *this, 5, EUpsDecNo);
   222 			(void)CRequest::NewL(iUpsSession, *this, 2, EUpsDecYes);
   223 			(void)CRequest::NewL(iUpsSession, *this, 7, EUpsDecNo);
   224 
   225 			(void)iFs.MkDirAll(KResourceFileDirC);
   226 
   227 			CFileMan *fileman = CFileMan::NewL(iFs);
   228 			CleanupStack::PushL(fileman);
   229 			TInt r = fileman->Copy(KCheckIfFailed, KResourceFileOnC);
   230 			User::LeaveIfError(r);
   231 			CleanupStack::PopAndDestroy(fileman);
   232 
   233 			TRequestStatus rs;
   234 			iManagementSession.NotifyPolicyFilesChanged(rs);
   235 			iManagementSession.CancelNotifyPolicyFilesChanged();
   236 			User::WaitForRequest(rs);
   237 			if(rs.Int() != KErrCancel) User::Leave(rs.Int());
   238 
   239 			iState = EPostPolicyChange;
   240 			iManagementSession.NotifyPolicyFilesChanged(iStatus);
   241 			SetActive();
   242 			break;
   243 			}
   244 		case EPostPolicyChange:
   245 			// Notify complete, do some more queries
   246 			(void)CRequest::NewL(iUpsSession, *this, 2, EUpsDecYes);
   247 			(void)CRequest::NewL(iUpsSession, *this, 8, EUpsDecYes);
   248 			(void)CRequest::NewL(iUpsSession, *this, 5, EUpsDecYes);
   249 			(void)CRequest::NewL(iUpsSession, *this, 4, EUpsDecYes);
   250 			(void)CRequest::NewL(iUpsSession, *this, 3, EUpsDecYes);
   251 
   252 			// Revert change
   253 			User::LeaveIfError(iFs.Delete(KResourceFileOnC));
   254 
   255 			iState = ERevertPolicyChange;
   256 			iManagementSession.NotifyPolicyFilesChanged(iStatus);
   257 			SetActive();
   258 			break;
   259 
   260 		case ERevertPolicyChange:
   261 			iState = ETestingComplete;
   262 			if(iUsers <= 0)
   263 				{
   264 				CActiveScheduler::Stop();
   265 				}
   266 			break;
   267 			
   268 		case ETestingComplete:
   269 			break;
   270 		}
   271 	}
   272 
   273 void CTestSwiIf::DoCancel()
   274 	{
   275 	switch(iState)
   276 		{
   277 		case EPrePolicyChange:
   278 			{
   279 			TRequestStatus *rs = &iStatus;
   280 			if(*rs == KRequestPending)
   281 				{
   282 				User::RequestComplete(rs, KErrCancel);
   283 				}
   284 			break;
   285 			}
   286 
   287 		case EPostPolicyChange:
   288 			iManagementSession.CancelNotifyPolicyFilesChanged();
   289 			break;
   290 
   291 		case ERevertPolicyChange:
   292 			iManagementSession.CancelNotifyPolicyFilesChanged();
   293 			break;
   294 
   295 		case ETestingComplete:
   296 			break;
   297 		default:
   298 			ASSERT(0); // Unknown state				
   299 		}
   300 
   301 	}
   302 
   303 TInt CTestSwiIf::RunError(TInt aError)
   304 	{
   305 	iResult = aError;
   306 	if(iUsers <= 0)
   307 		{
   308 		CActiveScheduler::Stop();
   309 		}
   310 	return KErrNone;
   311 	}
   312 
   313 CRequest *CRequest::NewL(RUpsSession &aSession, CTestSwiIf &aParent, TInt aId, TUpsDecision aExpected)
   314 	{
   315 	CRequest *self = new(ELeave) CRequest(aParent, aExpected);
   316 	CleanupStack::PushL(self);
   317 	self->ConstructL(aSession, aId);
   318 	CleanupStack::Pop(self);
   319 	return self;
   320 	}
   321 
   322 CRequest::CRequest(CTestSwiIf &aParent, TUpsDecision aExpected)
   323 	:	CActive(CActive::EPriorityStandard-1),
   324 		iParent(aParent),
   325 		iExpected(aExpected)
   326 	{
   327 	CActiveScheduler::Add(this);
   328 	iParent.IncUsers();
   329 	}
   330 
   331 void CRequest::ConstructL(RUpsSession &aSession, TInt aId)
   332 	{
   333 	RThread thd;
   334 	User::LeaveIfError(iSubSession.Initialise(aSession, thd));
   335 	TServiceId serviceId = {42};
   336 	if( aId & 1) serviceId.iUid = 43;
   337 	RBuf destination;
   338 	destination.CreateL(100);
   339 	CleanupClosePushL(destination);
   340 	destination.AppendFormat(_L("destination %x"), aId);
   341 		
   342 	iDec = EUpsDecNo;
   343 	iSubSession.Authorise(EFalse, serviceId, destination, _L8("Opaque data"), iDec, iStatus);
   344 	SetActive();
   345 
   346 	CleanupStack::PopAndDestroy(&destination);
   347 	}
   348 
   349 CRequest::~CRequest()
   350 	{
   351 	iSubSession.Close();
   352 	iParent.DecUsers();
   353 	}
   354 
   355 void CRequest::RunL()
   356 	{
   357 	test((iStatus.Int() == KErrNone) || (iStatus.Int() == KErrNoMemory));
   358 	if(iStatus.Int() == KErrNone)
   359 		{
   360 		// Some OOM situations appear to cause us to return NO.
   361 		test((iDec == iExpected) || (iDec == EUpsDecNo));
   362 		}
   363 	delete this;
   364 	}
   365 
   366 void CRequest::DoCancel()
   367 	{
   368 	}
   369 
   370 TInt CRequest::RunError(TInt aError)
   371 	{
   372 	User::Panic(_L("CRequest::RunError"), aError);
   373 	/*lint -unreachable*/
   374 	return KErrNone;
   375 	}
   376 
   377 
   378 #endif
   379 void TestSwiObserverL()
   380 	{
   381 	RUpsManagement session;
   382 	User::LeaveIfError(session.Connect());
   383 	CleanupClosePushL(session);
   384 
   385 	session.NotifyPluginsMayHaveChangedL();
   386 
   387 	TRequestStatus rs;
   388 	session.NotifyPolicyFilesChanged(rs);
   389 	User::WaitForRequest(rs);
   390 
   391 	test((rs.Int() == KErrNone) || (rs.Int() == KErrNoMemory));
   392 	if(rs.Int() == KErrNone)
   393 		{
   394 		session.CancelNotifyPolicyFilesChanged();
   395 		}
   396 
   397 	TSecureId ourSid(0x10283559);
   398 	session.DeleteDecisionsForExeL(ourSid);
   399 
   400 
   401 	CleanupStack::PopAndDestroy(&session);
   402 	}
   403 
   404 
   405 // -------- entrypoint --------
   406 void MainL()
   407 	{
   408  	// We need to increase the priority of the thread running the test code to make sure
   409  	// that asynchronous ups management calls, for example CreateView() , won't finish
   410  	// before following synchronous cancellation or termination calls, for example:
   411  	// DeleteDatabaseL() or CancelAndCloseView().
   412  	RThread thread;
   413  	TThreadPriority currentPri = thread.Priority();
   414  	currentPri = (TThreadPriority)((TInt)currentPri+10);
   415  	thread.SetPriority(currentPri);
   416 
   417 	CActiveScheduler *scheduler = new(ELeave) CActiveScheduler;
   418 	CActiveScheduler::Install(scheduler);
   419 	CleanupStack::PushL(scheduler);
   420 	
   421 	test.Title(_L("c:\\upstestobsifoom.log"));
   422 	test.Start(_L(" @SYMTestCaseID:SEC-UPS-OBSIF_OOM-0001 Testing RUpsSession SWI observer IF "));
   423 
   424 	RFs fs;
   425 	User::LeaveIfError(fs.Connect());
   426 	CleanupClosePushL(fs);
   427 
   428 	User::LeaveIfError(sMngmntSession.Connect());
   429 	sMngmntSession.ShutdownServer();
   430 	sMngmntSession.Close();
   431 
   432 	TBuf<21> notifierConfig(_L("!:\\upsrefnotifier.txt"));
   433 	notifierConfig[0] = fs.GetSystemDriveChar();
   434 
   435 	TInt lineLength = User::CommandLineLength();
   436 	switch(lineLength)
   437 		{
   438 		default:
   439 		// fall through - extra command line arguments are ignored
   440 		case 2:
   441 			// 2 char arg - Delete DB and run interactive
   442 			(void) fs.Delete(_L("c:\\Private\\10283558\\database\\ups.db"));
   443 			// Fall through to also delete notifier config file
   444 		case 1:
   445 			// 1 char arg - Run interactive, without deleting DB 
   446 			(void) fs.Delete(notifierConfig);
   447 			break;
   448 		case 0:
   449 			{
   450 			// No args - delete DB and run in silent mode
   451 			(void) fs.Delete(_L("c:\\Private\\10283558\\database\\ups.db"));
   452 
   453 			(void) fs.Delete(notifierConfig);
   454 			RFile file;
   455 			User::LeaveIfError(file.Create(fs, notifierConfig, EFileShareExclusive | EFileWrite));
   456 			User::LeaveIfError(file.Write(_L8("Always")));
   457 			file.Close();
   458 			break;
   459 			}
   460 		}
   461 
   462 	User::LeaveIfError(sMngmntSession.Connect());
   463 	CleanupClosePushL(sMngmntSession);
   464 
   465 
   466 	TInt err = KErrNone;
   467 	TInt errTmp = KErrNone;
   468 	TInt run = 0;
   469 	TInt passingRuns = 0;
   470 	static const TInt maxRun = 1000;
   471 	static const TInt passThreshold = 5;
   472 
   473 	for(run=1; run<=maxRun; ++run)
   474 		{
   475 		test.Printf(_L("\n\nOBSIF OOM -- Run %d\n"), run);
   476 
   477 		// Make sure the C: policy is deleted.
   478 		(void)fs.Delete(KResourceFileOnC);
   479 
   480 		// Make sure server is not holding cached values for the C: policy
   481 		// We could stop/restart the server, but that is very slow...
   482 		TRequestStatus rs;
   483 		sMngmntSession.NotifyPolicyFilesChanged(rs);
   484 		User::WaitForRequest(rs);
   485 
   486 		err = sMngmntSession.SetServerHeapFail(run);
   487 		if(err == KErrNoMemory)
   488 			{
   489 			// Reinitialisation failed
   490 			test.Printf(_L("\tReinitialisation failed\n"));
   491 			sMngmntSession.ResetServerHeapFail();
   492 			continue;
   493 			}
   494 		if(err != KErrNone)
   495 			{
   496 			// Failed to set heap fail, maybe the previous loop crashed the server??
   497 			test.Printf(_L("Failed to set heap fail with error code %d"), err);
   498 			test(EFalse);
   499 			break;
   500 			}
   501 
   502 		// Run the test
   503 		#if 1
   504 		CTestSwiIf *t = 0;
   505 		TRAP(err, t = CTestSwiIf::NewL());
   506 		if(err == KErrNone)
   507 			{
   508 			CActiveScheduler::Start();
   509 			err = t->Result();
   510 			delete t;
   511 			}
   512 		#else
   513 		err = KErrNone;
   514 		#endif
   515 
   516 #if 1
   517 		if(err == KErrNone)
   518 			{
   519 			TRAP(err, TestSwiObserverL());
   520 			}
   521 #endif
   522 
   523 		// Clear the heap fail
   524 		test.Printf(_L("Reseting heap failure\n"));
   525 		errTmp = sMngmntSession.ResetServerHeapFail();		
   526 		if((err == KErrServerTerminated) || (errTmp == KErrServerTerminated))
   527 			{
   528 			test.Printf(_L("\tUPS server died"));
   529 			test(EFalse);
   530 			break;
   531 			}
   532 		if((err == KErrNone) && (errTmp != KErrNone))
   533 			{
   534 			err = errTmp;
   535 			}
   536 		
   537 		// Did it work?
   538 		if(err == KErrNone)
   539 			{
   540 			++passingRuns;
   541 			}
   542 		else
   543 			{
   544 			passingRuns = 0;
   545 			}
   546 		
   547 		if(passingRuns > passThreshold) break;
   548 		} // End of OOM loop
   549 
   550 	if(run > maxRun)
   551 		{
   552 		User::Leave(err);
   553 		}
   554 
   555 	sMngmntSession.ShutdownServer();
   556 
   557 	// Close top level session (low level session was closed by
   558 	// ShutdownServer, but we still need to do the RUpsManagement
   559 	// cleanup).
   560 	CleanupStack::PopAndDestroy(&sMngmntSession);
   561 
   562 	(void) fs.Delete(notifierConfig);
   563 	CleanupStack::PopAndDestroy(&fs);
   564 	
   565 	test.End();
   566 	test.Close();
   567 
   568 	CleanupStack::PopAndDestroy(scheduler);
   569 }
   570 
   571 void PanicIfError(TInt r)
   572 	{
   573 	if(r != KErrNone)
   574 		{
   575 		User::Panic(_L("upstest failed: "), r);
   576 		}
   577 	}
   578 
   579 
   580 TInt E32Main()
   581 /**
   582 	Executable entrypoint establishes connection with UPS server
   583 	and then invokes tests for each functional area.
   584 	
   585 	@return					Symbian OS error code where KErrNone indicates
   586 							success and any other value indicates failure.
   587  */
   588 	{
   589 	// disable lazy DLL unloading so kernel heap balances at end
   590 	RLoader l;
   591 	PanicIfError(l.Connect());
   592 	PanicIfError(l.CancelLazyDllUnload());
   593 	l.Close();
   594 	
   595 	__UHEAP_MARK;
   596 	//__KHEAP_MARK;
   597 	
   598 	// allocating a cleanup stack also installs it
   599 	CTrapCleanup* tc = CTrapCleanup::New();
   600 	if (tc == 0)
   601 		return KErrNoMemory;
   602 
   603 
   604 	TRAPD(err, MainL());
   605 	if(err != KErrNone)
   606 		{
   607 		User::Panic(_L("upstest failed: "), err);
   608 		}
   609 	delete tc;
   610 	
   611 	//__KHEAP_MARKEND;
   612 	__UHEAP_MARKEND;
   613 	
   614 	
   615 	return KErrNone;
   616 	}
   617