Adding test coverage for eth transport overrides

Added test coverage regarding how EthernetTracker consumes the xml
config as set in config_ethernet_interfaces. Additionally, adding
test coverage for transport override functionality in
EthernetNetworkFactory.

Bug: 206170402
Test: atest com.android.server.ethernet.EthernetTrackerTest
&& atest com.android.server.ethernet.EthernetNetworkFactoryTest

Change-Id: I3d55a230d3f28154ed6fdac6d63ed57bf589d3bd
This commit is contained in:
James Mattis
2021-12-07 15:47:11 -08:00
parent 68c4a5108b
commit 2fc1c08cb5
3 changed files with 116 additions and 26 deletions

View File

@@ -18,6 +18,7 @@ package com.android.server.ethernet;
import static android.net.TestNetworkManager.TEST_TAP_PREFIX; import static android.net.TestNetworkManager.TEST_TAP_PREFIX;
import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.Context; import android.content.Context;
import android.net.IEthernetServiceListener; import android.net.IEthernetServiceListener;
@@ -453,21 +454,24 @@ final class EthernetTracker {
* <interface name|mac address>;[Network Capabilities];[IP config];[Override Transport]} * <interface name|mac address>;[Network Capabilities];[IP config];[Override Transport]}
*/ */
private void parseEthernetConfig(String configString) { private void parseEthernetConfig(String configString) {
String[] tokens = configString.split(";", /* limit of tokens */ 4); final EthernetTrackerConfig config = createEthernetTrackerConfig(configString);
String name = tokens[0];
String capabilities = tokens.length > 1 ? tokens[1] : null;
String transport = tokens.length > 3 ? tokens[3] : null;
NetworkCapabilities nc = createNetworkCapabilities( NetworkCapabilities nc = createNetworkCapabilities(
!TextUtils.isEmpty(capabilities) /* clear default capabilities */, capabilities, !TextUtils.isEmpty(config.mCapabilities) /* clear default capabilities */,
transport).build(); config.mCapabilities, config.mTransport).build();
mNetworkCapabilities.put(name, nc); mNetworkCapabilities.put(config.mName, nc);
if (tokens.length > 2 && !TextUtils.isEmpty(tokens[2])) { if (null != config.mIpConfig) {
IpConfiguration ipConfig = parseStaticIpConfiguration(tokens[2]); IpConfiguration ipConfig = parseStaticIpConfiguration(config.mIpConfig);
mIpConfigurations.put(name, ipConfig); mIpConfigurations.put(config.mName, ipConfig);
} }
} }
@VisibleForTesting
static EthernetTrackerConfig createEthernetTrackerConfig(@NonNull final String configString) {
Objects.requireNonNull(configString, "EthernetTrackerConfig requires non-null config");
return new EthernetTrackerConfig(configString.split(";", /* limit of tokens */ 4));
}
private static NetworkCapabilities createDefaultNetworkCapabilities(boolean isTestIface) { private static NetworkCapabilities createDefaultNetworkCapabilities(boolean isTestIface) {
NetworkCapabilities.Builder builder = createNetworkCapabilities( NetworkCapabilities.Builder builder = createNetworkCapabilities(
false /* clear default capabilities */, null, null) false /* clear default capabilities */, null, null)
@@ -672,4 +676,20 @@ final class EthernetTracker {
mFactory.dump(fd, pw, args); mFactory.dump(fd, pw, args);
}); });
} }
@VisibleForTesting
static class EthernetTrackerConfig {
final String mName;
final String mCapabilities;
final String mIpConfig;
final String mTransport;
EthernetTrackerConfig(@NonNull final String[] tokens) {
Objects.requireNonNull(tokens, "EthernetTrackerConfig requires non-null tokens");
mName = tokens[0];
mCapabilities = tokens.length > 1 ? tokens[1] : null;
mIpConfig = tokens.length > 2 && !TextUtils.isEmpty(tokens[2]) ? tokens[2] : null;
mTransport = tokens.length > 3 ? tokens[3] : null;
}
}
} }

View File

