Unit test UnderlyingNetworkTracker.

Bug: 177364490
Test: atest FrameworksVcnTests
Change-Id: I681b0bef27cdd1974a574e81b4b435578cd6e9cd
This commit is contained in:
Cody Kesting
2021-01-14 12:57:15 -08:00
parent a382c9ca0c
commit f029daa404

View File

@@ -0,0 +1,366 @@
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.vcn;
import static com.android.server.vcn.VcnTestUtils.setupSystemService;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.TelephonyNetworkSpecifier;
import android.os.ParcelUuid;
import android.os.test.TestLooper;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import com.android.server.vcn.UnderlyingNetworkTracker.NetworkBringupCallback;
import com.android.server.vcn.UnderlyingNetworkTracker.RouteSelectionCallback;
import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord;
import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkTrackerCallback;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
public class UnderlyingNetworkTrackerTest {
private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0));
private static final int INITIAL_SUB_ID_1 = 1;
private static final int INITIAL_SUB_ID_2 = 2;
private static final NetworkCapabilities INITIAL_NETWORK_CAPABILITIES =
new NetworkCapabilities.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
.build();
private static final NetworkCapabilities SUSPENDED_NETWORK_CAPABILITIES =
new NetworkCapabilities.Builder(INITIAL_NETWORK_CAPABILITIES)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)
.build();
private static final NetworkCapabilities UPDATED_NETWORK_CAPABILITIES =
new NetworkCapabilities.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.build();
private static final LinkProperties INITIAL_LINK_PROPERTIES =
getLinkPropertiesWithName("initial_iface");
private static final LinkProperties UPDATED_LINK_PROPERTIES =
getLinkPropertiesWithName("updated_iface");
@Mock private Context mContext;
@Mock private VcnNetworkProvider mVcnNetworkProvider;
@Mock private ConnectivityManager mConnectivityManager;
@Mock private SubscriptionManager mSubscriptionManager;
@Mock private UnderlyingNetworkTrackerCallback mNetworkTrackerCb;
@Mock private Network mNetwork;
@Captor private ArgumentCaptor<RouteSelectionCallback> mRouteSelectionCallbackCaptor;
private TestLooper mTestLooper;
private VcnContext mVcnContext;
private UnderlyingNetworkTracker mUnderlyingNetworkTracker;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mTestLooper = new TestLooper();
mVcnContext = spy(new VcnContext(mContext, mTestLooper.getLooper(), mVcnNetworkProvider));
doNothing().when(mVcnContext).ensureRunningOnLooperThread();
setupSystemService(
mContext,
mConnectivityManager,
Context.CONNECTIVITY_SERVICE,
ConnectivityManager.class);
setupSystemService(
mContext,
mSubscriptionManager,
Context.TELEPHONY_SUBSCRIPTION_SERVICE,
SubscriptionManager.class);
List<SubscriptionInfo> initialSubInfos =
Arrays.asList(
getSubscriptionInfoForSubId(INITIAL_SUB_ID_1),
getSubscriptionInfoForSubId(INITIAL_SUB_ID_2));
when(mSubscriptionManager.getSubscriptionsInGroup(eq(SUB_GROUP)))
.thenReturn(initialSubInfos);
mUnderlyingNetworkTracker =
new UnderlyingNetworkTracker(
mVcnContext,
SUB_GROUP,
Collections.singleton(NetworkCapabilities.NET_CAPABILITY_INTERNET),
mNetworkTrackerCb);
}
private static LinkProperties getLinkPropertiesWithName(String iface) {
LinkProperties linkProperties = new LinkProperties();
linkProperties.setInterfaceName(iface);
return linkProperties;
}
private SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
when(subInfo.getSubscriptionId()).thenReturn(subId);
return subInfo;
}
@Test
public void testNetworkCallbacksRegisteredOnStartup() {
// verify NetworkCallbacks registered when instantiated
verify(mConnectivityManager)
.requestBackgroundNetwork(
eq(getWifiRequest()),
any(),
any(NetworkBringupCallback.class));
verify(mConnectivityManager)
.requestBackgroundNetwork(
eq(getCellRequestForSubId(INITIAL_SUB_ID_1)),
any(),
any(NetworkBringupCallback.class));
verify(mConnectivityManager)
.requestBackgroundNetwork(
eq(getCellRequestForSubId(INITIAL_SUB_ID_2)),
any(),
any(NetworkBringupCallback.class));
verify(mConnectivityManager)
.requestBackgroundNetwork(
eq(getRouteSelectionRequest()),
any(),
any(RouteSelectionCallback.class));
verify(mSubscriptionManager).getSubscriptionsInGroup(eq(SUB_GROUP));
}
private NetworkRequest getWifiRequest() {
return getExpectedRequestBase()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build();
}
private NetworkRequest getCellRequestForSubId(int subId) {
return getExpectedRequestBase()
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(subId))
.build();
}
private NetworkRequest getRouteSelectionRequest() {
return getExpectedRequestBase().build();
}
private NetworkRequest.Builder getExpectedRequestBase() {
return new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
.addUnwantedCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
}
@Test
public void testTeardown() {
mUnderlyingNetworkTracker.teardown();
// Expect 3 NetworkBringupCallbacks to be unregistered: 1 for WiFi and 2 for Cellular (1x
// for each subId)
verify(mConnectivityManager, times(3))
.unregisterNetworkCallback(any(NetworkBringupCallback.class));
verify(mConnectivityManager).unregisterNetworkCallback(any(RouteSelectionCallback.class));
}
@Test
public void testUnderlyingNetworkRecordEquals() {
UnderlyingNetworkRecord recordA =
new UnderlyingNetworkRecord(
mNetwork,
INITIAL_NETWORK_CAPABILITIES,
INITIAL_LINK_PROPERTIES,
false /* isBlocked */);
UnderlyingNetworkRecord recordB =
new UnderlyingNetworkRecord(
mNetwork,
INITIAL_NETWORK_CAPABILITIES,
INITIAL_LINK_PROPERTIES,
false /* isBlocked */);
UnderlyingNetworkRecord recordC =
new UnderlyingNetworkRecord(
mNetwork,
UPDATED_NETWORK_CAPABILITIES,
UPDATED_LINK_PROPERTIES,
false /* isBlocked */);
assertEquals(recordA, recordB);
assertNotEquals(recordA, recordC);
}
@Test
public void testRecordTrackerCallbackNotifiedForNetworkChange() {
verifyRegistrationOnAvailableAndGetCallback();
}
private RouteSelectionCallback verifyRegistrationOnAvailableAndGetCallback() {
return verifyRegistrationOnAvailableAndGetCallback(INITIAL_NETWORK_CAPABILITIES);
}
private RouteSelectionCallback verifyRegistrationOnAvailableAndGetCallback(
NetworkCapabilities networkCapabilities) {
verify(mConnectivityManager)
.requestBackgroundNetwork(
eq(getRouteSelectionRequest()),
any(),
mRouteSelectionCallbackCaptor.capture());
RouteSelectionCallback cb = mRouteSelectionCallbackCaptor.getValue();
cb.onAvailable(mNetwork);
cb.onCapabilitiesChanged(mNetwork, networkCapabilities);
cb.onLinkPropertiesChanged(mNetwork, INITIAL_LINK_PROPERTIES);
cb.onBlockedStatusChanged(mNetwork, false /* isFalse */);
UnderlyingNetworkRecord expectedRecord =
new UnderlyingNetworkRecord(
mNetwork,
networkCapabilities,
INITIAL_LINK_PROPERTIES,
false /* isBlocked */);
verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord));
return cb;
}
@Test
public void testRecordTrackerCallbackNotifiedForNetworkCapabilitiesChange() {
RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback();
cb.onCapabilitiesChanged(mNetwork, UPDATED_NETWORK_CAPABILITIES);
UnderlyingNetworkRecord expectedRecord =
new UnderlyingNetworkRecord(
mNetwork,
UPDATED_NETWORK_CAPABILITIES,
INITIAL_LINK_PROPERTIES,
false /* isBlocked */);
verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord));
}
@Test
public void testRecordTrackerCallbackNotifiedForLinkPropertiesChange() {
RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback();
cb.onLinkPropertiesChanged(mNetwork, UPDATED_LINK_PROPERTIES);
UnderlyingNetworkRecord expectedRecord =
new UnderlyingNetworkRecord(
mNetwork,
INITIAL_NETWORK_CAPABILITIES,
UPDATED_LINK_PROPERTIES,
false /* isBlocked */);
verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord));
}
@Test
public void testRecordTrackerCallbackNotifiedForNetworkSuspended() {
RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback();
cb.onNetworkSuspended(mNetwork);
UnderlyingNetworkRecord expectedRecord =
new UnderlyingNetworkRecord(
mNetwork,
SUSPENDED_NETWORK_CAPABILITIES,
INITIAL_LINK_PROPERTIES,
false /* isBlocked */);
verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord));
}
@Test
public void testRecordTrackerCallbackNotifiedForNetworkResumed() {
RouteSelectionCallback cb =
verifyRegistrationOnAvailableAndGetCallback(SUSPENDED_NETWORK_CAPABILITIES);
cb.onNetworkResumed(mNetwork);
UnderlyingNetworkRecord expectedRecord =
new UnderlyingNetworkRecord(
mNetwork,
INITIAL_NETWORK_CAPABILITIES,
INITIAL_LINK_PROPERTIES,
false /* isBlocked */);
verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord));
}
@Test
public void testRecordTrackerCallbackNotifiedForBlocked() {
RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback();
cb.onBlockedStatusChanged(mNetwork, true /* isBlocked */);
UnderlyingNetworkRecord expectedRecord =
new UnderlyingNetworkRecord(
mNetwork,
INITIAL_NETWORK_CAPABILITIES,
INITIAL_LINK_PROPERTIES,
true /* isBlocked */);
verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(eq(expectedRecord));
}
@Test
public void testRecordTrackerCallbackNotifiedForNetworkLoss() {
RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback();
cb.onLost(mNetwork);
verify(mNetworkTrackerCb).onSelectedUnderlyingNetworkChanged(null);
}
@Test
public void testRecordTrackerCallbackIgnoresDuplicateRecord() {
RouteSelectionCallback cb = verifyRegistrationOnAvailableAndGetCallback();
cb.onCapabilitiesChanged(mNetwork, INITIAL_NETWORK_CAPABILITIES);
// Verify no more calls to the UnderlyingNetworkTrackerCallback when the
// UnderlyingNetworkRecord does not actually change
verifyNoMoreInteractions(mNetworkTrackerCb);
}
}