1 /*
2  * Copyright 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 package com.android.managedprovisioning.task;
17 
18 import static junit.framework.Assert.assertEquals;
19 import static junit.framework.Assert.assertFalse;
20 import static junit.framework.Assert.assertTrue;
21 
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.when;
24 
25 import android.content.Context;
26 import android.os.FileUtils;
27 import android.os.UserHandle;
28 import android.os.UserManager;
29 
30 import androidx.test.InstrumentationRegistry;
31 
32 import com.android.managedprovisioning.analytics.MetricsWriterFactory;
33 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker;
34 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences;
35 import com.android.managedprovisioning.common.SettingsFacade;
36 import com.android.managedprovisioning.task.nonrequiredapps.SystemAppsSnapshot;
37 import com.android.managedprovisioning.tests.R;
38 
39 import org.junit.After;
40 import org.junit.Assert;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.junit.runner.RunWith;
44 import org.mockito.Mock;
45 import org.mockito.junit.MockitoJUnitRunner;
46 
47 import java.io.File;
48 import java.io.FileOutputStream;
49 import java.io.InputStream;
50 import java.util.Arrays;
51 import java.util.HashSet;
52 import java.util.Set;
53 
54 @RunWith(MockitoJUnitRunner.class)
55 public class MigrateSystemAppsSnapshotTaskTest {
56     private static final int USER_A_ID = 10;
57     private static final int USER_A_SERIAL_NUMBER = 20;
58     private static final int USER_A_SNAPSHOT_FILE = R.raw.snapshot;
59 
60     private static final int USER_B_ID = 11;
61     private static final int USER_B_SERIAL_NUMBER = 21;
62     private static final int USER_B_SNAPSHOT_FILE = R.raw.snapshot2;
63 
64     private static final int NOT_EXIST_USER_ID = 99;
65     private static final int INVALID_SERIAL_NUMBER = -1;
66 
67     private static final Set<String> SNAPSHOT_A = new HashSet<>();
68     static {
69         SNAPSHOT_A.add("com.app.a");
70         SNAPSHOT_A.add("com.app.b");
71     }
72 
73     private static final Set<String> SNAPSHOT_B = new HashSet<>();
74     static {
75         SNAPSHOT_B.add("com.app.a");
76         SNAPSHOT_B.add("com.app.c");
77     }
78 
79     private MigrateSystemAppsSnapshotTask mMigrateSystemAppsSnapshotTask;
80     private SystemAppsSnapshot mSystemAppsSnapshot;
81     @Mock
82     private Context mContext;
83     @Mock
84     private AbstractProvisioningTask.Callback mCallback;
85     @Mock
86     private UserManager mUserManager;
87 
88     @Before
setup()89     public void setup() {
90         when(mContext.getFilesDir())
91                 .thenReturn(
92                         new File(InstrumentationRegistry.getTargetContext().getFilesDir(), "test"));
93         mMigrateSystemAppsSnapshotTask = new MigrateSystemAppsSnapshotTask(mContext, mCallback,
94                 mock(ProvisioningAnalyticsTracker.class));
95         mSystemAppsSnapshot = new SystemAppsSnapshot(mContext);
96     }
97 
98     @Before
setupUserManager()99     public void setupUserManager() {
100         when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
101         when(mUserManager.getUserSerialNumber(USER_A_ID)).thenReturn(USER_A_SERIAL_NUMBER);
102         when(mUserManager.getUserSerialNumber(USER_B_ID)).thenReturn(USER_B_SERIAL_NUMBER);
103         when(mUserManager.getUserSerialNumber(NOT_EXIST_USER_ID)).thenReturn(INVALID_SERIAL_NUMBER);
104     }
105 
106     @After
tearDown()107     public void tearDown() {
108         FileUtils.deleteContentsAndDir(SystemAppsSnapshot.getFolder(mContext));
109         FileUtils.deleteContentsAndDir(SystemAppsSnapshot.getLegacyFolder(mContext));
110     }
111 
112     @Test
testRun_nothingToMigrate()113     public void testRun_nothingToMigrate() {
114         mMigrateSystemAppsSnapshotTask.run(UserHandle.USER_SYSTEM);
115 
116         assertFalse(SystemAppsSnapshot.getFolder(mContext).exists());
117     }
118 
119     @Test
testRun_alreadyMigrated()120     public void testRun_alreadyMigrated() throws Exception {
121         copyTestFileTo(USER_A_SNAPSHOT_FILE, SystemAppsSnapshot.getFolder(mContext), "20.xml");
122 
123         mMigrateSystemAppsSnapshotTask.run(UserHandle.USER_SYSTEM);
124 
125         assertFilesAreMigrated(new String[]{"20.xml"});
126     }
127 
128     @Test
testRun_migrate_userExists()129     public void testRun_migrate_userExists() throws Exception {
130         File legacyFolder = SystemAppsSnapshot.getLegacyFolder(mContext);
131         copyTestFileTo(USER_A_SNAPSHOT_FILE, legacyFolder, "10.xml");
132         copyTestFileTo(USER_B_SNAPSHOT_FILE, legacyFolder, "11.xml");
133 
134         mMigrateSystemAppsSnapshotTask.run(UserHandle.USER_SYSTEM);
135 
136         assertFilesAreMigrated(new String[] {"20.xml", "21.xml"});
137         assertSnapshotFileContent(10, SNAPSHOT_A);
138         assertSnapshotFileContent(11, SNAPSHOT_B);
139     }
140 
141     @Test
testRun_migrate_userDoesNotExists()142     public void testRun_migrate_userDoesNotExists() throws Exception {
143         File legacyFolder = SystemAppsSnapshot.getLegacyFolder(mContext);
144         copyTestFileTo(USER_A_SNAPSHOT_FILE, legacyFolder, "99.xml");
145 
146         mMigrateSystemAppsSnapshotTask.run(UserHandle.USER_SYSTEM);
147 
148         assertFilesAreMigrated(new String[] {});
149     }
150 
151     @Test
testRun_migrate_invalidFileName()152     public void testRun_migrate_invalidFileName() throws Exception {
153         File legacyFolder = SystemAppsSnapshot.getLegacyFolder(mContext);
154         copyTestFileTo(USER_A_SNAPSHOT_FILE, legacyFolder, "random.xml");
155 
156         mMigrateSystemAppsSnapshotTask.run(UserHandle.USER_SYSTEM);
157 
158         assertFilesAreMigrated(new String[] {});
159     }
160 
copyTestFileTo( int fileToBeCopied, File destinationFolder, String fileName)161     private void copyTestFileTo(
162             int fileToBeCopied, File destinationFolder, String fileName) throws Exception {
163         File destination = new File(destinationFolder, fileName);
164         destination.getParentFile().mkdirs();
165         destination.createNewFile();
166         FileUtils.copy(getTestFile(fileToBeCopied), new FileOutputStream(destination));
167     }
168 
assertSnapshotFileContent(int userId, Set<String> expected)169     private void assertSnapshotFileContent(int userId, Set<String> expected) {
170         Set<String> actual = mSystemAppsSnapshot.getSnapshot(userId);
171         assertEquals(expected, actual);
172     }
173 
getTestFile(int resId)174     private InputStream getTestFile(int resId) {
175         return InstrumentationRegistry.getContext().getResources().openRawResource(resId);
176     }
177 
assertFilesAreMigrated(String[] expectedFileNames)178     private void assertFilesAreMigrated(String[] expectedFileNames) {
179         File legacyFolder = SystemAppsSnapshot.getLegacyFolder(mContext);
180         File newFolder = SystemAppsSnapshot.getFolder(mContext);
181 
182         assertFalse(legacyFolder.exists());
183         assertTrue(newFolder.exists());
184 
185         File[] files = newFolder.listFiles();
186         assertEquals(expectedFileNames.length, files.length);
187 
188         String[] actualFilesNames =
189                 Arrays.stream(files).map(file -> file.getName()).toArray(String[]::new);
190 
191         Arrays.sort(expectedFileNames);
192         Arrays.sort(actualFilesNames);
193         Assert.assertArrayEquals(expectedFileNames, actualFilesNames);
194     }
195 }
196