Merge "[Test] CTS for DNS query fail-fast feature" into main

This commit is contained in:
Ken Chen 2023-11-13 03:23:40 +00:00 • committed by Gerrit Code Review
commit a4e35a49b7
2 changed files with 86 additions and 9 deletions

View file

@ -62,6 +62,8 @@ import android.service.notification.NotificationListenerService;
import android.util.Log;
import android.util.Pair;
import androidx.annotation.Nullable;
import com.android.compatibility.common.util.AmUtils;
import com.android.compatibility.common.util.BatteryUtils;
import com.android.compatibility.common.util.DeviceConfigStateHelper;
@ -283,8 +285,30 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
}
protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception {
assertBackgroundNetworkAccess(expectAllowed, null);
}
/**
* Asserts whether the active network is available or not for the background app. If the network
* is unavailable, also checks whether it is blocked by the expected error.
*
* @param expectAllowed expect background network access to be allowed or not.
* @param expectedUnavailableError the expected error when {@code expectAllowed} is false. It's
* meaningful only when the {@code expectAllowed} is 'false'.
* Throws an IllegalArgumentException when {@code expectAllowed}
* is true and this parameter is not null. When the
* {@code expectAllowed} is 'false' and this parameter is null,
* this function does not compare error type of the networking
* access failure.
*/
protected void assertBackgroundNetworkAccess(boolean expectAllowed,
@Nullable final String expectedUnavailableError) throws Exception {
assertBackgroundState();
assertNetworkAccess(expectAllowed /* expectAvailable */, false /* needScreenOn */);
if (expectAllowed && expectedUnavailableError != null) {
throw new IllegalArgumentException("expectedUnavailableError is not null");
}
assertNetworkAccess(expectAllowed /* expectAvailable */, false /* needScreenOn */,
expectedUnavailableError);
}
protected void assertForegroundNetworkAccess() throws Exception {
@ -407,12 +431,17 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
*/
private void assertNetworkAccess(boolean expectAvailable, boolean needScreenOn)
throws Exception {
assertNetworkAccess(expectAvailable, needScreenOn, null);
}
private void assertNetworkAccess(boolean expectAvailable, boolean needScreenOn,
@Nullable final String expectedUnavailableError) throws Exception {
final int maxTries = 5;
String error = null;
int timeoutMs = 500;
for (int i = 1; i <= maxTries; i++) {
error = checkNetworkAccess(expectAvailable);
error = checkNetworkAccess(expectAvailable, expectedUnavailableError);
if (error == null) return;
@ -479,12 +508,15 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
*
* @return error message with the mismatch (or empty if assertion passed).
*/
private String checkNetworkAccess(boolean expectAvailable) throws Exception {
private String checkNetworkAccess(boolean expectAvailable,
@Nullable final String expectedUnavailableError) throws Exception {
final String resultData = mServiceClient.checkNetworkStatus();
return checkForAvailabilityInResultData(resultData, expectAvailable);
return checkForAvailabilityInResultData(resultData, expectAvailable,
expectedUnavailableError);
}
private String checkForAvailabilityInResultData(String resultData, boolean expectAvailable) {
private String checkForAvailabilityInResultData(String resultData, boolean expectAvailable,
@Nullable final String expectedUnavailableError) {
if (resultData == null) {
assertNotNull("Network status from app2 is null", resultData);
}
@ -516,6 +548,10 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
if (expectedState != state || expectedDetailedState != detailedState) {
errors.append(String.format("Connection state mismatch: expected %s/%s, got %s/%s\n",
expectedState, expectedDetailedState, state, detailedState));
} else if (!expectAvailable && (expectedUnavailableError != null)
&& !connectionCheckDetails.contains(expectedUnavailableError)) {
errors.append("Connection unavailable reason mismatch: expected "
+ expectedUnavailableError + "\n");
}
if (errors.length() > 0) {
@ -914,7 +950,7 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
final String resultData = result.get(0).second;
if (resultCode == INetworkStateObserver.RESULT_SUCCESS_NETWORK_STATE_CHECKED) {
final String error = checkForAvailabilityInResultData(
resultData, expectAvailable);
resultData, expectAvailable, null /* expectedUnavailableError */);
if (error != null) {
fail("Network is not available for activity in app2 (" + mUid + "): "
+ error);
@ -949,7 +985,7 @@ public abstract class AbstractRestrictBackgroundNetworkTestCase {
final String resultData = result.get(0).second;
if (resultCode == INetworkStateObserver.RESULT_SUCCESS_NETWORK_STATE_CHECKED) {
final String error = checkForAvailabilityInResultData(
resultData, expectAvailable);
resultData, expectAvailable, null /* expectedUnavailableError */);
if (error != null) {
Log.d(TAG, "Network state is unexpected, checking again. " + error);
// Right now we could end up in an unexpected state if expedited job

View file

@ -32,8 +32,11 @@ import static org.junit.Assume.assumeTrue;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.net.cts.util.CtsNetUtils;
import android.util.Log;
import com.android.modules.utils.build.SdkLevel;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
@ -46,6 +49,9 @@ import java.util.concurrent.TimeUnit;
public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCase {
private Network mNetwork;
private final TestNetworkCallback mTestNetworkCallback = new TestNetworkCallback();
private CtsNetUtils mCtsNetUtils;
private static final String GOOGLE_PRIVATE_DNS_SERVER = "dns.google";
@Rule
public final MeterednessConfigurationRule mMeterednessConfiguration
= new MeterednessConfigurationRule();
@ -218,6 +224,26 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
mTestNetworkCallback.expectCapabilitiesCallbackEventually(mNetwork,
false /* hasCapability */, NET_CAPABILITY_NOT_METERED);
mTestNetworkCallback.expectBlockedStatusCallback(mNetwork, false);
// Before Android T, DNS queries over private DNS should be but are not restricted by Power
// Saver or Data Saver. The issue is fixed in mainline update and apps can no longer request
// DNS queries when its network is restricted by Power Saver. The fix takes effect backwards
// starting from Android T. But for Data Saver, the fix is not backward compatible since
// there are some platform changes involved. It is only available on devices that a specific
// trunk flag is enabled.
//
// This test can not only verify that the network traffic from apps is blocked at the right
// time, but also verify whether it is correctly blocked at the DNS stage, or at a later
// socket connection stage.
if (SdkLevel.isAtLeastT()) {
// Enable private DNS
mCtsNetUtils = new CtsNetUtils(mContext);
mCtsNetUtils.storePrivateDnsSetting();
mCtsNetUtils.setPrivateDnsStrictMode(GOOGLE_PRIVATE_DNS_SERVER);
mCtsNetUtils.awaitPrivateDnsSetting(
"NetworkCallbackTest wait private DNS setting timeout", mNetwork,
GOOGLE_PRIVATE_DNS_SERVER, true);
}
}
@After
@ -227,6 +253,10 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
setRestrictBackground(false);
setBatterySaverMode(false);
unregisterNetworkCallback();
if (SdkLevel.isAtLeastT() && (mCtsNetUtils != null)) {
mCtsNetUtils.restorePrivateDnsSetting();
}
}
@RequiredProperties({DATA_SAVER_MODE})
@ -235,6 +265,8 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
try {
// Enable restrict background
setRestrictBackground(true);
// TODO: Verify expectedUnavailableError when aconfig support mainline.
// (see go/aconfig-in-mainline-problems)
assertBackgroundNetworkAccess(false);
assertNetworkAccessBlockedByBpf(true, mUid, true /* metered */);
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
@ -247,6 +279,7 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
// Remove from whitelist
removeRestrictBackgroundWhitelist(mUid);
// TODO: Verify expectedUnavailableError when aconfig support mainline.
assertBackgroundNetworkAccess(false);
assertNetworkAccessBlockedByBpf(true, mUid, true /* metered */);
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
@ -278,7 +311,11 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
try {
// Enable Power Saver
setBatterySaverMode(true);
assertBackgroundNetworkAccess(false);
if (SdkLevel.isAtLeastT()) {
assertBackgroundNetworkAccess(false, "java.net.UnknownHostException");
} else {
assertBackgroundNetworkAccess(false);
}
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
assertNetworkAccessBlockedByBpf(true, mUid, true /* metered */);
@ -298,7 +335,11 @@ public class NetworkCallbackTest extends AbstractRestrictBackgroundNetworkTestCa
try {
// Enable Power Saver
setBatterySaverMode(true);
assertBackgroundNetworkAccess(false);
if (SdkLevel.isAtLeastT()) {
assertBackgroundNetworkAccess(false, "java.net.UnknownHostException");
} else {
assertBackgroundNetworkAccess(false);
}
mTestNetworkCallback.expectBlockedStatusCallbackEventually(mNetwork, true);
assertNetworkAccessBlockedByBpf(true, mUid, false /* metered */);