|
1 /* |
|
2 * Copyright (c) 2004-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 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "t_policy.h" |
|
20 #include "t_input.h" |
|
21 #include "t_output.h" |
|
22 #include "t_testhandler.h" |
|
23 #include "utf.h" |
|
24 |
|
25 #include <s32file.h> |
|
26 |
|
27 // run failure tests first |
|
28 |
|
29 _LIT8(KTestExeStart, "<testexe>"); |
|
30 _LIT8(KExcludedCapsStart, "<excludedcapabilities>"); |
|
31 _LIT8(KPolicyStart, "<policy>"); |
|
32 _LIT8(KPreActionsStart, "<preactions>"); |
|
33 _LIT8(KPassAcionStart, "<passactions>"); |
|
34 _LIT8(KFailAcionStart, "<failactions>"); |
|
35 _LIT8(KPostActionsStart, "<postactions>"); |
|
36 _LIT8(KSecureIdStart, "<secureid>"); |
|
37 _LIT8(KSecureIdEnd, "</secureid>"); |
|
38 _LIT8(KVendorIdStart, "<vendorid>"); |
|
39 _LIT8(KVendorIdEnd, "</vendorid>"); |
|
40 |
|
41 _LIT(KFormat,"Action Name : %S \n"); |
|
42 _LIT(KSetCapExe, "setcap"); |
|
43 _LIT(KSetCapExe2, "setcap : "); |
|
44 //NOTE :If the below literal is uncommented , remove the c:\hardcoded reference |
|
45 // and replace with RFs::GetSystemDrive(). |
|
46 //_LIT(KTestExeTmpPath, "c:\\sys\\bin\\policytest_exe.exe"); |
|
47 _LIT(KPassScriptPath, "\\policytest_script_pass.txt"); |
|
48 _LIT(KFailScriptPath, "\\policytest_script_fail.txt"); |
|
49 _LIT(KLogTmpPath, "\\policytest_log.txt"); |
|
50 _LIT(KTestPath, "policytest_"); |
|
51 _LIT(KFailTestRunning, "Fail Test Script Running"); |
|
52 _LIT(KPassTestRunning, "Pass Test Script Running"); |
|
53 |
|
54 |
|
55 const TUint KCapabilityAll = 0xffffffff; |
|
56 |
|
57 CPolicyTest* CPolicyTest::NewL(CConsoleBase& aConsole, |
|
58 Output& aOut, |
|
59 const TTestActionSpec& aTestActionSpec) |
|
60 { |
|
61 CPolicyTest* self = CPolicyTest::NewLC(aConsole, aOut, aTestActionSpec); |
|
62 CleanupStack::Pop(self); |
|
63 return self; |
|
64 } |
|
65 |
|
66 CPolicyTest* CPolicyTest::NewLC(CConsoleBase& aConsole, |
|
67 Output& aOut, |
|
68 const TTestActionSpec& aTestActionSpec) |
|
69 { |
|
70 CPolicyTest* self = new(ELeave) CPolicyTest(aConsole, aOut); |
|
71 CleanupStack::PushL(self); |
|
72 self->ConstructL(aTestActionSpec); |
|
73 return self; |
|
74 } |
|
75 |
|
76 CPolicyTest::CPolicyTest(CConsoleBase& aConsole, |
|
77 Output& aOut) |
|
78 : CTestAction(aConsole, aOut) |
|
79 { |
|
80 } |
|
81 |
|
82 void CPolicyTest::ConstructL(const TTestActionSpec& aTestActionSpec) |
|
83 { |
|
84 CTestAction::ConstructL(aTestActionSpec); |
|
85 iExpectedResult = KErrNone; |
|
86 |
|
87 User::LeaveIfError(iFs.Connect()); |
|
88 |
|
89 RProcess thisProcess; |
|
90 User::LeaveIfError(thisProcess.Open(thisProcess.Id())); |
|
91 iProcessSecureId = thisProcess.SecureId(); |
|
92 iProcessVendorId = thisProcess.VendorId(); |
|
93 thisProcess.Close(); |
|
94 |
|
95 SetTestExeL(Input::ParseElement(aTestActionSpec.iActionBody, KTestExeStart)); |
|
96 Input::ParseCapabilitySetL(Input::ParseElement(aTestActionSpec.iActionBody, KExcludedCapsStart), iExcludedCaps); |
|
97 SetPolicyL(Input::ParseElement(aTestActionSpec.iActionBody, KPolicyStart)); |
|
98 iPreActions = Input::ParseElement(aTestActionSpec.iActionBody, KPreActionsStart).AllocL(); |
|
99 SetTestActionL(Input::ParseElement(aTestActionSpec.iActionBody, KPassAcionStart), |
|
100 Input::ParseElement(aTestActionSpec.iActionBody, KFailAcionStart)); |
|
101 iPostActions = Input::ParseElement(aTestActionSpec.iActionBody, KPostActionsStart).AllocL(); |
|
102 } |
|
103 |
|
104 CPolicyTest::~CPolicyTest() |
|
105 { |
|
106 iFs.Close(); |
|
107 delete iTestExe; |
|
108 iCapabilities.Close(); |
|
109 delete iPreActions; |
|
110 delete iPassAction; |
|
111 delete iFailAction; |
|
112 delete iPostActions; |
|
113 iProcess.Close(); |
|
114 } |
|
115 |
|
116 void CPolicyTest::BadUsageL(const TDesC& aMessage) |
|
117 { |
|
118 iOut.writeString(_L("Error in script action testpolicy")); |
|
119 iOut.writeNewLine(); |
|
120 iOut.writeString(aMessage); |
|
121 iOut.writeNewLine(); |
|
122 User::Leave(KErrArgument); |
|
123 } |
|
124 |
|
125 void CPolicyTest::SetTestExeL(const TDesC8& aPath) |
|
126 { |
|
127 if (aPath == KNullDesC8) |
|
128 { |
|
129 BadUsageL(_L("testexe not specified")); |
|
130 } |
|
131 |
|
132 iTestExe = HBufC::NewMaxL(aPath.Length()); |
|
133 TPtr ptr = iTestExe->Des(); |
|
134 ptr.Copy(aPath); |
|
135 } |
|
136 |
|
137 void CPolicyTest::SetPolicyL(const TDesC8& aSpec) |
|
138 { |
|
139 iSecureId = Input::ParseIntElement(aSpec, KSecureIdStart, KSecureIdEnd); |
|
140 iVendorId = Input::ParseIntElement(aSpec, KVendorIdStart, KVendorIdEnd); |
|
141 |
|
142 TCapabilitySet capSet; |
|
143 Input::ParseCapabilitySetL(aSpec, capSet); |
|
144 |
|
145 // Extract capabilities into array |
|
146 for (TInt i = 0 ; i < ECapability_Limit ; ++i) |
|
147 { |
|
148 TCapability c = static_cast<TCapability>(i); |
|
149 if (capSet.HasCapability(c)) |
|
150 { |
|
151 User::LeaveIfError(iCapabilities.Append(c)); |
|
152 } |
|
153 } |
|
154 } |
|
155 |
|
156 void CPolicyTest::SetTestActionL(const TDesC8& aPassAction, const TDesC8& aFailAction) |
|
157 { |
|
158 if (aPassAction == KNullDesC8) |
|
159 { |
|
160 BadUsageL(_L("passactions not specified")); |
|
161 } |
|
162 |
|
163 iPassAction = aPassAction.AllocL(); |
|
164 |
|
165 if (aFailAction == KNullDesC8) |
|
166 { |
|
167 BadUsageL(_L("failactions not specified")); |
|
168 } |
|
169 |
|
170 iFailAction = aFailAction.AllocL(); |
|
171 } |
|
172 |
|
173 void CPolicyTest::PerformAction(TRequestStatus& aStatus) |
|
174 { |
|
175 if (aStatus < 0) |
|
176 { |
|
177 iState = EFinished; |
|
178 } |
|
179 |
|
180 switch (iState) |
|
181 { |
|
182 case EInit: |
|
183 { |
|
184 TDriveUnit sysDrive (RFs::GetSystemDrive()); |
|
185 TDriveName sysDriveName (sysDrive.Name()); |
|
186 |
|
187 TBuf<128> scriptFile (sysDriveName); |
|
188 scriptFile.Append(KPassScriptPath); |
|
189 WriteScriptFileL(scriptFile, *iPassAction); |
|
190 |
|
191 scriptFile.Copy(sysDriveName); |
|
192 scriptFile.Append(KFailScriptPath); |
|
193 WriteScriptFileL(scriptFile, *iFailAction); |
|
194 } |
|
195 // fall through |
|
196 |
|
197 case ESetupTest: |
|
198 GetNextTest(); |
|
199 if (iTestState == ETestFinished) |
|
200 { |
|
201 iState = EFinished; |
|
202 TRequestStatus* status = &aStatus; |
|
203 User::RequestComplete(status, KErrNone); |
|
204 } |
|
205 else |
|
206 { |
|
207 SetupTestL(aStatus); |
|
208 iState = ERunTest; |
|
209 } |
|
210 break; |
|
211 |
|
212 case ERunTest: |
|
213 CheckProcessTermintationL(); |
|
214 RunTestL(aStatus); |
|
215 iState = EProcessResults; |
|
216 break; |
|
217 |
|
218 case EProcessResults: |
|
219 CheckProcessTermintationL(); |
|
220 ProcessResultsL(aStatus); |
|
221 iState = ESetupTest; |
|
222 break; |
|
223 |
|
224 case EFinished: |
|
225 iActionState = EPostrequisite; |
|
226 TRequestStatus* status = &aStatus; |
|
227 User::RequestComplete(status, aStatus.Int()); |
|
228 break; |
|
229 } |
|
230 } |
|
231 |
|
232 void CPolicyTest::StartProcessL(const TDesC& aExe, const TDesC& aCommandLine, TRequestStatus& aStatus) |
|
233 { |
|
234 iOut.writeString(_L("Starting child process: ")); |
|
235 iOut.writeString(aExe); |
|
236 iOut.writeString(_L(" ")); |
|
237 iOut.writeString(aCommandLine); |
|
238 iOut.writeNewLine(); |
|
239 |
|
240 User::LeaveIfError(iProcess.Create(aExe, aCommandLine)); |
|
241 iProcess.Logon(aStatus); |
|
242 iProcess.Resume(); |
|
243 } |
|
244 |
|
245 void CPolicyTest::CheckProcessTermintationL() |
|
246 { |
|
247 if (iProcess.ExitType() == EExitPanic) |
|
248 { |
|
249 iOut.writeString(_L("Child process panicked: ")); |
|
250 iOut.writeString(iProcess.ExitCategory()); |
|
251 iOut.writeString(_L(" ")); |
|
252 iOut.writeNum(iProcess.ExitReason()); |
|
253 iOut.writeNewLine(); |
|
254 User::Leave(KErrGeneral); |
|
255 } |
|
256 ASSERT(iProcess.ExitType() == EExitKill); |
|
257 iProcess.Close(); |
|
258 } |
|
259 |
|
260 void CPolicyTest::GetNextTest() |
|
261 { |
|
262 // Step through capabilities to be tested |
|
263 if (iTestState == ETestFailCap) |
|
264 { |
|
265 ++iCapIndex; |
|
266 if (iCapIndex < iCapabilities.Count()) |
|
267 return; |
|
268 } |
|
269 |
|
270 // Step through possible tests until we hit a vaild test |
|
271 do |
|
272 { |
|
273 iTestState = static_cast<TTestState>(iTestState + 1); |
|
274 } |
|
275 while (!((iTestState == ETestFailSID && iSecureId) || |
|
276 (iTestState == ETestFailVID && iVendorId) || |
|
277 (iTestState == ETestFailCap && iCapabilities.Count()) || |
|
278 (iTestState == ETestPass) || |
|
279 (iTestState == ETestFinished))); |
|
280 } |
|
281 |
|
282 void CPolicyTest::SetupTestL(TRequestStatus& aStatus) |
|
283 { |
|
284 switch (iTestState) |
|
285 { |
|
286 case ETestFailSID: |
|
287 { |
|
288 TInt wrongSecureId = iSecureId + 1; |
|
289 iOut.write(_L("Failure test: Wrong SID (%08x):\n\n"), wrongSecureId); |
|
290 SetTestSecurityInfoL(wrongSecureId, iVendorId, KCapabilityAll, aStatus); |
|
291 } |
|
292 break; |
|
293 |
|
294 case ETestFailVID: |
|
295 { |
|
296 TInt wrongVendorId = iVendorId + 1; |
|
297 iOut.write(_L("Failure test: Wrong VID (%08x):\n\n"), wrongVendorId); |
|
298 SetTestSecurityInfoL(iSecureId, wrongVendorId, KCapabilityAll, aStatus); |
|
299 } |
|
300 break; |
|
301 |
|
302 case ETestFailCap: |
|
303 { |
|
304 TCapability missingCap = iCapabilities[iCapIndex]; |
|
305 |
|
306 iOut.writeString(_L("Failure test: Missing capability (")); |
|
307 iOut.writeCapabilityL(missingCap); |
|
308 iOut.writeString(_L("):\n\n")); |
|
309 |
|
310 TUint capSet = ~ (1 << missingCap); |
|
311 SetTestSecurityInfoL(iSecureId, iVendorId, capSet, aStatus); |
|
312 } |
|
313 break; |
|
314 |
|
315 case ETestPass: |
|
316 { |
|
317 iOut.write(_L("Pass test:\n\n")); |
|
318 |
|
319 TUint capSet = 0; |
|
320 for (TInt i = 0 ; i < iCapabilities.Count() ; ++i) |
|
321 { |
|
322 capSet |= 1 << iCapabilities[i]; |
|
323 } |
|
324 |
|
325 SetTestSecurityInfoL(iSecureId, iVendorId, capSet, aStatus); |
|
326 } |
|
327 break; |
|
328 |
|
329 default: |
|
330 User::Invariant(); |
|
331 } |
|
332 } |
|
333 |
|
334 void CPolicyTest::SetTestSecurityInfoL(TInt aSecureId, TInt aVendorId, TUint aCapSet, TRequestStatus& aStatus) |
|
335 { |
|
336 // Remove excluded capabilities |
|
337 for (TInt i = 0 ; i < ECapability_Limit ; ++i) |
|
338 { |
|
339 if (iExcludedCaps.HasCapability(static_cast<TCapability>(i))) |
|
340 { |
|
341 aCapSet &= ~ (1 << i); |
|
342 } |
|
343 } |
|
344 |
|
345 TBuf<128> commandLine; |
|
346 commandLine.AppendFormat(_L("%S %08x "), iTestExe, aCapSet); |
|
347 if (aSecureId) |
|
348 { |
|
349 commandLine.AppendFormat(_L("-SID %08x "), aSecureId); |
|
350 } |
|
351 if (aVendorId) |
|
352 { |
|
353 commandLine.AppendFormat(_L("-VID %08x "), aVendorId); |
|
354 } |
|
355 // commandLine.Append(KTestExeTmpPath); |
|
356 iTestExeTmpNewPath = KTestPath; |
|
357 iTestExeTmpNewPath.Append(*iTestExe); |
|
358 commandLine.Append(iTestExeTmpNewPath); |
|
359 |
|
360 TBuf<128> isetcapTmpNewPath1; //stores the value of commandline |
|
361 TBuf<128> isetcapTmpNewPath; //stores the value of KsetCapexe2 |
|
362 isetcapTmpNewPath = KSetCapExe2; |
|
363 isetcapTmpNewPath1= commandLine; |
|
364 isetcapTmpNewPath.Append(isetcapTmpNewPath1); |
|
365 RDebug::RawPrint(isetcapTmpNewPath); |
|
366 StartProcessL(KSetCapExe, commandLine, aStatus); |
|
367 |
|
368 } |
|
369 |
|
370 void CPolicyTest::WriteScriptFileL(const TDesC& aPath, const TDesC8& aAction) |
|
371 { |
|
372 iFs.Delete(aPath); // ignore errors |
|
373 |
|
374 RFile file; |
|
375 User::LeaveIfError(file.Create(iFs, aPath, EFileShareExclusive | EFileWrite)); |
|
376 CleanupClosePushL(file); |
|
377 |
|
378 User::LeaveIfError(file.Write(*iPreActions)); |
|
379 User::LeaveIfError(file.Write(aAction)); |
|
380 User::LeaveIfError(file.Write(*iPostActions)); |
|
381 |
|
382 CleanupStack::PopAndDestroy(&file); |
|
383 } |
|
384 |
|
385 void CPolicyTest::RunTestL(TRequestStatus& aStatus) |
|
386 { |
|
387 |
|
388 HBufC* hptr16; |
|
389 hptr16 = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*iNameInfo); |
|
390 RDebug::Print(KFormat,hptr16); |
|
391 delete hptr16; |
|
392 |
|
393 TDriveUnit sysDrive (RFs::GetSystemDrive()); |
|
394 TDriveName sysDriveName (sysDrive.Name()); |
|
395 |
|
396 TBuf<128> passScriptFile (sysDriveName); |
|
397 passScriptFile.Append(KPassScriptPath); |
|
398 |
|
399 TBuf<128> failScriptFile (sysDriveName); |
|
400 failScriptFile.Append(KFailScriptPath); |
|
401 |
|
402 TPtrC script = (iTestState == ETestPass) ? passScriptFile : failScriptFile; |
|
403 (iTestState == ETestPass) ? RDebug::RawPrint(KPassTestRunning) : RDebug::RawPrint(KFailTestRunning); |
|
404 |
|
405 |
|
406 TBuf<128> logTmpFile (sysDriveName); |
|
407 logTmpFile.Append(KLogTmpPath); |
|
408 iFs.Delete(logTmpFile); // ignore errors |
|
409 |
|
410 TBuf<128> commandLine; |
|
411 commandLine.AppendFormat(_L("%S %S"), &script, &logTmpFile); |
|
412 |
|
413 StartProcessL(iTestExeTmpNewPath, commandLine, aStatus); |
|
414 } |
|
415 |
|
416 void CPolicyTest::ProcessResultsL(TRequestStatus& aStatus) |
|
417 { |
|
418 _LIT8(KSummaryLine, " tests failed out of "); |
|
419 _LIT8(KNewLine, "\r\n"); |
|
420 |
|
421 TInt failCount = KErrNotFound, runCount; |
|
422 |
|
423 // Read entire log file into memory to process |
|
424 RFile file; |
|
425 TDriveUnit sysDrive (RFs::GetSystemDrive()); |
|
426 TBuf<128> logTmpFile (sysDrive.Name()); |
|
427 logTmpFile.Append(KLogTmpPath); |
|
428 User::LeaveIfError(file.Open(iFs, logTmpFile, EFileShareReadersOnly | EFileRead)); |
|
429 CleanupClosePushL(file); |
|
430 |
|
431 TInt size; |
|
432 User::LeaveIfError(file.Size(size)); |
|
433 HBufC8* buffer = HBufC8::NewLC(size); |
|
434 TPtr8 ptr = buffer->Des(); |
|
435 |
|
436 User::LeaveIfError(file.Read(ptr)); |
|
437 |
|
438 iOut.writeString(_L("Child test output:\n")); |
|
439 |
|
440 TInt pos = 0; |
|
441 while (pos < size) |
|
442 { |
|
443 TInt nextNewline = buffer->Mid(pos).Find(KNewLine); |
|
444 |
|
445 // Split buffer into lines |
|
446 TPtrC8 line; |
|
447 if (nextNewline == KErrNotFound) |
|
448 { |
|
449 line.Set(buffer->Mid(pos)); |
|
450 } |
|
451 else |
|
452 { |
|
453 line.Set(buffer->Mid(pos, nextNewline + KNewLine().Length())); |
|
454 } |
|
455 pos += line.Length(); |
|
456 |
|
457 // Search for summary line |
|
458 TInt pos2 = line.Find(KSummaryLine); |
|
459 if (pos2 != KErrNotFound) |
|
460 { |
|
461 // Parse the summary line to work out if the test passed |
|
462 TLex8 lex1(line.Left(pos2)); |
|
463 TInt err1 = lex1.Val(failCount); |
|
464 TLex8 lex2(line.Mid(pos2 + KSummaryLine().Length())); |
|
465 TInt err2 = lex2.Val(runCount); |
|
466 |
|
467 if (err1 != KErrNone || err2 != KErrNone) |
|
468 { |
|
469 iOut.writeString(_L("Failed to parse summary line\n")); |
|
470 User::LeaveIfError(err1); |
|
471 User::LeaveIfError(err2); |
|
472 } |
|
473 } |
|
474 else |
|
475 { |
|
476 // Don't print the summary line as this will confuse whatever parsed |
|
477 // the main log |
|
478 iOut.writeString(_L("> ")); |
|
479 iOut.writeString(line); |
|
480 } |
|
481 } |
|
482 |
|
483 if (failCount == KErrNotFound) |
|
484 { |
|
485 iOut.writeString(_L("Couldn't find summary line in test output\n")); |
|
486 User::Leave(KErrNotFound); |
|
487 } |
|
488 iFailCount += failCount; |
|
489 |
|
490 // Print results in different format |
|
491 iOut.write(_L("Tests run: %d\n"), runCount); |
|
492 iOut.write(_L("Tests failed: %d\n"), failCount); |
|
493 iOut.writeNewLine(); |
|
494 |
|
495 CleanupStack::PopAndDestroy(2, &file); |
|
496 |
|
497 TRequestStatus* status = &aStatus; |
|
498 User::RequestComplete(status, KErrNone); |
|
499 } |
|
500 |
|
501 void CPolicyTest::PerformCancel() |
|
502 { |
|
503 // not implemented - need to pass original status object to LogonCancel |
|
504 User::Invariant(); |
|
505 /* |
|
506 switch (iState) |
|
507 { |
|
508 case ESetCapsPass: |
|
509 case ERunTest: |
|
510 iProcess.LogonCancel(); |
|
511 iProcess.Kill(KErrCancel); |
|
512 iProcess.Close(); |
|
513 break; |
|
514 } |
|
515 */ |
|
516 } |
|
517 |
|
518 void CPolicyTest::Reset() |
|
519 { |
|
520 iProcess.Close(); |
|
521 iState = ESetupTest; |
|
522 iTestState = ETestNone; |
|
523 iCapIndex = -1; |
|
524 iFailCount = 0; |
|
525 } |
|
526 |
|
527 void CPolicyTest::DoReportAction() |
|
528 { |
|
529 iOut.writeString(_L("Running policy tests...\n\n")); |
|
530 } |
|
531 |
|
532 void CPolicyTest::DoCheckResult(TInt aError) |
|
533 { |
|
534 if (aError == KErrNone && iFailCount > 0) |
|
535 { |
|
536 iOut.write(_L("%d tests failed\n"), iFailCount); |
|
537 aError = KErrGeneral; |
|
538 } |
|
539 |
|
540 iResult = (aError == iExpectedResult); |
|
541 } |