sl@0: /* sl@0: * Copyright (c) 2004-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: * sl@0: */ sl@0: sl@0: sl@0: #include "t_policy.h" sl@0: #include "t_input.h" sl@0: #include "t_output.h" sl@0: #include "t_testhandler.h" sl@0: #include "utf.h" sl@0: sl@0: #include sl@0: sl@0: // run failure tests first sl@0: sl@0: _LIT8(KTestExeStart, ""); sl@0: _LIT8(KExcludedCapsStart, ""); sl@0: _LIT8(KPolicyStart, ""); sl@0: _LIT8(KPreActionsStart, ""); sl@0: _LIT8(KPassAcionStart, ""); sl@0: _LIT8(KFailAcionStart, ""); sl@0: _LIT8(KPostActionsStart, ""); sl@0: _LIT8(KSecureIdStart, ""); sl@0: _LIT8(KSecureIdEnd, ""); sl@0: _LIT8(KVendorIdStart, ""); sl@0: _LIT8(KVendorIdEnd, ""); sl@0: sl@0: _LIT(KFormat,"Action Name : %S \n"); sl@0: _LIT(KSetCapExe, "setcap"); sl@0: _LIT(KSetCapExe2, "setcap : "); sl@0: //NOTE :If the below literal is uncommented , remove the c:\hardcoded reference sl@0: // and replace with RFs::GetSystemDrive(). sl@0: //_LIT(KTestExeTmpPath, "c:\\sys\\bin\\policytest_exe.exe"); sl@0: _LIT(KPassScriptPath, "\\policytest_script_pass.txt"); sl@0: _LIT(KFailScriptPath, "\\policytest_script_fail.txt"); sl@0: _LIT(KLogTmpPath, "\\policytest_log.txt"); sl@0: _LIT(KTestPath, "policytest_"); sl@0: _LIT(KFailTestRunning, "Fail Test Script Running"); sl@0: _LIT(KPassTestRunning, "Pass Test Script Running"); sl@0: sl@0: sl@0: const TUint KCapabilityAll = 0xffffffff; sl@0: sl@0: CPolicyTest* CPolicyTest::NewL(CConsoleBase& aConsole, sl@0: Output& aOut, sl@0: const TTestActionSpec& aTestActionSpec) sl@0: { sl@0: CPolicyTest* self = CPolicyTest::NewLC(aConsole, aOut, aTestActionSpec); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CPolicyTest* CPolicyTest::NewLC(CConsoleBase& aConsole, sl@0: Output& aOut, sl@0: const TTestActionSpec& aTestActionSpec) sl@0: { sl@0: CPolicyTest* self = new(ELeave) CPolicyTest(aConsole, aOut); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aTestActionSpec); sl@0: return self; sl@0: } sl@0: sl@0: CPolicyTest::CPolicyTest(CConsoleBase& aConsole, sl@0: Output& aOut) sl@0: : CTestAction(aConsole, aOut) sl@0: { sl@0: } sl@0: sl@0: void CPolicyTest::ConstructL(const TTestActionSpec& aTestActionSpec) sl@0: { sl@0: CTestAction::ConstructL(aTestActionSpec); sl@0: iExpectedResult = KErrNone; sl@0: sl@0: User::LeaveIfError(iFs.Connect()); sl@0: sl@0: RProcess thisProcess; sl@0: User::LeaveIfError(thisProcess.Open(thisProcess.Id())); sl@0: iProcessSecureId = thisProcess.SecureId(); sl@0: iProcessVendorId = thisProcess.VendorId(); sl@0: thisProcess.Close(); sl@0: sl@0: SetTestExeL(Input::ParseElement(aTestActionSpec.iActionBody, KTestExeStart)); sl@0: Input::ParseCapabilitySetL(Input::ParseElement(aTestActionSpec.iActionBody, KExcludedCapsStart), iExcludedCaps); sl@0: SetPolicyL(Input::ParseElement(aTestActionSpec.iActionBody, KPolicyStart)); sl@0: iPreActions = Input::ParseElement(aTestActionSpec.iActionBody, KPreActionsStart).AllocL(); sl@0: SetTestActionL(Input::ParseElement(aTestActionSpec.iActionBody, KPassAcionStart), sl@0: Input::ParseElement(aTestActionSpec.iActionBody, KFailAcionStart)); sl@0: iPostActions = Input::ParseElement(aTestActionSpec.iActionBody, KPostActionsStart).AllocL(); sl@0: } sl@0: sl@0: CPolicyTest::~CPolicyTest() sl@0: { sl@0: iFs.Close(); sl@0: delete iTestExe; sl@0: iCapabilities.Close(); sl@0: delete iPreActions; sl@0: delete iPassAction; sl@0: delete iFailAction; sl@0: delete iPostActions; sl@0: iProcess.Close(); sl@0: } sl@0: sl@0: void CPolicyTest::BadUsageL(const TDesC& aMessage) sl@0: { sl@0: iOut.writeString(_L("Error in script action testpolicy")); sl@0: iOut.writeNewLine(); sl@0: iOut.writeString(aMessage); sl@0: iOut.writeNewLine(); sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: void CPolicyTest::SetTestExeL(const TDesC8& aPath) sl@0: { sl@0: if (aPath == KNullDesC8) sl@0: { sl@0: BadUsageL(_L("testexe not specified")); sl@0: } sl@0: sl@0: iTestExe = HBufC::NewMaxL(aPath.Length()); sl@0: TPtr ptr = iTestExe->Des(); sl@0: ptr.Copy(aPath); sl@0: } sl@0: sl@0: void CPolicyTest::SetPolicyL(const TDesC8& aSpec) sl@0: { sl@0: iSecureId = Input::ParseIntElement(aSpec, KSecureIdStart, KSecureIdEnd); sl@0: iVendorId = Input::ParseIntElement(aSpec, KVendorIdStart, KVendorIdEnd); sl@0: sl@0: TCapabilitySet capSet; sl@0: Input::ParseCapabilitySetL(aSpec, capSet); sl@0: sl@0: // Extract capabilities into array sl@0: for (TInt i = 0 ; i < ECapability_Limit ; ++i) sl@0: { sl@0: TCapability c = static_cast(i); sl@0: if (capSet.HasCapability(c)) sl@0: { sl@0: User::LeaveIfError(iCapabilities.Append(c)); sl@0: } sl@0: } sl@0: } sl@0: sl@0: void CPolicyTest::SetTestActionL(const TDesC8& aPassAction, const TDesC8& aFailAction) sl@0: { sl@0: if (aPassAction == KNullDesC8) sl@0: { sl@0: BadUsageL(_L("passactions not specified")); sl@0: } sl@0: sl@0: iPassAction = aPassAction.AllocL(); sl@0: sl@0: if (aFailAction == KNullDesC8) sl@0: { sl@0: BadUsageL(_L("failactions not specified")); sl@0: } sl@0: sl@0: iFailAction = aFailAction.AllocL(); sl@0: } sl@0: sl@0: void CPolicyTest::PerformAction(TRequestStatus& aStatus) sl@0: { sl@0: if (aStatus < 0) sl@0: { sl@0: iState = EFinished; sl@0: } sl@0: sl@0: switch (iState) sl@0: { sl@0: case EInit: sl@0: { sl@0: TDriveUnit sysDrive (RFs::GetSystemDrive()); sl@0: TDriveName sysDriveName (sysDrive.Name()); sl@0: sl@0: TBuf<128> scriptFile (sysDriveName); sl@0: scriptFile.Append(KPassScriptPath); sl@0: WriteScriptFileL(scriptFile, *iPassAction); sl@0: sl@0: scriptFile.Copy(sysDriveName); sl@0: scriptFile.Append(KFailScriptPath); sl@0: WriteScriptFileL(scriptFile, *iFailAction); sl@0: } sl@0: // fall through sl@0: sl@0: case ESetupTest: sl@0: GetNextTest(); sl@0: if (iTestState == ETestFinished) sl@0: { sl@0: iState = EFinished; sl@0: TRequestStatus* status = &aStatus; sl@0: User::RequestComplete(status, KErrNone); sl@0: } sl@0: else sl@0: { sl@0: SetupTestL(aStatus); sl@0: iState = ERunTest; sl@0: } sl@0: break; sl@0: sl@0: case ERunTest: sl@0: CheckProcessTermintationL(); sl@0: RunTestL(aStatus); sl@0: iState = EProcessResults; sl@0: break; sl@0: sl@0: case EProcessResults: sl@0: CheckProcessTermintationL(); sl@0: ProcessResultsL(aStatus); sl@0: iState = ESetupTest; sl@0: break; sl@0: sl@0: case EFinished: sl@0: iActionState = EPostrequisite; sl@0: TRequestStatus* status = &aStatus; sl@0: User::RequestComplete(status, aStatus.Int()); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: void CPolicyTest::StartProcessL(const TDesC& aExe, const TDesC& aCommandLine, TRequestStatus& aStatus) sl@0: { sl@0: iOut.writeString(_L("Starting child process: ")); sl@0: iOut.writeString(aExe); sl@0: iOut.writeString(_L(" ")); sl@0: iOut.writeString(aCommandLine); sl@0: iOut.writeNewLine(); sl@0: sl@0: User::LeaveIfError(iProcess.Create(aExe, aCommandLine)); sl@0: iProcess.Logon(aStatus); sl@0: iProcess.Resume(); sl@0: } sl@0: sl@0: void CPolicyTest::CheckProcessTermintationL() sl@0: { sl@0: if (iProcess.ExitType() == EExitPanic) sl@0: { sl@0: iOut.writeString(_L("Child process panicked: ")); sl@0: iOut.writeString(iProcess.ExitCategory()); sl@0: iOut.writeString(_L(" ")); sl@0: iOut.writeNum(iProcess.ExitReason()); sl@0: iOut.writeNewLine(); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: ASSERT(iProcess.ExitType() == EExitKill); sl@0: iProcess.Close(); sl@0: } sl@0: sl@0: void CPolicyTest::GetNextTest() sl@0: { sl@0: // Step through capabilities to be tested sl@0: if (iTestState == ETestFailCap) sl@0: { sl@0: ++iCapIndex; sl@0: if (iCapIndex < iCapabilities.Count()) sl@0: return; sl@0: } sl@0: sl@0: // Step through possible tests until we hit a vaild test sl@0: do sl@0: { sl@0: iTestState = static_cast(iTestState + 1); sl@0: } sl@0: while (!((iTestState == ETestFailSID && iSecureId) || sl@0: (iTestState == ETestFailVID && iVendorId) || sl@0: (iTestState == ETestFailCap && iCapabilities.Count()) || sl@0: (iTestState == ETestPass) || sl@0: (iTestState == ETestFinished))); sl@0: } sl@0: sl@0: void CPolicyTest::SetupTestL(TRequestStatus& aStatus) sl@0: { sl@0: switch (iTestState) sl@0: { sl@0: case ETestFailSID: sl@0: { sl@0: TInt wrongSecureId = iSecureId + 1; sl@0: iOut.write(_L("Failure test: Wrong SID (%08x):\n\n"), wrongSecureId); sl@0: SetTestSecurityInfoL(wrongSecureId, iVendorId, KCapabilityAll, aStatus); sl@0: } sl@0: break; sl@0: sl@0: case ETestFailVID: sl@0: { sl@0: TInt wrongVendorId = iVendorId + 1; sl@0: iOut.write(_L("Failure test: Wrong VID (%08x):\n\n"), wrongVendorId); sl@0: SetTestSecurityInfoL(iSecureId, wrongVendorId, KCapabilityAll, aStatus); sl@0: } sl@0: break; sl@0: sl@0: case ETestFailCap: sl@0: { sl@0: TCapability missingCap = iCapabilities[iCapIndex]; sl@0: sl@0: iOut.writeString(_L("Failure test: Missing capability (")); sl@0: iOut.writeCapabilityL(missingCap); sl@0: iOut.writeString(_L("):\n\n")); sl@0: sl@0: TUint capSet = ~ (1 << missingCap); sl@0: SetTestSecurityInfoL(iSecureId, iVendorId, capSet, aStatus); sl@0: } sl@0: break; sl@0: sl@0: case ETestPass: sl@0: { sl@0: iOut.write(_L("Pass test:\n\n")); sl@0: sl@0: TUint capSet = 0; sl@0: for (TInt i = 0 ; i < iCapabilities.Count() ; ++i) sl@0: { sl@0: capSet |= 1 << iCapabilities[i]; sl@0: } sl@0: sl@0: SetTestSecurityInfoL(iSecureId, iVendorId, capSet, aStatus); sl@0: } sl@0: break; sl@0: sl@0: default: sl@0: User::Invariant(); sl@0: } sl@0: } sl@0: sl@0: void CPolicyTest::SetTestSecurityInfoL(TInt aSecureId, TInt aVendorId, TUint aCapSet, TRequestStatus& aStatus) sl@0: { sl@0: // Remove excluded capabilities sl@0: for (TInt i = 0 ; i < ECapability_Limit ; ++i) sl@0: { sl@0: if (iExcludedCaps.HasCapability(static_cast(i))) sl@0: { sl@0: aCapSet &= ~ (1 << i); sl@0: } sl@0: } sl@0: sl@0: TBuf<128> commandLine; sl@0: commandLine.AppendFormat(_L("%S %08x "), iTestExe, aCapSet); sl@0: if (aSecureId) sl@0: { sl@0: commandLine.AppendFormat(_L("-SID %08x "), aSecureId); sl@0: } sl@0: if (aVendorId) sl@0: { sl@0: commandLine.AppendFormat(_L("-VID %08x "), aVendorId); sl@0: } sl@0: // commandLine.Append(KTestExeTmpPath); sl@0: iTestExeTmpNewPath = KTestPath; sl@0: iTestExeTmpNewPath.Append(*iTestExe); sl@0: commandLine.Append(iTestExeTmpNewPath); sl@0: sl@0: TBuf<128> isetcapTmpNewPath1; //stores the value of commandline sl@0: TBuf<128> isetcapTmpNewPath; //stores the value of KsetCapexe2 sl@0: isetcapTmpNewPath = KSetCapExe2; sl@0: isetcapTmpNewPath1= commandLine; sl@0: isetcapTmpNewPath.Append(isetcapTmpNewPath1); sl@0: RDebug::RawPrint(isetcapTmpNewPath); sl@0: StartProcessL(KSetCapExe, commandLine, aStatus); sl@0: sl@0: } sl@0: sl@0: void CPolicyTest::WriteScriptFileL(const TDesC& aPath, const TDesC8& aAction) sl@0: { sl@0: iFs.Delete(aPath); // ignore errors sl@0: sl@0: RFile file; sl@0: User::LeaveIfError(file.Create(iFs, aPath, EFileShareExclusive | EFileWrite)); sl@0: CleanupClosePushL(file); sl@0: sl@0: User::LeaveIfError(file.Write(*iPreActions)); sl@0: User::LeaveIfError(file.Write(aAction)); sl@0: User::LeaveIfError(file.Write(*iPostActions)); sl@0: sl@0: CleanupStack::PopAndDestroy(&file); sl@0: } sl@0: sl@0: void CPolicyTest::RunTestL(TRequestStatus& aStatus) sl@0: { sl@0: sl@0: HBufC* hptr16; sl@0: hptr16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*iNameInfo); sl@0: RDebug::Print(KFormat,hptr16); sl@0: delete hptr16; sl@0: sl@0: TDriveUnit sysDrive (RFs::GetSystemDrive()); sl@0: TDriveName sysDriveName (sysDrive.Name()); sl@0: sl@0: TBuf<128> passScriptFile (sysDriveName); sl@0: passScriptFile.Append(KPassScriptPath); sl@0: sl@0: TBuf<128> failScriptFile (sysDriveName); sl@0: failScriptFile.Append(KFailScriptPath); sl@0: sl@0: TPtrC script = (iTestState == ETestPass) ? passScriptFile : failScriptFile; sl@0: (iTestState == ETestPass) ? RDebug::RawPrint(KPassTestRunning) : RDebug::RawPrint(KFailTestRunning); sl@0: sl@0: sl@0: TBuf<128> logTmpFile (sysDriveName); sl@0: logTmpFile.Append(KLogTmpPath); sl@0: iFs.Delete(logTmpFile); // ignore errors sl@0: sl@0: TBuf<128> commandLine; sl@0: commandLine.AppendFormat(_L("%S %S"), &script, &logTmpFile); sl@0: sl@0: StartProcessL(iTestExeTmpNewPath, commandLine, aStatus); sl@0: } sl@0: sl@0: void CPolicyTest::ProcessResultsL(TRequestStatus& aStatus) sl@0: { sl@0: _LIT8(KSummaryLine, " tests failed out of "); sl@0: _LIT8(KNewLine, "\r\n"); sl@0: sl@0: TInt failCount = KErrNotFound, runCount; sl@0: sl@0: // Read entire log file into memory to process sl@0: RFile file; sl@0: TDriveUnit sysDrive (RFs::GetSystemDrive()); sl@0: TBuf<128> logTmpFile (sysDrive.Name()); sl@0: logTmpFile.Append(KLogTmpPath); sl@0: User::LeaveIfError(file.Open(iFs, logTmpFile, EFileShareReadersOnly | EFileRead)); sl@0: CleanupClosePushL(file); sl@0: sl@0: TInt size; sl@0: User::LeaveIfError(file.Size(size)); sl@0: HBufC8* buffer = HBufC8::NewLC(size); sl@0: TPtr8 ptr = buffer->Des(); sl@0: sl@0: User::LeaveIfError(file.Read(ptr)); sl@0: sl@0: iOut.writeString(_L("Child test output:\n")); sl@0: sl@0: TInt pos = 0; sl@0: while (pos < size) sl@0: { sl@0: TInt nextNewline = buffer->Mid(pos).Find(KNewLine); sl@0: sl@0: // Split buffer into lines sl@0: TPtrC8 line; sl@0: if (nextNewline == KErrNotFound) sl@0: { sl@0: line.Set(buffer->Mid(pos)); sl@0: } sl@0: else sl@0: { sl@0: line.Set(buffer->Mid(pos, nextNewline + KNewLine().Length())); sl@0: } sl@0: pos += line.Length(); sl@0: sl@0: // Search for summary line sl@0: TInt pos2 = line.Find(KSummaryLine); sl@0: if (pos2 != KErrNotFound) sl@0: { sl@0: // Parse the summary line to work out if the test passed sl@0: TLex8 lex1(line.Left(pos2)); sl@0: TInt err1 = lex1.Val(failCount); sl@0: TLex8 lex2(line.Mid(pos2 + KSummaryLine().Length())); sl@0: TInt err2 = lex2.Val(runCount); sl@0: sl@0: if (err1 != KErrNone || err2 != KErrNone) sl@0: { sl@0: iOut.writeString(_L("Failed to parse summary line\n")); sl@0: User::LeaveIfError(err1); sl@0: User::LeaveIfError(err2); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: // Don't print the summary line as this will confuse whatever parsed sl@0: // the main log sl@0: iOut.writeString(_L("> ")); sl@0: iOut.writeString(line); sl@0: } sl@0: } sl@0: sl@0: if (failCount == KErrNotFound) sl@0: { sl@0: iOut.writeString(_L("Couldn't find summary line in test output\n")); sl@0: User::Leave(KErrNotFound); sl@0: } sl@0: iFailCount += failCount; sl@0: sl@0: // Print results in different format sl@0: iOut.write(_L("Tests run: %d\n"), runCount); sl@0: iOut.write(_L("Tests failed: %d\n"), failCount); sl@0: iOut.writeNewLine(); sl@0: sl@0: CleanupStack::PopAndDestroy(2, &file); sl@0: sl@0: TRequestStatus* status = &aStatus; sl@0: User::RequestComplete(status, KErrNone); sl@0: } sl@0: sl@0: void CPolicyTest::PerformCancel() sl@0: { sl@0: // not implemented - need to pass original status object to LogonCancel sl@0: User::Invariant(); sl@0: /* sl@0: switch (iState) sl@0: { sl@0: case ESetCapsPass: sl@0: case ERunTest: sl@0: iProcess.LogonCancel(); sl@0: iProcess.Kill(KErrCancel); sl@0: iProcess.Close(); sl@0: break; sl@0: } sl@0: */ sl@0: } sl@0: sl@0: void CPolicyTest::Reset() sl@0: { sl@0: iProcess.Close(); sl@0: iState = ESetupTest; sl@0: iTestState = ETestNone; sl@0: iCapIndex = -1; sl@0: iFailCount = 0; sl@0: } sl@0: sl@0: void CPolicyTest::DoReportAction() sl@0: { sl@0: iOut.writeString(_L("Running policy tests...\n\n")); sl@0: } sl@0: sl@0: void CPolicyTest::DoCheckResult(TInt aError) sl@0: { sl@0: if (aError == KErrNone && iFailCount > 0) sl@0: { sl@0: iOut.write(_L("%d tests failed\n"), iFailCount); sl@0: aError = KErrGeneral; sl@0: } sl@0: sl@0: iResult = (aError == iExpectedResult); sl@0: }