diff options
author | David Su <dysu@google.com> | 2020-03-06 20:58:19 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-03-06 20:58:19 +0000 |
commit | 544e531dc8534bbf197c2abe58748c897a0f5a75 (patch) | |
tree | dbdf62746839e951f447bc5e64430f9c577085ac /tests | |
parent | 20869409e420dade9f2295f8fa2f78550f1ea7a3 (diff) | |
parent | 560b70f1a5b1273f8fe3e8d5d4dbbf08473be985 (diff) |
Merge "Wifi: Add MTS-only test for dumpsys metrics" into rvc-dev
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Android.bp | 1 | ||||
-rw-r--r-- | tests/mts/Android.bp | 49 | ||||
-rw-r--r-- | tests/mts/AndroidManifest.xml | 35 | ||||
-rw-r--r-- | tests/mts/AndroidTest.xml | 40 | ||||
-rw-r--r-- | tests/mts/src/android/net/wifi/mts/StreamReader.java | 115 | ||||
-rw-r--r-- | tests/mts/src/android/net/wifi/mts/WifiDumpsysMetricsTest.java | 80 | ||||
-rw-r--r-- | tests/mts/src/android/net/wifi/mts/WifiFeature.java | 32 |
7 files changed, 352 insertions, 0 deletions
diff --git a/tests/Android.bp b/tests/Android.bp index 087691d89..67fea52b2 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -16,4 +16,5 @@ // ============================================================ subdirs = [ "wifitests", + "mts", ] diff --git a/tests/mts/Android.bp b/tests/mts/Android.bp new file mode 100644 index 000000000..19b0eb1f7 --- /dev/null +++ b/tests/mts/Android.bp @@ -0,0 +1,49 @@ +// Copyright (C) 2020 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. + +// Wifi MTS-only tests i.e. not part of CTS or GTS +// Used to test functionality that is only guaranteed to be implemented in the Wifi Mainline module, +// but is not required if the Wifi Mainline module is not present on the device. +android_test { + name: "MtsWifiTestCases", + defaults: ["cts_defaults"], + + libs: [ + "org.apache.http.legacy", + "android.test.base.stubs", + ], + + srcs: [ "src/**/*.java" ], + + static_libs: [ + // for ShellIdentityUtils, builds against test_current + "compatibility-device-util-axt", + "ctstestrunner-axt", + "ctstestserver", + "junit", + "junit-params", + "truth-prebuilt", + // for Wifi protos, builds against system_current + "wifi-nano-protos", + // for AndroidJUnit4 + "androidx.test.ext.junit", + "androidx.test.runner", + ], + + // need access to system_current and test_current, so needs to be platform_apis: true + platform_apis: true, + + test_suites: [ "mts" ], + test_config: "AndroidTest.xml", +} diff --git a/tests/mts/AndroidManifest.xml b/tests/mts/AndroidManifest.xml new file mode 100644 index 000000000..7130e6d89 --- /dev/null +++ b/tests/mts/AndroidManifest.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2020 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. + --> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.net.wifi.mts" + android:targetSandboxVersion="2"> + + <application android:usesCleartextTraffic="true"> + <uses-library android:name="android.test.runner" /> + <uses-library android:name="org.apache.http.legacy" android:required="false" /> + </application> + + <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" + android:targetPackage="android.net.wifi.mts" + android:label="MTS tests for android.net.wifi"> + <meta-data android:name="listener" + android:value="com.android.cts.runner.CtsTestRunListener" /> + </instrumentation> + +</manifest> + diff --git a/tests/mts/AndroidTest.xml b/tests/mts/AndroidTest.xml new file mode 100644 index 000000000..ee5878600 --- /dev/null +++ b/tests/mts/AndroidTest.xml @@ -0,0 +1,40 @@ +<!-- + ~ Copyright (C) 2020 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. + --> +<configuration description="Test config for MtsWifiTestCases"> + <option name="test-suite-tag" value="cts" /> + <option name="config-descriptor:metadata" key="component" value="networking" /> + <option name="config-descriptor:metadata" key="parameter" value="instant_app" /> + <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" /> + <option name="config-descriptor:metadata" key="parameter" value="secondary_user" /> + <option name="not-shardable" value="true" /> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="MtsWifiTestCases.apk" /> + </target_preparer> + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="android.net.wifi.mts" /> + <option name="runtime-hint" value="9m4s" /> + <option name="hidden-api-checks" value="false" /> + <option name="isolated-storage" value="false" /> + </test> + + <!-- Only run MtsWifiTestCases if the Wifi Mainline module is installed. If the Wifi Mainline + module is not installed, the device is not required to pass these test cases. --> + <object type="module_controller" + class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController"> + <option name="mainline-module-package-name" value="com.google.android.wifi" /> + </object> +</configuration> diff --git a/tests/mts/src/android/net/wifi/mts/StreamReader.java b/tests/mts/src/android/net/wifi/mts/StreamReader.java new file mode 100644 index 000000000..c0c35bbb5 --- /dev/null +++ b/tests/mts/src/android/net/wifi/mts/StreamReader.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2020 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 android.net.wifi.mts; + +import android.util.Log; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +/** + * Reads from the given BufferedReader and saves the output to a string. + */ +public class StreamReader extends Thread { + private static final String TAG = "ConnMetrics:" + StreamReader.class.getSimpleName(); + private BufferedReader mSource; + private String mOutput; + + public StreamReader(BufferedReader source) { + mSource = source; + } + + public String getOutput() { + if (mOutput == null) { + throw new IllegalStateException( + "Should call start and join before trying to get output"); + } + return mOutput; + } + + @Override + public void run() { + StringBuilder sb = new StringBuilder(); + String s; + try { + while ((s = mSource.readLine()) != null) { + sb.append(s); + sb.append("\n"); + } + } catch (IOException e) { + Log.e(TAG, "Error reading input", e); + } finally { + try { + mSource.close(); + } catch (IOException e) { + Log.e(TAG, "Error closing reader", e); + } + } + mOutput = sb.toString(); + } + + /** + * Runs the specified process command and returns the results of the input and error streams. + * + * @return The output of the input stream, or null if there was an exception. + */ + public static String runProcessCommand(String command) { + try { + Process process = Runtime.getRuntime().exec(command); + + BufferedReader stdInput = new BufferedReader( + new InputStreamReader(process.getInputStream())); + BufferedReader stdError = new BufferedReader( + new InputStreamReader(process.getErrorStream())); + StreamReader inputReader = new StreamReader(stdInput); + StreamReader errorReader = new StreamReader(stdError); + + inputReader.start(); + errorReader.start(); + + process.waitFor(); + try { + inputReader.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + Log.e(TAG, "Error joining thread", e); + } + try { + errorReader.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + Log.e(TAG, "Error joining thread", e); + } + + // Some commands will return some valid data while also printing a message in + // the error stream, so returning result of the input stream regardless of if + // there's a message in the error stream. + if (errorReader.getOutput().length() > 0) { + Log.e(TAG, errorReader.getOutput()); + } + return inputReader.getOutput(); + } catch (IOException e) { + Log.e(TAG, "Error running command", e); + return null; + } catch (InterruptedException e) { + Log.e(TAG, "Process was interrupted", e); + Thread.currentThread().interrupt(); + return null; + } + } +} diff --git a/tests/mts/src/android/net/wifi/mts/WifiDumpsysMetricsTest.java b/tests/mts/src/android/net/wifi/mts/WifiDumpsysMetricsTest.java new file mode 100644 index 000000000..c548b852c --- /dev/null +++ b/tests/mts/src/android/net/wifi/mts/WifiDumpsysMetricsTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2020 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 android.net.wifi.mts; + +import static com.google.common.truth.Truth.assertThat; + +import static org.junit.Assume.assumeTrue; + +import android.content.Context; +import android.util.Base64; + +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.compatibility.common.util.ShellIdentityUtils; +import com.android.server.wifi.proto.nano.WifiMetricsProto.WifiLog; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +public class WifiDumpsysMetricsTest { + + private static final String WIFI_DUMP_PROTO_CMD = "/system/bin/dumpsys wifi wifiMetricsProto"; + + private static final String START_TAG = "WifiMetrics:\n"; + private static final String END_TAG = "\nEndWifiMetrics"; + + @Before + public void setUp() throws Exception { + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assumeTrue(WifiFeature.isWifiSupported(context)); + } + + /** + * Test that Wifi dumps metrics in the expected format. + * + * Assumption: + * - Test device should have at least 1 saved network + */ + @Test + public void testWifiDumpMetrics() throws Exception { + String rawDumpOutput = ShellIdentityUtils.invokeWithShellPermissions( + () -> StreamReader.runProcessCommand(WIFI_DUMP_PROTO_CMD)); + + assertThat(rawDumpOutput).isNotNull(); + + int protoStart = rawDumpOutput.indexOf(START_TAG); + int protoEnd = rawDumpOutput.indexOf(END_TAG); + + assertThat(protoStart).isAtLeast(0); + assertThat(protoEnd).isAtLeast(protoStart); + + String protoString = rawDumpOutput.substring(protoStart + START_TAG.length(), protoEnd); + byte[] protoBytes = Base64.decode(protoString, Base64.DEFAULT); + + WifiLog wifiLog = WifiLog.parseFrom(protoBytes); + + assertThat(wifiLog.numSavedNetworks).isAtLeast(1); + assertThat(wifiLog.numOpenNetworks).isAtLeast(0); + assertThat(wifiLog.numHiddenNetworks).isAtLeast(0); + assertThat(wifiLog.numWificondCrashes).isAtLeast(0); + assertThat(wifiLog.numSupplicantCrashes).isAtLeast(0); + } +} diff --git a/tests/mts/src/android/net/wifi/mts/WifiFeature.java b/tests/mts/src/android/net/wifi/mts/WifiFeature.java new file mode 100644 index 000000000..701f38453 --- /dev/null +++ b/tests/mts/src/android/net/wifi/mts/WifiFeature.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2020 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 android.net.wifi.mts; + +import android.content.Context; +import android.content.pm.PackageManager; + +public class WifiFeature { + static boolean isWifiSupported(Context context) { + PackageManager packageManager = context.getPackageManager(); + return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI); + } + + static boolean isP2pSupported(Context context) { + PackageManager packageManager = context.getPackageManager(); + return packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI_DIRECT); + } +} |