|
1 // Copyright (c) 1998-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 // The purpose of this test harness is to test a fix for INC37442. |
|
15 // In order to test this, it is necessary to start 2 connections to the same IAP off and then |
|
16 // cancel one of them. This must be done before the CImConnect has finished connecting. |
|
17 // |
|
18 // |
|
19 |
|
20 |
|
21 #include "TESTENV.h" |
|
22 #include <nd_err.h> |
|
23 |
|
24 #include <imsk.h> |
|
25 |
|
26 #include <s32mem.h> |
|
27 #include <s32file.h> |
|
28 #include <iapprefs.h> |
|
29 #include "emailtestutils.h" |
|
30 #include <commdb.h> |
|
31 |
|
32 |
|
33 LOCAL_D RTest test(_L("IMSK Multiple CImTextServerSessions Test")); |
|
34 |
|
35 LOCAL_D CTrapCleanup* theCleanup; |
|
36 LOCAL_D RFs theFs; |
|
37 LOCAL_D CActiveScheduler* scheduler; |
|
38 LOCAL_D CEmailTestUtils* testUtils; |
|
39 |
|
40 // Test Harness Prototypes |
|
41 LOCAL_C void DoTestThreadWorkL(); |
|
42 static TInt DoTestThreadStart(TAny*); |
|
43 |
|
44 // Foward declare |
|
45 class CMsgConnect; |
|
46 CMsgConnect* gConnect; |
|
47 |
|
48 |
|
49 // we use a freeserve account; |
|
50 // this will need to be set up as COMMDB_ID 1 in the cdbv3.dat file |
|
51 _LIT(KServerAddressConn0, "pop.freeserve.net"); |
|
52 _LIT(KServerAddressConn1, "www.guardian.co.uk"); |
|
53 const TInt KPortNumber = 110; |
|
54 |
|
55 const TInt KConnectingProgressValue = 2500; |
|
56 const TInt KConnectionMadeProgressValue = 7000; |
|
57 |
|
58 |
|
59 // create an active object to connect |
|
60 class CMsgConnect : public CActive |
|
61 { |
|
62 public: |
|
63 static CMsgConnect* NewLC(TInt aConn); |
|
64 ~CMsgConnect(); |
|
65 |
|
66 public: // CActive |
|
67 void RunL(); |
|
68 void DoCancel(); |
|
69 |
|
70 public: |
|
71 void RequestConnectL(); |
|
72 void CancelConnectL(); |
|
73 TInt ConnectProgress(); |
|
74 TInt GetIAPValue(TUint32 &aIAP); |
|
75 TInt GetIAPBearer(TUint32 &aBearer); |
|
76 |
|
77 private: |
|
78 CMsgConnect(TInt aConn); |
|
79 void ConstructL(); |
|
80 |
|
81 private: |
|
82 CImTextServerSession* iImSocket; |
|
83 CImIAPPreferences* iIAPPreferences; |
|
84 TInt iConn; |
|
85 }; |
|
86 |
|
87 |
|
88 CMsgConnect::CMsgConnect(TInt aConn) |
|
89 :CActive(EPriorityNormal), |
|
90 iConn(aConn) |
|
91 { |
|
92 } |
|
93 |
|
94 CMsgConnect* CMsgConnect::NewLC(TInt aConn) |
|
95 { |
|
96 CMsgConnect* self = new (ELeave) CMsgConnect(aConn); |
|
97 CleanupStack::PushL(self); |
|
98 self->ConstructL(); |
|
99 return self; |
|
100 } |
|
101 |
|
102 void CMsgConnect::ConstructL() |
|
103 { |
|
104 CActiveScheduler::Add(this); // add to active scheduler |
|
105 iImSocket = CImTextServerSession::NewL(); |
|
106 testUtils->WriteComment(_L("CMsgConnect::ConstructL() OK")); |
|
107 } |
|
108 |
|
109 CMsgConnect::~CMsgConnect() |
|
110 { |
|
111 Cancel(); |
|
112 delete iImSocket; |
|
113 delete iIAPPreferences; |
|
114 } |
|
115 |
|
116 void CMsgConnect::DoCancel() |
|
117 { |
|
118 iImSocket->Cancel(); |
|
119 } |
|
120 |
|
121 void CMsgConnect::RunL() |
|
122 { |
|
123 testUtils->WriteComment(_L("CMsgConnect::RunL() start")); |
|
124 |
|
125 // if we have cancelled the connection, then the value here will be KErrCancel |
|
126 if(iStatus.Int() == KErrCancel) |
|
127 { |
|
128 testUtils->WriteComment(_L("CMsgConnect - connection cancelled")); |
|
129 test.Printf(_L("cancelled")); |
|
130 return; |
|
131 } |
|
132 |
|
133 testUtils->WriteComment(_L("CMsgConnect - connection made")); |
|
134 // if we've connected, then say so |
|
135 test.Printf(_L("connected")); |
|
136 CActiveScheduler::Stop(); |
|
137 } |
|
138 |
|
139 void CMsgConnect::RequestConnectL() |
|
140 { |
|
141 testUtils->WriteComment(_L("CMsgConnect::RequestConnectL() start")); |
|
142 test.Next(_L("connecting")); |
|
143 |
|
144 iIAPPreferences = CImIAPPreferences::NewLC(); // PUSH (there is not a NewL() function) |
|
145 CleanupStack::Pop(iIAPPreferences); // POP |
|
146 |
|
147 TImIAPChoice iap; |
|
148 iap.iIAP = 1; // COMMDB_ID 1 |
|
149 iap.iDialogPref = ECommDbDialogPrefDoNotPrompt; |
|
150 iIAPPreferences->AddIAPL(iap); |
|
151 |
|
152 TBuf<32> serverAddress; |
|
153 if(iConn == 0) |
|
154 serverAddress = KServerAddressConn0; |
|
155 else |
|
156 serverAddress = KServerAddressConn1; |
|
157 |
|
158 testUtils->WriteComment(_L("CMsgConnect - queuing connect with CImTextServerSesison")); |
|
159 iImSocket->QueueConnectL(iStatus, serverAddress, KPortNumber, *iIAPPreferences); |
|
160 SetActive(); |
|
161 } |
|
162 |
|
163 void CMsgConnect::CancelConnectL() |
|
164 { |
|
165 testUtils->WriteComment(_L("CMsgConnect cancelling connection")); |
|
166 test.Next(_L("Cancel connecting")); |
|
167 iImSocket->Disconnect(); |
|
168 } |
|
169 |
|
170 TInt CMsgConnect::ConnectProgress() |
|
171 { |
|
172 return iImSocket->GetConnectionStage(); |
|
173 } |
|
174 |
|
175 TInt CMsgConnect::GetIAPValue(TUint32 &aIAP) |
|
176 { |
|
177 return iImSocket->GetIAPValue(aIAP); |
|
178 } |
|
179 |
|
180 TInt CMsgConnect::GetIAPBearer(TUint32 &aBearer) |
|
181 { |
|
182 return iImSocket->GetIAPBearer(aBearer); |
|
183 } |
|
184 |
|
185 // |
|
186 |
|
187 LOCAL_C void Init() |
|
188 { |
|
189 scheduler = new (ELeave) CActiveScheduler; |
|
190 CActiveScheduler::Install(scheduler); |
|
191 |
|
192 User::LeaveIfError(theFs.Connect()); |
|
193 |
|
194 // set up the log file |
|
195 testUtils = CEmailTestUtils::NewLC(test); |
|
196 testUtils->TestStart(0); |
|
197 testUtils->SetLogToFile(ETrue); |
|
198 testUtils->WriteComment(_L("This tests a change to CImConnect so that it no longer calls iConn.Stop()")); |
|
199 testUtils->WriteComment(_L("in its DoCancel(), but iConn.Close() instead.")); |
|
200 testUtils->WriteComment(_L("This should not cancel other connections to the internet using that IAP.")); |
|
201 testUtils->WriteComment(_L("\n")); |
|
202 } |
|
203 |
|
204 LOCAL_C void Closedown() |
|
205 { |
|
206 testUtils->TestHarnessCompleted(); |
|
207 CleanupStack::PopAndDestroy(testUtils); |
|
208 |
|
209 theFs.Close(); |
|
210 delete scheduler; |
|
211 } |
|
212 // This tests the change made for "INC040630 - Panic while disconnecting a |
|
213 // service". Calling CImTextServerSession::GetConnectionStage with a cancelled |
|
214 // RConnection caused a panic. |
|
215 LOCAL_C void TestCancelWithProgress() |
|
216 { |
|
217 _LIT(KTestThreadName, "CancelWithProgress Test Thread"); |
|
218 const TInt KMinTestHeapSize = 0x10000; |
|
219 const TInt KMaxTestHeapSize = 0x100000; |
|
220 |
|
221 TRequestStatus requestStatus; |
|
222 RThread testThread; |
|
223 |
|
224 gConnect = CMsgConnect::NewLC(0); // PUSH |
|
225 |
|
226 User::SetJustInTime(EFalse); |
|
227 |
|
228 // Set up the conditions which cause the panic. I.e. request a connection |
|
229 // then cancel it. |
|
230 gConnect->RequestConnectL(); |
|
231 |
|
232 // Call GetConnectionStage, GetIAPValue, and GetIAPBearer to ensure they |
|
233 // return the correct results. |
|
234 TUint32 bearer = 1; |
|
235 TUint32 iap = 1; |
|
236 TInt returnValue; |
|
237 |
|
238 // Test normal behaviour in this state with a valid but unconnected connection. |
|
239 returnValue = gConnect->GetIAPBearer(bearer); |
|
240 (*testUtils)(returnValue == KErrNotReady); |
|
241 returnValue = gConnect->GetIAPValue(iap); |
|
242 (*testUtils)(returnValue == KErrNone || returnValue == KErrNotReady); |
|
243 (*testUtils)(iap == 1); |
|
244 returnValue = gConnect->ConnectProgress(); |
|
245 (*testUtils)(returnValue != KErrBadHandle); |
|
246 |
|
247 // Cancel the CImTextServerSession |
|
248 gConnect->CancelConnectL(); |
|
249 |
|
250 // Test after cancel. |
|
251 returnValue = gConnect->GetIAPBearer(bearer); |
|
252 // GetIAPBearer now returns KErrBadHandle. |
|
253 (*testUtils)(returnValue == KErrBadHandle); |
|
254 |
|
255 returnValue = gConnect->GetIAPValue(iap); |
|
256 // GetIAPValue now returns KErrBadHandle. |
|
257 (*testUtils)(returnValue == KErrBadHandle); |
|
258 |
|
259 // CImConnect::Progress now returns KErrBadHandle. |
|
260 returnValue = gConnect->ConnectProgress(); |
|
261 (*testUtils)(returnValue == KErrBadHandle); |
|
262 |
|
263 // Create a separate thread to call GetConnectionStage |
|
264 testThread.Create( |
|
265 KTestThreadName, |
|
266 DoTestThreadStart, // replace |
|
267 KDefaultStackSize, |
|
268 KMinTestHeapSize, |
|
269 KMaxTestHeapSize, |
|
270 NULL, |
|
271 EOwnerThread); |
|
272 testThread.Logon(requestStatus); |
|
273 |
|
274 // Let the thread run |
|
275 testThread.Resume(); |
|
276 User::WaitForRequest(requestStatus); |
|
277 |
|
278 // Test whether the thread exitied with a panic. |
|
279 TInt result = (testThread.ExitType() == EExitPanic); |
|
280 if (result) |
|
281 testUtils->WriteComment( |
|
282 _L("GetConnectionStage caused panic after Cancel")); |
|
283 // Pass or fail the test based on whether the thread stopped because of a |
|
284 // panic. |
|
285 (*testUtils)(!result); |
|
286 testThread.Close(); |
|
287 User::SetJustInTime(ETrue); |
|
288 |
|
289 CleanupStack::PopAndDestroy(gConnect); |
|
290 } |
|
291 |
|
292 LOCAL_C void DoTestThreadWorkL() |
|
293 { |
|
294 CActiveScheduler* scheduler = new (ELeave) CActiveScheduler; |
|
295 CActiveScheduler::Install(scheduler); |
|
296 CleanupStack::PushL(scheduler); |
|
297 // ConnectProgress calls GetConnectionStage in CImTextServerSession. |
|
298 gConnect->ConnectProgress(); |
|
299 CleanupStack::PopAndDestroy(scheduler); |
|
300 } |
|
301 |
|
302 static TInt DoTestThreadStart(TAny*) |
|
303 { |
|
304 // Entry function for the child thread which is created then killed. |
|
305 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
306 test(cleanup != NULL); |
|
307 |
|
308 TRAPD(ret, DoTestThreadWorkL()); |
|
309 delete cleanup; |
|
310 return 0; |
|
311 } |
|
312 |
|
313 |
|
314 // |
|
315 |
|
316 LOCAL_C void doMainL() |
|
317 { |
|
318 Init(); |
|
319 |
|
320 TInt testNo = 1; |
|
321 testUtils->TestStart(testNo); |
|
322 testUtils->WriteComment( |
|
323 _L("Testing calls to CImTextServerSession Cancel then GetConnectionStage")); |
|
324 TestCancelWithProgress(); |
|
325 testUtils->TestFinish(testNo); |
|
326 testNo += 1; |
|
327 |
|
328 CMsgConnect* connect1 = CMsgConnect::NewLC(0); // PUSH |
|
329 CMsgConnect* connect2 = CMsgConnect::NewLC(1); // PUSH |
|
330 |
|
331 testUtils->WriteComment(_L("1st connect object connecting")); |
|
332 connect1->RequestConnectL(); |
|
333 // wait a while before starting the next connection |
|
334 testUtils->WriteComment(_L("waiting a little while before starting the 2nd connection")); |
|
335 User::After(1000000); |
|
336 |
|
337 testUtils->WriteComment(_L("2nd connect object connecting")); |
|
338 connect2->RequestConnectL(); |
|
339 |
|
340 // we wait until the connect2 is actually connecting, |
|
341 // this is when the progress value = 2500 |
|
342 testUtils->WriteComment(_L("we should only cancel the connection when it is connecting")); |
|
343 |
|
344 for(TInt a = 0; a < 100; a++) |
|
345 { |
|
346 // if connect2 has got so far as connecting, then we should fail the test because |
|
347 // this test relies on us cancelling the connection when it is connecting |
|
348 if(connect2->ConnectProgress() == KConnectionMadeProgressValue) |
|
349 { |
|
350 testUtils->WriteComment(_L("connection made before we can cancel it")); |
|
351 testUtils->WriteComment(_L("TEST FAILED")); |
|
352 CleanupStack::PopAndDestroy(2); // connect2 & connect1 |
|
353 Closedown(); |
|
354 return; |
|
355 } |
|
356 |
|
357 // note that the connect progress could have skipped past the connecting value, whilst we |
|
358 // are waiting for the 1second to pass, so if the progress is higher than the connecting |
|
359 // value, then we should cancel it as well |
|
360 if(connect2->ConnectProgress() > KConnectingProgressValue) |
|
361 { |
|
362 testUtils->WriteComment(_L("cancelling the 2nd connection")); |
|
363 connect2->CancelConnectL(); |
|
364 break; |
|
365 } |
|
366 |
|
367 User::After(1000000); |
|
368 } |
|
369 |
|
370 // wait until the 1st one has connected correctly |
|
371 testUtils->WriteComment(_L("wait for the 1st connection object to connect")); |
|
372 CActiveScheduler::Start(); |
|
373 |
|
374 // cancel the connection of the connection that is up and running |
|
375 testUtils->WriteComment(_L("cancel the 1st connection object")); |
|
376 connect1->CancelConnectL(); |
|
377 |
|
378 CleanupStack::PopAndDestroy(2); // connect2 & connect1 |
|
379 Closedown(); |
|
380 } |
|
381 |
|
382 |
|
383 GLDEF_C TInt E32Main() |
|
384 { |
|
385 test.SetLogged(ETrue); |
|
386 test.Title(); |
|
387 test.Start(_L("Testing Multiple connections on one IAP using CImTextServerSession")); |
|
388 __UHEAP_MARK; |
|
389 |
|
390 theCleanup=CTrapCleanup::New(); |
|
391 test (theCleanup!=NULL); |
|
392 TRAPD(ret,doMainL()); |
|
393 test (ret==KErrNone); |
|
394 delete theCleanup; |
|
395 |
|
396 __UHEAP_MARKEND; |
|
397 test.End(); |
|
398 return 0; |
|
399 } |