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