|
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file Te_LbsApiSuiteStepBase.cpp |
|
18 @internalTechnology |
|
19 */ |
|
20 |
|
21 #include "te_lbsapisuitestepbase.h" |
|
22 #include "te_lbsapisuitedefs.h" |
|
23 |
|
24 #include "lcfsbucommondefinitions.h" |
|
25 |
|
26 _LIT(KPanicThreadName, "TestPanicThread"); |
|
27 const TInt KTestHeapMinSize = 0x4000; |
|
28 const TInt KTestHeapMaxSize = 0x8000; |
|
29 |
|
30 // Device driver constants |
|
31 |
|
32 TVerdict CTe_LbsApiSuiteStepBase::doTestStepPreambleL() |
|
33 /** |
|
34 * @return - TVerdict |
|
35 * Implementation of CTestStep base class virtual |
|
36 * It is used for doing all initialisation common to derived classes in here. |
|
37 * Make it being able to leave if there are any errors here as there's no point in |
|
38 * trying to run a test step if anything fails. |
|
39 * The leave will be picked up by the framework. |
|
40 */ |
|
41 { |
|
42 SetTestStepResult(EPass); |
|
43 return TestStepResult(); |
|
44 } |
|
45 |
|
46 TVerdict CTe_LbsApiSuiteStepBase::doTestStepPostambleL() |
|
47 /** |
|
48 * @return - TVerdict |
|
49 * Implementation of CTestStep base class virtual |
|
50 * It is used for doing all after test treatment common to derived classes in here. |
|
51 * Make it being able to leave |
|
52 * The leave will be picked up by the framework. |
|
53 */ |
|
54 { |
|
55 //SetTestStepResult(EPass); // or EFail |
|
56 return TestStepResult(); |
|
57 } |
|
58 |
|
59 CTe_LbsApiSuiteStepBase::~CTe_LbsApiSuiteStepBase() |
|
60 { |
|
61 } |
|
62 |
|
63 CTe_LbsApiSuiteStepBase::CTe_LbsApiSuiteStepBase() |
|
64 { |
|
65 } |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 // |
|
71 // |
|
72 // TOOL FUNCTIONS |
|
73 // |
|
74 // |
|
75 void CTe_LbsApiSuiteStepBase::StandardPrepareL() |
|
76 { |
|
77 START_ERROR_LOGGING; |
|
78 } |
|
79 |
|
80 void CTe_LbsApiSuiteStepBase::StandardCleanup() |
|
81 { |
|
82 } |
|
83 |
|
84 // |
|
85 // PANIC TEST SUPPORT |
|
86 // |
|
87 |
|
88 void TurnJITBackOn(TAny* /*aPtr*/) |
|
89 { |
|
90 User::SetJustInTime (ETrue); |
|
91 } |
|
92 |
|
93 TInt PanicThreadFunction(TAny* aPtr) |
|
94 { |
|
95 CTrapCleanup* cs = CTrapCleanup::New (); |
|
96 if ( cs == NULL) |
|
97 return KErrNoMemory; |
|
98 |
|
99 // we may need an ActiveScheduler |
|
100 CActiveScheduler scheduler; |
|
101 CActiveScheduler::Install (&scheduler); |
|
102 |
|
103 SPanicThreadFunctionData* data = |
|
104 reinterpret_cast<SPanicThreadFunctionData*>(aPtr); |
|
105 TInt err; |
|
106 TRAP(err, data->iPanicFunction(data->iPtr)); // should panic |
|
107 |
|
108 delete cs; |
|
109 User::Exit (err); |
|
110 return err; |
|
111 } |
|
112 |
|
113 TInt CTe_LbsApiSuiteStepBase::DoPanicTestL ( |
|
114 TThreadFunction aThreadFunction, TExitCategoryName aExpectedExitCat, |
|
115 TInt aExpectedExitReason, TTimeIntervalMicroSeconds32 aTimeoutValue, |
|
116 TAny* aPtr) |
|
117 |
|
118 { |
|
119 DECLARE_ERROR_LOGGING |
|
120 ; |
|
121 |
|
122 #ifdef __WINS__ |
|
123 User::SetJustInTime (EFalse); |
|
124 CleanupStack::PushL (TCleanupItem (TurnJITBackOn)); |
|
125 #endif |
|
126 RThread panickingThread; |
|
127 |
|
128 SPanicThreadFunctionData threadData; |
|
129 threadData.iPanicFunction = aThreadFunction; |
|
130 threadData.iPtr = aPtr; |
|
131 |
|
132 // check that thread does not already exist |
|
133 TInt result = KErrNone; |
|
134 TBuf<24> threadName(KPanicThreadName); |
|
135 |
|
136 result = panickingThread.Create (threadName, PanicThreadFunction, |
|
137 KDefaultStackSize, KTestHeapMinSize, KTestHeapMaxSize, &threadData, |
|
138 EOwnerProcess); |
|
139 |
|
140 CHECK_EQUAL(result, KErrNone, "Unexpected error while creating panic thread") |
|
141 ; |
|
142 User::LeaveIfError (result); |
|
143 |
|
144 CleanupClosePushL (panickingThread); |
|
145 |
|
146 RTimer timeoutTimer; |
|
147 User::LeaveIfError (timeoutTimer.CreateLocal ()); |
|
148 CleanupClosePushL (timeoutTimer); |
|
149 |
|
150 TRequestStatus timerStatus; |
|
151 timeoutTimer.After (timerStatus, aTimeoutValue); |
|
152 |
|
153 TRequestStatus threadStatus; |
|
154 |
|
155 panickingThread.Rendezvous (threadStatus); |
|
156 if ( threadStatus != KRequestPending) |
|
157 { |
|
158 // logon failed - thread is not yet running, so cannot have terminated |
|
159 User::WaitForRequest (threadStatus); // eat signal |
|
160 panickingThread.Kill (threadStatus.Int ()); // abort startup |
|
161 } |
|
162 else |
|
163 { |
|
164 panickingThread.Resume (); |
|
165 User::WaitForRequest (threadStatus, timerStatus); |
|
166 } |
|
167 |
|
168 TInt exitReason = KErrNone; |
|
169 if ( threadStatus == KRequestPending) |
|
170 { |
|
171 ERR("Thread didn't die. Killing it..."); |
|
172 panickingThread.Kill (KErrTimedOut); |
|
173 User::WaitForRequest (threadStatus); |
|
174 } |
|
175 else // (timerStatus == KRequestPending) |
|
176 { |
|
177 // stop timer |
|
178 timeoutTimer.Cancel (); |
|
179 User::WaitForRequest (timerStatus); |
|
180 } |
|
181 |
|
182 exitReason = panickingThread.ExitReason (); |
|
183 |
|
184 TExitCategoryName exitCat; |
|
185 |
|
186 switch (panickingThread.ExitType ()) |
|
187 { |
|
188 case EExitKill: |
|
189 message.Format (_L("Thread was Killed with Reason %d"), exitReason); |
|
190 LOG_DES(message); |
|
191 break; |
|
192 case EExitTerminate: |
|
193 message.Format (_L("Thread was Terminated with Reason %d"), exitReason); |
|
194 LOG_DES(message); |
|
195 break; |
|
196 case EExitPanic: |
|
197 // check exit reasons |
|
198 exitCat = panickingThread.ExitCategory (); |
|
199 if ( exitCat.Compare (aExpectedExitCat) != 0) |
|
200 { |
|
201 message.Format (_L("Unexpected panic category: Actual '%S', Expected '%S'"), |
|
202 &exitCat, &aExpectedExitCat); |
|
203 LOG_DES(message); |
|
204 } |
|
205 CHECK_EQUAL(exitReason, aExpectedExitReason, "Unexpected panic reason"); |
|
206 break; |
|
207 default: |
|
208 CHECK_EQUAL((TInt)EExitPanic, threadStatus.Int(), "Unexpected thread exit type!"); |
|
209 break; |
|
210 } |
|
211 |
|
212 CleanupStack::PopAndDestroy (&timeoutTimer); |
|
213 CleanupStack::PopAndDestroy (&panickingThread); |
|
214 #ifdef __WINS__ |
|
215 CleanupStack::PopAndDestroy (); //TurnJITBackOn |
|
216 #endif |
|
217 // wait a bit to make sure this thread is over |
|
218 const TTimeIntervalMicroSeconds32 KThreadDelay = 1000 * 1000; // 1 s |
|
219 User::After (KThreadDelay); |
|
220 |
|
221 return exitReason; |
|
222 } |
|
223 |
|
224 void CheckPanic(const char* aFileName, TInt aLine) |
|
225 { |
|
226 TBuf<64> file; |
|
227 TBuf<80> panic; |
|
228 |
|
229 file.Copy(TPtrC8(_S8(aFileName)).Right(file.MaxLength())); |
|
230 file = file.Mid(file.LocateReverse('\\')+1); |
|
231 |
|
232 panic.Format(_L("%d-%S"), aLine, &file); |
|
233 User::Panic(panic, KErrGeneral); |
|
234 } |