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