Unit test TelephonySubscriptionSnapshot changes for VCNs.
This CL adds unit testing for TelephonySubscriptionSnapshot updates in UnderlyingNetworkTracker, Vcn, and VcnManagementService. Bug: 177364490 Test: atest FrameworksVcnTests Change-Id: I244744194a1360c7c7dee062a302e04f9b5efc32
This commit is contained in:
@@ -27,11 +27,16 @@ import android.os.Message;
|
||||
import android.os.ParcelUuid;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.annotations.VisibleForTesting.Visibility;
|
||||
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Represents an single instance of a VCN.
|
||||
@@ -99,7 +104,8 @@ public class Vcn extends Handler {
|
||||
this(vcnContext, subscriptionGroup, config, snapshot, new Dependencies());
|
||||
}
|
||||
|
||||
private Vcn(
|
||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||
public Vcn(
|
||||
@NonNull VcnContext vcnContext,
|
||||
@NonNull ParcelUuid subscriptionGroup,
|
||||
@NonNull VcnConfig config,
|
||||
@@ -137,6 +143,12 @@ public class Vcn extends Handler {
|
||||
sendMessageAtFrontOfQueue(obtainMessage(MSG_CMD_TEARDOWN));
|
||||
}
|
||||
|
||||
/** Get current Gateways for testing purposes */
|
||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||
public Set<VcnGatewayConnection> getVcnGatewayConnections() {
|
||||
return Collections.unmodifiableSet(new HashSet<>(mVcnGatewayConnections.values()));
|
||||
}
|
||||
|
||||
private class VcnNetworkRequestListener implements VcnNetworkProvider.NetworkRequestListener {
|
||||
@Override
|
||||
public void onNetworkRequested(@NonNull NetworkRequest request, int score, int providerId) {
|
||||
@@ -217,7 +229,7 @@ public class Vcn extends Handler {
|
||||
"Bringing up new VcnGatewayConnection for request " + request.requestId);
|
||||
|
||||
final VcnGatewayConnection vcnGatewayConnection =
|
||||
new VcnGatewayConnection(
|
||||
mDeps.newVcnGatewayConnection(
|
||||
mVcnContext,
|
||||
mSubscriptionGroup,
|
||||
mLastSnapshot,
|
||||
@@ -259,5 +271,17 @@ public class Vcn extends Handler {
|
||||
return 52;
|
||||
}
|
||||
|
||||
private static class Dependencies {}
|
||||
/** External dependencies used by Vcn, for injection in tests */
|
||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||
public static class Dependencies {
|
||||
/** Builds a new VcnGatewayConnection */
|
||||
public VcnGatewayConnection newVcnGatewayConnection(
|
||||
VcnContext vcnContext,
|
||||
ParcelUuid subscriptionGroup,
|
||||
TelephonySubscriptionSnapshot snapshot,
|
||||
VcnGatewayConnectionConfig connectionConfig) {
|
||||
return new VcnGatewayConnection(
|
||||
vcnContext, subscriptionGroup, snapshot, connectionConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@ import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.annotations.VisibleForTesting.Visibility;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -52,8 +55,13 @@ public class VcnNetworkProvider extends NetworkProvider {
|
||||
super(context, looper, VcnNetworkProvider.class.getSimpleName());
|
||||
}
|
||||
|
||||
// Package-private
|
||||
void registerListener(@NonNull NetworkRequestListener listener) {
|
||||
/**
|
||||
* Registers a NetworkRequestListener with this NetworkProvider.
|
||||
*
|
||||
* <p>Upon registering, the provided listener will receive all cached requests.
|
||||
*/
|
||||
@VisibleForTesting(visibility = Visibility.PACKAGE)
|
||||
public void registerListener(@NonNull NetworkRequestListener listener) {
|
||||
mListeners.add(listener);
|
||||
|
||||
// Send listener all cached requests
|
||||
@@ -62,8 +70,9 @@ public class VcnNetworkProvider extends NetworkProvider {
|
||||
}
|
||||
}
|
||||
|
||||
// Package-private
|
||||
void unregisterListener(@NonNull NetworkRequestListener listener) {
|
||||
/** Unregisters the specified listener from receiving future NetworkRequests. */
|
||||
@VisibleForTesting(visibility = Visibility.PACKAGE)
|
||||
public void unregisterListener(@NonNull NetworkRequestListener listener) {
|
||||
mListeners.remove(listener);
|
||||
}
|
||||
|
||||
|
||||
@@ -598,4 +598,16 @@ public class VcnManagementServiceTest {
|
||||
|
||||
mVcnMgmtSvc.getUnderlyingNetworkPolicy(new NetworkCapabilities(), new LinkProperties());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubscriptionSnapshotUpdateNotifiesVcn() {
|
||||
mVcnMgmtSvc.setVcnConfig(TEST_UUID_2, TEST_VCN_CONFIG, TEST_PACKAGE_NAME);
|
||||
final Map<ParcelUuid, Vcn> vcnInstances = mVcnMgmtSvc.getAllVcns();
|
||||
final Vcn vcnInstance = vcnInstances.get(TEST_UUID_2);
|
||||
|
||||
TelephonySubscriptionSnapshot snapshot =
|
||||
triggerSubscriptionTrackerCbAndGetSnapshot(Collections.singleton(TEST_UUID_2));
|
||||
|
||||
verify(vcnInstance).updateSubscriptionSnapshot(eq(snapshot));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,12 @@ 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 int UPDATED_SUB_ID = 3;
|
||||
|
||||
private static final Set<Integer> INITIAL_SUB_IDS =
|
||||
new ArraySet<>(Arrays.asList(INITIAL_SUB_ID_1, INITIAL_SUB_ID_2));
|
||||
private static final Set<Integer> UPDATED_SUB_IDS =
|
||||
new ArraySet<>(Arrays.asList(UPDATED_SUB_ID));
|
||||
|
||||
private static final NetworkCapabilities INITIAL_NETWORK_CAPABILITIES =
|
||||
new NetworkCapabilities.Builder()
|
||||
@@ -115,9 +121,7 @@ public class UnderlyingNetworkTrackerTest {
|
||||
Context.CONNECTIVITY_SERVICE,
|
||||
ConnectivityManager.class);
|
||||
|
||||
Set<Integer> initialSubIds =
|
||||
new ArraySet<>(Arrays.asList(INITIAL_SUB_ID_1, INITIAL_SUB_ID_2));
|
||||
when(mSubscriptionSnapshot.getAllSubIdsInGroup(eq(SUB_GROUP))).thenReturn(initialSubIds);
|
||||
when(mSubscriptionSnapshot.getAllSubIdsInGroup(eq(SUB_GROUP))).thenReturn(INITIAL_SUB_IDS);
|
||||
|
||||
mUnderlyingNetworkTracker =
|
||||
new UnderlyingNetworkTracker(
|
||||
@@ -148,23 +152,45 @@ public class UnderlyingNetworkTrackerTest {
|
||||
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));
|
||||
verifyBackgroundCellRequests(mSubscriptionSnapshot, SUB_GROUP, INITIAL_SUB_IDS);
|
||||
|
||||
verify(mConnectivityManager)
|
||||
.requestBackgroundNetwork(
|
||||
eq(getRouteSelectionRequest()),
|
||||
any(),
|
||||
any(RouteSelectionCallback.class));
|
||||
}
|
||||
|
||||
verify(mSubscriptionSnapshot).getAllSubIdsInGroup(eq(SUB_GROUP));
|
||||
private void verifyBackgroundCellRequests(
|
||||
TelephonySubscriptionSnapshot snapshot,
|
||||
ParcelUuid subGroup,
|
||||
Set<Integer> expectedSubIds) {
|
||||
verify(snapshot).getAllSubIdsInGroup(eq(subGroup));
|
||||
|
||||
for (final int subId : expectedSubIds) {
|
||||
verify(mConnectivityManager)
|
||||
.requestBackgroundNetwork(
|
||||
eq(getCellRequestForSubId(subId)),
|
||||
any(),
|
||||
any(NetworkBringupCallback.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateSubscriptionSnapshot() {
|
||||
// Verify initial cell background requests filed
|
||||
verifyBackgroundCellRequests(mSubscriptionSnapshot, SUB_GROUP, INITIAL_SUB_IDS);
|
||||
|
||||
TelephonySubscriptionSnapshot subscriptionUpdate =
|
||||
mock(TelephonySubscriptionSnapshot.class);
|
||||
when(subscriptionUpdate.getAllSubIdsInGroup(eq(SUB_GROUP))).thenReturn(UPDATED_SUB_IDS);
|
||||
|
||||
mUnderlyingNetworkTracker.updateSubscriptionSnapshot(subscriptionUpdate);
|
||||
|
||||
// verify that initially-filed bringup requests are unregistered
|
||||
verify(mConnectivityManager, times(INITIAL_SUB_IDS.size()))
|
||||
.unregisterNetworkCallback(any(NetworkBringupCallback.class));
|
||||
verifyBackgroundCellRequests(subscriptionUpdate, SUB_GROUP, UPDATED_SUB_IDS);
|
||||
}
|
||||
|
||||
private NetworkRequest getWifiRequest() {
|
||||
|
||||
@@ -24,10 +24,10 @@ import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
@@ -37,14 +37,15 @@ import android.net.vcn.VcnTransportInfo;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.os.ParcelUuid;
|
||||
import android.os.Process;
|
||||
import android.os.test.TestLooper;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
||||
import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@@ -56,8 +57,9 @@ import java.util.UUID;
|
||||
/** Tests for TelephonySubscriptionTracker */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class VcnGatewayConnectionTest {
|
||||
public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
|
||||
private static final int TEST_UID = Process.myUid();
|
||||
|
||||
private static final ParcelUuid TEST_PARCEL_UUID = new ParcelUuid(UUID.randomUUID());
|
||||
private static final int TEST_SIM_SLOT_INDEX = 1;
|
||||
private static final int TEST_SUBSCRIPTION_ID_1 = 2;
|
||||
@@ -73,17 +75,12 @@ public class VcnGatewayConnectionTest {
|
||||
TEST_SUBID_TO_GROUP_MAP = Collections.unmodifiableMap(subIdToGroupMap);
|
||||
}
|
||||
|
||||
@NonNull private final Context mContext;
|
||||
@NonNull private final TestLooper mTestLooper;
|
||||
@NonNull private final VcnNetworkProvider mVcnNetworkProvider;
|
||||
@NonNull private final VcnGatewayConnection.Dependencies mDeps;
|
||||
@NonNull private final WifiInfo mWifiInfo;
|
||||
private WifiInfo mWifiInfo;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
public VcnGatewayConnectionTest() {
|
||||
mContext = mock(Context.class);
|
||||
mTestLooper = new TestLooper();
|
||||
mVcnNetworkProvider = mock(VcnNetworkProvider.class);
|
||||
mDeps = mock(VcnGatewayConnection.Dependencies.class);
|
||||
mWifiInfo = mock(WifiInfo.class);
|
||||
}
|
||||
|
||||
@@ -132,4 +129,13 @@ public class VcnGatewayConnectionTest {
|
||||
public void testBuildNetworkCapabilitiesUnderlyingCell() throws Exception {
|
||||
verifyBuildNetworkCapabilitiesCommon(TRANSPORT_CELLULAR);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubscriptionSnapshotUpdateNotifiesUnderlyingNetworkTracker() {
|
||||
final TelephonySubscriptionSnapshot updatedSnapshot =
|
||||
mock(TelephonySubscriptionSnapshot.class);
|
||||
mGatewayConnection.updateSubscriptionSnapshot(updatedSnapshot);
|
||||
|
||||
verify(mUnderlyingNetworkTracker).updateSubscriptionSnapshot(eq(updatedSnapshot));
|
||||
}
|
||||
}
|
||||
|
||||
129
tests/vcn/java/com/android/server/vcn/VcnTest.java
Normal file
129
tests/vcn/java/com/android/server/vcn/VcnTest.java
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* 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 org.junit.Assert.assertFalse;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.vcn.VcnConfig;
|
||||
import android.net.vcn.VcnGatewayConnectionConfigTest;
|
||||
import android.os.ParcelUuid;
|
||||
import android.os.test.TestLooper;
|
||||
|
||||
import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
|
||||
import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class VcnTest {
|
||||
private static final String PKG_NAME = VcnTest.class.getPackage().getName();
|
||||
private static final ParcelUuid TEST_SUB_GROUP = new ParcelUuid(new UUID(0, 0));
|
||||
private static final int NETWORK_SCORE = 0;
|
||||
private static final int PROVIDER_ID = 5;
|
||||
|
||||
private Context mContext;
|
||||
private VcnContext mVcnContext;
|
||||
private TelephonySubscriptionSnapshot mSubscriptionSnapshot;
|
||||
private VcnNetworkProvider mVcnNetworkProvider;
|
||||
private Vcn.Dependencies mDeps;
|
||||
|
||||
private TestLooper mTestLooper;
|
||||
private VcnConfig mConfig;
|
||||
private Vcn mVcn;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = mock(Context.class);
|
||||
mVcnContext = mock(VcnContext.class);
|
||||
mSubscriptionSnapshot = mock(TelephonySubscriptionSnapshot.class);
|
||||
mVcnNetworkProvider = mock(VcnNetworkProvider.class);
|
||||
mDeps = mock(Vcn.Dependencies.class);
|
||||
|
||||
mTestLooper = new TestLooper();
|
||||
|
||||
doReturn(PKG_NAME).when(mContext).getOpPackageName();
|
||||
doReturn(mContext).when(mVcnContext).getContext();
|
||||
doReturn(mTestLooper.getLooper()).when(mVcnContext).getLooper();
|
||||
doReturn(mVcnNetworkProvider).when(mVcnContext).getVcnNetworkProvider();
|
||||
|
||||
// Setup VcnGatewayConnection instance generation
|
||||
doAnswer((invocation) -> {
|
||||
// Mock-within a doAnswer is safe, because it doesn't actually run nested.
|
||||
return mock(VcnGatewayConnection.class);
|
||||
}).when(mDeps).newVcnGatewayConnection(any(), any(), any(), any());
|
||||
|
||||
mConfig =
|
||||
new VcnConfig.Builder(mContext)
|
||||
.addGatewayConnectionConfig(
|
||||
VcnGatewayConnectionConfigTest.buildTestConfig())
|
||||
.build();
|
||||
|
||||
mVcn = new Vcn(mVcnContext, TEST_SUB_GROUP, mConfig, mSubscriptionSnapshot, mDeps);
|
||||
}
|
||||
|
||||
private NetworkRequestListener verifyAndGetRequestListener() {
|
||||
ArgumentCaptor<NetworkRequestListener> mNetworkRequestListenerCaptor =
|
||||
ArgumentCaptor.forClass(NetworkRequestListener.class);
|
||||
verify(mVcnNetworkProvider).registerListener(mNetworkRequestListenerCaptor.capture());
|
||||
|
||||
return mNetworkRequestListenerCaptor.getValue();
|
||||
}
|
||||
|
||||
private NetworkRequest getNetworkRequestWithCapabilities(int[] networkCapabilities) {
|
||||
final NetworkRequest.Builder builder = new NetworkRequest.Builder();
|
||||
for (final int netCapability : networkCapabilities) {
|
||||
builder.addCapability(netCapability);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubscriptionSnapshotUpdatesVcnGatewayConnections() {
|
||||
final NetworkRequestListener requestListener = verifyAndGetRequestListener();
|
||||
|
||||
requestListener.onNetworkRequested(
|
||||
getNetworkRequestWithCapabilities(VcnGatewayConnectionConfigTest.EXPOSED_CAPS),
|
||||
NETWORK_SCORE,
|
||||
PROVIDER_ID);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
final Set<VcnGatewayConnection> gatewayConnections = mVcn.getVcnGatewayConnections();
|
||||
assertFalse(gatewayConnections.isEmpty());
|
||||
|
||||
final TelephonySubscriptionSnapshot updatedSnapshot =
|
||||
mock(TelephonySubscriptionSnapshot.class);
|
||||
|
||||
mVcn.updateSubscriptionSnapshot(updatedSnapshot);
|
||||
mTestLooper.dispatchAll();
|
||||
|
||||
for (final VcnGatewayConnection gateway : gatewayConnections) {
|
||||
verify(gateway).updateSubscriptionSnapshot(eq(updatedSnapshot));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user