1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.email.service;
18 
19 import android.content.ContentValues;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.test.suitebuilder.annotation.SmallTest;
23 
24 import com.android.emailcommon.provider.EmailContent;
25 import com.android.emailcommon.service.EmailServiceStatus;
26 import com.android.mail.providers.UIProvider;
27 
28 import junit.framework.TestCase;
29 
30 /**
31  * Tests of the AttachmentService
32  *
33  * You can run this entire test case with:
34  *   runtest -c com.android.email.service.AttachmentServiceTests email
35  */
36 @SmallTest
37 public class AttachmentServiceTests extends TestCase {
38 
testDownloadRequestIsEquals()39     public void testDownloadRequestIsEquals() {
40         final AttachmentService.DownloadRequest dr =
41                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
42         final AttachmentService.DownloadRequest dr2 =
43                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 2);
44         assertTrue(dr.equals(dr));
45         assertFalse(dr.equals(dr2));
46     }
47 
testDownloadQueueEmptyQueue()48     public void testDownloadQueueEmptyQueue() {
49         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
50         assertEquals(0, dq.getSize());
51         assertTrue(dq.isEmpty());
52     }
53 
testDownloadQueueAddRequest()54     public void testDownloadQueueAddRequest() {
55         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
56         final AttachmentService.DownloadRequest dr =
57                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
58         final boolean result = dq.addRequest(dr);
59         assertTrue(result);
60         assertEquals(1, dq.getSize());
61         assertFalse(dq.isEmpty());
62     }
63 
testDownloadQueueAddRequestNull()64     public void testDownloadQueueAddRequestNull() {
65         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
66         boolean exceptionThrown = false;
67         try {
68             dq.addRequest(null);
69         } catch (NullPointerException ex) {
70             exceptionThrown = true;
71         }
72         assertTrue(exceptionThrown);
73         assertEquals(0, dq.getSize());
74         assertTrue(dq.isEmpty());
75     }
76 
testDownloadQueueAddRequestExisting()77     public void testDownloadQueueAddRequestExisting() {
78         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
79         final AttachmentService.DownloadRequest dr =
80                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
81         boolean result = dq.addRequest(dr);
82         assertTrue(result);
83         assertEquals(1, dq.getSize());
84         assertFalse(dq.isEmpty());
85 
86         // Now try to add the same one again. The queue should remain the same size.
87         result = dq.addRequest(dr);
88         assertTrue(result);
89         assertEquals(1, dq.getSize());
90         assertFalse(dq.isEmpty());
91     }
92 
testDownloadQueueRemoveRequest()93     public void testDownloadQueueRemoveRequest() {
94         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
95         final AttachmentService.DownloadRequest dr =
96                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
97         boolean result = dq.addRequest(dr);
98         assertTrue(result);
99         assertEquals(1, dq.getSize());
100         assertFalse(dq.isEmpty());
101 
102         // Now remove the request and check the status of the queue
103         result = dq.removeRequest(dr);
104         assertTrue(result);
105 
106         // The queue should be empty.
107         assertEquals(0, dq.getSize());
108         assertTrue(dq.isEmpty());
109     }
110 
testDownloadQueueRemoveRequestNull()111     public void testDownloadQueueRemoveRequestNull() {
112         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
113         final AttachmentService.DownloadRequest dr =
114                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
115         boolean result = dq.addRequest(dr);
116         assertTrue(result);
117         assertEquals(dq.getSize(), 1);
118         assertFalse(dq.isEmpty());
119 
120         // Now remove the request and check the status of the queue
121         result = dq.removeRequest(null);
122         assertTrue(result);
123 
124         // The queue should still have 1.
125         assertEquals(1, dq.getSize());
126         assertFalse(dq.isEmpty());
127     }
128 
testDownloadQueueRemoveRequestDoesNotExist()129     public void testDownloadQueueRemoveRequestDoesNotExist() {
130         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
131         final AttachmentService.DownloadRequest dr =
132                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
133         boolean result = dq.addRequest(dr);
134         assertTrue(result);
135         assertEquals(1, dq.getSize());
136         assertFalse(dq.isEmpty());
137 
138         // Generate a new request and try to remove it.
139         result = dq.removeRequest(new AttachmentService.DownloadRequest(
140                 AttachmentService.PRIORITY_FOREGROUND, 2));
141         assertFalse(result);
142 
143         // The queue should still have 1.
144         assertEquals(1, dq.getSize());
145         assertFalse(dq.isEmpty());
146     }
147 
testDownloadQueueFindRequestById()148     public void testDownloadQueueFindRequestById() {
149         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
150         final AttachmentService.DownloadRequest dr =
151                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
152         final boolean result = dq.addRequest(dr);
153         assertTrue(result);
154 
155         final AttachmentService.DownloadRequest drResult = dq.findRequestById(1);
156         assertNotNull(drResult);
157 
158         // Now let's make sure that these objects are the same
159         assertEquals(dr, drResult);
160     }
161 
testDownloadQueueFindRequestByIdInvalidId()162     public void testDownloadQueueFindRequestByIdInvalidId() {
163         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
164         final AttachmentService.DownloadRequest dr =
165                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
166         final boolean result = dq.addRequest(dr);
167         assertTrue(result);
168 
169         final AttachmentService.DownloadRequest drResult = dq.findRequestById(-1);
170         assertNull(drResult);
171     }
172 
testDownloadQueueFindRequestByIdUnknownId()173     public void testDownloadQueueFindRequestByIdUnknownId() {
174         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
175         final AttachmentService.DownloadRequest dr =
176                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
177         final boolean result = dq.addRequest(dr);
178         assertTrue(result);
179 
180         final AttachmentService.DownloadRequest drResult = dq.findRequestById(5);
181         assertNull(drResult);
182     }
183 
184     /**
185      * This is just to test the FIFOness of our queue.  We test priorities in a latter
186      * test case.
187      */
testDownloadQueueGetNextRequest()188     public void testDownloadQueueGetNextRequest() {
189         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
190         final AttachmentService.DownloadRequest dr =
191                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
192         boolean result = dq.addRequest(dr);
193         assertTrue(result);
194 
195         final AttachmentService.DownloadRequest dr2 =
196                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_SEND_MAIL, 2);
197         result = dq.addRequest(dr2);
198         assertTrue(result);
199 
200         final AttachmentService.DownloadRequest dr3 =
201                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_BACKGROUND, 3);
202         result = dq.addRequest(dr3);
203         assertTrue(result);
204 
205         assertEquals(3, dq.getSize());
206         assertFalse(dq.isEmpty());
207 
208         AttachmentService.DownloadRequest drResult = dq.getNextRequest();
209         assertEquals(dr, drResult);
210         assertEquals(2, dq.getSize());
211         assertFalse(dq.isEmpty());
212 
213         drResult = dq.getNextRequest();
214         assertEquals(dr2, drResult);
215         assertEquals(1, dq.getSize());
216         assertFalse(dq.isEmpty());
217 
218         drResult = dq.getNextRequest();
219         assertEquals(dr3, drResult);
220         assertEquals(0, dq.getSize());
221         assertTrue(dq.isEmpty());
222     }
223 
testDownloadQueueGetNextRequestEmptyQueue()224     public void testDownloadQueueGetNextRequestEmptyQueue() {
225         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
226         AttachmentService.DownloadRequest drResult = dq.getNextRequest();
227         assertNull(drResult);
228     }
229 
testDownloadQueueSizeReporting()230     public void testDownloadQueueSizeReporting() {
231         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
232 
233         // Start adding some download request objects, note that the empty queue case has been
234         // tested in above.
235         final AttachmentService.DownloadRequest dr =
236                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
237 
238         // Add the first DownloadRequest to the queue
239         boolean result = dq.addRequest(dr);
240         assertTrue(result);
241         assertEquals(1, dq.getSize());
242         assertFalse(dq.isEmpty());
243 
244         // Add the same one again, the size should be the same.
245         result = dq.addRequest(dr);
246         assertTrue(result);
247         assertEquals(1, dq.getSize());
248         assertFalse(dq.isEmpty());
249 
250         final AttachmentService.DownloadRequest dr2 =
251                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 2);
252 
253         // Add another DownloadRequest
254         result = dq.addRequest(dr2);
255         assertTrue(result);
256         assertEquals(2, dq.getSize());
257         assertFalse(dq.isEmpty());
258 
259         final AttachmentService.DownloadRequest dr3 =
260                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 3);
261 
262         result = dq.addRequest(dr3);
263         assertTrue(result);
264         assertEquals(3, dq.getSize());
265         assertFalse(dq.isEmpty());
266 
267         // Remove a request and check new size.
268         AttachmentService.DownloadRequest returnRequest = dq.getNextRequest();
269         assertNotNull(returnRequest);
270         assertEquals(2, dq.getSize());
271         assertFalse(dq.isEmpty());
272 
273         final AttachmentService.DownloadRequest dr4 =
274                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 4);
275 
276         // Adding the last DownloadRequest
277         result = dq.addRequest(dr4);
278         assertTrue(result);
279         assertEquals(3, dq.getSize());
280         assertFalse(dq.isEmpty());
281 
282         // Start removing all the final requests and check sizes.
283         returnRequest = dq.getNextRequest();
284         assertNotNull(returnRequest);
285         assertEquals(2, dq.getSize());
286         assertFalse(dq.isEmpty());
287 
288         returnRequest = dq.getNextRequest();
289         assertNotNull(returnRequest);
290         assertEquals(1, dq.getSize());
291         assertFalse(dq.isEmpty());
292 
293         returnRequest = dq.getNextRequest();
294         assertNotNull(returnRequest);
295         assertEquals(0, dq.getSize());
296         assertTrue(dq.isEmpty());
297     }
298 
299     /**
300      * Insert DownloadRequest obje cts in a random priority sequence and make sure that
301      * The highest priority items come out of the queue first.
302      */
testDownloadQueueTestPriority()303     public void testDownloadQueueTestPriority() {
304         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
305 
306         // Start adding some download request objects, note that the empty queue case has been
307         // tested in above.
308         final AttachmentService.DownloadRequest dr =
309                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
310         boolean result = dq.addRequest(dr);
311         assertTrue(result);
312 
313         final AttachmentService.DownloadRequest dr2 =
314                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_BACKGROUND, 2);
315         result = dq.addRequest(dr2);
316         assertTrue(result);
317 
318         final AttachmentService.DownloadRequest dr3 =
319                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_SEND_MAIL, 3);
320         result = dq.addRequest(dr3);
321         assertTrue(result);
322 
323         final AttachmentService.DownloadRequest dr4 =
324                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_SEND_MAIL, 4);
325         result = dq.addRequest(dr4);
326         assertTrue(result);
327 
328         final AttachmentService.DownloadRequest dr5 =
329                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 5);
330         result = dq.addRequest(dr5);
331         assertTrue(result);
332 
333         final AttachmentService.DownloadRequest dr6 =
334                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_BACKGROUND, 6);
335         result = dq.addRequest(dr6);
336         assertTrue(result);
337 
338         // Set the priority to the highest possible value and everything show be
339         // in descending order.
340         int lastPriority = AttachmentService.PRIORITY_HIGHEST;
341         for (int i = 0; i < dq.getSize(); i++){
342             final AttachmentService.DownloadRequest returnRequest = dq.getNextRequest();
343             assertNotNull(returnRequest);
344             final int requestPriority = returnRequest.mPriority;
345             // The values should be going up or staying the same...indicating a lower priority
346             assertTrue(requestPriority >= lastPriority);
347             lastPriority = requestPriority;
348         }
349     }
350 
351     /**
352      * Insert DownloadRequest objects in a random time based sequence and make sure that
353      * The oldest requests come out of the queue first.
354      */
testDownloadQueueTestDate()355     public void testDownloadQueueTestDate() {
356         final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
357 
358         // Start adding some unique attachments but with the same priority
359         final AttachmentService.DownloadRequest dr =
360                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
361         boolean result = dq.addRequest(dr);
362         assertTrue(result);
363 
364         final AttachmentService.DownloadRequest dr2 =
365                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 2);
366         result = dq.addRequest(dr2);
367         assertTrue(result);
368 
369         final AttachmentService.DownloadRequest dr3 =
370                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 3);
371         result = dq.addRequest(dr3);
372         assertTrue(result);
373 
374         final AttachmentService.DownloadRequest dr4 =
375                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 4);
376         result = dq.addRequest(dr4);
377         assertTrue(result);
378 
379         final AttachmentService.DownloadRequest dr5 =
380                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 5);
381         result = dq.addRequest(dr5);
382         assertTrue(result);
383 
384         final AttachmentService.DownloadRequest dr6 =
385                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 6);
386         result = dq.addRequest(dr6);
387         assertTrue(result);
388 
389         // The output should return requests in increasing time.
390         long lastTime = 0;
391         for (int i = 0; i < dq.getSize(); i++){
392             final AttachmentService.DownloadRequest returnRequest = dq.getNextRequest();
393             assertNotNull(returnRequest);
394             final long requestTime = returnRequest.mCreatedTime;
395             // The time should be going up.
396             assertTrue(requestTime >= lastTime);
397             lastTime = requestTime;
398         }
399     }
400 
401     /**
402      * This function will test the function AttachmentWatchdog.watchdogAlarm() that is executed
403      * whenever the onReceive() call is made by the AlarmManager
404      */
testAttachmentWatchdogAlarm()405     public void testAttachmentWatchdogAlarm() {
406         final AttachmentService attachmentService = new AttachmentService();
407         final AttachmentService.AttachmentWatchdog watchdog = attachmentService.mWatchdog;
408 
409         final long now = System.currentTimeMillis();
410 
411         // Add one download request object to the in process map that should
412         // should not need to be cancelled.
413         final AttachmentService.DownloadRequest dr =
414                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
415         dr.mLastCallbackTime = now;
416         attachmentService.mDownloadsInProgress.put(dr.mAttachmentId, dr);
417 
418         // Only request the DownloadRequest to cancelled if it is older than 60 seconds,
419         // which is not true in this case.
420         final boolean shouldCancel = watchdog.validateDownloadRequest(dr, 60000, now);
421 
422         // Now check the results. We should not be asked to cancel this DownloadRequest
423         assertFalse(shouldCancel);
424     }
425 
426     /**
427      * This function will test the function AttachmentWatchdog.watchdogAlarm() that is executed
428      * whenever the onReceive() call is made by the AlarmManager
429      */
testAttachmentWatchdogAlarmNeedsCancel()430     public void testAttachmentWatchdogAlarmNeedsCancel() {
431         final AttachmentService attachmentService = new AttachmentService();
432         final AttachmentService.AttachmentWatchdog watchdog = attachmentService.mWatchdog;
433 
434         final long now = System.currentTimeMillis();
435 
436         // Add one download request object to the in process map that should
437         // should not need to be cancelled.
438         final AttachmentService.DownloadRequest dr =
439                 new AttachmentService.DownloadRequest(AttachmentService.PRIORITY_FOREGROUND, 1);
440         dr.mLastCallbackTime = now - 60000; // Set this request to be 60 seconds old.
441         attachmentService.mDownloadsInProgress.put(dr.mAttachmentId, dr);
442 
443         // Request cancellation for DownloadRequests that are older than a second.
444         // For this test, this is true.
445         final boolean shouldCancel = watchdog.validateDownloadRequest(dr, 1000, now);
446 
447         // Now check the results. We should not be asked to cancel this DownloadRequest
448         assertTrue(shouldCancel);
449     }
450 
testServiceCallbackAttachmentCompleteUpdate()451     public void testServiceCallbackAttachmentCompleteUpdate() {
452         final AttachmentService attachmentService = new AttachmentService();
453         final EmailContent.Attachment attachment = new EmailContent.Attachment();
454         attachment.mSize = 1000;
455 
456         // Only in progress status receives any updates so the function should not return any
457         // values.
458         final ContentValues values =
459                 attachmentService.mServiceCallback.getAttachmentUpdateValues(attachment,
460                         EmailServiceStatus.SUCCESS, 75);
461         assertTrue(values.size() == 0);
462     }
463 
testServiceCallbackAttachmentErrorUpdate()464     public void testServiceCallbackAttachmentErrorUpdate() {
465         final AttachmentService attachmentService = new AttachmentService();
466         final EmailContent.Attachment attachment = new EmailContent.Attachment();
467         attachment.mSize = 1000;
468 
469         // Only in progress status receives any updates so the function should not return any
470         // values.
471         final ContentValues values =
472                 attachmentService.mServiceCallback.getAttachmentUpdateValues(attachment,
473                         EmailServiceStatus.CONNECTION_ERROR, 75);
474         assertTrue(values.size() == 0);
475     }
476 
testServiceCallbackAttachmentInProgressUpdate()477     public void testServiceCallbackAttachmentInProgressUpdate() {
478         final AttachmentService attachmentService = new AttachmentService();
479         final EmailContent.Attachment attachment = new EmailContent.Attachment();
480         attachment.mSize = 1000;
481 
482         // Only in progress status receives any updates so this should send us some valid
483         // values in return.
484         final ContentValues values =
485                 attachmentService.mServiceCallback.getAttachmentUpdateValues(attachment,
486                         EmailServiceStatus.IN_PROGRESS, 75);
487 
488         assertTrue(values.size() == 2);
489         assertTrue(values.containsKey(EmailContent.AttachmentColumns.UI_STATE));
490         assertTrue(values.containsKey(EmailContent.AttachmentColumns.UI_DOWNLOADED_SIZE));
491 
492         assertTrue(values.getAsInteger(EmailContent.AttachmentColumns.UI_STATE) ==
493                 UIProvider.AttachmentState.DOWNLOADING);
494         assertTrue(values.getAsInteger(
495                 EmailContent.AttachmentColumns.UI_DOWNLOADED_SIZE).intValue() == 750);
496     }
497 }
498