Add CTS tests for getMultipathPreference
Test: Test passing with 1 or more connected wifis
No wifi won't pass but it's already a requirement
Bug: 34630278
Change-Id: I43bf18943fbd00dc29417b18604e29f9111ec0b2
Merged-in: I43bf18943fbd00dc29417b18604e29f9111ec0b2
Merged-in: Ie90ca72ea3606dea4259984d42762dd742d59970
This commit is contained in:
@@ -18,11 +18,16 @@ package android.net.cts;
|
||||
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||
import static android.provider.Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE;
|
||||
import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
|
||||
|
||||
import android.app.Instrumentation;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
@@ -38,12 +43,17 @@ import android.net.NetworkInfo.State;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.provider.Settings;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.system.Os;
|
||||
import android.system.OsConstants;
|
||||
import android.test.AndroidTestCase;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.telephony.PhoneConstants;
|
||||
|
||||
import java.io.File;
|
||||
@@ -51,6 +61,7 @@ import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.NumberFormatException;
|
||||
import java.net.Socket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.HashMap;
|
||||
@@ -58,6 +69,8 @@ import java.util.Scanner;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ConnectivityManagerTest extends AndroidTestCase {
|
||||
|
||||
@@ -72,6 +85,9 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
||||
private static final String TEST_HOST = "connectivitycheck.gstatic.com";
|
||||
private static final int SOCKET_TIMEOUT_MS = 2000;
|
||||
private static final int SEND_BROADCAST_TIMEOUT = 30000;
|
||||
private static final int NETWORK_CHANGE_METEREDNESS_TIMEOUT = 5000;
|
||||
private static final int NUM_TRIES_MULTIPATH_PREF_CHECK = 20;
|
||||
private static final long INTERVAL_MULTIPATH_PREF_CHECK_MS = 500;
|
||||
private static final int HTTP_PORT = 80;
|
||||
private static final String HTTP_REQUEST =
|
||||
"GET /generate_204 HTTP/1.0\r\n" +
|
||||
@@ -101,6 +117,7 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
||||
private static final int MIN_NUM_NETWORK_TYPES = 1;
|
||||
|
||||
private Context mContext;
|
||||
private Instrumentation mInstrumentation;
|
||||
private ConnectivityManager mCm;
|
||||
private WifiManager mWifiManager;
|
||||
private PackageManager mPackageManager;
|
||||
@@ -113,6 +130,7 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
||||
super.setUp();
|
||||
Looper.prepare();
|
||||
mContext = getContext();
|
||||
mInstrumentation = InstrumentationRegistry.getInstrumentation();
|
||||
mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
|
||||
mPackageManager = mContext.getPackageManager();
|
||||
@@ -835,4 +853,146 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
||||
assertTrue(lowerBoundSec <= interval);
|
||||
assertTrue(interval <= upperBoundSec);
|
||||
}
|
||||
|
||||
// Returns "true", "false" or "none"
|
||||
private String getWifiMeteredStatus(String ssid) throws Exception {
|
||||
// Interestingly giving the SSID as an argument to list wifi-networks
|
||||
// only works iff the network in question has the "false" policy.
|
||||
// Also unfortunately runShellCommand does not pass the command to the interpreter
|
||||
// so it's not possible to | grep the ssid.
|
||||
final String command = "cmd netpolicy list wifi-networks";
|
||||
final String policyString = runShellCommand(mInstrumentation, command);
|
||||
|
||||
final Matcher m = Pattern.compile("^" + ssid + ";(true|false|none)$",
|
||||
Pattern.MULTILINE | Pattern.UNIX_LINES).matcher(policyString);
|
||||
if (!m.find()) {
|
||||
fail("Unexpected format from cmd netpolicy");
|
||||
}
|
||||
return m.group(1);
|
||||
}
|
||||
|
||||
// metered should be "true", "false" or "none"
|
||||
private void setWifiMeteredStatus(String ssid, String metered) throws Exception {
|
||||
final String setCommand = "cmd netpolicy set metered-network " + ssid + " " + metered;
|
||||
runShellCommand(mInstrumentation, setCommand);
|
||||
assertEquals(getWifiMeteredStatus(ssid), metered);
|
||||
}
|
||||
|
||||
private String unquoteSSID(String ssid) {
|
||||
// SSID is returned surrounded by quotes if it can be decoded as UTF-8.
|
||||
// Otherwise it's guaranteed not to start with a quote.
|
||||
if (ssid.charAt(0) == '"') {
|
||||
return ssid.substring(1, ssid.length() - 1);
|
||||
} else {
|
||||
return ssid;
|
||||
}
|
||||
}
|
||||
|
||||
private void waitForActiveNetworkMetered(boolean requestedMeteredness) throws Exception {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final NetworkCallback networkCallback = new NetworkCallback() {
|
||||
@Override
|
||||
public void onCapabilitiesChanged(Network network, NetworkCapabilities nc) {
|
||||
final boolean metered = !nc.hasCapability(NET_CAPABILITY_NOT_METERED);
|
||||
if (metered == requestedMeteredness) {
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
};
|
||||
// Registering a callback here guarantees onCapabilitiesChanged is called immediately
|
||||
// with the current setting. Therefore, if the setting has already been changed,
|
||||
// this method will return right away, and if not it will wait for the setting to change.
|
||||
mCm.registerDefaultNetworkCallback(networkCallback);
|
||||
if (!latch.await(NETWORK_CHANGE_METEREDNESS_TIMEOUT, TimeUnit.MILLISECONDS)) {
|
||||
fail("Timed out waiting for active network metered status to change to "
|
||||
+ requestedMeteredness + " ; network = " + mCm.getActiveNetwork());
|
||||
}
|
||||
mCm.unregisterNetworkCallback(networkCallback);
|
||||
}
|
||||
|
||||
private void assertMultipathPreferenceIsEventually(Network network, int oldValue,
|
||||
int expectedValue) {
|
||||
// Sanity check : if oldValue == expectedValue, there is no way to guarantee the test
|
||||
// is not flaky.
|
||||
assertNotSame(oldValue, expectedValue);
|
||||
|
||||
for (int i = 0; i < NUM_TRIES_MULTIPATH_PREF_CHECK; ++i) {
|
||||
final int actualValue = mCm.getMultipathPreference(network);
|
||||
if (actualValue == expectedValue) {
|
||||
return;
|
||||
}
|
||||
if (actualValue != oldValue) {
|
||||
fail("Multipath preference is neither previous (" + oldValue
|
||||
+ ") nor expected (" + expectedValue + ")");
|
||||
}
|
||||
SystemClock.sleep(INTERVAL_MULTIPATH_PREF_CHECK_MS);
|
||||
}
|
||||
fail("Timed out waiting for multipath preference to change. expected = "
|
||||
+ expectedValue + " ; actual = " + mCm.getMultipathPreference(network));
|
||||
}
|
||||
|
||||
private int getCurrentMeteredMultipathPreference(ContentResolver resolver) {
|
||||
final String rawMeteredPref = Settings.Global.getString(resolver,
|
||||
NETWORK_METERED_MULTIPATH_PREFERENCE);
|
||||
return TextUtils.isEmpty(rawMeteredPref)
|
||||
? mContext.getResources().getInteger(R.integer.config_networkMeteredMultipathPreference)
|
||||
: Integer.parseInt(rawMeteredPref);
|
||||
}
|
||||
|
||||
private int findNextPrefValue(ContentResolver resolver) {
|
||||
// A bit of a nuclear hammer, but race conditions in CTS are bad. To be able to
|
||||
// detect a correct setting value without race conditions, the next pref must
|
||||
// be a valid value (range 0..3) that is different from the old setting of the
|
||||
// metered preference and from the unmetered preference.
|
||||
final int meteredPref = getCurrentMeteredMultipathPreference(resolver);
|
||||
final int unmeteredPref = ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED;
|
||||
if (0 != meteredPref && 0 != unmeteredPref) return 0;
|
||||
if (1 != meteredPref && 1 != unmeteredPref) return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that getMultipathPreference does return appropriate values
|
||||
* for metered and unmetered networks.
|
||||
*/
|
||||
public void testGetMultipathPreference() throws Exception {
|
||||
final ContentResolver resolver = mContext.getContentResolver();
|
||||
final Network network = ensureWifiConnected();
|
||||
final String ssid = unquoteSSID(mWifiManager.getConnectionInfo().getSSID());
|
||||
final String oldMeteredSetting = getWifiMeteredStatus(ssid);
|
||||
final String oldMeteredMultipathPreference = Settings.Global.getString(
|
||||
resolver, NETWORK_METERED_MULTIPATH_PREFERENCE);
|
||||
try {
|
||||
final int initialMeteredPreference = getCurrentMeteredMultipathPreference(resolver);
|
||||
int newMeteredPreference = findNextPrefValue(resolver);
|
||||
Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
|
||||
Integer.toString(newMeteredPreference));
|
||||
setWifiMeteredStatus(ssid, "true");
|
||||
waitForActiveNetworkMetered(true);
|
||||
assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
|
||||
NET_CAPABILITY_NOT_METERED), false);
|
||||
assertMultipathPreferenceIsEventually(network, initialMeteredPreference,
|
||||
newMeteredPreference);
|
||||
|
||||
final int oldMeteredPreference = newMeteredPreference;
|
||||
newMeteredPreference = findNextPrefValue(resolver);
|
||||
Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
|
||||
Integer.toString(newMeteredPreference));
|
||||
assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
|
||||
NET_CAPABILITY_NOT_METERED), false);
|
||||
assertMultipathPreferenceIsEventually(network,
|
||||
oldMeteredPreference, newMeteredPreference);
|
||||
|
||||
setWifiMeteredStatus(ssid, "false");
|
||||
waitForActiveNetworkMetered(false);
|
||||
assertEquals(mCm.getNetworkCapabilities(network).hasCapability(
|
||||
NET_CAPABILITY_NOT_METERED), true);
|
||||
assertMultipathPreferenceIsEventually(network, newMeteredPreference,
|
||||
ConnectivityManager.MULTIPATH_PREFERENCE_UNMETERED);
|
||||
} finally {
|
||||
Settings.Global.putString(resolver, NETWORK_METERED_MULTIPATH_PREFERENCE,
|
||||
oldMeteredMultipathPreference);
|
||||
setWifiMeteredStatus(ssid, oldMeteredSetting);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user