e59aff085cb42304e03e845a4783340adab7a2e1
[android/platform/packages/providers/DownloadProvider.git] / tests / src / com / android / providers / downloads / AbstractDownloadProviderFunctionalTest.java
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.providers.downloads;
18
19 import static org.mockito.Mockito.mock;
20
21 import android.app.NotificationManager;
22 import android.content.ComponentName;
23 import android.content.ContentResolver;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.database.ContentObserver;
27 import android.database.Cursor;
28 import android.net.Uri;
29 import android.provider.Downloads;
30 import android.test.MoreAsserts;
31 import android.test.RenamingDelegatingContext;
32 import android.test.ServiceTestCase;
33 import android.test.mock.MockContentResolver;
34 import android.util.Log;
35
36 import com.google.mockwebserver.MockResponse;
37 import com.google.mockwebserver.MockStreamResponse;
38 import com.google.mockwebserver.MockWebServer;
39 import com.google.mockwebserver.RecordedRequest;
40 import com.google.mockwebserver.SocketPolicy;
41
42 import java.io.BufferedReader;
43 import java.io.File;
44 import java.io.IOException;
45 import java.io.InputStream;
46 import java.io.InputStreamReader;
47 import java.net.MalformedURLException;
48 import java.net.UnknownHostException;
49
50 public abstract class AbstractDownloadProviderFunctionalTest extends
51         ServiceTestCase<DownloadService> {
52
53     protected static final String LOG_TAG = "DownloadProviderFunctionalTest";
54     private static final String PROVIDER_AUTHORITY = "downloads";
55     protected static final long RETRY_DELAY_MILLIS = 61 * 1000;
56
57     protected static final String
58             FILE_CONTENT = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
59
60     private final MockitoHelper mMockitoHelper = new MockitoHelper();
61
62     protected MockWebServer mServer;
63     protected MockContentResolverWithNotify mResolver;
64     protected TestContext mTestContext;
65     protected FakeSystemFacade mSystemFacade;
66     protected static String STRING_1K;
67     static {
68         StringBuilder buff = new StringBuilder();
69         for (int i = 0; i < 1024; i++) {
70             buff.append("a" + i % 26);
71         }
72         STRING_1K = buff.toString();
73     }
74
75     static class MockContentResolverWithNotify extends MockContentResolver {
76         public boolean mNotifyWasCalled = false;
77
78         public synchronized void resetNotified() {
79             mNotifyWasCalled = false;
80         }
81
82         @Override
83         public synchronized void notifyChange(Uri uri, ContentObserver observer,
84                 boolean syncToNetwork) {
85             mNotifyWasCalled = true;
86             notifyAll();
87         }
88     }
89
90     /**
91      * Context passed to the provider and the service.  Allows most methods to pass through to the
92      * real Context (this is a LargeTest), with a few exceptions, including renaming file operations
93      * to avoid file and DB conflicts (via RenamingDelegatingContext).
94      */
95     static class TestContext extends RenamingDelegatingContext {
96         private static final String FILENAME_PREFIX = "test.";
97
98         private ContentResolver mResolver;
99         private final NotificationManager mNotifManager;
100
101         boolean mHasServiceBeenStarted = false;
102
103         public TestContext(Context realContext) {
104             super(realContext, FILENAME_PREFIX);
105             mNotifManager = mock(NotificationManager.class);
106         }
107
108         public void setResolver(ContentResolver resolver) {
109             mResolver = resolver;
110         }
111
112         /**
113          * Direct DownloadService to our test instance of DownloadProvider.
114          */
115         @Override
116         public ContentResolver getContentResolver() {
117             return mResolver;
118         }
119
120         /**
121          * Stub some system services, allow access to others, and block the rest.
122          */
123         @Override
124         public Object getSystemService(String name) {
125             if (Context.NOTIFICATION_SERVICE.equals(name)) {
126                 return mNotifManager;
127             }
128
129             return super.getSystemService(name);
130         }
131
132         /**
133          * Record when DownloadProvider starts DownloadService.
134          */
135         @Override
136         public ComponentName startService(Intent service) {
137             if (service.getComponent().getClassName().equals(DownloadService.class.getName())) {
138                 mHasServiceBeenStarted = true;
139                 return service.getComponent();
140             }
141             throw new UnsupportedOperationException("Unexpected service: " + service);
142         }
143     }
144
145     public AbstractDownloadProviderFunctionalTest(FakeSystemFacade systemFacade) {
146         super(DownloadService.class);
147         mSystemFacade = systemFacade;
148     }
149
150     @Override
151     protected void setUp() throws Exception {
152         super.setUp();
153         mMockitoHelper.setUp(getClass());
154
155         // Since we're testing a system app, AppDataDirGuesser doesn't find our
156         // cache dir, so set it explicitly.
157         System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
158
159         final Context realContext = getContext();
160         mTestContext = new TestContext(realContext);
161         setupProviderAndResolver();
162         mTestContext.setResolver(mResolver);
163         setContext(mTestContext);
164         setupService();
165         getService().mSystemFacade = mSystemFacade;
166         mSystemFacade.setUp();
167         assertTrue(isDatabaseEmpty()); // ensure we're not messing with real data
168         mServer = new MockWebServer();
169         mServer.play();
170     }
171
172     @Override
173     protected void tearDown() throws Exception {
174         cleanUpDownloads();
175         mServer.shutdown();
176         mMockitoHelper.tearDown();
177         super.tearDown();
178     }
179
180     private boolean isDatabaseEmpty() {
181         Cursor cursor = mResolver.query(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI,
182                 null, null, null, null);
183         try {
184             return cursor.getCount() == 0;
185         } finally {
186             cursor.close();
187         }
188     }
189
190     void setupProviderAndResolver() {
191         DownloadProvider provider = new DownloadProvider();
192         provider.mSystemFacade = mSystemFacade;
193         provider.attachInfo(mTestContext, null);
194         mResolver = new MockContentResolverWithNotify();
195         mResolver.addProvider(PROVIDER_AUTHORITY, provider);
196     }
197
198     /**
199      * Remove any downloaded files and delete any lingering downloads.
200      */
201     void cleanUpDownloads() {
202         if (mResolver == null) {
203             return;
204         }
205         String[] columns = new String[] {Downloads.Impl._DATA};
206         Cursor cursor = mResolver.query(Downloads.Impl.CONTENT_URI, columns, null, null, null);
207         try {
208             for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
209                 String filePath = cursor.getString(0);
210                 if (filePath == null) continue;
211                 Log.d(LOG_TAG, "Deleting " + filePath);
212                 new File(filePath).delete();
213             }
214         } finally {
215             cursor.close();
216         }
217         mResolver.delete(Downloads.Impl.CONTENT_URI, null, null);
218     }
219
220     void enqueueResponse(MockResponse resp) {
221         mServer.enqueue(resp);
222     }
223
224     void enqueueResponse(MockStreamResponse resp) {
225         mServer.enqueue(resp);
226     }
227
228     MockResponse buildResponse(int status, String body) {
229         return new MockResponse().setResponseCode(status).setBody(body)
230                 .setHeader("Content-type", "text/plain")
231                 .setSocketPolicy(SocketPolicy.DISCONNECT_AT_END);
232     }
233
234     MockResponse buildResponse(int status, byte[] body) {
235         return new MockResponse().setResponseCode(status).setBody(body)
236                 .setHeader("Content-type", "text/plain")
237                 .setSocketPolicy(SocketPolicy.DISCONNECT_AT_END);
238     }
239
240     MockResponse buildEmptyResponse(int status) {
241         return buildResponse(status, "");
242     }
243
244     /**
245      * Fetch the last request received by the MockWebServer.
246      */
247     protected RecordedRequest takeRequest() throws InterruptedException {
248         RecordedRequest request = mServer.takeRequest();
249         assertNotNull("Expected request was not made", request);
250         return request;
251     }
252
253     String getServerUri(String path) throws MalformedURLException, UnknownHostException {
254         return mServer.getUrl(path).toString();
255     }
256
257     protected String readStream(InputStream inputStream) throws IOException {
258         BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
259         try {
260             char[] buffer = new char[1024];
261             int length = reader.read(buffer);
262             assertTrue("Failed to read anything from input stream", length > -1);
263             return String.valueOf(buffer, 0, length);
264         } finally {
265             reader.close();
266         }
267     }
268
269     protected void assertStartsWith(String expectedPrefix, String actual) {
270         String regex = "^" + expectedPrefix + ".*";
271         MoreAsserts.assertMatchesRegex(regex, actual);
272     }
273 }