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
17package com.android.email.service;
18
19import android.content.ContentValues;
20import android.content.Context;
21import android.content.Intent;
22import android.test.suitebuilder.annotation.SmallTest;
23
24import com.android.emailcommon.provider.EmailContent;
25import com.android.emailcommon.service.EmailServiceStatus;
26import com.android.mail.providers.UIProvider;
27
28import 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
37public class AttachmentServiceTests extends TestCase {
38
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
48    public void testDownloadQueueEmptyQueue() {
49        final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
50        assertEquals(0, dq.getSize());
51        assertTrue(dq.isEmpty());
52    }
53
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
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
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
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
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
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
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
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
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     */
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
224    public void testDownloadQueueGetNextRequestEmptyQueue() {
225        final AttachmentService.DownloadQueue dq = new AttachmentService.DownloadQueue();
226        AttachmentService.DownloadRequest drResult = dq.getNextRequest();
227        assertNull(drResult);
228    }
229
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     */
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     */
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     */
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     */
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
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
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
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