sl@0: // Copyright (c) 2005-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 "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: // SWIS test step implementation sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: */ sl@0: sl@0: #include "installStep.h" sl@0: #include "common.h" sl@0: #include "tui.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "swi/sisregistrysession.h" sl@0: #include "swi/sisregistrypackage.h" sl@0: #include "swi/sisregistryentry.h" sl@0: #include "cleanuputils.h" sl@0: sl@0: using namespace Swi; sl@0: sl@0: // sl@0: // CinstallStep sl@0: // sl@0: sl@0: CinstallStep::~CinstallStep() sl@0: { sl@0: delete iUi; sl@0: } sl@0: sl@0: sl@0: CinstallStep::CinstallStep(TInstallType aInstallType, TBool aDoCancelTest) sl@0: : iInstallType(aInstallType), iDoCancelTest(aDoCancelTest), sl@0: iInstallSuccess(EFalse) sl@0: { sl@0: // Call base class method to set up the human readable name for logging sl@0: sl@0: switch (aInstallType) sl@0: { sl@0: case EUseFileHandle: sl@0: SetTestStepName(KInstallFHStep); sl@0: break; sl@0: sl@0: case EUseMemory: sl@0: SetTestStepName(KInstallMemStep); sl@0: break; sl@0: sl@0: case EUseFileName: sl@0: SetTestStepName(KInstallStep); sl@0: break; sl@0: sl@0: case EUseCAF: sl@0: SetTestStepName(KInstallCAFStep); sl@0: break; sl@0: sl@0: case EUseOpenFileName: sl@0: SetTestStepName(KInstallOpenFileStep); sl@0: break; sl@0: sl@0: case ECheckExitValue: sl@0: SetTestStepName(KCheckedInstallStep); sl@0: break; sl@0: sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * Override of base class virtual. Prepares for the test run of SWIS sl@0: * @return TVerdict code sl@0: */ sl@0: TVerdict CinstallStep::doTestStepPreambleL() sl@0: { sl@0: SetTestStepResult(EPass); sl@0: // get step parameters sl@0: TPtrC str; sl@0: if (!GetStringFromConfig(ConfigSection(), _L("sis"), str)) sl@0: { sl@0: INFO_PRINTF1(HTML_RED); sl@0: ERR_PRINTF1(_L("FAIL: Missing SIS file name")); sl@0: INFO_PRINTF1(HTML_RED_OFF); sl@0: SetTestStepResult(EFail); sl@0: return TestStepResult(); sl@0: } sl@0: iSisFileName.Copy(str); sl@0: INFO_PRINTF2(_L("Installing '%S'"), &iSisFileName); sl@0: sl@0: // create UI handler and populate the answers from XML file sl@0: iUi = new(ELeave) TUI(); sl@0: sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: * Override of base class pure virtual sl@0: * Demonstrates reading configuration parameters fom an ini file section sl@0: * @return TVerdict code sl@0: */ sl@0: TVerdict CinstallStep::doTestStepL() sl@0: { sl@0: INFO_PRINTF1(KInstallStep); sl@0: sl@0: // Try to set up a repository object, we'll need this if any sl@0: // NotifyRequests are listed. Only open the repository if there are sl@0: // notifys. sl@0: sl@0: TInt bRet; sl@0: sl@0: // First find out if the install step is supposed to be successful. sl@0: TInt insterr=KErrNone; sl@0: bRet = GetIntFromConfig(ConfigSection(), KExpectedError, insterr ); sl@0: if(bRet!=1) insterr=KErrNone; sl@0: sl@0: CInstallPrefs* prefs = CInstallPrefs::NewLC(); sl@0: TInt err = DoInstallL(*prefs); sl@0: iInstallSuccess = (err == KErrNone); sl@0: sl@0: // Expected error? sl@0: if(insterr != err) sl@0: { sl@0: INFO_PRINTF1(HTML_RED); sl@0: ERR_PRINTF3( _L("Installation return wrong error code, expected %d, got %d."), insterr, err ); sl@0: INFO_PRINTF1(HTML_RED_OFF); sl@0: SetTestStepResult(EFail); sl@0: } sl@0: else sl@0: { sl@0: INFO_PRINTF2( _L("Installation error code %d (expected)."), err ); sl@0: } sl@0: sl@0: sl@0: CleanupStack::PopAndDestroy(prefs); sl@0: sl@0: return TestStepResult(); sl@0: sl@0: } sl@0: sl@0: TInt CinstallStep::DoInstallL(CInstallPrefs& aInstallPrefs) sl@0: { sl@0: TInt err=KErrNone; sl@0: RFs fs; sl@0: RFile file; sl@0: switch (iInstallType) sl@0: { sl@0: case EUseFileName: sl@0: err = Launcher::Install(*iUi, iSisFileName, aInstallPrefs); sl@0: INFO_PRINTF2(_L("EUseFileName: Install return code was %d"), err); sl@0: return err; sl@0: sl@0: case EUseOpenFileName: sl@0: // open the file as a shared for readers only sl@0: { sl@0: User::LeaveIfError(fs.Connect()); sl@0: fs.ShareProtected(); sl@0: CleanupClosePushL(fs); sl@0: RFile file; sl@0: User::LeaveIfError(file.Open(fs, iSisFileName, EFileShareReadersOnly)); sl@0: CleanupClosePushL(file); sl@0: TInt error = Launcher::Install(*iUi, iSisFileName, aInstallPrefs); sl@0: CleanupStack::PopAndDestroy(2, &fs); sl@0: return error; sl@0: } sl@0: sl@0: case EUseFileHandle: sl@0: { sl@0: RFs fs; sl@0: User::LeaveIfError(fs.Connect()); sl@0: fs.ShareProtected(); sl@0: CleanupClosePushL(fs); sl@0: RFile file; sl@0: User::LeaveIfError(file.Open(fs, iSisFileName, 0)); sl@0: CleanupClosePushL(file); sl@0: TInt error=Launcher::Install(*iUi, file, aInstallPrefs); sl@0: CleanupStack::PopAndDestroy(2, &fs); sl@0: return error; sl@0: } sl@0: sl@0: case ECheckExitValue: sl@0: { sl@0: // This test case does an install and checks for pass or failure sl@0: // TInt err = Launcher::Install(*iUi, iSisFileName, *prefs); sl@0: TInt err = Launcher::Install(*iUi, iSisFileName, aInstallPrefs); sl@0: INFO_PRINTF2(_L("Install return code was %d"), err); sl@0: sl@0: TPtrC expected; sl@0: if (!GetStringFromConfig(ConfigSection(), _L("result"), expected)) sl@0: { sl@0: return ETestSuiteError; sl@0: } sl@0: else sl@0: { sl@0: _LIT(KSucess, "sucess"); sl@0: _LIT(KFailure, "failure"); sl@0: sl@0: TVerdict result; sl@0: sl@0: if (expected.CompareF(KSucess) == 0) sl@0: { sl@0: result = (err == KErrNone ? EPass : EFail); sl@0: } sl@0: else if (expected.CompareF(KFailure) == 0) sl@0: { sl@0: result = (err != KErrNone ? EPass : EFail); sl@0: } sl@0: else sl@0: { sl@0: result = ETestSuiteError; sl@0: } sl@0: return result; sl@0: } sl@0: } sl@0: // Unreachable. sl@0: // break; sl@0: } sl@0: sl@0: // Shouldn't get here sl@0: return KErrGeneral; sl@0: } sl@0: sl@0: /** sl@0: * Override of base class virtual sl@0: * @return TVerdict code sl@0: */ sl@0: TVerdict CinstallStep::doTestStepPostambleL() sl@0: { sl@0: CheckFilesExistL(); sl@0: CheckFilesNonExistL(); sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: /** Need to wait a few seconds for ECOM to sl@0: discover the change. Otherwise the next step may fail. sl@0: @pre caller has checked the install/uninstall sl@0: is successful. Otherwise will waste 30 s. sl@0: */ sl@0: void Cinstallers::WaitForEComReDiscoveryL() sl@0: { sl@0: REComSession& ecomSession = REComSession::OpenL(); sl@0: CleanupClosePushL(ecomSession); sl@0: TRequestStatus ecomstatus; sl@0: ecomSession.NotifyOnChange(ecomstatus); sl@0: sl@0: RTimer timer; sl@0: User::LeaveIfError(timer.CreateLocal()); sl@0: CleanupClosePushL(timer); sl@0: const TInt KInterval = 30000000; // 30 s sl@0: TRequestStatus timerstatus; sl@0: timer.After(timerstatus, KInterval); sl@0: sl@0: User::WaitForRequest(ecomstatus, timerstatus); sl@0: sl@0: if (ecomstatus == KRequestPending) sl@0: { sl@0: ecomSession.CancelNotifyOnChange(ecomstatus); sl@0: User::WaitForRequest(ecomstatus); sl@0: sl@0: INFO_PRINTF1(HTML_RED); sl@0: ERR_PRINTF1(_L("No notification from ECOM")); sl@0: INFO_PRINTF1(HTML_RED_OFF); sl@0: // does not affect test result as this is the equivalent of sl@0: // DELAY 30000 in the script. sl@0: } sl@0: else sl@0: { sl@0: timer.Cancel(); sl@0: User::WaitForRequest(timerstatus); sl@0: INFO_PRINTF1(_L("ECOM has discovered the change")); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(2); // ecomsession, RTimer sl@0: REComSession::FinalClose(); sl@0: } sl@0: sl@0: /** Resolver installation step */ sl@0: sl@0: /** constructor */ sl@0: CResolverInstallStep::CResolverInstallStep(CinstallStep::TInstallType aInstallType) sl@0: : CinstallStep(aInstallType) sl@0: { sl@0: } sl@0: sl@0: /** destructor */ sl@0: CResolverInstallStep::~CResolverInstallStep() sl@0: { sl@0: iLibrary.Close(); sl@0: } sl@0: sl@0: /** uses CinstallStep::dotestStepL to do the install. sl@0: But adds an optional step of loading a DLL before, and sl@0: a step to wait for ECom rediscovery after. sl@0: */ sl@0: TVerdict CResolverInstallStep::doTestStepL() sl@0: { sl@0: TPtrC libraryPath; sl@0: if (GetStringFromConfig(ConfigSection(), _L("loadresolver"), libraryPath)) sl@0: { sl@0: TUidType nullUid; sl@0: TInt err = iLibrary.Load(libraryPath, nullUid); sl@0: if (err != KErrNone) sl@0: { sl@0: ERR_PRINTF2(_L("Preload resolver failed %d"), err); sl@0: return EFail; sl@0: } sl@0: } sl@0: sl@0: // continue to do the actual install. sl@0: TVerdict ret = CinstallStep::doTestStepL(); sl@0: sl@0: if (iInstallSuccess) sl@0: { sl@0: WaitForEComReDiscoveryL(); sl@0: } sl@0: sl@0: return ret; sl@0: } sl@0: sl@0: /* ******************************************************************************* sl@0: * Code below was copies from sl@0: * \master\common\generic\security\swi\test\tuiscriptadaptors\tswisstep.cpp sl@0: * sl@0: * If there are any problems with this code, it may be worth contacting the sl@0: * Security team. sl@0: * *******************************************************************************/ sl@0: sl@0: // sl@0: // CuninstallStep sl@0: // sl@0: sl@0: CuninstallStep::~CuninstallStep() sl@0: { sl@0: delete iUi; sl@0: } sl@0: sl@0: CuninstallStep::CuninstallStep(TUninstallType aType, TBool aDoCancelTest) sl@0: : iType(aType), iDoCancelTest(aDoCancelTest) sl@0: { sl@0: // Call base class method to set up the human readable name for logging sl@0: SetTestStepName(KUninstallStep); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: /** sl@0: * Override of base class virtual. Prepares for the test run of SWIS sl@0: * @return TVerdict code sl@0: */ sl@0: TVerdict CuninstallStep::doTestStepPreambleL() sl@0: { sl@0: // get step parameters sl@0: TInt uid=0; sl@0: sl@0: TPtrC str; sl@0: sl@0: if (!GetHexFromConfig(ConfigSection(), _L("uid"), uid)) sl@0: { sl@0: INFO_PRINTF1(HTML_RED); sl@0: ERR_PRINTF1(_L("Missing uid")); sl@0: INFO_PRINTF1(HTML_RED_OFF); sl@0: SetTestStepResult(EFail); sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: iUid.iUid=uid; sl@0: sl@0: if (iType == EByPackage) sl@0: { sl@0: TPtrC vendorName; sl@0: if (!GetStringFromConfig(ConfigSection(), _L("vendorName"), vendorName)) sl@0: { sl@0: INFO_PRINTF1(HTML_RED); sl@0: ERR_PRINTF1(_L("Missing Vendor Name")); sl@0: INFO_PRINTF1(HTML_RED_OFF); sl@0: SetTestStepResult(EFail); sl@0: return TestStepResult(); sl@0: } sl@0: iVendorName.Set(vendorName); sl@0: sl@0: TPtrC packageName; sl@0: if (!GetStringFromConfig(ConfigSection(), _L("packageName"), packageName)) sl@0: { sl@0: INFO_PRINTF1(HTML_RED); sl@0: ERR_PRINTF1(_L("Missing Package Name")); sl@0: INFO_PRINTF1(HTML_RED_OFF); sl@0: SetTestStepResult(EFail); sl@0: return TestStepResult(); sl@0: } sl@0: iPackageName.Set(packageName); sl@0: sl@0: INFO_PRINTF4(_L("Uninstalling %D, %S, %S"), sl@0: iUid.iUid, &iPackageName, &iVendorName); sl@0: // create UI handler and populate the answers from XML file sl@0: iUi = new(ELeave) TUI; sl@0: sl@0: } sl@0: else if (iType== EByUid) sl@0: { sl@0: INFO_PRINTF2(_L("Uninstalling '%D'"), iUid.iUid); sl@0: // create UI handler and populate the answers from XML file sl@0: iUi = new(ELeave) TUI; sl@0: sl@0: } sl@0: sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: /** sl@0: * Override of base class pure virtual sl@0: * Demonstrates reading configuration parameters fom an ini file section sl@0: * @return TVerdict code sl@0: */ sl@0: sl@0: TInt CuninstallStep::DoUninstallL() sl@0: { sl@0: TInt err=0; sl@0: sl@0: INFO_PRINTF1(KUninstallStep); sl@0: sl@0: if (iType == EByUid) sl@0: { sl@0: // launch the installation sl@0: err = Launcher::Uninstall(*iUi, iUid); sl@0: return err; sl@0: } sl@0: else if (iType == EByPackage) sl@0: { sl@0: err = 0; sl@0: sl@0: // Go through list of packages from base package to get augmentations. sl@0: CSisRegistryPackage* uninstallPackage=CSisRegistryPackage::NewLC(iUid, iPackageName, iVendorName); sl@0: INFO_PRINTF3(_L("UnInstalling '%S', '%S'"), &iPackageName, &iVendorName); sl@0: sl@0: // err=Launcher::Uninstall(*iUi, *uninstallPackage); sl@0: sl@0: RSisRegistrySession registrySession; sl@0: User::LeaveIfError(registrySession.Connect()); sl@0: CleanupClosePushL(registrySession); sl@0: sl@0: RSisRegistryEntry registryEntry; sl@0: sl@0: User::LeaveIfError(registryEntry.Open(registrySession, iUid)); sl@0: CleanupClosePushL(registryEntry); sl@0: sl@0: CSisRegistryPackage* package=registryEntry.PackageL(); sl@0: CleanupStack::PushL(package); sl@0: sl@0: if (*package == *uninstallPackage) sl@0: { sl@0: err=Launcher::Uninstall(*iUi, *package); sl@0: } sl@0: else sl@0: { sl@0: // check augmenations sl@0: RPointerArray augmentationPackages; sl@0: CleanupResetAndDestroy >::PushL(augmentationPackages); sl@0: sl@0: registryEntry.AugmentationsL(augmentationPackages); sl@0: sl@0: for (TInt i=0; i < augmentationPackages.Count(); ++i) sl@0: { sl@0: if (*augmentationPackages[i] == *uninstallPackage) sl@0: { sl@0: err=User::LeaveIfError(Launcher::Uninstall(*iUi, *augmentationPackages[i])); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: if (err != 0) sl@0: { sl@0: INFO_PRINTF1(HTML_RED); sl@0: ERR_PRINTF2(_L("Package Augmentation Not found for '%s' "), &iPackageName); sl@0: INFO_PRINTF1(HTML_RED_OFF); sl@0: SetTestStepResult(EFail); sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(&augmentationPackages); sl@0: } sl@0: sl@0: CleanupStack::PopAndDestroy(3, ®istrySession); sl@0: CleanupStack::PopAndDestroy(uninstallPackage); sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: /* ****************************************************************************** sl@0: * End of copied code. sl@0: * ******************************************************************************/ sl@0: sl@0: TVerdict CuninstallStep::doTestStepL() sl@0: { sl@0: INFO_PRINTF1(KUninstallStep); sl@0: sl@0: sl@0: sl@0: // Wait a fraction over a second. This is necessary because we may just sl@0: // have been messing about with repository settings and if the install sl@0: // happens really quickly we might not see a datestamp change (esp. on sl@0: // hardware where the timestamp granularity is poor). sl@0: User::After(1100000); sl@0: User::LeaveIfError(DoUninstallL()); sl@0: sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: /** sl@0: * Override of base class virtual sl@0: * @return TVerdict code sl@0: */ sl@0: TVerdict CuninstallStep::doTestStepPostambleL() sl@0: { sl@0: CheckFilesExistL(); sl@0: CheckFilesNonExistL(); sl@0: return TestStepResult(); sl@0: } sl@0: sl@0: // CResolverUninstallStep class sl@0: sl@0: /** constructor */ sl@0: CResolverUninstallStep::CResolverUninstallStep(CuninstallStep::TUninstallType aType) sl@0: : CuninstallStep(aType) sl@0: { sl@0: } sl@0: sl@0: /** nothing to do in destructor */ sl@0: CResolverUninstallStep::~CResolverUninstallStep() sl@0: { sl@0: } sl@0: sl@0: /** runs CuninstallStep::doTestStepL and then sl@0: do a WaitForEComReDiscoveryL */ sl@0: TVerdict CResolverUninstallStep::doTestStepL() sl@0: { sl@0: TVerdict ret = CuninstallStep::doTestStepL(); sl@0: if (ret == EPass) sl@0: { sl@0: WaitForEComReDiscoveryL(); sl@0: } sl@0: return ret; sl@0: } sl@0: sl@0: Cinstallers::~Cinstallers() sl@0: /** sl@0: * Destructor sl@0: */ sl@0: { sl@0: } sl@0: sl@0: Cinstallers::Cinstallers() sl@0: /** sl@0: * Constructor sl@0: */ sl@0: { sl@0: } sl@0: sl@0: void Cinstallers::CheckFilesL(const TDesC& aNumEntries, sl@0: const TDesC& aEntryBase, TBool aCheckExist) sl@0: { sl@0: TInt numEntries=0; sl@0: TInt nErr=0; sl@0: sl@0: _LIT(Report_CheckFiles, "CheckFilesL"); sl@0: INFO_PRINTF1(Report_CheckFiles); sl@0: sl@0: RFs fs; sl@0: User::LeaveIfError(fs.Connect()); sl@0: fs.ShareProtected(); sl@0: CleanupClosePushL(fs); sl@0: sl@0: if (GetIntFromConfig(ConfigSection(), aNumEntries, numEntries) && numEntries!=0) sl@0: { sl@0: INFO_PRINTF1(Report_CheckFiles); sl@0: TPtrC fname; sl@0: for (TInt i=0; i keyBuf(aEntryBase); sl@0: keyBuf.AppendNum(i); sl@0: sl@0: if (GetStringFromConfig(ConfigSection(), keyBuf, fname)) sl@0: { sl@0: TInt timeout=1e7; sl@0: TInt wait=2.5e5; sl@0: // check if the file (doesn't) exist. Give it some time if sl@0: // we see a failure in case there's a race with the sl@0: // (un)installer sl@0: sl@0: if (aCheckExist) sl@0: { sl@0: TInt sec=timeout; sl@0: while (!BaflUtils::FileExists(fs, fname) && (sec>0)) sl@0: { sl@0: User::After(wait); sl@0: sec -= wait; sl@0: }; sl@0: if (!BaflUtils::FileExists(fs, fname)) sl@0: { sl@0: INFO_PRINTF1(HTML_RED); sl@0: ERR_PRINTF2(_L("File missing: %S"), &fname); sl@0: INFO_PRINTF1(HTML_RED_OFF); sl@0: nErr++; sl@0: } sl@0: } sl@0: else sl@0: { sl@0: TInt sec=timeout; sl@0: while (BaflUtils::FileExists(fs, fname) && (sec>0)) sl@0: { sl@0: User::After(wait); sl@0: sec -= wait; sl@0: }; sl@0: if (BaflUtils::FileExists(fs, fname)) sl@0: { sl@0: INFO_PRINTF1(HTML_RED); sl@0: ERR_PRINTF2(_L("File exists (but shouldn't): %S"), &fname); sl@0: INFO_PRINTF1(HTML_RED_OFF); sl@0: nErr++; sl@0: } sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // the string must exist, otherwise the config is invalid sl@0: INFO_PRINTF1(HTML_RED); sl@0: ERR_PRINTF2(_L("Missing file name for key '%S'"), &keyBuf); sl@0: INFO_PRINTF1(HTML_RED_OFF); sl@0: nErr++; sl@0: } sl@0: } sl@0: } sl@0: sl@0: if (nErr) sl@0: SetTestStepResult(EFail); sl@0: CleanupStack::PopAndDestroy(1, &fs); sl@0: } sl@0: sl@0: void Cinstallers::CheckFilesExistL() sl@0: { sl@0: _LIT(KNumExist, "numexist"); // this specifies how many files to check for sl@0: _LIT(KExistBase, "exist"); // + number (0-based) = file to check for sl@0: CheckFilesL(KNumExist, KExistBase, ETrue); sl@0: } sl@0: sl@0: void Cinstallers::CheckFilesNonExistL() sl@0: { sl@0: _LIT(KNumNonExist, "numnonexist"); // this specifies how many files to check for sl@0: _LIT(KNonExistBase, "nonexist"); // + number (0-based) = file to check for sl@0: CheckFilesL(KNumNonExist, KNonExistBase, EFalse); sl@0: } sl@0: