Merge changes Id6ae7929,I70474ef5,I4958df65,Ifc0e1ba2

* changes:
  ethernet: remove callback from factory updateInterfaceLinkState
  ethernet: updateConfiguration result should not rely on ip provisioning
  ethernet: remove callback boilerplate from EthernetNetworkFactory
  ethernet: add EthernetCallback class to wrap OutcomeReceiver
This commit is contained in:
Patrick Rohr
2022-08-24 17:45:04 +00:00
committed by Gerrit Code Review
7 changed files with 147 additions and 289 deletions

View File

@@ -20,7 +20,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
@@ -38,9 +37,7 @@ import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.content.Context;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.EthernetNetworkManagementException;
import android.net.EthernetNetworkSpecifier;
import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.IpConfiguration;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -55,7 +52,6 @@ import android.net.ip.IpClientCallbacks;
import android.net.ip.IpClientManager;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.test.TestLooper;
@@ -74,9 +70,6 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@SmallTest
@RunWith(DevSdkIgnoreRunner.class)
@@ -84,7 +77,6 @@ import java.util.concurrent.TimeUnit;
public class EthernetNetworkFactoryTest {
private static final int TIMEOUT_MS = 2_000;
private static final String TEST_IFACE = "test123";
private static final INetworkInterfaceOutcomeReceiver NULL_LISTENER = null;
private static final String IP_ADDR = "192.0.2.2/25";
private static final LinkAddress LINK_ADDR = new LinkAddress(IP_ADDR);
private static final String HW_ADDR = "01:02:03:04:05:06";
@@ -241,7 +233,7 @@ public class EthernetNetworkFactoryTest {
final IpConfiguration ipConfig = createDefaultIpConfig();
mNetFactory.addInterface(iface, HW_ADDR, ipConfig,
createInterfaceCapsBuilder(transportType).build());
assertTrue(mNetFactory.updateInterfaceLinkState(iface, true, NULL_LISTENER));
assertTrue(mNetFactory.updateInterfaceLinkState(iface, true));
ArgumentCaptor<NetworkOfferCallback> captor = ArgumentCaptor.forClass(
NetworkOfferCallback.class);
@@ -295,7 +287,7 @@ public class EthernetNetworkFactoryTest {
// then calling onNetworkUnwanted.
mNetFactory.addInterface(iface, HW_ADDR, createDefaultIpConfig(),
createInterfaceCapsBuilder(NetworkCapabilities.TRANSPORT_ETHERNET).build());
assertTrue(mNetFactory.updateInterfaceLinkState(iface, true, NULL_LISTENER));
assertTrue(mNetFactory.updateInterfaceLinkState(iface, true));
clearInvocations(mIpClient);
clearInvocations(mNetworkAgent);
@@ -305,81 +297,63 @@ public class EthernetNetworkFactoryTest {
public void testUpdateInterfaceLinkStateForActiveProvisioningInterface() throws Exception {
initEthernetNetworkFactory();
createInterfaceUndergoingProvisioning(TEST_IFACE);
final TestNetworkManagementListener listener = new TestNetworkManagementListener();
// verify that the IpClient gets shut down when interface state changes to down.
final boolean ret =
mNetFactory.updateInterfaceLinkState(TEST_IFACE, false /* up */, listener);
final boolean ret = mNetFactory.updateInterfaceLinkState(TEST_IFACE, false /* up */);
assertTrue(ret);
verify(mIpClient).shutdown();
assertEquals(TEST_IFACE, listener.expectOnResult());
}
@Test
public void testUpdateInterfaceLinkStateForProvisionedInterface() throws Exception {
initEthernetNetworkFactory();
createAndVerifyProvisionedInterface(TEST_IFACE);
final TestNetworkManagementListener listenerDown = new TestNetworkManagementListener();
final TestNetworkManagementListener listenerUp = new TestNetworkManagementListener();
final boolean retDown =
mNetFactory.updateInterfaceLinkState(TEST_IFACE, false /* up */, listenerDown);
final boolean retDown = mNetFactory.updateInterfaceLinkState(TEST_IFACE, false /* up */);
assertTrue(retDown);
verifyStop();
assertEquals(TEST_IFACE, listenerDown.expectOnResult());
final boolean retUp =
mNetFactory.updateInterfaceLinkState(TEST_IFACE, true /* up */, listenerUp);
final boolean retUp = mNetFactory.updateInterfaceLinkState(TEST_IFACE, true /* up */);
assertTrue(retUp);
assertEquals(TEST_IFACE, listenerUp.expectOnResult());
}
@Test
public void testUpdateInterfaceLinkStateForUnprovisionedInterface() throws Exception {
initEthernetNetworkFactory();
createUnprovisionedInterface(TEST_IFACE);
final TestNetworkManagementListener listener = new TestNetworkManagementListener();
final boolean ret =
mNetFactory.updateInterfaceLinkState(TEST_IFACE, false /* up */, listener);
final boolean ret = mNetFactory.updateInterfaceLinkState(TEST_IFACE, false /* up */);
assertTrue(ret);
// There should not be an active IPClient or NetworkAgent.
verify(mDeps, never()).makeIpClient(any(), any(), any());
verify(mDeps, never())
.makeEthernetNetworkAgent(any(), any(), any(), any(), any(), any(), any());
assertEquals(TEST_IFACE, listener.expectOnResult());
}
@Test
public void testUpdateInterfaceLinkStateForNonExistingInterface() throws Exception {
initEthernetNetworkFactory();
final TestNetworkManagementListener listener = new TestNetworkManagementListener();
// if interface was never added, link state cannot be updated.
final boolean ret =
mNetFactory.updateInterfaceLinkState(TEST_IFACE, true /* up */, listener);
final boolean ret = mNetFactory.updateInterfaceLinkState(TEST_IFACE, true /* up */);
assertFalse(ret);
verifyNoStopOrStart();
listener.expectOnError();
}
@Test
public void testUpdateInterfaceLinkStateWithNoChanges() throws Exception {
initEthernetNetworkFactory();
createAndVerifyProvisionedInterface(TEST_IFACE);
final TestNetworkManagementListener listener = new TestNetworkManagementListener();
final boolean ret =
mNetFactory.updateInterfaceLinkState(TEST_IFACE, true /* up */, listener);
final boolean ret = mNetFactory.updateInterfaceLinkState(TEST_IFACE, true /* up */);
assertFalse(ret);
verifyNoStopOrStart();
listener.expectOnError();
}
@Test
@@ -571,127 +545,16 @@ public class EthernetNetworkFactoryTest {
verify(mNetworkAgent).markConnected();
}
private static final class TestNetworkManagementListener
implements INetworkInterfaceOutcomeReceiver {
private final CompletableFuture<String> mResult = new CompletableFuture<>();
@Override
public void onResult(@NonNull String iface) {
mResult.complete(iface);
}
@Override
public void onError(@NonNull EthernetNetworkManagementException exception) {
mResult.completeExceptionally(exception);
}
String expectOnResult() throws Exception {
return mResult.get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
}
void expectOnError() throws Exception {
assertThrows(EthernetNetworkManagementException.class, () -> {
try {
mResult.get();
} catch (ExecutionException e) {
throw e.getCause();
}
});
}
@Override
public IBinder asBinder() {
return null;
}
}
@Test
public void testUpdateInterfaceCallsListenerCorrectlyOnSuccess() throws Exception {
initEthernetNetworkFactory();
createAndVerifyProvisionedInterface(TEST_IFACE);
final NetworkCapabilities capabilities = createDefaultFilterCaps();
final IpConfiguration ipConfiguration = createStaticIpConfig();
final TestNetworkManagementListener listener = new TestNetworkManagementListener();
mNetFactory.updateInterface(TEST_IFACE, ipConfiguration, capabilities, listener);
triggerOnProvisioningSuccess();
assertEquals(TEST_IFACE, listener.expectOnResult());
}
@Test
public void testUpdateInterfaceAbortsOnConcurrentRemoveInterface() throws Exception {
initEthernetNetworkFactory();
verifyNetworkManagementCallIsAbortedWhenInterrupted(
TEST_IFACE,
() -> mNetFactory.removeInterface(TEST_IFACE));
}
@Test
public void testUpdateInterfaceAbortsOnConcurrentUpdateInterfaceLinkState() throws Exception {
initEthernetNetworkFactory();
verifyNetworkManagementCallIsAbortedWhenInterrupted(
TEST_IFACE,
() -> mNetFactory.updateInterfaceLinkState(TEST_IFACE, false, NULL_LISTENER));
}
@Test
public void testUpdateInterfaceAbortsOnNetworkUneededRemovesAllRequests() throws Exception {
initEthernetNetworkFactory();
verifyNetworkManagementCallIsAbortedWhenInterrupted(
TEST_IFACE,
() -> mNetworkOfferCallback.onNetworkUnneeded(mRequestToKeepNetworkUp));
}
@Test
public void testUpdateInterfaceCallsListenerCorrectlyOnConcurrentRequests() throws Exception {
initEthernetNetworkFactory();
final NetworkCapabilities capabilities = createDefaultFilterCaps();
final IpConfiguration ipConfiguration = createStaticIpConfig();
final TestNetworkManagementListener successfulListener =
new TestNetworkManagementListener();
// If two calls come in before the first one completes, the first listener will be aborted
// and the second one will be successful.
verifyNetworkManagementCallIsAbortedWhenInterrupted(
TEST_IFACE,
() -> {
mNetFactory.updateInterface(
TEST_IFACE, ipConfiguration, capabilities, successfulListener);
triggerOnProvisioningSuccess();
});
assertEquals(successfulListener.expectOnResult(), TEST_IFACE);
assertEquals(TEST_IFACE, successfulListener.expectOnResult());
}
private void verifyNetworkManagementCallIsAbortedWhenInterrupted(
@NonNull final String iface,
@NonNull final Runnable interruptingRunnable) throws Exception {
createAndVerifyProvisionedInterface(iface);
final NetworkCapabilities capabilities = createDefaultFilterCaps();
final IpConfiguration ipConfiguration = createStaticIpConfig();
final TestNetworkManagementListener failedListener = new TestNetworkManagementListener();
// An active update request will be aborted on interrupt prior to provisioning completion.
mNetFactory.updateInterface(iface, ipConfiguration, capabilities, failedListener);
interruptingRunnable.run();
failedListener.expectOnError();
}
@Test
public void testUpdateInterfaceRestartsAgentCorrectly() throws Exception {
initEthernetNetworkFactory();
createAndVerifyProvisionedInterface(TEST_IFACE);
final NetworkCapabilities capabilities = createDefaultFilterCaps();
final IpConfiguration ipConfiguration = createStaticIpConfig();
final TestNetworkManagementListener listener = new TestNetworkManagementListener();
mNetFactory.updateInterface(TEST_IFACE, ipConfiguration, capabilities, listener);
mNetFactory.updateInterface(TEST_IFACE, ipConfiguration, capabilities);
triggerOnProvisioningSuccess();
assertEquals(TEST_IFACE, listener.expectOnResult());
verify(mDeps).makeEthernetNetworkAgent(any(), any(),
eq(capabilities), any(), any(), any(), any());
verifyRestart(ipConfiguration);
@@ -703,12 +566,10 @@ public class EthernetNetworkFactoryTest {
// No interface exists due to not calling createAndVerifyProvisionedInterface(...).
final NetworkCapabilities capabilities = createDefaultFilterCaps();
final IpConfiguration ipConfiguration = createStaticIpConfig();
final TestNetworkManagementListener listener = new TestNetworkManagementListener();
mNetFactory.updateInterface(TEST_IFACE, ipConfiguration, capabilities, listener);
mNetFactory.updateInterface(TEST_IFACE, ipConfiguration, capabilities);
verifyNoStopOrStart();
listener.expectOnError();
}
@Test
@@ -717,8 +578,8 @@ public class EthernetNetworkFactoryTest {
createAndVerifyProvisionedInterface(TEST_IFACE);
final IpConfiguration initialIpConfig = createStaticIpConfig();
mNetFactory.updateInterface(TEST_IFACE, initialIpConfig, null /*capabilities*/,
null /*listener*/);
mNetFactory.updateInterface(TEST_IFACE, initialIpConfig, null /*capabilities*/);
triggerOnProvisioningSuccess();
verifyRestart(initialIpConfig);
@@ -729,8 +590,7 @@ public class EthernetNetworkFactoryTest {
// verify that sending a null ipConfig does not update the current ipConfig.
mNetFactory.updateInterface(TEST_IFACE, null /*ipConfig*/, null /*capabilities*/,
null /*listener*/);
mNetFactory.updateInterface(TEST_IFACE, null /*ipConfig*/, null /*capabilities*/);
triggerOnProvisioningSuccess();
verifyRestart(initialIpConfig);
}
@@ -739,7 +599,7 @@ public class EthernetNetworkFactoryTest {
public void testOnNetworkNeededOnStaleNetworkOffer() throws Exception {
initEthernetNetworkFactory();
createAndVerifyProvisionedInterface(TEST_IFACE);
mNetFactory.updateInterfaceLinkState(TEST_IFACE, false, null);
mNetFactory.updateInterfaceLinkState(TEST_IFACE, false);
verify(mNetworkProvider).unregisterNetworkOffer(mNetworkOfferCallback);
// It is possible that even after a network offer is unregistered, CS still sends it
// onNetworkNeeded() callbacks.

View File

@@ -21,6 +21,7 @@ import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
@@ -209,7 +210,8 @@ public class EthernetServiceImplTest {
NULL_LISTENER);
verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE),
eq(UPDATE_REQUEST_WITHOUT_CAPABILITIES.getIpConfiguration()),
eq(UPDATE_REQUEST_WITHOUT_CAPABILITIES.getNetworkCapabilities()), isNull());
eq(UPDATE_REQUEST_WITHOUT_CAPABILITIES.getNetworkCapabilities()),
any(EthernetCallback.class));
}
private void denyManageEthPermission() {
@@ -285,7 +287,8 @@ public class EthernetServiceImplTest {
verify(mEthernetTracker).updateConfiguration(
eq(TEST_IFACE),
eq(UPDATE_REQUEST.getIpConfiguration()),
eq(UPDATE_REQUEST.getNetworkCapabilities()), eq(NULL_LISTENER));
eq(UPDATE_REQUEST.getNetworkCapabilities()),
any(EthernetCallback.class));
}
@Test
@@ -303,19 +306,20 @@ public class EthernetServiceImplTest {
verify(mEthernetTracker).updateConfiguration(
eq(TEST_IFACE),
isNull(),
eq(ncWithSpecifier), eq(NULL_LISTENER));
eq(ncWithSpecifier), any(EthernetCallback.class));
}
@Test
public void testEnableInterface() {
mEthernetServiceImpl.enableInterface(TEST_IFACE, NULL_LISTENER);
verify(mEthernetTracker).enableInterface(eq(TEST_IFACE), eq(NULL_LISTENER));
verify(mEthernetTracker).enableInterface(eq(TEST_IFACE),
any(EthernetCallback.class));
}
@Test
public void testDisableInterface() {
mEthernetServiceImpl.disableInterface(TEST_IFACE, NULL_LISTENER);
verify(mEthernetTracker).disableInterface(eq(TEST_IFACE), eq(NULL_LISTENER));
verify(mEthernetTracker).disableInterface(eq(TEST_IFACE), any(EthernetCallback.class));
}
@Test
@@ -328,7 +332,7 @@ public class EthernetServiceImplTest {
mEthernetServiceImpl.updateConfiguration(TEST_IFACE, request, NULL_LISTENER);
verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE),
eq(request.getIpConfiguration()),
eq(request.getNetworkCapabilities()), isNull());
eq(request.getNetworkCapabilities()), any(EthernetCallback.class));
}
@Test
@@ -337,7 +341,8 @@ public class EthernetServiceImplTest {
NULL_LISTENER);
verify(mEthernetTracker).updateConfiguration(eq(TEST_IFACE),
eq(UPDATE_REQUEST_WITHOUT_IP_CONFIG.getIpConfiguration()),
eq(UPDATE_REQUEST_WITHOUT_IP_CONFIG.getNetworkCapabilities()), isNull());
eq(UPDATE_REQUEST_WITHOUT_IP_CONFIG.getNetworkCapabilities()),
any(EthernetCallback.class));
}
@Test
@@ -369,7 +374,7 @@ public class EthernetServiceImplTest {
verify(mEthernetTracker).updateConfiguration(
eq(TEST_IFACE),
eq(request.getIpConfiguration()),
eq(request.getNetworkCapabilities()), eq(NULL_LISTENER));
eq(request.getNetworkCapabilities()), any(EthernetCallback.class));
}
@Test
@@ -379,7 +384,8 @@ public class EthernetServiceImplTest {
denyManageEthPermission();
mEthernetServiceImpl.enableInterface(TEST_IFACE, NULL_LISTENER);
verify(mEthernetTracker).enableInterface(eq(TEST_IFACE), eq(NULL_LISTENER));
verify(mEthernetTracker).enableInterface(eq(TEST_IFACE),
any(EthernetCallback.class));
}
@Test
@@ -389,7 +395,8 @@ public class EthernetServiceImplTest {
denyManageEthPermission();
mEthernetServiceImpl.disableInterface(TEST_IFACE, NULL_LISTENER);
verify(mEthernetTracker).disableInterface(eq(TEST_IFACE), eq(NULL_LISTENER));
verify(mEthernetTracker).disableInterface(eq(TEST_IFACE),
any(EthernetCallback.class));
}
private void denyPermissions(String... permissions) {

View File

@@ -39,7 +39,6 @@ import android.content.Context;
import android.net.EthernetManager;
import android.net.IEthernetServiceListener;
import android.net.INetd;
import android.net.INetworkInterfaceOutcomeReceiver;
import android.net.InetAddresses;
import android.net.InterfaceConfigurationParcel;
import android.net.IpConfiguration;
@@ -76,7 +75,7 @@ public class EthernetTrackerTest {
private static final String TEST_IFACE = "test123";
private static final int TIMEOUT_MS = 1_000;
private static final String THREAD_NAME = "EthernetServiceThread";
private static final INetworkInterfaceOutcomeReceiver NULL_LISTENER = null;
private static final EthernetCallback NULL_CB = new EthernetCallback(null);
private EthernetTracker tracker;
private HandlerThread mHandlerThread;
@Mock private Context mContext;
@@ -88,7 +87,7 @@ public class EthernetTrackerTest {
public void setUp() throws RemoteException {
MockitoAnnotations.initMocks(this);
initMockResources();
when(mFactory.updateInterfaceLinkState(anyString(), anyBoolean(), any())).thenReturn(false);
when(mFactory.updateInterfaceLinkState(anyString(), anyBoolean())).thenReturn(false);
when(mNetd.interfaceGetList()).thenReturn(new String[0]);
mHandlerThread = new HandlerThread(THREAD_NAME);
mHandlerThread.start();
@@ -344,31 +343,29 @@ public class EthernetTrackerTest {
new StaticIpConfiguration.Builder().setIpAddress(linkAddr).build();
final IpConfiguration ipConfig =
new IpConfiguration.Builder().setStaticIpConfiguration(staticIpConfig).build();
final INetworkInterfaceOutcomeReceiver listener = null;
final EthernetCallback listener = new EthernetCallback(null);
tracker.updateConfiguration(TEST_IFACE, ipConfig, capabilities, listener);
waitForIdle();
verify(mFactory).updateInterface(
eq(TEST_IFACE), eq(ipConfig), eq(capabilities), eq(listener));
eq(TEST_IFACE), eq(ipConfig), eq(capabilities));
}
@Test
public void testEnableInterfaceCorrectlyCallsFactory() {
tracker.enableInterface(TEST_IFACE, NULL_LISTENER);
tracker.enableInterface(TEST_IFACE, NULL_CB);
waitForIdle();
verify(mFactory).updateInterfaceLinkState(eq(TEST_IFACE), eq(true /* up */),
eq(NULL_LISTENER));
verify(mFactory).updateInterfaceLinkState(eq(TEST_IFACE), eq(true /* up */));
}
@Test
public void testDisableInterfaceCorrectlyCallsFactory() {
tracker.disableInterface(TEST_IFACE, NULL_LISTENER);
tracker.disableInterface(TEST_IFACE, NULL_CB);
waitForIdle();
verify(mFactory).updateInterfaceLinkState(eq(TEST_IFACE), eq(false /* up */),
eq(NULL_LISTENER));
verify(mFactory).updateInterfaceLinkState(eq(TEST_IFACE), eq(false /* up */));
}
@Test