PerformInitializeTaskTest.java revision 516ac95746bd1091732e4bc407e2941debdc38d9
1/*
2 * Copyright (C) 2017 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.server.backup.internal;
18
19import static android.app.backup.BackupTransport.TRANSPORT_ERROR;
20import static android.app.backup.BackupTransport.TRANSPORT_OK;
21
22import static com.android.server.backup.testing.TransportTestUtils.TRANSPORT_NAME;
23import static com.android.server.backup.testing.TransportTestUtils.TRANSPORT_NAMES;
24
25import static com.google.common.truth.Truth.assertThat;
26
27import static org.mockito.ArgumentMatchers.any;
28import static org.mockito.ArgumentMatchers.anyInt;
29import static org.mockito.ArgumentMatchers.anyLong;
30import static org.mockito.ArgumentMatchers.eq;
31import static org.mockito.Mockito.mock;
32import static org.mockito.Mockito.never;
33import static org.mockito.Mockito.verify;
34import static org.mockito.Mockito.when;
35
36import android.app.AlarmManager;
37import android.app.Application;
38import android.app.PendingIntent;
39import android.app.backup.IBackupObserver;
40import android.os.DeadObjectException;
41import android.platform.test.annotations.Presubmit;
42
43import com.android.internal.backup.IBackupTransport;
44import com.android.server.backup.RefactoredBackupManagerService;
45import com.android.server.backup.TransportManager;
46import com.android.server.backup.testing.TransportTestUtils;
47import com.android.server.backup.testing.TransportTestUtils.TransportData;
48import com.android.server.backup.transport.TransportClient;
49import com.android.server.testing.FrameworkRobolectricTestRunner;
50import com.android.server.testing.SystemLoaderClasses;
51
52import org.junit.Before;
53import org.junit.Test;
54import org.junit.runner.RunWith;
55import org.mockito.Mock;
56import org.mockito.MockitoAnnotations;
57import org.robolectric.RuntimeEnvironment;
58import org.robolectric.annotation.Config;
59
60import java.io.File;
61import java.util.List;
62
63@RunWith(FrameworkRobolectricTestRunner.class)
64@Config(manifest = Config.NONE, sdk = 26)
65@SystemLoaderClasses({PerformInitializeTaskTest.class, TransportManager.class})
66@Presubmit
67public class PerformInitializeTaskTest {
68    @Mock private RefactoredBackupManagerService mBackupManagerService;
69    @Mock private TransportManager mTransportManager;
70    @Mock private OnTaskFinishedListener mListener;
71    @Mock private IBackupTransport mTransport;
72    @Mock private IBackupObserver mObserver;
73    @Mock private AlarmManager mAlarmManager;
74    @Mock private PendingIntent mRunInitIntent;
75    private File mBaseStateDir;
76
77    @Before
78    public void setUp() throws Exception {
79        MockitoAnnotations.initMocks(this);
80
81        Application context = RuntimeEnvironment.application;
82        mBaseStateDir = new File(context.getCacheDir(), "base_state_dir");
83        assertThat(mBaseStateDir.mkdir()).isTrue();
84
85        when(mBackupManagerService.getAlarmManager()).thenReturn(mAlarmManager);
86        when(mBackupManagerService.getRunInitIntent()).thenReturn(mRunInitIntent);
87    }
88
89    @Test
90    public void testRun_callsTransportCorrectly() throws Exception {
91        setUpTransport(TRANSPORT_NAME);
92        configureTransport(mTransport, TRANSPORT_OK, TRANSPORT_OK);
93        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
94
95        performInitializeTask.run();
96
97        verify(mTransport).initializeDevice();
98        verify(mTransport).finishBackup();
99    }
100
101    @Test
102    public void testRun_callsBackupManagerCorrectly() throws Exception {
103        setUpTransport(TRANSPORT_NAME);
104        configureTransport(mTransport, TRANSPORT_OK, TRANSPORT_OK);
105        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
106
107        performInitializeTask.run();
108
109        verify(mBackupManagerService)
110                .recordInitPending(
111                        false, TRANSPORT_NAME, TransportTestUtils.transportDirName(TRANSPORT_NAME));
112        verify(mBackupManagerService)
113                .resetBackupState(
114                        eq(
115                                new File(
116                                        mBaseStateDir,
117                                        TransportTestUtils.transportDirName(TRANSPORT_NAME))));
118    }
119
120    @Test
121    public void testRun_callsObserverAndListenerCorrectly() throws Exception {
122        setUpTransport(TRANSPORT_NAME);
123        configureTransport(mTransport, TRANSPORT_OK, TRANSPORT_OK);
124        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
125
126        performInitializeTask.run();
127
128        verify(mObserver).onResult(eq(TRANSPORT_NAME), eq(TRANSPORT_OK));
129        verify(mObserver).backupFinished(eq(TRANSPORT_OK));
130        verify(mListener).onFinished(any());
131    }
132
133    @Test
134    public void testRun_whenInitializeDeviceFails() throws Exception {
135        setUpTransport(TRANSPORT_NAME);
136        configureTransport(mTransport, TRANSPORT_ERROR, 0);
137        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
138
139        performInitializeTask.run();
140
141        verify(mTransport).initializeDevice();
142        verify(mTransport, never()).finishBackup();
143        verify(mBackupManagerService)
144                .recordInitPending(
145                        true, TRANSPORT_NAME, TransportTestUtils.transportDirName(TRANSPORT_NAME));
146    }
147
148    @Test
149    public void testRun_whenInitializeDeviceFails_callsObserverAndListenerCorrectly()
150            throws Exception {
151        setUpTransport(TRANSPORT_NAME);
152        configureTransport(mTransport, TRANSPORT_ERROR, 0);
153        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
154
155        performInitializeTask.run();
156
157        verify(mObserver).onResult(eq(TRANSPORT_NAME), eq(TRANSPORT_ERROR));
158        verify(mObserver).backupFinished(eq(TRANSPORT_ERROR));
159        verify(mListener).onFinished(any());
160    }
161
162    @Test
163    public void testRun_whenInitializeDeviceFails_schedulesAlarm() throws Exception {
164        setUpTransport(TRANSPORT_NAME);
165        configureTransport(mTransport, TRANSPORT_ERROR, 0);
166        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
167
168        performInitializeTask.run();
169
170        verify(mAlarmManager).set(anyInt(), anyLong(), eq(mRunInitIntent));
171    }
172
173    @Test
174    public void testRun_whenFinishBackupFails() throws Exception {
175        setUpTransport(TRANSPORT_NAME);
176        configureTransport(mTransport, TRANSPORT_OK, TRANSPORT_ERROR);
177        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
178
179        performInitializeTask.run();
180
181        verify(mTransport).initializeDevice();
182        verify(mTransport).finishBackup();
183        verify(mBackupManagerService)
184                .recordInitPending(
185                        true, TRANSPORT_NAME, TransportTestUtils.transportDirName(TRANSPORT_NAME));
186    }
187
188    @Test
189    public void testRun_whenFinishBackupFails_callsObserverAndListenerCorrectly() throws Exception {
190        setUpTransport(TRANSPORT_NAME);
191        configureTransport(mTransport, TRANSPORT_OK, TRANSPORT_ERROR);
192        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
193
194        performInitializeTask.run();
195
196        verify(mObserver).onResult(eq(TRANSPORT_NAME), eq(TRANSPORT_ERROR));
197        verify(mObserver).backupFinished(eq(TRANSPORT_ERROR));
198        verify(mListener).onFinished(any());
199    }
200
201    @Test
202    public void testRun_whenFinishBackupFails_schedulesAlarm() throws Exception {
203        setUpTransport(TRANSPORT_NAME);
204        configureTransport(mTransport, TRANSPORT_OK, TRANSPORT_ERROR);
205        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
206
207        performInitializeTask.run();
208
209        verify(mAlarmManager).set(anyInt(), anyLong(), eq(mRunInitIntent));
210    }
211
212    @Test
213    public void testRun_whenOnlyOneTransportFails() throws Exception {
214        List<TransportData> transports =
215                TransportTestUtils.setUpTransports(
216                        mTransportManager, TRANSPORT_NAMES[0], TRANSPORT_NAMES[1]);
217        configureTransport(transports.get(0).transportMock, TRANSPORT_ERROR, 0);
218        configureTransport(transports.get(1).transportMock, TRANSPORT_OK, TRANSPORT_OK);
219        PerformInitializeTask performInitializeTask =
220                createPerformInitializeTask(TRANSPORT_NAMES[0], TRANSPORT_NAMES[1]);
221
222        performInitializeTask.run();
223
224        verify(transports.get(1).transportMock).initializeDevice();
225        verify(mObserver).onResult(eq(TRANSPORT_NAMES[0]), eq(TRANSPORT_ERROR));
226        verify(mObserver).onResult(eq(TRANSPORT_NAMES[1]), eq(TRANSPORT_OK));
227        verify(mObserver).backupFinished(eq(TRANSPORT_ERROR));
228    }
229
230    @Test
231    public void testRun_withMultipleTransports() throws Exception {
232        List<TransportData> transports =
233                TransportTestUtils.setUpTransports(mTransportManager, TRANSPORT_NAMES);
234        configureTransport(transports.get(0).transportMock, TRANSPORT_OK, TRANSPORT_OK);
235        configureTransport(transports.get(1).transportMock, TRANSPORT_OK, TRANSPORT_OK);
236        configureTransport(transports.get(2).transportMock, TRANSPORT_OK, TRANSPORT_OK);
237        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAMES);
238
239        performInitializeTask.run();
240
241        for (TransportData transport : transports) {
242            verify(mTransportManager).getTransportClient(eq(transport.transportName), any());
243            verify(mTransportManager)
244                    .disposeOfTransportClient(eq(transport.transportClientMock), any());
245        }
246    }
247
248    @Test
249    public void testRun_whenOnlyOneTransportFails_disposesAllTransports() throws Exception {
250        List<TransportData> transports =
251                TransportTestUtils.setUpTransports(
252                        mTransportManager, TRANSPORT_NAMES[0], TRANSPORT_NAMES[1]);
253        configureTransport(transports.get(0).transportMock, TRANSPORT_ERROR, 0);
254        configureTransport(transports.get(1).transportMock, TRANSPORT_OK, TRANSPORT_OK);
255        PerformInitializeTask performInitializeTask =
256                createPerformInitializeTask(TRANSPORT_NAMES[0], TRANSPORT_NAMES[1]);
257
258        performInitializeTask.run();
259
260        verify(mTransportManager)
261                .disposeOfTransportClient(eq(transports.get(0).transportClientMock), any());
262        verify(mTransportManager)
263                .disposeOfTransportClient(eq(transports.get(1).transportClientMock), any());
264    }
265
266    @Test
267    public void testRun_whenTransportNotRegistered() throws Exception {
268        TransportTestUtils.setUpTransports(
269                mTransportManager, new TransportData(TRANSPORT_NAME, null, null));
270
271        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
272
273        performInitializeTask.run();
274
275        verify(mTransportManager, never()).disposeOfTransportClient(any(), any());
276        verify(mObserver, never()).onResult(any(), anyInt());
277        verify(mObserver).backupFinished(eq(TRANSPORT_OK));
278    }
279
280    @Test
281    public void testRun_whenOnlyOneTransportNotRegistered() throws Exception {
282        List<TransportData> transports =
283                TransportTestUtils.setUpTransports(
284                        mTransportManager,
285                        new TransportData(TRANSPORT_NAMES[0], null, null),
286                        new TransportData(TRANSPORT_NAMES[1]));
287        String registeredTransportName = transports.get(1).transportName;
288        IBackupTransport registeredTransport = transports.get(1).transportMock;
289        TransportClient registeredTransportClient = transports.get(1).transportClientMock;
290        PerformInitializeTask performInitializeTask =
291                createPerformInitializeTask(TRANSPORT_NAMES[0], TRANSPORT_NAMES[1]);
292
293        performInitializeTask.run();
294
295        verify(registeredTransport).initializeDevice();
296        verify(mTransportManager).disposeOfTransportClient(eq(registeredTransportClient), any());
297        verify(mObserver).onResult(eq(registeredTransportName), eq(TRANSPORT_OK));
298    }
299
300    @Test
301    public void testRun_whenTransportNotAvailable() throws Exception {
302        TransportClient transportClient = mock(TransportClient.class);
303        TransportTestUtils.setUpTransports(
304                mTransportManager, new TransportData(TRANSPORT_NAME, null, transportClient));
305        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
306
307        performInitializeTask.run();
308
309        verify(mTransportManager).disposeOfTransportClient(eq(transportClient), any());
310        verify(mObserver).backupFinished(eq(TRANSPORT_ERROR));
311        verify(mListener).onFinished(any());
312    }
313
314    @Test
315    public void testRun_whenTransportThrowsDeadObjectException() throws Exception {
316        TransportClient transportClient = mock(TransportClient.class);
317        TransportTestUtils.setUpTransports(
318                mTransportManager, new TransportData(TRANSPORT_NAME, mTransport, transportClient));
319        when(mTransport.initializeDevice()).thenThrow(DeadObjectException.class);
320        PerformInitializeTask performInitializeTask = createPerformInitializeTask(TRANSPORT_NAME);
321
322        performInitializeTask.run();
323
324        verify(mTransportManager).disposeOfTransportClient(eq(transportClient), any());
325        verify(mObserver).backupFinished(eq(TRANSPORT_ERROR));
326        verify(mListener).onFinished(any());
327    }
328
329    private PerformInitializeTask createPerformInitializeTask(String... transportNames) {
330        return new PerformInitializeTask(
331                mBackupManagerService,
332                mTransportManager,
333                transportNames,
334                mObserver,
335                mListener,
336                mBaseStateDir);
337    }
338
339    private void configureTransport(
340            IBackupTransport transportMock, int initializeDeviceStatus, int finishBackupStatus)
341            throws Exception {
342        when(transportMock.initializeDevice()).thenReturn(initializeDeviceStatus);
343        when(transportMock.finishBackup()).thenReturn(finishBackupStatus);
344    }
345
346    private void setUpTransport(String transportName) throws Exception {
347        TransportTestUtils.setUpTransport(
348                mTransportManager,
349                new TransportData(transportName, mTransport, mock(TransportClient.class)));
350    }
351}
352