@@ -21,6 +21,7 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same; import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.clearInvocations;
@@ -29,9 +30,11 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.annotation.NonNull;
import android.app.test.MockAnswerUtil.AnswerWithArguments; import android.app.test.MockAnswerUtil.AnswerWithArguments;
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.EthernetNetworkSpecifier; import android.net.EthernetNetworkSpecifier;
import android.net.IpConfiguration; import android.net.IpConfiguration;
import android.net.LinkProperties; import android.net.LinkProperties;
@@ -145,9 +148,9 @@ public class EthernetNetworkFactoryTest {
.build(); .build();
} }
private NetworkCapabilities.Builder createInterfaceCapsBuilder() { private NetworkCapabilities.Builder createInterfaceCapsBuilder(final int transportType) {
return new NetworkCapabilities.Builder() return new NetworkCapabilities.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET) .addTransportType(transportType)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED); .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
} }
@@ -172,7 +175,13 @@ public class EthernetNetworkFactoryTest {
// creates an interface with provisioning in progress (since updating the interface link state // creates an interface with provisioning in progress (since updating the interface link state
// automatically starts the provisioning process) // automatically starts the provisioning process)
private void createInterfaceUndergoingProvisioning(String iface) throws Exception { private void createInterfaceUndergoingProvisioning(String iface) throws Exception {
mNetFactory.addInterface(iface, iface, createInterfaceCapsBuilder().build(), // Default to the ethernet transport type.
createInterfaceUndergoingProvisioning(iface, NetworkCapabilities.TRANSPORT_ETHERNET);
}
private void createInterfaceUndergoingProvisioning(
@NonNull final String iface, final int transportType) throws Exception {
mNetFactory.addInterface(iface, iface, createInterfaceCapsBuilder(transportType).build(),
createDefaultIpConfig()); createDefaultIpConfig());
assertTrue(mNetFactory.updateInterfaceLinkState(iface, true)); assertTrue(mNetFactory.updateInterfaceLinkState(iface, true));
verify(mDeps).makeIpClient(any(Context.class), anyString(), any()); verify(mDeps).makeIpClient(any(Context.class), anyString(), any());
@@ -182,13 +191,22 @@ public class EthernetNetworkFactoryTest {
} }
// creates a provisioned interface // creates a provisioned interface
private void createProvisionedInterface(String iface) throws Exception { private void createAndVerifyProvisionedInterface(String iface) throws Exception {
createInterfaceUndergoingProvisioning(iface); // Default to the ethernet transport type.
createAndVerifyProvisionedInterface(iface, NetworkCapabilities.TRANSPORT_ETHERNET,
ConnectivityManager.TYPE_ETHERNET);
}
private void createAndVerifyProvisionedInterface(
@NonNull final String iface, final int transportType, final int expectedLegacyType)
throws Exception {
createInterfaceUndergoingProvisioning(iface, transportType);
mIpClientCallbacks.onProvisioningSuccess(new LinkProperties()); mIpClientCallbacks.onProvisioningSuccess(new LinkProperties());
mLooper.dispatchAll(); mLooper.dispatchAll();
// provisioning succeeded, verify that the network agent is created, registered, and marked // provisioning succeeded, verify that the network agent is created, registered, marked
// as connected. // as connected and legacy type are correctly set.
verify(mDeps).makeEthernetNetworkAgent(any(), any(), any(), any(), any(), any(), any()); verify(mDeps).makeEthernetNetworkAgent(any(), any(), any(), any(),
argThat(x -> x.getLegacyType() == expectedLegacyType), any(), any());
verify(mNetworkAgent).register(); verify(mNetworkAgent).register();
verify(mNetworkAgent).markConnected(); verify(mNetworkAgent).markConnected();
clearInvocations(mDeps); clearInvocations(mDeps);
@@ -201,7 +219,7 @@ public class EthernetNetworkFactoryTest {
// followed by releaseNetworkFor which will stop the NetworkAgent and IpClient. When // followed by releaseNetworkFor which will stop the NetworkAgent and IpClient. When
// EthernetNetworkFactory#updateInterfaceLinkState(iface, true) is called, the interface // EthernetNetworkFactory#updateInterfaceLinkState(iface, true) is called, the interface
// is automatically provisioned even if nobody has ever called needNetworkFor // is automatically provisioned even if nobody has ever called needNetworkFor
createProvisionedInterface(iface); createAndVerifyProvisionedInterface(iface);
// Interface is already provisioned, so startProvisioning / register should not be called // Interface is already provisioned, so startProvisioning / register should not be called
// again // again
@@ -240,7 +258,7 @@ public class EthernetNetworkFactoryTest {
@Test @Test
public void testUpdateInterfaceLinkStateForProvisionedInterface() throws Exception { public void testUpdateInterfaceLinkStateForProvisionedInterface() throws Exception {
String iface = "eth0"; String iface = "eth0";
createProvisionedInterface(iface); createAndVerifyProvisionedInterface(iface);
assertTrue(mNetFactory.updateInterfaceLinkState(iface, false)); assertTrue(mNetFactory.updateInterfaceLinkState(iface, false));
verify(mIpClient).shutdown(); verify(mIpClient).shutdown();
verify(mNetworkAgent).unregister(); verify(mNetworkAgent).unregister();
@@ -266,7 +284,7 @@ public class EthernetNetworkFactoryTest {
@Test @Test
public void testNeedNetworkForOnProvisionedInterface() throws Exception { public void testNeedNetworkForOnProvisionedInterface() throws Exception {
createProvisionedInterface("eth0"); createAndVerifyProvisionedInterface("eth0");
mNetFactory.needNetworkFor(createDefaultRequest()); mNetFactory.needNetworkFor(createDefaultRequest());
verify(mIpClient, never()).startProvisioning(any()); verify(mIpClient, never()).startProvisioning(any());
} }
@@ -299,7 +317,7 @@ public class EthernetNetworkFactoryTest {
public void testProvisioningLoss() throws Exception { public void testProvisioningLoss() throws Exception {
String iface = "eth0"; String iface = "eth0";
when(mDeps.getNetworkInterfaceByName(iface)).thenReturn(mInterfaceParams); when(mDeps.getNetworkInterfaceByName(iface)).thenReturn(mInterfaceParams);
createProvisionedInterface(iface); createAndVerifyProvisionedInterface(iface);
mIpClientCallbacks.onProvisioningFailure(new LinkProperties()); mIpClientCallbacks.onProvisioningFailure(new LinkProperties());
mLooper.dispatchAll(); mLooper.dispatchAll();
@@ -315,7 +333,7 @@ public class EthernetNetworkFactoryTest {
// mocked method returns null by default, but just to be explicit in the test: // mocked method returns null by default, but just to be explicit in the test:
when(mDeps.getNetworkInterfaceByName(eq(iface))).thenReturn(null); when(mDeps.getNetworkInterfaceByName(eq(iface))).thenReturn(null);
createProvisionedInterface(iface); createAndVerifyProvisionedInterface(iface);
mIpClientCallbacks.onProvisioningFailure(new LinkProperties()); mIpClientCallbacks.onProvisioningFailure(new LinkProperties());
mLooper.dispatchAll(); mLooper.dispatchAll();
verify(mIpClient).shutdown(); verify(mIpClient).shutdown();
@@ -345,7 +363,7 @@ public class EthernetNetworkFactoryTest {
@Test @Test
public void testLinkPropertiesChanged() throws Exception { public void testLinkPropertiesChanged() throws Exception {
createProvisionedInterface("eth0"); createAndVerifyProvisionedInterface("eth0");
LinkProperties lp = new LinkProperties(); LinkProperties lp = new LinkProperties();
mIpClientCallbacks.onLinkPropertiesChange(lp); mIpClientCallbacks.onLinkPropertiesChange(lp);
@@ -355,7 +373,7 @@ public class EthernetNetworkFactoryTest {
@Test @Test
public void testNetworkUnwanted() throws Exception { public void testNetworkUnwanted() throws Exception {
createProvisionedInterface("eth0"); createAndVerifyProvisionedInterface("eth0");
mNetworkAgent.getCallbacks().onNetworkUnwanted(); mNetworkAgent.getCallbacks().onNetworkUnwanted();
mLooper.dispatchAll(); mLooper.dispatchAll();
@@ -368,7 +386,7 @@ public class EthernetNetworkFactoryTest {
String iface = "eth0"; String iface = "eth0";
// ensures provisioning is restarted after provisioning loss // ensures provisioning is restarted after provisioning loss
when(mDeps.getNetworkInterfaceByName(iface)).thenReturn(mInterfaceParams); when(mDeps.getNetworkInterfaceByName(iface)).thenReturn(mInterfaceParams);
createProvisionedInterface(iface); createAndVerifyProvisionedInterface(iface);
EthernetNetworkAgent.Callbacks oldCbs = mNetworkAgent.getCallbacks(); EthernetNetworkAgent.Callbacks oldCbs = mNetworkAgent.getCallbacks();
// replace network agent in EthernetNetworkFactory // replace network agent in EthernetNetworkFactory
@@ -388,4 +406,32 @@ public class EthernetNetworkFactoryTest {
verify(mIpClient, never()).shutdown(); verify(mIpClient, never()).shutdown();
verify(mNetworkAgent, never()).unregister(); verify(mNetworkAgent, never()).unregister();
} }
@Test
public void testTransportOverrideIsCorrectlySet() throws Exception {
final String iface = "eth0";
// createProvisionedInterface() has verifications in place for transport override
// functionality which for EthernetNetworkFactory is network score and legacy type mappings.
createAndVerifyProvisionedInterface(iface, NetworkCapabilities.TRANSPORT_ETHERNET,
ConnectivityManager.TYPE_ETHERNET);
mNetFactory.removeInterface(iface);
createAndVerifyProvisionedInterface(iface, NetworkCapabilities.TRANSPORT_BLUETOOTH,
ConnectivityManager.TYPE_BLUETOOTH);
mNetFactory.removeInterface(iface);
createAndVerifyProvisionedInterface(iface, NetworkCapabilities.TRANSPORT_WIFI,
ConnectivityManager.TYPE_WIFI);
mNetFactory.removeInterface(iface);
createAndVerifyProvisionedInterface(iface, NetworkCapabilities.TRANSPORT_CELLULAR,
ConnectivityManager.TYPE_MOBILE);
mNetFactory.removeInterface(iface);
createAndVerifyProvisionedInterface(iface, NetworkCapabilities.TRANSPORT_LOWPAN,
ConnectivityManager.TYPE_NONE);
mNetFactory.removeInterface(iface);
createAndVerifyProvisionedInterface(iface, NetworkCapabilities.TRANSPORT_WIFI_AWARE,
ConnectivityManager.TYPE_NONE);
mNetFactory.removeInterface(iface);
createAndVerifyProvisionedInterface(iface, NetworkCapabilities.TRANSPORT_TEST,
ConnectivityManager.TYPE_NONE);
mNetFactory.removeInterface(iface);
}
} }

View File

@@ -17,6 +17,7 @@
package com.android.server.ethernet; package com.android.server.ethernet;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import android.net.InetAddresses; import android.net.InetAddresses;
@@ -242,4 +243,27 @@ public class EthernetTrackerTest {
EthernetTracker.createNetworkCapabilities(clearCapabilties, configCapabiltiies, EthernetTracker.createNetworkCapabilities(clearCapabilties, configCapabiltiies,
configTransports).build()); configTransports).build());
} }
@Test
public void testCreateEthernetTrackerConfigReturnsCorrectValue() {
final String name = "1";
final String capabilities = "2";
final String ipConfig = "3";
final String transport = "4";
final String configString = String.join(";", name, capabilities, ipConfig, transport);
final EthernetTracker.EthernetTrackerConfig config =
EthernetTracker.createEthernetTrackerConfig(configString);
assertEquals(name, config.mName);
assertEquals(capabilities, config.mCapabilities);
assertEquals(ipConfig, config.mIpConfig);
assertEquals(transport, config.mTransport);
}
@Test
public void testCreateEthernetTrackerConfigThrowsNpeWithNullInput() {
assertThrows(NullPointerException.class,
() -> EthernetTracker.createEthernetTrackerConfig(null));
}
} }