blob: d9e8f0f4867b75d975ff3e5f7a766362781a1fea [file] [log] [blame]
Bernardo Rufinofa518532018-01-02 16:01:53 +00001/*
2 * Copyright (C) 2018 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;
18
19import static com.google.common.truth.Truth.assertThat;
20
21import static org.mockito.ArgumentMatchers.any;
22import static org.mockito.ArgumentMatchers.eq;
23import static org.mockito.Mockito.verify;
24import static org.mockito.Mockito.when;
25import static org.testng.Assert.expectThrows;
26
27import android.content.ContextWrapper;
28import android.os.HandlerThread;
29import android.platform.test.annotations.Presubmit;
30
31import com.android.server.backup.testing.ShadowAppBackupUtils;
32import com.android.server.backup.testing.TransportTestUtils;
33import com.android.server.backup.testing.TransportTestUtils.TransportData;
34import com.android.server.backup.transport.TransportNotRegisteredException;
35import com.android.server.testing.FrameworkRobolectricTestRunner;
36import com.android.server.testing.SystemLoaderClasses;
37
38import org.junit.After;
39import org.junit.Before;
40import org.junit.Test;
41import org.junit.runner.RunWith;
42import org.mockito.Mock;
43import org.mockito.MockitoAnnotations;
44import org.robolectric.RuntimeEnvironment;
45import org.robolectric.Shadows;
46import org.robolectric.annotation.Config;
47import org.robolectric.shadows.ShadowContextWrapper;
48import org.robolectric.shadows.ShadowLog;
49
50import java.io.File;
51import java.util.HashMap;
52import java.util.Map;
53
54@RunWith(FrameworkRobolectricTestRunner.class)
55@Config(
56 manifest = Config.NONE,
57 sdk = 26,
58 shadows = {ShadowAppBackupUtils.class}
59)
60@SystemLoaderClasses({RefactoredBackupManagerService.class, TransportManager.class})
61@Presubmit
62public class BackupManagerServiceRoboTest {
63 private static final String TAG = "BMSTest";
64 private static final String TRANSPORT_NAME =
65 "com.google.android.gms/.backup.BackupTransportService";
66
67 @Mock private TransportManager mTransportManager;
68 private HandlerThread mBackupThread;
69 private File mBaseStateDir;
70 private File mDataDir;
71 private RefactoredBackupManagerService mBackupManagerService;
72 private ShadowContextWrapper mShadowContext;
73
74 @Before
75 public void setUp() throws Exception {
76 MockitoAnnotations.initMocks(this);
77
78 mBackupThread = new HandlerThread("backup-test");
79 mBackupThread.setUncaughtExceptionHandler(
80 (t, e) -> ShadowLog.e(TAG, "Uncaught exception in test thread " + t.getName(), e));
81 mBackupThread.start();
82
83 ContextWrapper context = RuntimeEnvironment.application;
84 mShadowContext = Shadows.shadowOf(context);
85
86 File cacheDir = context.getCacheDir();
87 mBaseStateDir = new File(cacheDir, "base_state_dir");
88 mDataDir = new File(cacheDir, "data_dir");
89
90 mBackupManagerService =
91 new RefactoredBackupManagerService(
92 context,
93 new Trampoline(context),
94 mBackupThread,
95 mBaseStateDir,
96 mDataDir,
97 mTransportManager);
98 }
99
100 @After
101 public void tearDown() throws Exception {
102 mBackupThread.quit();
103 ShadowAppBackupUtils.reset();
104 }
105
106 @Test
107 public void testDestinationString() throws Exception {
108 mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
109 when(mTransportManager.getTransportCurrentDestinationString(eq(TRANSPORT_NAME)))
110 .thenReturn("destinationString");
111
112 String destination = mBackupManagerService.getDestinationString(TRANSPORT_NAME);
113
114 assertThat(destination).isEqualTo("destinationString");
115 }
116
117 @Test
118 public void testDestinationString_whenTransportNotRegistered() throws Exception {
119 mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
120 when(mTransportManager.getTransportCurrentDestinationString(eq(TRANSPORT_NAME)))
121 .thenThrow(TransportNotRegisteredException.class);
122
123 String destination = mBackupManagerService.getDestinationString(TRANSPORT_NAME);
124
125 assertThat(destination).isNull();
126 }
127
128 @Test
129 public void testDestinationString_withoutPermission() throws Exception {
130 mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
131 when(mTransportManager.getTransportCurrentDestinationString(eq(TRANSPORT_NAME)))
132 .thenThrow(TransportNotRegisteredException.class);
133
134 expectThrows(
135 SecurityException.class,
136 () -> mBackupManagerService.getDestinationString(TRANSPORT_NAME));
137 }
138
139 @Test
140 public void testIsAppEligibleForBackup_whenAppEligible() throws Exception {
141 mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
142 TransportData transport =
143 TransportTestUtils.setUpCurrentTransport(mTransportManager, TRANSPORT_NAME);
144 ShadowAppBackupUtils.sAppIsRunningAndEligibleForBackupWithTransport = p -> true;
145
146 boolean result = mBackupManagerService.isAppEligibleForBackup("app.package");
147
148 assertThat(result).isTrue();
149 verify(mTransportManager)
150 .disposeOfTransportClient(eq(transport.transportClientMock), any());
151 }
152
153 @Test
154 public void testIsAppEligibleForBackup_whenAppNotEligible() throws Exception {
155 mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
156 TransportTestUtils.setUpCurrentTransport(mTransportManager, TRANSPORT_NAME);
157 ShadowAppBackupUtils.sAppIsRunningAndEligibleForBackupWithTransport = p -> false;
158
159 boolean result = mBackupManagerService.isAppEligibleForBackup("app.package");
160
161 assertThat(result).isFalse();
162 }
163
164 @Test
165 public void testIsAppEligibleForBackup_withoutPermission() throws Exception {
166 mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
167 TransportTestUtils.setUpCurrentTransport(mTransportManager, TRANSPORT_NAME);
168
169 expectThrows(
170 SecurityException.class,
171 () -> mBackupManagerService.isAppEligibleForBackup("app.package"));
172 }
173
174 @Test
175 public void testFilterAppsEligibleForBackup() throws Exception {
176 mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
177 TransportData transport =
178 TransportTestUtils.setUpCurrentTransport(mTransportManager, TRANSPORT_NAME);
179 Map<String, Boolean> packagesMap = new HashMap<>();
180 packagesMap.put("package.a", true);
181 packagesMap.put("package.b", false);
182 ShadowAppBackupUtils.sAppIsRunningAndEligibleForBackupWithTransport = packagesMap::get;
183 String[] packages = packagesMap.keySet().toArray(new String[packagesMap.size()]);
184
185 String[] filtered = mBackupManagerService.filterAppsEligibleForBackup(packages);
186
187 assertThat(filtered).asList().containsExactly("package.a");
188 verify(mTransportManager)
189 .disposeOfTransportClient(eq(transport.transportClientMock), any());
190 }
191
192 @Test
193 public void testFilterAppsEligibleForBackup_whenNoneIsEligible() throws Exception {
194 mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
195 ShadowAppBackupUtils.sAppIsRunningAndEligibleForBackupWithTransport = p -> false;
196
197 String[] filtered =
198 mBackupManagerService.filterAppsEligibleForBackup(
199 new String[] {"package.a", "package.b"});
200
201 assertThat(filtered).isEmpty();
202 }
203
204 @Test
205 public void testFilterAppsEligibleForBackup_withoutPermission() throws Exception {
206 mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
207 TransportTestUtils.setUpCurrentTransport(mTransportManager, TRANSPORT_NAME);
208
209 expectThrows(
210 SecurityException.class,
211 () ->
212 mBackupManagerService.filterAppsEligibleForBackup(
213 new String[] {"package.a", "package.b"}));
214 }
215}