Merge "Add a unittest to cover the retry of load escrow data"

This commit is contained in:
Tianjie Xu
2021-03-04 23:10:57 +00:00
committed by Gerrit Code Review
2 changed files with 67 additions and 5 deletions

View File

@@ -193,6 +193,17 @@ class RebootEscrowManager {
0);
}
public int getLoadEscrowDataRetryLimit() {
return DeviceConfig.getInt(DeviceConfig.NAMESPACE_OTA,
"load_escrow_data_retry_count", DEFAULT_LOAD_ESCROW_DATA_RETRY_COUNT);
}
public int getLoadEscrowDataRetryIntervalSeconds() {
return DeviceConfig.getInt(DeviceConfig.NAMESPACE_OTA,
"load_escrow_data_retry_interval_seconds",
DEFAULT_LOAD_ESCROW_DATA_RETRY_INTERVAL_SECONDS);
}
public void reportMetric(boolean success) {
// TODO(b/179105110) design error code; and report the true value for other fields.
FrameworkStatsLog.write(FrameworkStatsLog.REBOOT_ESCROW_RECOVERY_REPORTED, 0, 1, 1,
@@ -251,11 +262,8 @@ class RebootEscrowManager {
List<UserInfo> users, List<UserInfo> rebootEscrowUsers) {
Objects.requireNonNull(retryHandler);
final int retryLimit = DeviceConfig.getInt(DeviceConfig.NAMESPACE_OTA,
"load_escrow_data_retry_count", DEFAULT_LOAD_ESCROW_DATA_RETRY_COUNT);
final int retryIntervalInSeconds = DeviceConfig.getInt(DeviceConfig.NAMESPACE_OTA,
"load_escrow_data_retry_interval_seconds",
DEFAULT_LOAD_ESCROW_DATA_RETRY_INTERVAL_SECONDS);
final int retryLimit = mInjector.getLoadEscrowDataRetryLimit();
final int retryIntervalInSeconds = mInjector.getLoadEscrowDataRetryIntervalSeconds();
if (attemptNumber < retryLimit) {
Slog.i(TAG, "Scheduling loadRebootEscrowData retry number: " + attemptNumber);

View File

@@ -44,6 +44,7 @@ import android.content.ContextWrapper;
import android.content.pm.UserInfo;
import android.hardware.rebootescrow.IRebootEscrow;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.os.UserManager;
@@ -62,6 +63,7 @@ import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.crypto.SecretKey;
@@ -180,6 +182,18 @@ public class RebootEscrowManagerTests {
return mInjected.getBootCount();
}
@Override
public int getLoadEscrowDataRetryLimit() {
// Try two times
return 2;
}
@Override
public int getLoadEscrowDataRetryIntervalSeconds() {
// Retry in 1 seconds
return 1;
}
@Override
public void reportMetric(boolean success) {
mInjected.reportMetric(success);
@@ -447,6 +461,46 @@ public class RebootEscrowManagerTests {
verify(mKeyStoreManager).clearKeyStoreEncryptionKey();
}
@Test
public void loadRebootEscrowDataIfAvailable_ServerBased_RetrySuccess() throws Exception {
setServerBasedRebootEscrowProvider();
when(mInjected.getBootCount()).thenReturn(0);
RebootEscrowListener mockListener = mock(RebootEscrowListener.class);
mService.setRebootEscrowListener(mockListener);
mService.prepareRebootEscrow();
clearInvocations(mServiceConnection);
mService.callToRebootEscrowIfNeeded(PRIMARY_USER_ID, FAKE_SP_VERSION, FAKE_AUTH_TOKEN);
verify(mockListener).onPreparedForReboot(eq(true));
verify(mServiceConnection, never()).wrapBlob(any(), anyLong(), anyLong());
// Use x -> x for both wrap & unwrap functions.
when(mServiceConnection.wrapBlob(any(), anyLong(), anyLong()))
.thenAnswer(invocation -> invocation.getArgument(0));
assertTrue(mService.armRebootEscrowIfNeeded());
verify(mServiceConnection).wrapBlob(any(), anyLong(), anyLong());
assertTrue(mStorage.hasRebootEscrowServerBlob());
// pretend reboot happens here
when(mInjected.getBootCount()).thenReturn(1);
ArgumentCaptor<Boolean> metricsSuccessCaptor = ArgumentCaptor.forClass(Boolean.class);
doNothing().when(mInjected).reportMetric(metricsSuccessCaptor.capture());
when(mServiceConnection.unwrap(any(), anyLong()))
.thenThrow(new IOException())
.thenAnswer(invocation -> invocation.getArgument(0));
HandlerThread thread = new HandlerThread("RebootEscrowManagerTest");
thread.start();
mService.loadRebootEscrowDataIfAvailable(new Handler(thread.getLooper()));
// Sleep 5s for the retry to complete
Thread.sleep(5 * 1000);
verify(mServiceConnection, times(2)).unwrap(any(), anyLong());
assertTrue(metricsSuccessCaptor.getValue());
verify(mKeyStoreManager).clearKeyStoreEncryptionKey();
}
@Test
public void loadRebootEscrowDataIfAvailable_TooManyBootsInBetween_NoMetrics() throws Exception {
when(mInjected.getBootCount()).thenReturn(0);