Commit fdfcc104 authored by skirmani's avatar skirmani Committed by Commit bot

Added Signin Utilites (RE-LAND)

Re-Land of https://codereview.chromium.org/1258563005/

- Made Google OS Sign-in Tests FlakyTest
- Fixed test account preferences that caused the real Google account sign-in tests to fail previously.

BUG=

Review URL: https://codereview.chromium.org/1279483003

Cr-Commit-Position: refs/heads/master@{#342385}
parent e1c3d024
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.test.util;
import android.test.FlakyTest;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import org.chromium.base.test.util.Restriction;
import org.chromium.sync.signin.ChromeSigninController;
/**
* Tests for {@link ChromeSigninUtils}.
*/
public class ChromeSigninUtilsTest extends InstrumentationTestCase {
private static final String FAKE_ACCOUNT_USERNAME = "test@google.com";
private static final String FAKE_ACCOUNT_PASSWORD = "$3cr3t";
private static final String GOOGLE_ACCOUNT_USERNAME = "chromiumforandroid01@gmail.com";
private static final String GOOGLE_ACCOUNT_PASSWORD = "chromeforandroid";
private static final String GOOGLE_ACCOUNT_TYPE = "mail";
private ChromeSigninUtils mSigninUtil;
private ChromeSigninController mSigninController;
@Override
public void setUp() throws Exception {
super.setUp();
mSigninUtil = new ChromeSigninUtils(this);
mSigninController = ChromeSigninController.get(getInstrumentation().getTargetContext());
mSigninController.clearSignedInUser();
mSigninUtil.removeAllFakeAccountsFromOs();
mSigninUtil.removeAllGoogleAccountsFromOs();
}
@SmallTest
public void testActivityIsNotSignedInOnAppOrFakeOSorGoogleOS() {
assertFalse("Should not be signed into app.",
mSigninController.isSignedIn());
assertFalse("Should not be signed into OS with fake account.",
mSigninUtil.isExistingFakeAccountOnOs(FAKE_ACCOUNT_USERNAME));
assertFalse("Should not be signed in on OS with Google account.",
mSigninUtil.isExistingGoogleAccountOnOs(GOOGLE_ACCOUNT_USERNAME));
}
@SmallTest
public void testIsSignedInOnApp() {
mSigninUtil.addAccountToApp(FAKE_ACCOUNT_USERNAME);
assertTrue("Should be signed on app.",
mSigninController.isSignedIn());
assertFalse("Should not be signed on OS with fake account.",
mSigninUtil.isExistingFakeAccountOnOs(FAKE_ACCOUNT_USERNAME));
assertFalse("Should not be signed in on OS with Google account.",
mSigninUtil.isExistingGoogleAccountOnOs(GOOGLE_ACCOUNT_USERNAME));
}
@SmallTest
public void testIsSignedInOnFakeOS() {
mSigninUtil.addFakeAccountToOs(FAKE_ACCOUNT_USERNAME, FAKE_ACCOUNT_PASSWORD);
assertFalse("Should not be signed in on app.",
mSigninController.isSignedIn());
assertTrue("Should be signed in on OS with fake account.",
mSigninUtil.isExistingFakeAccountOnOs(FAKE_ACCOUNT_USERNAME));
assertFalse("Should not be signed in on OS with Google account.",
mSigninUtil.isExistingGoogleAccountOnOs(GOOGLE_ACCOUNT_USERNAME));
}
@FlakyTest
@Restriction(Restriction.RESTRICTION_TYPE_INTERNET)
public void testIsSignedInOnGoogleOS() {
mSigninUtil.addGoogleAccountToOs(GOOGLE_ACCOUNT_USERNAME, GOOGLE_ACCOUNT_PASSWORD,
GOOGLE_ACCOUNT_TYPE);
assertFalse("Should not be signed into app.",
mSigninController.isSignedIn());
assertFalse("Should not be signed into OS with fake account.",
mSigninUtil.isExistingFakeAccountOnOs(FAKE_ACCOUNT_USERNAME));
assertTrue("Should be signed in on OS with Google account.",
mSigninUtil.isExistingGoogleAccountOnOs(GOOGLE_ACCOUNT_USERNAME));
}
@SmallTest
public void testIsSignedInOnFakeOSandApp() {
mSigninUtil.addAccountToApp(FAKE_ACCOUNT_USERNAME);
mSigninUtil.addFakeAccountToOs(FAKE_ACCOUNT_USERNAME, FAKE_ACCOUNT_PASSWORD);
assertTrue("Should be signed in on app.",
mSigninController.isSignedIn());
assertTrue("Should be signed in on OS with fake account.",
mSigninUtil.isExistingFakeAccountOnOs(FAKE_ACCOUNT_USERNAME));
assertFalse("Should not be signed in on OS with Google account.",
mSigninUtil.isExistingGoogleAccountOnOs(GOOGLE_ACCOUNT_USERNAME));
}
@FlakyTest
@Restriction(Restriction.RESTRICTION_TYPE_INTERNET)
public void testIsSignedInOnAppAndGoogleOS() {
mSigninUtil.addAccountToApp(FAKE_ACCOUNT_USERNAME);
mSigninUtil.addGoogleAccountToOs(GOOGLE_ACCOUNT_USERNAME, GOOGLE_ACCOUNT_PASSWORD,
GOOGLE_ACCOUNT_TYPE);
assertTrue("Should be signed into app.",
mSigninController.isSignedIn());
assertFalse("Should not be signed into OS with fake account.",
mSigninUtil.isExistingFakeAccountOnOs(FAKE_ACCOUNT_USERNAME));
assertTrue("Should be signed in on OS with Google account.",
mSigninUtil.isExistingGoogleAccountOnOs(GOOGLE_ACCOUNT_USERNAME));
}
@FlakyTest
@Restriction(Restriction.RESTRICTION_TYPE_INTERNET)
public void testIsSignedInOnFakeOSandGoogleOS() {
mSigninUtil.addFakeAccountToOs(FAKE_ACCOUNT_USERNAME, FAKE_ACCOUNT_PASSWORD);
mSigninUtil.addGoogleAccountToOs(GOOGLE_ACCOUNT_USERNAME, GOOGLE_ACCOUNT_PASSWORD,
GOOGLE_ACCOUNT_TYPE);
assertFalse("Should not be signed into app.",
mSigninController.isSignedIn());
assertTrue("Should be signed into OS with fake account.",
mSigninUtil.isExistingFakeAccountOnOs(FAKE_ACCOUNT_USERNAME));
assertTrue("Should be signed in on OS with Google account.",
mSigninUtil.isExistingGoogleAccountOnOs(GOOGLE_ACCOUNT_USERNAME));
}
@FlakyTest
@Restriction(Restriction.RESTRICTION_TYPE_INTERNET)
public void testIsSignedInOnAppAndFakeOSandGoogleOS() {
mSigninUtil.addAccountToApp(FAKE_ACCOUNT_USERNAME);
mSigninUtil.addFakeAccountToOs(FAKE_ACCOUNT_USERNAME, FAKE_ACCOUNT_PASSWORD);
mSigninUtil.addGoogleAccountToOs(GOOGLE_ACCOUNT_USERNAME, GOOGLE_ACCOUNT_PASSWORD,
GOOGLE_ACCOUNT_TYPE);
assertTrue("Should be signed into app.",
mSigninController.isSignedIn());
assertTrue("Should be signed into OS with fake account.",
mSigninUtil.isExistingFakeAccountOnOs(FAKE_ACCOUNT_USERNAME));
assertTrue("Should be signed in on OS with Google account.",
mSigninUtil.isExistingGoogleAccountOnOs(GOOGLE_ACCOUNT_USERNAME));
}
@Override
protected void tearDown() throws Exception {
mSigninController.clearSignedInUser();
mSigninUtil.removeAllFakeAccountsFromOs();
mSigninUtil.removeAllGoogleAccountsFromOs();
super.tearDown();
}
}
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.test.util;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.Context;
import android.os.Bundle;
import android.test.InstrumentationTestCase;
import android.text.TextUtils;
import org.chromium.sync.signin.ChromeSigninController;
import org.chromium.sync.test.util.AccountHolder;
import org.chromium.sync.test.util.MockAccountManager;
import java.io.IOException;
/**
* A tool used for running tests as signed in.
*/
public class ChromeSigninUtils {
/** Bundle tags */
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static final String ALLOW_SKIP = "allowSkip";
/** Information for Google OS account */
private static final String GOOGLE_ACCOUNT_TYPE = "com.google";
private AccountManager mAccountManager;
private MockAccountManager mMockAccountManager;
private Context mContext;
private Context mTargetContext;
/**
* The constructor for SigninUtils for a given test case.
*
* @param testCase the test case to perform signin operations with.
*/
public ChromeSigninUtils(InstrumentationTestCase testCase) {
mContext = testCase.getInstrumentation().getContext();
mTargetContext = testCase.getInstrumentation().getTargetContext();
mAccountManager = AccountManager.get(mContext);
mMockAccountManager = new MockAccountManager(mContext, mTargetContext);
}
/**
* Adds an account to the app.
*
* @param username the username for the logged in account; must be a Google account.
*/
public void addAccountToApp(String username) {
if (TextUtils.isEmpty(username)) {
throw new IllegalArgumentException("ERROR: must specify account");
}
if (ChromeSigninController.get(mContext).isSignedIn()) {
ChromeSigninController.get(mContext).clearSignedInUser();
}
ChromeSigninController.get(mContext).setSignedInAccountName(username);
}
/**
* Adds a fake account to the OS.
*/
public void addFakeAccountToOs(String username, String password) {
if (TextUtils.isEmpty(username)) {
throw new IllegalArgumentException("ERROR: must specify account");
}
Account account = new Account(username, GOOGLE_ACCOUNT_TYPE);
mMockAccountManager = new MockAccountManager(mContext, mTargetContext, account);
AccountHolder accountHolder = new AccountHolder.Builder()
.account(account)
.password(password)
.build();
mMockAccountManager.addAccountHolderExplicitly(accountHolder);
}
/**
* Removes all fake accounts from the OS.
*/
public void removeAllFakeAccountsFromOs() {
for (Account acct : mMockAccountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE)) {
mMockAccountManager.removeAccountHolderExplicitly(
new AccountHolder.Builder().account(acct).build(), true);
}
}
/**
* Checks if an existing fake account is on the OS.
*
* @param username the username of the account you want to check if signed in
* @return {@code true} if fake account is on OS, false otherwise.
*/
public boolean isExistingFakeAccountOnOs(String username) {
if (mMockAccountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE).length == 0) {
return false;
}
for (Account acct : mMockAccountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE)) {
if (username.equals(acct.name)) {
return true;
}
}
return false;
}
/**
* Adds a Google account to the OS.
*
* @param username the username for the logged in account; must be a Google account.
* @param password the password for the username specified
* @param googleAccountType the account type to log into (e.g. @gmail.com accounts use "mail")
*/
public void addGoogleAccountToOs(String username, String password, String googleAccountType) {
final Bundle options = new Bundle();
options.putString(USERNAME, username);
options.putString(PASSWORD, password);
options.putBoolean(ALLOW_SKIP, true);
AuthenticationCallback authCallback = new AuthenticationCallback();
mAccountManager.addAccount(GOOGLE_ACCOUNT_TYPE, googleAccountType, null, options, null,
authCallback, null);
Bundle authResult = authCallback.waitForAuthCompletion();
if (authResult.containsKey(AccountManager.KEY_ERROR_CODE)) {
throw new IllegalStateException(String.format("AddAccount failed. Reason: %s",
authResult.get(AccountManager.KEY_ERROR_MESSAGE)));
}
}
/**
* Checks to see if an existing Google account is on OS.
*
* @param username the username of the account you want to check if signed in
* @return {@code true} if one or more Google accounts exists on OS, {@code false} otherwise
*/
public boolean isExistingGoogleAccountOnOs(String username) {
if (mAccountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE).length == 0) {
return false;
}
for (Account acct : mAccountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE)) {
if (username.equals(acct.name)) {
return true;
}
}
return false;
}
/**
* Removes all Google accounts from the OS.
*/
public void removeAllGoogleAccountsFromOs() {
for (Account acct : mAccountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE)) {
mAccountManager.removeAccount(acct, null, null);
}
}
/**
* Helper class for adding Google accounts to OS.
*
* Usage: Use this as the callback parameter when using {@link addAccount} in
* {@link android.accounts.AccountManager}.
*/
private static class AuthenticationCallback implements AccountManagerCallback<Bundle> {
private final Object mAuthenticationCompletionLock = new Object();
/** Stores the result of account authentication. Null means not finished. */
private Bundle mResultBundle = null;
/**
* Block and wait for the authentication callback to complete.
*
* @return the {@link Bundle} result from the authentication.
*/
public Bundle waitForAuthCompletion() {
synchronized (mAuthenticationCompletionLock) {
while (mResultBundle == null) {
try {
mAuthenticationCompletionLock.wait();
} catch (InterruptedException e) {
// ignore
}
}
return mResultBundle;
}
}
public void run(AccountManagerFuture<Bundle> future) {
Bundle resultBundle;
try {
resultBundle = future.getResult();
} catch (OperationCanceledException e) {
resultBundle = buildExceptionBundle(e);
} catch (IOException e) {
resultBundle = buildExceptionBundle(e);
} catch (AuthenticatorException e) {
resultBundle = buildExceptionBundle(e);
}
synchronized (mAuthenticationCompletionLock) {
mResultBundle = resultBundle;
mAuthenticationCompletionLock.notify();
}
}
/**
* Create a result bundle for a given exception.
*
* @param e the exception to be made into a {@link Bundle}
* @return the {@link Bundle} for the given exception e.
*/
private Bundle buildExceptionBundle(Exception e) {
Bundle bundle = new Bundle();
bundle.putInt(AccountManager.KEY_ERROR_CODE,
AccountManager.ERROR_CODE_INVALID_RESPONSE);
bundle.putString(AccountManager.KEY_ERROR_MESSAGE, e.toString());
return bundle;
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment