|
1 // Copyright (c) 2004-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 // Mobile IP to Simple IP fallback mechanism test classes implementation. |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file |
|
20 @internalComponent |
|
21 */ |
|
22 |
|
23 |
|
24 #include "fallbackteststeps.h" |
|
25 #include <c32comm.h> // call to StartC32WithCMISuppressions |
|
26 #include <nifman.h> // For Nifman progress notification codes. |
|
27 |
|
28 // If "using namespace", Lint reports an error. |
|
29 using te_mobile_ip_to_simple_ip_fallback::CFallbackStepBase; |
|
30 using te_mobile_ip_to_simple_ip_fallback::CFallbackSucceedsStep; |
|
31 using te_mobile_ip_to_simple_ip_fallback::CFallbackFailsStep; |
|
32 |
|
33 using te_mobile_ip_to_simple_ip_fallback::KFallbackSucceedsStepName; |
|
34 using te_mobile_ip_to_simple_ip_fallback::KFallbackFailsStepName; |
|
35 |
|
36 namespace |
|
37 { |
|
38 // Connection attempt constants. |
|
39 const TInt KNoConnAttemptYet = 0; |
|
40 const TInt KFirstConnAttempt = 1; |
|
41 const TInt KSecondConnAttempt = 2; |
|
42 |
|
43 // Progress Notification used to verify that Dummy MIP daemon has run |
|
44 // This constant must be the same as in DummyMipDaemon. |
|
45 const TInt KDummyMipDaemonProgress = KConfigDaemonStartingRegistration + 13; |
|
46 } |
|
47 |
|
48 |
|
49 |
|
50 /** |
|
51 Logs an error and panics. |
|
52 |
|
53 If provided error code != KErrNone, logs error message and panics. |
|
54 Format of the message is: |
|
55 "ERROR: %%s, error code= %%d", where 's' and 'd' are the message and the error code. |
|
56 |
|
57 @param aErrorCode the error code to check. |
|
58 @param aMessage the message to log. |
|
59 */ |
|
60 void CFallbackStepBase::LogAndPanicIfError(const TInt aErrorCode, const TDesC& aMessage) |
|
61 { |
|
62 if(KErrNone != aErrorCode) |
|
63 { |
|
64 INFO_PRINTF3(_L("ERROR: %s, error code= %d"), aMessage.Ptr(), aErrorCode); |
|
65 SetTestStepResult(EFail); |
|
66 User::Panic(_L("Test Setup Error. "), aErrorCode); |
|
67 } |
|
68 } |
|
69 |
|
70 /** |
|
71 Carries out the test TestExecute TestStep preamble. |
|
72 |
|
73 @return EFail always. |
|
74 @post Phonebook Synchronizer is disabled. TestStepResult is set to EFail. |
|
75 */ |
|
76 TVerdict CFallbackStepBase::doTestStepPreambleL() |
|
77 { |
|
78 _LIT(KPhbkSyncCMI, "phbsync.cmi"); |
|
79 TInt err = StartC32WithCMISuppressions(KPhbkSyncCMI); |
|
80 TEST(err == KErrNone || err == KErrAlreadyExists); |
|
81 INFO_PRINTF1(_L("Test Step Preamble: disabled Phonebook Synchronizer. ")); |
|
82 |
|
83 SetTestStepResult(EFail); |
|
84 return TestStepResult(); |
|
85 } |
|
86 |
|
87 /** |
|
88 Carries out cleanup which is not relevant to testing. |
|
89 |
|
90 @return Test verdict |
|
91 */ |
|
92 TVerdict CFallbackStepBase::doTestStepPostambleL() |
|
93 { |
|
94 INFO_PRINTF1(_L("Postamble: closing RConnection and ESock")); |
|
95 iPppConn.Close(); |
|
96 iEsock.Close(); |
|
97 INFO_PRINTF1(_L("Test Completed.")); |
|
98 |
|
99 return TestStepResult(); |
|
100 } |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 /** |
|
106 C++ Constructor |
|
107 |
|
108 @post Test name is setup. |
|
109 */ |
|
110 CFallbackSucceedsStep::CFallbackSucceedsStep() |
|
111 { |
|
112 SetTestStepName(KFallbackSucceedsStepName); |
|
113 } |
|
114 |
|
115 /** |
|
116 Carries out the test. |
|
117 Executes the test sequence for each test case. |
|
118 |
|
119 |
|
120 @return Test Step verdict: EPass if fallback is successful and transparent. |
|
121 @pre Phonebook Synchronizer is disabled. |
|
122 */ |
|
123 |
|
124 TVerdict CFallbackStepBase::doTestStepL() |
|
125 { |
|
126 TInt testIterations = 0; |
|
127 GetIntFromConfig(ConfigSection(), _L("TestIterations"), testIterations); |
|
128 |
|
129 |
|
130 TBool doLogStressTest = EFalse; |
|
131 GetBoolFromConfig(ConfigSection(), _L("LogStressTest"), doLogStressTest); |
|
132 |
|
133 // Run once with logging: |
|
134 TVerdict loggedRunVerdict = doTestSequenceL(ETrue, -1); |
|
135 |
|
136 // Now run "stress" tests, without logging |
|
137 INFO_PRINTF2(_L("Running stress testing: [%d] iterations"), testIterations); |
|
138 TInt stressRunFailures = 0; |
|
139 for(TInt curIteration = 0; curIteration < testIterations; curIteration++) |
|
140 { |
|
141 if(EPass != doTestSequenceL(doLogStressTest, curIteration)) |
|
142 { |
|
143 ++stressRunFailures; |
|
144 } |
|
145 |
|
146 if(doLogStressTest) INFO_PRINTF1(_L("============================================================")); |
|
147 if(curIteration % 50 == 0) |
|
148 { |
|
149 INFO_PRINTF2(_L("Executed iteration[%d]."), curIteration); |
|
150 } |
|
151 |
|
152 User::After(2 * 1000000); // Give nifman a chance to reclaim memory. |
|
153 // If this wait is missing, Nifman eventually runs out of memory and tests crash. |
|
154 } |
|
155 if(EPass == loggedRunVerdict && |
|
156 0 == stressRunFailures |
|
157 ) |
|
158 { |
|
159 SetTestStepResult(EPass); |
|
160 } |
|
161 else |
|
162 { |
|
163 SetTestStepResult(EFail); |
|
164 } |
|
165 |
|
166 INFO_PRINTF3(_L("Stress run summary: test iterations= %d. Failures= %d"), testIterations, stressRunFailures); |
|
167 |
|
168 return TestStepResult(); |
|
169 } |
|
170 |
|
171 |
|
172 |
|
173 /** |
|
174 Carries out the test. |
|
175 Verifies that with proper CommDB configuration, when Mobile IP registartion fails, |
|
176 the fallback to Simple IP is transparent. |
|
177 |
|
178 CommDB is configured with the "fallback" IAP to succeed, by using ConnectionPreferences table. |
|
179 |
|
180 @return Test Step verdict: EPass if fallback is transparent. |
|
181 @pre Phonebook Synchronizer is disabled. |
|
182 */ |
|
183 TVerdict CFallbackSucceedsStep::doTestSequenceL(const TBool aLog, const TInt aIteration) |
|
184 { |
|
185 iTestSequenceVerdict = EFail; |
|
186 |
|
187 LogAndPanicIfError(iEsock.Connect(), _L("RSocketServ::Connect")); |
|
188 LogAndPanicIfError(iPppConn.Open(iEsock), _L("RConnection::Open")); |
|
189 |
|
190 TRequestStatus pppConnReq; |
|
191 iPppConn.Start(pppConnReq); // We ignore the status, because we use Progress notifications instead. |
|
192 if(aLog) INFO_PRINTF1(_L("Mobile IP over PPP Connection Requested via CommDB ConnectionPreferences Table")); |
|
193 |
|
194 TInt connAttempt = KNoConnAttemptYet; |
|
195 TBool pppIsRunning = ETrue; // The test runs until ppp is stopped by us. |
|
196 TNifProgressBuf pppProgress; // Accept Nifman progress notifications. |
|
197 TRequestStatus pppProgressRequest; // Progress notification request is asynchronous. |
|
198 |
|
199 TBool dummyMipDaemonHasRun = EFalse; |
|
200 |
|
201 do // process Nifman progress notifications. |
|
202 { |
|
203 iPppConn.ProgressNotification(pppProgress, pppProgressRequest); // Request progress notification. |
|
204 User::WaitForRequest(pppProgressRequest); // Wait for progress notification from Nifman |
|
205 |
|
206 if(KErrNone != pppProgress().iError) |
|
207 { |
|
208 iTestSequenceVerdict = EFail; |
|
209 INFO_PRINTF3(_L("Error Progress Notification: stage= %d error= %d"), pppProgress().iStage, pppProgress().iError); |
|
210 INFO_PRINTF2(_L("ERROR[iteration= %d]: Unexpected Error Progress Notification before second preference IAP is attempted. This means Fallback to Simple IP is not transparent."), aIteration); |
|
211 |
|
212 break; // Error is test failure, so we just terminate. PPP stage is irrelevant. |
|
213 } |
|
214 |
|
215 TInt pppStopErr = KErrGeneral; // return of RConnection::Stop (on PPP). |
|
216 // We must define it here, otherwise THUMB build fails. |
|
217 switch(pppProgress().iStage) // We are interested in the stage of PPP link. |
|
218 { |
|
219 case KDummyMipDaemonProgress: |
|
220 dummyMipDaemonHasRun = ETrue; |
|
221 if(aLog) INFO_PRINTF1(_L("KConfigDaemonStartingRegistration + 13")); |
|
222 break; |
|
223 |
|
224 case KLinkLayerOpen: // PPP LCP and IPCP negotiation are successful. |
|
225 if(aLog) INFO_PRINTF2(_L("KLinkLayerOpen: Simple IP PPP successful at connection attempt[%d]"),connAttempt); |
|
226 // Determine test outcome based on which connection attempt is successful, |
|
227 if(KSecondConnAttempt == connAttempt) // We expect to succeed at the second attempt |
|
228 { |
|
229 if(dummyMipDaemonHasRun) |
|
230 { |
|
231 if(aLog) INFO_PRINTF1(_L("SUCCESS: Mobile IP to Simple IP Fallback is completed.")); |
|
232 pppStopErr = iPppConn.Stop(); |
|
233 if(aLog) INFO_PRINTF2(_L("Stopped PPP Nif with error= %d"),pppStopErr); |
|
234 if(KErrNone == pppStopErr) |
|
235 { |
|
236 //--------------------------------------------------------------------------------------- |
|
237 // If we get here, then PPP negotiation (LCP and IPCP) completed succesfully. |
|
238 // That is, IP address was negotiated successfully. |
|
239 // I.E., getting KLinkLayerOpen progress is our test for proper IP address assignment. |
|
240 // (It is assumed that PPP & Nifman function correctly.) |
|
241 //---------------------------------------------------------------------------------------- |
|
242 |
|
243 iTestSequenceVerdict = EPass; |
|
244 } |
|
245 } |
|
246 else |
|
247 { |
|
248 INFO_PRINTF2(_L("ERROR[iteration= %d]: The fallback has succeeded, but the dummy MIP daemon has not run.Is CommDB configured correctly?"), aIteration); |
|
249 iTestSequenceVerdict = EFail; |
|
250 } |
|
251 } |
|
252 else if(KFirstConnAttempt == connAttempt) // Test Failure: first connection attempt succeeded. |
|
253 { |
|
254 INFO_PRINTF2(_L("ERROR[iteration= %d]: first connection attempt succeeded unespectedly. Is CommDB configured correctly? Has the daemon succeeded?"), aIteration); |
|
255 iTestSequenceVerdict = EFail; |
|
256 } |
|
257 else |
|
258 { |
|
259 INFO_PRINTF3(_L("ERROR[iteration= %d]: connection attempt %d succeeded unexpectedly. Is CommDB confirued correctly?"), connAttempt, aIteration); |
|
260 iTestSequenceVerdict = EFail; |
|
261 } |
|
262 |
|
263 pppIsRunning = EFalse; // The testing is complete at this point. |
|
264 break; |
|
265 |
|
266 |
|
267 case KFinishedSelection: |
|
268 ++connAttempt; //KFinishedSelection signals the beginning of connection attempt |
|
269 if(aLog) INFO_PRINTF2(_L("KFinishedSelection: Connection attempt [%d] is staring."), connAttempt); |
|
270 break; |
|
271 |
|
272 default: // Other irrelevant progress notifications. |
|
273 //NB: This statement should be enabled for debug purposes only. |
|
274 // If used for testing, it slows down the test, and thus occasionally causes progress notification queue |
|
275 // to overlow, resulting in lost notifications and unexpected test failures. |
|
276 //if(aLog) INFO_PRINTF3(_L("Other progress: stage= %d error= %d. Ignored."), pppProgress().iStage, pppProgress().iError); |
|
277 break; |
|
278 } |
|
279 } |
|
280 while(pppIsRunning); // Until we choose to stop PPP, we ask for and receive Nifman progress notifiactions. |
|
281 iPppConn.CancelProgressNotification(); |
|
282 iPppConn.Stop(); // we are executing multiple tests, so we need to do cleanup after each one. |
|
283 |
|
284 iPppConn.Close();// Give nifman a chance to reclaim all the memory associated with the connection. |
|
285 iEsock.Close(); |
|
286 |
|
287 |
|
288 return iTestSequenceVerdict; |
|
289 } |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 /** |
|
295 C++ Constructor |
|
296 |
|
297 @post Test name is setup. |
|
298 */ |
|
299 CFallbackFailsStep::CFallbackFailsStep() |
|
300 { |
|
301 SetTestStepName(KFallbackFailsStepName); |
|
302 } |
|
303 |
|
304 |
|
305 /** |
|
306 Carries out the test. |
|
307 Verifies that if fallback to Simple IP fails, the failure is graceful. |
|
308 |
|
309 CommDB is configured with the "fallback" IAP to fail, by using invalid PPP |
|
310 authentication name and password in CDMA2000PacketService table. |
|
311 |
|
312 @return Test Step verdict: EPass if fallback fails gracefully. |
|
313 @pre Phonebook Synchronizer is disabled. |
|
314 */ |
|
315 TVerdict CFallbackFailsStep::doTestSequenceL(const TBool aLog, const TInt aIteration) |
|
316 { |
|
317 iTestSequenceVerdict = EFail; |
|
318 |
|
319 |
|
320 LogAndPanicIfError(iEsock.Connect(), _L("RSocketServ::Connect")); |
|
321 LogAndPanicIfError(iPppConn.Open(iEsock), _L("RConnection::Open")); |
|
322 |
|
323 |
|
324 TRequestStatus pppConnReq; |
|
325 iPppConn.Start(pppConnReq); // We ignore the status, because we use Progress notifications instead. |
|
326 if(aLog) INFO_PRINTF1(_L("Mobile IP over PPP Connection Requested via CommDB ConnectionPreferences Table")); |
|
327 |
|
328 TInt connAttempt = KNoConnAttemptYet; |
|
329 TBool pppIsRunning = ETrue; // The test runs until ppp is stopped by us. |
|
330 TNifProgressBuf pppProgress; // Accept Nifman progress notifications. |
|
331 TRequestStatus pppProgressRequest; // Progress request notification is anynchronous. |
|
332 |
|
333 TBool dummyMipDaemonHasRun = EFalse; |
|
334 |
|
335 do // accept Nifman progress notifications. |
|
336 { |
|
337 iPppConn.ProgressNotification(pppProgress, pppProgressRequest); |
|
338 User::WaitForRequest(pppProgressRequest); // Wait for progress notification from Nifman |
|
339 |
|
340 if(KErrNone == pppProgress().iError) // Success progress notification. |
|
341 { |
|
342 switch(pppProgress().iStage) // We are interested in the stage of PPP link. |
|
343 { |
|
344 case KFinishedSelection: |
|
345 ++connAttempt; //KStartung selection signals the beginning of connection attempt |
|
346 if(aLog) INFO_PRINTF2(_L("KFinishedSelection. Connection attempt [%d] is starting"), connAttempt); |
|
347 break; |
|
348 |
|
349 case KDummyMipDaemonProgress: |
|
350 dummyMipDaemonHasRun = ETrue; |
|
351 if(aLog) INFO_PRINTF1(_L("KConfigDaemonStartingRegistration + 13")); |
|
352 break; |
|
353 |
|
354 case KLinkLayerOpen: // We do not expect Nif to go up. If we do get here, the test fails. |
|
355 INFO_PRINTF1(_L("KLinkLayerOpen")); |
|
356 INFO_PRINTF2(_L("ERROR[iteration= %d]: Link Layer opened unexpectedly. Are CommDB ModemBearer table and Wintunnel configured correctly for failure?"), aIteration); |
|
357 iTestSequenceVerdict = EFail; |
|
358 iPppConn.Stop(); // We don't care if this operation is successful. |
|
359 pppIsRunning = EFalse; |
|
360 break; |
|
361 |
|
362 case KLinkLayerClosed: // We get this at the end of the second connection attempt. |
|
363 ASSERT(KFirstConnAttempt == connAttempt || KSecondConnAttempt == connAttempt); |
|
364 if(aLog) INFO_PRINTF2(_L("KLinkLayerClosed. Connection attempt [%d] failed."), connAttempt); |
|
365 break; |
|
366 |
|
367 default: // Other irrelevant progress notifications. |
|
368 //NB: This statement should be enabled for debug purposes only. |
|
369 //If used for testing, it slows down the test, and thus occasionally causes progress notification queue |
|
370 //to overlow, resulting in lost notifications and unexpected test failures. |
|
371 //if(aLog) INFO_PRINTF3(_L("Other progress: stage= %d error= %d. Ignored."), pppProgress().iStage, pppProgress().iError); |
|
372 |
|
373 break; |
|
374 } |
|
375 } |
|
376 else // Error progress notification. The connection attempt this happens at determines success of failure of the test. |
|
377 { |
|
378 if(aLog) INFO_PRINTF3(_L("Error Progress Notification: stage= %d error= %d"), pppProgress().iStage, pppProgress().iError); |
|
379 |
|
380 ASSERT(KFirstConnAttempt == connAttempt || KSecondConnAttempt == connAttempt); |
|
381 |
|
382 if(KFirstConnAttempt == connAttempt) // Error progress notification at first attempt == Test failure. |
|
383 { // Because we have an error even before attempting fallback. |
|
384 iTestSequenceVerdict = EFail; |
|
385 INFO_PRINTF2(_L("ERROR[iteration= %d]: Unexpected Error Progress Notification before second preference IAP is attempted. This means Fallback to Simple IP is not transparent."), aIteration); |
|
386 } |
|
387 else // Error progress notification, but at second attempt. This is expected and is OK. |
|
388 { |
|
389 if(KErrCouldNotConnect == pppProgress().iError) |
|
390 { |
|
391 if(dummyMipDaemonHasRun) |
|
392 { |
|
393 if(aLog) INFO_PRINTF1(_L("SUCCESS: Fallback to Simple IP failed gracefully.")); |
|
394 iTestSequenceVerdict = EPass; |
|
395 } |
|
396 else |
|
397 { |
|
398 INFO_PRINTF1(_L("ERROR: the dummy MIP Daemon has not run. The test sequence has not executed properly. Check CommDB.")); |
|
399 iTestSequenceVerdict = EFail; |
|
400 } |
|
401 } |
|
402 else |
|
403 { |
|
404 iTestSequenceVerdict = EFail; |
|
405 INFO_PRINTF2(_L("ERROR: unexpected error Progress Notification KErrCouldNotConnect[-34], received error [%d]. Test sequence did not execute as expected. Did Nifman progress notification mechanism change?"),pppProgress().iError); |
|
406 } |
|
407 //-------------------------------------------------------------------------------------- |
|
408 // We do not try to close the PPP link because it was never open in the first place. |
|
409 // The progress error is most likely KErrServerTerminated(-15) |
|
410 // Calling RConnection::Stop() usually returns KErrNotReady(-18). |
|
411 // These error codes are not tested, because Nifman progress notification mechanism |
|
412 // and thus error codes may change. |
|
413 //-------------------------------------------------------------------------------------- |
|
414 } |
|
415 |
|
416 pppIsRunning = EFalse; // Once we have an error notification, we stop regardless of the stage. |
|
417 } |
|
418 } |
|
419 while(pppIsRunning); // Until we choose to stop PPP, we ask for and receive Nifman progress notifications. |
|
420 |
|
421 iPppConn.CancelProgressNotification(); |
|
422 iPppConn.Stop(); |
|
423 iPppConn.Close();// Give nifman a chance to reclaim all the memory associated with the connection. |
|
424 iEsock.Close(); |
|
425 |
|
426 return iTestSequenceVerdict; |
|
427 } |
|
428 |
|
429 |
|
430 |
|
431 |
|
432 |
|
433 |
|
434 |
|
435 |
|
436 |
|
437 |