From 560b70f1a5b1273f8fe3e8d5d4dbbf08473be985 Mon Sep 17 00:00:00 2001 From: David Su Date: Tue, 3 Mar 2020 21:10:50 -0800 Subject: Wifi: Add MTS-only test for dumpsys metrics Add MTS-only test (i.e. not in CTS/GTS) for Wifi metrics dumpsys, since only the Wifi Mainline module is required to implement this feature. Bug: 150650681 Test: atest MtsWifiTestCases Test: m mts && mts-tradefed run mts -m MtsWifiTestCases Change-Id: I3d85c5fc41f1db5e4b1c87f4dd1b0141bd5094f1 --- tests/Android.bp | 1 + tests/mts/Android.bp | 49 +++++++++ tests/mts/AndroidManifest.xml | 35 +++++++ tests/mts/AndroidTest.xml | 40 +++++++ .../mts/src/android/net/wifi/mts/StreamReader.java | 115 +++++++++++++++++++++ .../net/wifi/mts/WifiDumpsysMetricsTest.java | 80 ++++++++++++++ .../mts/src/android/net/wifi/mts/WifiFeature.java | 32 ++++++ 7 files changed, 352 insertions(+) create mode 100644 tests/mts/Android.bp create mode 100644 tests/mts/AndroidManifest.xml create mode 100644 tests/mts/AndroidTest.xml create mode 100644 tests/mts/src/android/net/wifi/mts/StreamReader.java create mode 100644 tests/mts/src/android/net/wifi/mts/WifiDumpsysMetricsTest.java create mode 100644 tests/mts/src/android/net/wifi/mts/WifiFeature.java (limited to 'tests') 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 @@ + + + + + + + + + + + + + + + + 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 @@ + + + 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); + } +} -- cgit v1.2.3