|
1 // Copyright (c) 2000-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 #include <e32std.h> |
|
17 #include <e32test.h> |
|
18 #include <s32file.h> |
|
19 |
|
20 #include <push/pushmessage.h> |
|
21 #include "cmultipartbiniterator.h" |
|
22 #include "cmultiparttextiterator.h" |
|
23 |
|
24 #include <push/pushlog.h> |
|
25 #include "testlog.h" |
|
26 #include "t_pushmessage.h" |
|
27 |
|
28 /** literals */ |
|
29 _LIT8(KWBContentType, "X-WBML-Content-Type: "); |
|
30 _LIT8(KHeaderBoundary, "\r\n\r\n"); |
|
31 _LIT(KTestTitle,"T_PushMessage"); |
|
32 TChar KEOL('\n'); |
|
33 TChar KCOMMA(','); |
|
34 TChar KSEMICOLON(';'); |
|
35 |
|
36 /** global variables */ |
|
37 RTest gTest(KTestTitle); |
|
38 RFs gFs; |
|
39 |
|
40 |
|
41 |
|
42 /** |
|
43 factory construction method to allocate and construct a new CPushMessageTester |
|
44 @param aWapLog Implementation of logging interface |
|
45 */ |
|
46 CPushMessageTester* CPushMessageTester::NewLC(CWapPushLog& aWapLog) |
|
47 { |
|
48 CPushMessageTester* self = new (ELeave) CPushMessageTester(aWapLog); |
|
49 CleanupStack::PushL(self); |
|
50 return self; |
|
51 } |
|
52 |
|
53 /** |
|
54 factory construction method to allocate and construct a new CPushMessageTester |
|
55 @param aWapLog Implementation of logging interface |
|
56 */ |
|
57 CPushMessageTester* CPushMessageTester::NewL(CWapPushLog& aWapLog) |
|
58 { |
|
59 CPushMessageTester* self = CPushMessageTester::NewLC(aWapLog); |
|
60 CleanupStack::Pop(); |
|
61 return self; |
|
62 } |
|
63 |
|
64 /** |
|
65 constructor |
|
66 @param aWapLog Implementation of logging interface |
|
67 */ |
|
68 CPushMessageTester::CPushMessageTester(CWapPushLog& aWapLog) |
|
69 :iLog(aWapLog) |
|
70 { |
|
71 } |
|
72 |
|
73 /** destructor */ |
|
74 CPushMessageTester::~CPushMessageTester() |
|
75 { |
|
76 delete iPushMessage1; |
|
77 delete iPushMessage2; |
|
78 delete iPushMessage3; |
|
79 delete iPushMessage4; |
|
80 delete iPushMessage5; |
|
81 delete iPushMessage6; |
|
82 delete iPushMessage7; |
|
83 delete iPushMultiMessage; |
|
84 } |
|
85 |
|
86 |
|
87 /* creates a descriptors containing the data from arrays */ |
|
88 HBufC8* CPushMessageTester::CreateMsgDataLC(const TUint8* aMessage, TInt aLength) |
|
89 { |
|
90 HBufC8* msgData = HBufC8::NewLC(aLength); |
|
91 TBuf8<140> tempBuf; |
|
92 TUint8 value=0; |
|
93 |
|
94 for (TInt i=0; i<aLength; i++) |
|
95 { |
|
96 value = aMessage[i]; |
|
97 tempBuf.Append(value); |
|
98 } |
|
99 |
|
100 msgData->Des().Copy(tempBuf); |
|
101 return msgData; |
|
102 } |
|
103 |
|
104 |
|
105 /** create push messages for the tests */ |
|
106 void CPushMessageTester::CreateMessagesL() |
|
107 { |
|
108 __LOG_ALWAYS("Test Results"); |
|
109 __LOG_ALWAYS(" "); |
|
110 |
|
111 HBufC8* header1 = CreateMsgDataLC(KMessageHeader2,15); |
|
112 HBufC8* body1 = KLongPushMessageBody().AllocLC(); |
|
113 HBufC8* address1 = KPushMessageServerAddress().AllocLC(); |
|
114 |
|
115 iPushMessage1 = CPushMessage::NewL(header1, body1, 22, address1); |
|
116 CleanupStack::Pop(3, header1); //header1, body1, address1 |
|
117 |
|
118 HBufC8* header2 = CreateMsgDataLC(KMessageHeader3,9); |
|
119 HBufC8* body2 = KShortPushMessageBody().AllocLC(); |
|
120 iPushMessage2 = CPushMessage::NewL(header2, body2); |
|
121 CleanupStack::Pop(2, header2); //header2, body2 |
|
122 |
|
123 HBufC8* header3 = CreateMsgDataLC(KMessageHeader4,32); |
|
124 HBufC8* body3 = KShortPushMessageBody().AllocLC(); |
|
125 iPushMessage3 = CPushMessage::NewL(header3, body3); |
|
126 CleanupStack::Pop(2, header3); //header3, body3 |
|
127 |
|
128 HBufC8* header4 = CreateMsgDataLC(KMessageHeaderMultipart,42); |
|
129 HBufC8* body4 = CreateMsgDataLC(KMessageBodyMultipart,42); |
|
130 iPushMultiMessage = CPushMessage::NewL(header4, body4); |
|
131 CleanupStack::Pop(2, header4); // header4, body4 |
|
132 |
|
133 HBufC8* header5 = CreateMsgDataLC(KMessageHeader5,22); |
|
134 HBufC8* body5 = KLongPushMessageBody().AllocLC(); |
|
135 HBufC8* address2 = KPushMessageServerAddress().AllocLC(); |
|
136 iPushMessage4 = CPushMessage::NewL(header5, body5, 255, address2); |
|
137 CleanupStack::Pop(3, header5); // header5, body5, address2 |
|
138 |
|
139 HBufC8* header6 = CreateMsgDataLC(KMessageHeader6,51); |
|
140 HBufC8* body6 = KLongPushMessageBody().AllocLC(); |
|
141 iPushMessage5 = CPushMessage::NewL(header6, body6); |
|
142 CleanupStack::Pop(2, header6); // header6, body6 |
|
143 |
|
144 HBufC8* header7 = CreateMsgDataLC(KMessageHeader7,9); |
|
145 HBufC8* body7 = KLongPushMessageBody().AllocLC(); |
|
146 iPushMessage6 = CPushMessage::NewL(header7, body7); |
|
147 CleanupStack::Pop(2, header7); // header7, body7 |
|
148 |
|
149 HBufC8* header8 = CreateMsgDataLC(KMessageHeader8,139); |
|
150 HBufC8* body8 = KLongPushMessageBody().AllocLC(); |
|
151 iPushMessage7 = CPushMessage::NewL(header8, body8); |
|
152 CleanupStack::Pop(2, header8); // header8, body8 |
|
153 } |
|
154 |
|
155 |
|
156 /** dump relevant bits of the message to the console */ |
|
157 void CPushMessageTester::OutputMessageDataL() |
|
158 { |
|
159 __LOG_MSG_DEBUG(*iPushMessage1); |
|
160 __LOG_MSG_DEBUG(*iPushMessage2); |
|
161 __LOG_MSG_DEBUG(*iPushMessage3); |
|
162 __LOG_MSG_DEBUG(*iPushMessage4); |
|
163 __LOG_MSG_DEBUG(*iPushMessage5); |
|
164 __LOG_MSG_DEBUG(*iPushMessage6); |
|
165 __LOG_MSG_DEBUG(*iPushMessage7); |
|
166 |
|
167 TPtrC contentType; |
|
168 iPushMultiMessage->GetContentType(contentType); |
|
169 |
|
170 _LIT(KMultipartMixedBin, "application/vnd.wap.multipart.mixed"); |
|
171 if (contentType==KMultipartMixedBin) |
|
172 { |
|
173 CMultipartBinIterator* multiMsg = CMultipartBinIterator::NewL(*iPushMultiMessage); |
|
174 CleanupStack::PushL(multiMsg); |
|
175 do |
|
176 { |
|
177 CPushMessage * pm = multiMsg->PartL(); |
|
178 CleanupStack::PushL(pm); |
|
179 __LOG_MSG_DEBUG(*pm); |
|
180 CleanupStack::PopAndDestroy(pm); |
|
181 } while (multiMsg->NextL()); |
|
182 CleanupStack::PopAndDestroy(multiMsg); |
|
183 } |
|
184 } |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 /** create multipart messages from text? */ |
|
192 void CPushMessageTester::TestMultiTextMsgFromFilesL() |
|
193 { |
|
194 _LIT(KPushTxtFilePath, "C:\\tpushmessage\\"); |
|
195 CDir* dir; |
|
196 TInt err = gFs.GetDir(KPushTxtFilePath, KEntryAttMatchMask, ESortByName, dir); |
|
197 CleanupStack::PushL(dir); |
|
198 if (err == KErrPathNotFound) |
|
199 User::LeaveIfError(gFs.MkDirAll(KPushTxtFilePath)); |
|
200 else |
|
201 User::LeaveIfError(err); |
|
202 CleanupStack::PopAndDestroy(dir); |
|
203 |
|
204 |
|
205 // Set the session path for the RFs |
|
206 gFs.SetSessionPath(KPushTxtFilePath); |
|
207 _LIT(KPushTxtFilePattern,"*.txt"); |
|
208 dir=NULL; |
|
209 User::LeaveIfError(gFs.GetDir(KPushTxtFilePattern, KEntryAttNormal, ESortByName, dir)); |
|
210 CleanupStack::PushL(dir); |
|
211 TInt count = dir->Count(); |
|
212 if(count != 0) |
|
213 { |
|
214 TFileName currentFile; |
|
215 TBuf8<256> msgType; |
|
216 for(TInt i = 0; i < count; i++) |
|
217 { |
|
218 currentFile=( (*dir)[i].iName ); |
|
219 GenMessageTypeL(currentFile, msgType); |
|
220 |
|
221 //if (msgType[0] == 0x8C && msgType[0] <= 0x8E) |
|
222 { |
|
223 CPushMessage* pushMessage = CreateMultiTextPushMessageL(currentFile, msgType); |
|
224 CleanupStack::PushL(pushMessage); |
|
225 |
|
226 CMultipartTextIterator* multiMsg = CMultipartTextIterator::NewL(*pushMessage); |
|
227 CleanupStack::PushL(multiMsg); |
|
228 do |
|
229 { |
|
230 CPushMessage * pm = multiMsg->PartL(); |
|
231 __LOG_MSG_DEBUG(*pm); |
|
232 delete pm; |
|
233 } while (multiMsg->NextL()); |
|
234 CleanupStack::PopAndDestroy(2); //multiMsg, pushMessage |
|
235 } |
|
236 } |
|
237 } |
|
238 CleanupStack::PopAndDestroy(dir); |
|
239 } |
|
240 |
|
241 |
|
242 |
|
243 |
|
244 void CPushMessageTester::GenMessageTypeL(const TDesC& aFileName, TDes8& rMsgType) |
|
245 { |
|
246 TBuf8<256> lineBuffer; // Buffer from Read function. |
|
247 TInt aPos = 0; |
|
248 |
|
249 HBufC8* contentType = NULL; |
|
250 |
|
251 RFile file; |
|
252 TInt err = file.Open(gFs,aFileName,EFileStreamText|EFileRead|EFileShareAny); |
|
253 |
|
254 // Didn't find the file, so leave - should only get valid filenames! |
|
255 if(err != KErrNone) |
|
256 User::Leave(KErrNotFound); |
|
257 |
|
258 |
|
259 file.Seek(ESeekAddress,aPos); |
|
260 err = file.Read(lineBuffer, 256);// Read upto 256 chars, '\n' and all... |
|
261 if (err==KErrNone) // Made a valid read, |
|
262 if (lineBuffer.Length()==0) // but read 0 chars |
|
263 err=KErrEof; // so set err value to end processing |
|
264 |
|
265 if(err == KErrNone) |
|
266 { |
|
267 // now we'ver read in a line |
|
268 TInt ctOffset = lineBuffer.FindF(KWBContentType); |
|
269 if (ctOffset != KErrNotFound) |
|
270 { |
|
271 contentType = lineBuffer.Mid(ctOffset).AllocL(); |
|
272 // we've found content-type ... make sure we've read the whole line |
|
273 TInt eolOffset = contentType->Locate(KEOL); |
|
274 if (ctOffset == KErrNotFound) |
|
275 { |
|
276 // must get the rest of the line |
|
277 err = file.Read(lineBuffer, 256);// Read upto 256 chars, '\n' and all... |
|
278 eolOffset = contentType->Locate(KEOL); |
|
279 contentType = contentType->ReAllocL(contentType->Length() + eolOffset); |
|
280 contentType->Des().Append(lineBuffer.Mid(eolOffset)); |
|
281 } |
|
282 } |
|
283 } |
|
284 |
|
285 // set ContentType the whole WBContent line |
|
286 TInt eolOffset = contentType->Locate(KEOL); |
|
287 TPtrC8 wbContentType = contentType->Mid(KWBContentType().Length(), eolOffset - KWBContentType().Length() - 1); |
|
288 |
|
289 // First value is the binary value of content type; |
|
290 TInt commaOffset = wbContentType.Locate(KCOMMA); |
|
291 TPtrC8 binType = wbContentType.Mid(0, commaOffset); |
|
292 |
|
293 TLex8 ctTypeLex(binType); |
|
294 TUint8 ctVal = 0; |
|
295 ctTypeLex.Val(ctVal, EHex); |
|
296 |
|
297 TBuf8<256> binHeader; |
|
298 binHeader.Zero(); |
|
299 binHeader.Append(ctVal); |
|
300 |
|
301 // is this a multipart/ |
|
302 if (ctVal >= 0x8C && ctVal <= 0x8E) |
|
303 { |
|
304 // next field is boundary |
|
305 TPtrC8 boundary = wbContentType.Mid(commaOffset+1); |
|
306 binHeader.Append(KBoundaryParam); |
|
307 binHeader.Append(0); |
|
308 binHeader.Append(boundary); |
|
309 binHeader.Append(0); |
|
310 } |
|
311 |
|
312 rMsgType.Zero(); |
|
313 |
|
314 TInt len = binHeader.Length(); |
|
315 if (len <= 30) |
|
316 rMsgType.Append(len); |
|
317 else if (len < 128) |
|
318 { |
|
319 // make sure the top bit isn't set |
|
320 TUint8 wapUint = 31; |
|
321 len &= 0x7F; |
|
322 rMsgType.Append(wapUint); |
|
323 rMsgType.Append(len); |
|
324 } |
|
325 else |
|
326 { |
|
327 |
|
328 |
|
329 } |
|
330 |
|
331 rMsgType.Append(binHeader); |
|
332 delete contentType; |
|
333 file.Close(); |
|
334 } |
|
335 |
|
336 |
|
337 CPushMessage* CPushMessageTester::CreateMultiTextPushMessageL(const TDesC& aFileName, const TDesC8& aHdr) |
|
338 { |
|
339 RFile file; |
|
340 TBuf8<256> lineBuffer; // Buffer from Read function. |
|
341 TInt err=KErrNone; |
|
342 TInt aPos = 0; |
|
343 HBufC8* headers = NULL; |
|
344 HBufC8* body = NULL; |
|
345 TBool bBodyFound = EFalse; |
|
346 |
|
347 err = file.Open(gFs,aFileName,EFileStreamText|EFileRead|EFileShareAny); |
|
348 |
|
349 if(err != KErrNone) // Didn't find the file, so leave - should only get valid filenames! |
|
350 { |
|
351 User::Leave(KErrNotFound); |
|
352 } |
|
353 |
|
354 headers = aHdr.AllocLC(); |
|
355 |
|
356 file.Seek(ESeekAddress,aPos); |
|
357 err = file.Read(lineBuffer, 256);// Read upto 256 chars, '\n' and all... |
|
358 if (err==KErrNone) // Made a valid read, |
|
359 if (lineBuffer.Length()==0) // but read 0 chars |
|
360 err=KErrEof; // so set err value to end processing |
|
361 |
|
362 if(err == KErrNone) |
|
363 do { |
|
364 // now we'ver read in a line |
|
365 TInt bdOffset = lineBuffer.FindF(KHeaderBoundary); |
|
366 if ( !bBodyFound && bdOffset == KErrNotFound) |
|
367 { |
|
368 HBufC8* oldHeaders = headers; |
|
369 headers = headers->ReAllocL(headers->Length() + lineBuffer.Length()); |
|
370 CleanupStack::Pop(oldHeaders); |
|
371 CleanupStack::PushL(headers); |
|
372 |
|
373 headers->Des().Append(lineBuffer); |
|
374 } |
|
375 |
|
376 else // we've found our break |
|
377 { |
|
378 if (!bBodyFound) |
|
379 { |
|
380 HBufC8* oldHeaders = headers; |
|
381 headers = headers->ReAllocL(headers->Length() + lineBuffer.Length() - bdOffset ); |
|
382 CleanupStack::Pop(oldHeaders); |
|
383 CleanupStack::PushL(headers); |
|
384 |
|
385 headers->Des().Append(lineBuffer.Mid(0, lineBuffer.Length() - bdOffset)); |
|
386 |
|
387 body = lineBuffer.Mid(bdOffset+2, lineBuffer.Length() - bdOffset-2).AllocLC(); |
|
388 bBodyFound = ETrue; |
|
389 } |
|
390 |
|
391 else |
|
392 { |
|
393 HBufC8* oldBody = body; |
|
394 body = body->ReAllocL(body->Length() + lineBuffer.Length() ); |
|
395 CleanupStack::Pop(oldBody); |
|
396 CleanupStack::PushL(body); |
|
397 |
|
398 body->Des().Append(lineBuffer); |
|
399 } |
|
400 |
|
401 } |
|
402 err = file.Read(lineBuffer, 256);// Read upto 256 chars, '\n' and all... |
|
403 } while ( lineBuffer.Length()); |
|
404 |
|
405 |
|
406 file.Close(); |
|
407 CPushMessage* rPush = CPushMessage::NewL(headers, body); |
|
408 if (body == NULL) |
|
409 CleanupStack::Pop(headers); |
|
410 else |
|
411 CleanupStack::Pop(2, headers); //headers, body |
|
412 return rPush; |
|
413 } |
|
414 |
|
415 void CPushMessageTester::TestFinished() |
|
416 { |
|
417 __LOG_ALWAYS(" "); |
|
418 __LOG_ALWAYS("Tests Completed"); |
|
419 } |
|
420 |
|
421 /** what does this do? - i assume this was used to create messages */ |
|
422 LOCAL_C void CalcTimePeriod() |
|
423 { |
|
424 // Get num bytes encoding the date - |
|
425 // we are positioned at that location in the source descriptor |
|
426 // TInt32 time = 0; |
|
427 |
|
428 // The WSP Date encoding is the number of seconds since the start of the |
|
429 // UNIX epoch (00:00:00.000, 01-Jan-1970), as a long integer |
|
430 TDateTime targetDT(2000, EAugust, 15,10,20,0,0); |
|
431 TDateTime unixEpocDT(1970, EJanuary, 0, 0, 0, 0, 0); |
|
432 TTime targetTime(targetDT); |
|
433 TTimeIntervalSeconds timeSeconds; |
|
434 |
|
435 targetTime.SecondsFrom(unixEpocDT,timeSeconds); |
|
436 |
|
437 timeSeconds.Int(); |
|
438 } |
|
439 |
|
440 |
|
441 |
|
442 |
|
443 /** Setup test environment and run tests */ |
|
444 LOCAL_C void doMainL() |
|
445 { |
|
446 gTest.Start(KTestTitle); |
|
447 |
|
448 gTest.Printf(_L("@SYMTestCaseID IWS-WAPBROWSER-PUSHUTILS-T_PUSHMESSAGE-0001 ")); |
|
449 |
|
450 CWapPushLog* log = CWapPushLog::NewL(*gTest.Console()); |
|
451 log->SetLogFileName(_L("TPushMessage.txt")); |
|
452 CleanupStack::PushL(log); |
|
453 User::LeaveIfError(gFs.Connect()); |
|
454 CleanupClosePushL(gFs); |
|
455 CalcTimePeriod(); |
|
456 |
|
457 CPushMessageTester* myTester = CPushMessageTester::NewLC(*log); |
|
458 myTester->CreateMessagesL(); |
|
459 myTester->OutputMessageDataL(); |
|
460 myTester->TestMultiTextMsgFromFilesL(); |
|
461 myTester->TestFinished(); |
|
462 |
|
463 CleanupStack::PopAndDestroy(3); //gFs.Close(), log, myTester |
|
464 gTest.End(); |
|
465 gTest.Close(); |
|
466 } |
|
467 |
|
468 |
|
469 |
|
470 /** Entry point to test executable */ |
|
471 GLDEF_C TInt E32Main() |
|
472 { |
|
473 __UHEAP_MARK; |
|
474 CTrapCleanup* theCleanup = CTrapCleanup::New(); |
|
475 TRAPD(ret,doMainL()); |
|
476 gTest(ret==KErrNone); |
|
477 delete theCleanup; |
|
478 __UHEAP_MARKEND; |
|
479 return(KErrNone); |
|
480 } |