• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.managedprovisioning.task;
18 
19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
20 
21 import static org.mockito.Matchers.any;
22 import static org.mockito.Matchers.anyLong;
23 import static org.mockito.Matchers.eq;
24 import static org.mockito.Matchers.nullable;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.verifyNoMoreInteractions;
28 import static org.mockito.Mockito.verifyZeroInteractions;
29 import static org.mockito.Mockito.when;
30 
31 import android.accounts.Account;
32 import android.accounts.AccountManager;
33 import android.accounts.AccountManagerCallback;
34 import android.accounts.AccountManagerFuture;
35 import android.accounts.OperationCanceledException;
36 import android.content.Context;
37 import android.os.Handler;
38 import android.os.UserHandle;
39 import android.test.AndroidTestCase;
40 import android.test.suitebuilder.annotation.SmallTest;
41 
42 import androidx.test.filters.FlakyTest;
43 
44 import com.android.managedprovisioning.analytics.MetricsWriter;
45 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker;
46 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences;
47 import com.android.managedprovisioning.common.SettingsFacade;
48 import com.android.managedprovisioning.model.ProvisioningParams;
49 
50 import org.mockito.Mock;
51 import org.mockito.MockitoAnnotations;
52 
53 import java.util.concurrent.TimeUnit;
54 
55 /**
56  * Unit tests for {@link CopyAccountToUserTask}.
57  */
58 @FlakyTest // TODO: http://b/34117742
59 public class CopyAccountToUserTaskTest extends AndroidTestCase {
60     private static final String TEST_MDM_PACKAGE_NAME = "mdm.package.name";
61     private static final Account TEST_ACCOUNT = new Account("test@afw-test.com", "com.google");
62     private static final int TEST_SOURCE_USER_ID = 1;
63     private static final int TEST_TARGET_USER_ID = 2;
64 
65     @Mock private Context mContext;
66     @Mock private AccountManager mAccountManager;
67     @Mock private AccountManagerFuture mAccountManagerFuture;
68     @Mock private AbstractProvisioningTask.Callback mCallback;
69     @Mock private MetricsWriter mMetricsWriter;
70     @Mock private ManagedProvisioningSharedPreferences mSharedPreferences;
71     private CopyAccountToUserTask mTask;
72 
setUp()73     public void setUp() {
74         // this is necessary for mockito to work
75         System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
76         MockitoAnnotations.initMocks(this);
77 
78         when(mContext.getSystemService(Context.ACCOUNT_SERVICE)).thenReturn(mAccountManager);
79         when(mAccountManager.copyAccountToUser(
80                 eq(TEST_ACCOUNT),
81                 eq(UserHandle.of(TEST_SOURCE_USER_ID)),
82                 eq(UserHandle.of(TEST_TARGET_USER_ID)),
83                 nullable(AccountManagerCallback.class),
84                 nullable(Handler.class))).thenReturn(mAccountManagerFuture);
85     }
86 
87     @SmallTest
testRun()88     public void testRun() throws Exception {
89         // GIVEN an account on the source user
90         createTask(TEST_SOURCE_USER_ID, TEST_ACCOUNT);
91 
92         // GIVEN no timeout or error occurred during migration
93         when(mAccountManagerFuture.getResult(anyLong(), any(TimeUnit.class))).thenReturn(true);
94 
95         // THEN when the task is run
96         mTask.run(TEST_TARGET_USER_ID);
97 
98         // THEN the account migration was triggered
99         verify(mAccountManager).copyAccountToUser(
100                 eq(TEST_ACCOUNT),
101                 eq(UserHandle.of(TEST_SOURCE_USER_ID)),
102                 eq(UserHandle.of(TEST_TARGET_USER_ID)),
103                 nullable(AccountManagerCallback.class),
104                 nullable(Handler.class));
105 
106         // THEN the success callback should be given
107         verify(mCallback).onSuccess(mTask);
108         verifyNoMoreInteractions(mCallback);
109     }
110 
111     @SmallTest
testRun_error()112     public void testRun_error() throws Exception {
113         // GIVEN an account on the source user
114         createTask(TEST_SOURCE_USER_ID, TEST_ACCOUNT);
115 
116         // GIVEN no timeout or error occurred during migration
117         when(mAccountManagerFuture.getResult(anyLong(), any(TimeUnit.class))).thenReturn(false);
118 
119         // THEN when the task is run
120         mTask.run(TEST_TARGET_USER_ID);
121 
122         // THEN the account migration was triggered
123         verify(mAccountManager).copyAccountToUser(
124                 eq(TEST_ACCOUNT),
125                 eq(UserHandle.of(TEST_SOURCE_USER_ID)),
126                 eq(UserHandle.of(TEST_TARGET_USER_ID)),
127                 nullable(AccountManagerCallback.class),
128                 nullable(Handler.class));
129 
130         // THEN the success callback should be given
131         verify(mCallback).onSuccess(mTask);
132         verifyNoMoreInteractions(mCallback);
133     }
134 
135     @SmallTest
testRun_nullAccount()136     public void testRun_nullAccount() {
137         // GIVEN no account is passed
138         createTask(TEST_SOURCE_USER_ID, null);
139 
140         // WHEN running the task
141         mTask.run(TEST_TARGET_USER_ID);
142 
143         // THEN nothing should happen
144         verifyZeroInteractions(mAccountManager);
145 
146         // THEN the success callback should still occur
147         verify(mCallback).onSuccess(mTask);
148         verifyNoMoreInteractions(mCallback);
149     }
150 
151     @SmallTest
testRun_sameUser()152     public void testRun_sameUser() {
153         // GIVEN an account on a user
154         createTask(TEST_SOURCE_USER_ID, TEST_ACCOUNT);
155 
156         // WHEN running the task for the same user
157         mTask.run(TEST_SOURCE_USER_ID);
158 
159         // THEN nothing should happen
160         verifyZeroInteractions(mAccountManager);
161 
162         // THEN the success callback should still occur
163         verify(mCallback).onSuccess(mTask);
164         verifyNoMoreInteractions(mCallback);
165     }
166 
167     @SmallTest
testMaybeCopyAccount_success()168     public void testMaybeCopyAccount_success() throws Exception {
169         // GIVEN an account on the source user
170         createTask(TEST_SOURCE_USER_ID, TEST_ACCOUNT);
171 
172         // GIVEN no timeout or error occurred during migration
173         when(mAccountManagerFuture.getResult(anyLong(), any(TimeUnit.class))).thenReturn(true);
174 
175         // WHEN copying the account from the source user to the target user
176         // THEN the account migration succeeds
177         assertTrue(mTask.maybeCopyAccount(TEST_TARGET_USER_ID));
178     }
179 
180     @SmallTest
testMaybeCopyAccount_error()181     public void testMaybeCopyAccount_error() throws Exception {
182         // GIVEN an account on the source user
183         createTask(TEST_SOURCE_USER_ID, TEST_ACCOUNT);
184 
185         // GIVEN an error occurred during migration
186         when(mAccountManagerFuture.getResult(anyLong(), any(TimeUnit.class))).thenReturn(false);
187 
188         // WHEN copying the account from the source user to the target user
189         // THEN the account migration fails
190         assertFalse(mTask.maybeCopyAccount(TEST_TARGET_USER_ID));
191     }
192 
193     @SmallTest
testMaybeCopyAccount_timeout()194     public void testMaybeCopyAccount_timeout() throws Exception {
195         // GIVEN an account on the source user
196         createTask(TEST_SOURCE_USER_ID, TEST_ACCOUNT);
197 
198         // GIVEN a timeout occurred during migration, which is indicated by an
199         // OperationCanceledException
200         when(mAccountManagerFuture.getResult(anyLong(), any(TimeUnit.class)))
201                 .thenThrow(new OperationCanceledException());
202 
203         // WHEN copying the account from the source user to the target user
204         // THEN the account migration fails
205         assertFalse(mTask.maybeCopyAccount(TEST_TARGET_USER_ID));
206     }
207 
createTask(int sourceUserId, Account account)208     private void createTask(int sourceUserId, Account account) {
209         ProvisioningParams params = new ProvisioningParams.Builder()
210                 .setProvisioningAction(ACTION_PROVISION_MANAGED_PROFILE)
211                 .setDeviceAdminPackageName(TEST_MDM_PACKAGE_NAME)
212                 .setAccountToMigrate(account)
213                 .build();
214         mTask = new CopyAccountToUserTask(sourceUserId, mContext, params, mCallback,
215                 mock(ProvisioningAnalyticsTracker.class));
216     }
217 }
218