• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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.Context;
20 import android.test.suitebuilder.annotation.Suppress;
21 
22 import com.android.email.AccountTestCase;
23 import com.android.email.EmailConnectivityManager;
24 import com.android.email.provider.ProviderTestUtils;
25 import com.android.email.service.AttachmentDownloadService.DownloadRequest;
26 import com.android.email.service.AttachmentDownloadService.DownloadSet;
27 import com.android.emailcommon.provider.Account;
28 import com.android.emailcommon.provider.EmailContent.Attachment;
29 import com.android.emailcommon.provider.EmailContent.Message;
30 import com.android.emailcommon.provider.Mailbox;
31 import com.android.emailcommon.service.EmailServiceStatus;
32 
33 import java.io.File;
34 import java.util.Iterator;
35 
36 /**
37  * Tests of the AttachmentDownloadService
38  *
39  * You can run this entire test case with:
40  *   runtest -c com.android.email.service.AttachmentDownloadServiceTests email
41  */
42 @Suppress
43 public class AttachmentDownloadServiceTests extends AccountTestCase {
44     private AttachmentDownloadService mService;
45     private Context mMockContext;
46     private Account mAccount;
47     private Mailbox mMailbox;
48     private long mAccountId;
49     private long mMailboxId;
50     private AttachmentDownloadService.AccountManagerStub mAccountManagerStub;
51     private MockDirectory mMockDirectory;
52 
53     private DownloadSet mDownloadSet;
54 
55     @Override
setUp()56     public void setUp() throws Exception {
57         super.setUp();
58         mMockContext = getMockContext();
59 
60         // Set up an account and mailbox
61         mAccount = ProviderTestUtils.setupAccount("account", false, mMockContext);
62         mAccount.mFlags |= Account.FLAGS_BACKGROUND_ATTACHMENTS;
63         mAccount.save(mMockContext);
64         mAccountId = mAccount.mId;
65 
66         mMailbox = ProviderTestUtils.setupMailbox("mailbox", mAccountId, true, mMockContext);
67         mMailboxId = mMailbox.mId;
68 
69         // Set up our download service to simulate a running environment
70         // Use the NullEmailService so that the loadAttachment calls become no-ops
71         mService = new AttachmentDownloadService();
72         mService.mContext = mMockContext;
73         // there's no NullEmailService class
74         /*mService.addServiceIntentForTest(mAccountId, new Intent(mContext,
75                 NullEmailService.class));*/
76         mAccountManagerStub = new AttachmentDownloadService.AccountManagerStub(null);
77         mService.mAccountManagerStub = mAccountManagerStub;
78         mService.mConnectivityManager = new MockConnectivityManager(mContext, "mock");
79         mDownloadSet = mService.mDownloadSet;
80         mMockDirectory =
81             new MockDirectory(mService.mContext.getCacheDir().getAbsolutePath());
82     }
83 
84     @Override
tearDown()85     public void tearDown() throws Exception {
86         super.tearDown();
87     }
88 
89     /**
90      * This test creates attachments and places them in the DownloadSet; we then do various checks
91      * that exercise its functionality.
92      */
testDownloadSet()93     public void testDownloadSet() {
94         // TODO: Make sure that this doesn't interfere with the "real" ADS that might be running
95         // on device
96         Message message = ProviderTestUtils.setupMessage("message", mAccountId, mMailboxId, false,
97                 true, mMockContext);
98         Attachment att1 = ProviderTestUtils.setupAttachment(message.mId, "filename1", 1000,
99                 Attachment.FLAG_DOWNLOAD_USER_REQUEST, true, mMockContext);
100         Attachment att2 = ProviderTestUtils.setupAttachment(message.mId, "filename2", 1000,
101                 Attachment.FLAG_DOWNLOAD_FORWARD, true, mMockContext);
102         Attachment att3 = ProviderTestUtils.setupAttachment(message.mId, "filename3", 1000,
103                 Attachment.FLAG_DOWNLOAD_FORWARD, true, mMockContext);
104         Attachment att4 = ProviderTestUtils.setupAttachment(message.mId, "filename4", 1000,
105                 Attachment.FLAG_DOWNLOAD_USER_REQUEST, true, mMockContext);
106         // Indicate that these attachments have changed; they will be added to the queue
107         mDownloadSet.onChange(mMockContext, att1);
108         mDownloadSet.onChange(mMockContext, att2);
109         mDownloadSet.onChange(mMockContext, att3);
110         mDownloadSet.onChange(mMockContext, att4);
111         Iterator<DownloadRequest> iterator = mDownloadSet.descendingIterator();
112         // Check the expected ordering; 1 & 4 are higher priority than 2 & 3
113         // 1 and 3 were created earlier than their priority equals
114         long[] expectedAttachmentIds = new long[] {att1.mId, att4.mId, att2.mId, att3.mId};
115         for (int i = 0; i < expectedAttachmentIds.length; i++) {
116             assertTrue(iterator.hasNext());
117             DownloadRequest req = iterator.next();
118             assertEquals(expectedAttachmentIds[i], req.attachmentId);
119         }
120 
121         // Process the queue; attachment 1 should be marked "in progress", and should be in
122         // the in-progress map
123         mDownloadSet.processQueue();
124         DownloadRequest req = mDownloadSet.findDownloadRequest(att1.mId);
125         assertNotNull(req);
126         assertTrue(req.inProgress);
127         assertTrue(mDownloadSet.mDownloadsInProgress.containsKey(att1.mId));
128         // There should also be only one download in progress (testing the per-account limitation)
129         assertEquals(1, mDownloadSet.mDownloadsInProgress.size());
130         // End the "download" with a connection error; we should still have this in the queue,
131         // but it should no longer be in-progress
132         mDownloadSet.endDownload(att1.mId, EmailServiceStatus.CONNECTION_ERROR);
133         assertFalse(req.inProgress);
134         assertEquals(0, mDownloadSet.mDownloadsInProgress.size());
135 
136         mDownloadSet.processQueue();
137         // Things should be as they were earlier; att1 should be an in-progress download
138         req = mDownloadSet.findDownloadRequest(att1.mId);
139         assertNotNull(req);
140         assertTrue(req.inProgress);
141         assertTrue(mDownloadSet.mDownloadsInProgress.containsKey(att1.mId));
142         // Successfully download the attachment; there should be no downloads in progress, and
143         // att1 should no longer be in the queue
144         mDownloadSet.endDownload(att1.mId, EmailServiceStatus.SUCCESS);
145         assertEquals(0, mDownloadSet.mDownloadsInProgress.size());
146         assertNull(mDownloadSet.findDownloadRequest(att1.mId));
147 
148         // Test dequeue and isQueued
149         assertEquals(3, mDownloadSet.size());
150         mService.dequeue(att2.mId);
151         assertEquals(2, mDownloadSet.size());
152         assertTrue(mService.isQueued(att4.mId));
153         assertTrue(mService.isQueued(att3.mId));
154 
155         mDownloadSet.processQueue();
156         // att4 should be the download in progress
157         req = mDownloadSet.findDownloadRequest(att4.mId);
158         assertNotNull(req);
159         assertTrue(req.inProgress);
160         assertTrue(mDownloadSet.mDownloadsInProgress.containsKey(att4.mId));
161     }
162 
163     /**
164      * A mock file directory containing a single (Mock)File.  The total space, usable space, and
165      * length of the single file can be set
166      */
167     private static class MockDirectory extends File {
168         private static final long serialVersionUID = 1L;
169         private long mTotalSpace;
170         private long mUsableSpace;
171         private MockFile[] mFiles;
172         private final MockFile mMockFile = new MockFile();
173 
174 
MockDirectory(String path)175         public MockDirectory(String path) {
176             super(path);
177             mFiles = new MockFile[1];
178             mFiles[0] = mMockFile;
179         }
180 
setTotalAndUsableSpace(long total, long usable)181         private void setTotalAndUsableSpace(long total, long usable) {
182             mTotalSpace = total;
183             mUsableSpace = usable;
184         }
185 
186         @Override
getTotalSpace()187         public long getTotalSpace() {
188             return mTotalSpace;
189         }
190 
191         @Override
getUsableSpace()192         public long getUsableSpace() {
193             return mUsableSpace;
194         }
195 
setFileLength(long length)196         public void setFileLength(long length) {
197             mMockFile.mLength = length;
198         }
199 
200         @Override
listFiles()201         public File[] listFiles() {
202             return mFiles;
203         }
204     }
205 
206     /**
207      * A mock file that reports back a pre-set length
208      */
209     private static class MockFile extends File {
210         private static final long serialVersionUID = 1L;
211         private long mLength = 0;
212 
MockFile()213         public MockFile() {
214             super("_mock");
215         }
216 
217         @Override
length()218         public long length() {
219             return mLength;
220         }
221     }
222 
223     private static class MockConnectivityManager extends EmailConnectivityManager {
MockConnectivityManager(Context context, String name)224         public MockConnectivityManager(Context context, String name) {
225             super(context, name);
226         }
227 
228         @Override
waitForConnectivity()229         public void waitForConnectivity() {
230         }
231 
232         @Override
isAutoSyncAllowed()233         public boolean isAutoSyncAllowed() {
234             return true;
235         }
236     }
237 
testCanPrefetchForAccount()238     public void testCanPrefetchForAccount() {
239         // First, test our "global" limits (based on free storage)
240         // Mock storage @ 100 total and 26 available
241         // Note that all file lengths in this test are in arbitrary units
242         mMockDirectory.setTotalAndUsableSpace(100L, 26L);
243         // Mock 2 accounts in total
244         mAccountManagerStub.setNumberOfAccounts(2);
245         // With 26% available, we should be ok to prefetch
246         assertTrue(mService.canPrefetchForAccount(mAccount, mMockDirectory));
247         // Now change to 24 available
248         mMockDirectory.setTotalAndUsableSpace(100L, 24L);
249         // With 24% available, we should NOT be ok to prefetch
250         assertFalse(mService.canPrefetchForAccount(mAccount, mMockDirectory));
251 
252         // Now, test per-account storage
253         // Mock storage @ 100 total and 50 available
254         mMockDirectory.setTotalAndUsableSpace(100L, 50L);
255         // Mock a file of length 12, but need to uncache previous amount first
256         mService.mAttachmentStorageMap.remove(mAccountId);
257         mMockDirectory.setFileLength(11);
258         // We can prefetch since 11 < 50/4
259         assertTrue(mService.canPrefetchForAccount(mAccount, mMockDirectory));
260         // Mock a file of length 13, but need to uncache previous amount first
261         mService.mAttachmentStorageMap.remove(mAccountId);
262         mMockDirectory.setFileLength(13);
263         // We can't prefetch since 13 > 50/4
264         assertFalse(mService.canPrefetchForAccount(mAccount, mMockDirectory));
265     }
266 
testCanPrefetchForAccountNoBackgroundDownload()267     public void testCanPrefetchForAccountNoBackgroundDownload() {
268         Account account = ProviderTestUtils.setupAccount("account2", false, mMockContext);
269         account.mFlags &= ~Account.FLAGS_BACKGROUND_ATTACHMENTS;
270         account.save(mMockContext);
271 
272         // First, test our "global" limits (based on free storage)
273         // Mock storage @ 100 total and 26 available
274         // Note that all file lengths in this test are in arbitrary units
275         mMockDirectory.setTotalAndUsableSpace(100L, 26L);
276         // Mock 2 accounts in total
277         mAccountManagerStub.setNumberOfAccounts(2);
278 
279         // With 26% available, we should be ok to prefetch,
280         // *but* bg download is disabled on the account.
281         assertFalse(mService.canPrefetchForAccount(account, mMockDirectory));
282     }
283 }
284