diff options
author | Vikram Gaur <vikramgaur@google.com> | 2024-04-02 21:49:32 +0000 |
---|---|---|
committer | Vikram Gaur <vikramgaur@google.com> | 2024-04-03 00:42:20 +0000 |
commit | 60d19de97b672158e19ba74c9291c8e145eee490 (patch) | |
tree | 291344306506170e9d78b1285ac4646654c53c34 | |
parent | 7d37101b50d2f0c8be9406ed15319d403e168803 (diff) | |
download | RemoteKeyProvisioning-60d19de97b672158e19ba74c9291c8e145eee490.tar.gz |
Fix unit tests to avoid failures when no network is present.
Although unit tests do not actually make any real network calls, network
check happens before making calls to the fake server. This causes
unintentional failures. With this change, we fake the connection signal
so that unit tests can simply make the calls without actually failing
due to missing network.
Test: atest RkpdAppUnitTests after enabling/disabling network
Bug: 332583967
Change-Id: Ifc26c32a77a87a1dfca07f3bb33c4dfdd6cd374a
3 files changed, 57 insertions, 48 deletions
diff --git a/app/tests/unit/src/com/android/rkpdapp/unittest/PeriodicProvisionerTests.java b/app/tests/unit/src/com/android/rkpdapp/unittest/PeriodicProvisionerTests.java index 0bccd28..b726aeb 100644 --- a/app/tests/unit/src/com/android/rkpdapp/unittest/PeriodicProvisionerTests.java +++ b/app/tests/unit/src/com/android/rkpdapp/unittest/PeriodicProvisionerTests.java @@ -53,8 +53,10 @@ import com.android.rkpdapp.utils.Settings; import org.junit.After; import org.junit.Assume; import org.junit.Before; +import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.Mockito; import java.time.Duration; import java.time.Instant; @@ -70,37 +72,41 @@ public class PeriodicProvisionerTests { private static final RkpKey FAKE_RKP_KEY = new RkpKey(new byte[1], new byte[2], new Array(), "fake-hal", new byte[3]); + private static Context sContext; private PeriodicProvisioner mProvisioner; - private Context mContext; + + @BeforeClass + public static void init() { + sContext = Mockito.spy(ApplicationProvider.getApplicationContext()); + } @Before public void setUp() { - mContext = ApplicationProvider.getApplicationContext(); - Assume.assumeFalse(Settings.getDefaultUrl().isEmpty()); - RkpdDatabase.getDatabase(mContext).provisionedKeyDao().deleteAllKeys(); + RkpdDatabase.getDatabase(sContext).provisionedKeyDao().deleteAllKeys(); mProvisioner = TestWorkerBuilder.from( - mContext, + sContext, PeriodicProvisioner.class, Executors.newSingleThreadExecutor()).build(); Configuration config = new Configuration.Builder() .setExecutor(new SynchronousExecutor()) .build(); - WorkManagerTestInitHelper.initializeTestWorkManager(mContext, config); - Settings.clearPreferences(mContext); + WorkManagerTestInitHelper.initializeTestWorkManager(sContext, config); + Settings.clearPreferences(sContext); + Utils.mockConnectivityState(sContext, Utils.ConnectivityState.CONNECTED); } @After public void tearDown() { - RkpdDatabase.getDatabase(mContext).provisionedKeyDao().deleteAllKeys(); + RkpdDatabase.getDatabase(sContext).provisionedKeyDao().deleteAllKeys(); ServiceManagerInterface.setInstances(null); - Settings.clearPreferences(mContext); + Settings.clearPreferences(sContext); } private WorkInfo getProvisionerWorkInfo() throws ExecutionException, InterruptedException { - WorkManager workManager = WorkManager.getInstance(mContext); + WorkManager workManager = WorkManager.getInstance(sContext); List<WorkInfo> infos = workManager.getWorkInfosForUniqueWork( PeriodicProvisioner.UNIQUE_WORK_NAME).get(); assertThat(infos.size()).isEqualTo(1); @@ -110,20 +116,20 @@ public class PeriodicProvisionerTests { @Test public void provisionWithNoHals() throws Exception { // setup work with boot receiver - new BootReceiver().onReceive(mContext, null); + new BootReceiver().onReceive(sContext, null); WorkInfo worker = getProvisionerWorkInfo(); assertThat(worker.getState()).isEqualTo(WorkInfo.State.ENQUEUED); ServiceManagerInterface.setInstances(new SystemInterface[0]); - WorkManagerTestInitHelper.getTestDriver(mContext).setAllConstraintsMet(worker.getId()); + WorkManagerTestInitHelper.getTestDriver(sContext).setAllConstraintsMet(worker.getId()); // the worker should uninstall itself once it realizes it's not needed on this system worker = getProvisionerWorkInfo(); assertThat(worker.getState()).isEqualTo(WorkInfo.State.CANCELLED); // verify the worker doesn't run again - WorkManagerTestInitHelper.getTestDriver(mContext).setAllConstraintsMet(worker.getId()); + WorkManagerTestInitHelper.getTestDriver(sContext).setAllConstraintsMet(worker.getId()); worker = getProvisionerWorkInfo(); assertThat(worker.getState()).isEqualTo(WorkInfo.State.CANCELLED); } @@ -131,14 +137,14 @@ public class PeriodicProvisionerTests { @Test public void provisionWithNoHostNameWithoutServerUrl() throws Exception { // setup work with boot receiver - new BootReceiver().onReceive(mContext, null); + new BootReceiver().onReceive(sContext, null); try (SystemPropertySetter ignored = SystemPropertySetter.setHostname("")) { SystemInterface mockHal = mock(SystemInterface.class); ServiceManagerInterface.setInstances(new SystemInterface[]{mockHal}); WorkInfo worker = getProvisionerWorkInfo(); - WorkManagerTestInitHelper.getTestDriver(mContext).setAllConstraintsMet(worker.getId()); + WorkManagerTestInitHelper.getTestDriver(sContext).setAllConstraintsMet(worker.getId()); } WorkInfo worker = getProvisionerWorkInfo(); @@ -148,16 +154,16 @@ public class PeriodicProvisionerTests { @Test public void provisionWithNoHostNameWithServerUrl() throws Exception { // setup work with boot receiver - new BootReceiver().onReceive(mContext, null); + new BootReceiver().onReceive(sContext, null); try (SystemPropertySetter ignored = SystemPropertySetter.setHostname("")) { SystemInterface mockHal = mock(SystemInterface.class); ServiceManagerInterface.setInstances(new SystemInterface[]{mockHal}); - Settings.setDeviceConfig(mContext, Settings.EXTRA_SIGNED_KEYS_AVAILABLE_DEFAULT, + Settings.setDeviceConfig(sContext, Settings.EXTRA_SIGNED_KEYS_AVAILABLE_DEFAULT, Duration.ofDays(3), "https://notsure.whetherthisworks.combutjustincase"); WorkInfo worker = getProvisionerWorkInfo(); - WorkManagerTestInitHelper.getTestDriver(mContext).setAllConstraintsMet(worker.getId()); + WorkManagerTestInitHelper.getTestDriver(sContext).setAllConstraintsMet(worker.getId()); } WorkInfo worker = getProvisionerWorkInfo(); @@ -186,7 +192,7 @@ public class PeriodicProvisionerTests { FakeRkpServer.Response.INTERNAL_ERROR, FakeRkpServer.Response.SIGN_CERTS_OK_VALID_CBOR)) { saveUrlInSettings(fakeRkpServer); - Settings.setMaxRequestTime(mContext, 100); + Settings.setMaxRequestTime(sContext, 100); SystemInterface mockHal = mock(SystemInterface.class); ServiceManagerInterface.setInstances(new SystemInterface[]{mockHal}); assertThat(mProvisioner.doWork()).isEqualTo(ListenableWorker.Result.failure()); @@ -198,7 +204,7 @@ public class PeriodicProvisionerTests { @Test public void fetchEekDisablesRkp() throws Exception { - ProvisionedKeyDao dao = RkpdDatabase.getDatabase(mContext).provisionedKeyDao(); + ProvisionedKeyDao dao = RkpdDatabase.getDatabase(sContext).provisionedKeyDao(); ProvisionedKey fakeKey = new ProvisionedKey(new byte[42], "fake-irpc", new byte[3], new byte[2], Instant.now().plusSeconds(120)); dao.insertKeys(List.of(fakeKey)); @@ -222,7 +228,7 @@ public class PeriodicProvisionerTests { @Test public void provisioningExpiresOldKeys() throws Exception { - ProvisionedKeyDao dao = RkpdDatabase.getDatabase(mContext).provisionedKeyDao(); + ProvisionedKeyDao dao = RkpdDatabase.getDatabase(sContext).provisionedKeyDao(); ProvisionedKey oldKey = new ProvisionedKey(new byte[1], "fake-irpc", new byte[2], new byte[3], Instant.now().minus(RegistrationBinder.MIN_KEY_LIFETIME.multipliedBy(2))); @@ -324,6 +330,6 @@ public class PeriodicProvisionerTests { } private void saveUrlInSettings(FakeRkpServer server) { - Settings.setDeviceConfig(mContext, 1, Duration.ofSeconds(10), server.getUrl()); + Settings.setDeviceConfig(sContext, 1, Duration.ofSeconds(10), server.getUrl()); } } diff --git a/app/tests/unit/src/com/android/rkpdapp/unittest/ServerInterfaceTest.java b/app/tests/unit/src/com/android/rkpdapp/unittest/ServerInterfaceTest.java index ed1f64a..12ab92d 100644 --- a/app/tests/unit/src/com/android/rkpdapp/unittest/ServerInterfaceTest.java +++ b/app/tests/unit/src/com/android/rkpdapp/unittest/ServerInterfaceTest.java @@ -22,8 +22,6 @@ import static com.google.common.truth.Truth.assertWithMessage; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.NetworkCapabilities; import android.util.Base64; import androidx.test.core.app.ApplicationProvider; @@ -64,6 +62,7 @@ public class ServerInterfaceTest { public void setUp() { Settings.clearPreferences(sContext); mServerInterface = new ServerInterface(sContext, false); + Utils.mockConnectivityState(sContext, Utils.ConnectivityState.CONNECTED); } @After @@ -243,9 +242,6 @@ public class ServerInterfaceTest { ProvisioningAttempt metrics = ProvisioningAttempt.createScheduledAttemptMetrics( sContext); - // We are okay in mocking connectivity failure since err data budget is the first thing - // to be checked. - mockConnectivityFailure(ConnectivityState.CONNECTED); mServerInterface.fetchGeek(metrics); assertWithMessage("Network transaction should not have proceeded.").fail(); } catch (RkpdException e) { @@ -268,7 +264,7 @@ public class ServerInterfaceTest { // We are okay in mocking connectivity failure since network check is the first thing // to happen. - mockConnectivityFailure(ConnectivityState.DISCONNECTED); + Utils.mockConnectivityState(sContext, Utils.ConnectivityState.DISCONNECTED); mServerInterface.fetchGeek(metrics); assertWithMessage("Network transaction should not have proceeded.").fail(); } catch (RkpdException e) { @@ -440,24 +436,4 @@ public class ServerInterfaceTest { fakeApplicationInfo.enabled = false; assertThat(ServerInterface.assumeNetworkConsent(mockedContext)).isTrue(); } - - private void mockConnectivityFailure(ConnectivityState state) { - ConnectivityManager mockedConnectivityManager = Mockito.mock(ConnectivityManager.class); - - Mockito.when(sContext.getSystemService(ConnectivityManager.class)) - .thenReturn(mockedConnectivityManager); - NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder(); - builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); - if (state == ConnectivityState.CONNECTED) { - builder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); - } - Mockito.when(mockedConnectivityManager.getNetworkCapabilities(Mockito.any())) - .thenReturn(builder.build()); - } - - private enum ConnectivityState { - DISCONNECTED, - CONNECTED - } - } diff --git a/app/tests/unit/src/com/android/rkpdapp/unittest/Utils.java b/app/tests/unit/src/com/android/rkpdapp/unittest/Utils.java index bbce2d9..320f572 100644 --- a/app/tests/unit/src/com/android/rkpdapp/unittest/Utils.java +++ b/app/tests/unit/src/com/android/rkpdapp/unittest/Utils.java @@ -20,6 +20,10 @@ package com.android.rkpdapp.unittest; import static com.google.crypto.tink.subtle.EllipticCurves.EcdsaEncoding.IEEE_P1363; import static com.google.crypto.tink.subtle.Enums.HashType.SHA256; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkCapabilities; + import com.google.crypto.tink.subtle.EcdsaSignJce; import com.google.crypto.tink.subtle.Ed25519Sign; import com.google.crypto.tink.subtle.EllipticCurves; @@ -28,6 +32,7 @@ import org.bouncycastle.asn1.x509.BasicConstraints; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.x509.X509V3CertificateGenerator; +import org.mockito.Mockito; import java.io.ByteArrayOutputStream; import java.math.BigInteger; @@ -292,4 +297,26 @@ public class Utils { .build()); return baos.toByteArray(); } + + /** + * Mocks out the connectivity status for unit tests. + */ + public static void mockConnectivityState(Context context, ConnectivityState state) { + ConnectivityManager mockedConnectivityManager = Mockito.mock(ConnectivityManager.class); + + Mockito.when(context.getSystemService(ConnectivityManager.class)) + .thenReturn(mockedConnectivityManager); + NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder(); + builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET); + if (state == ConnectivityState.CONNECTED) { + builder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED); + } + Mockito.when(mockedConnectivityManager.getNetworkCapabilities(Mockito.any())) + .thenReturn(builder.build()); + } + + public enum ConnectivityState { + DISCONNECTED, + CONNECTED + } } |