Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4298941 authored by jackqdyulei's avatar jackqdyulei
Browse files

Add functional test for bt anomaly detector

This cl:
Set up the environment for functional test
1. Update Android.mk by adding instrumentation and libs
2. Update AndroidManifest.xml by adding runner

Add functional test for bt anomaly, with the following workflow
1. reset battery stats
2. pretend unplug and screen off
3. Start AnomalyTester app, set values and click start button
4. Wait its running
5. Check anomaly preference in battery main page
6. reset all parameters

Bug: 63815938
Test: runtest -x BluetoothAnomalyTest
Change-Id: Ief02a314d21f6c32d70729047a1d4bdce9ad9920
parent 0cc62f86
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -2,6 +2,15 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := tests
LOCAL_CERTIFICATE := platform

LOCAL_JAVA_LIBRARIES := android.test.runner bouncycastle

LOCAL_STATIC_JAVA_LIBRARIES := \
    android-support-test \
    mockito-target \
    ub-uiautomator \
    truth-prebuilt \

LOCAL_SRC_FILES := $(call all-subdir-java-files)

@@ -9,7 +18,7 @@ LOCAL_PROGUARD_ENABLED := disabled

LOCAL_PACKAGE_NAME := AnomalyTester

LOCAL_CERTIFICATE := platform
LOCAL_INSTRUMENTATION_FOR := Settings

LOCAL_USE_AAPT2 := true

+8 −0
Original line number Diff line number Diff line
@@ -22,11 +22,13 @@
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>

    <application
        android:allowBackup="false"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@android:style/Theme.Material.Light.DarkActionBar">
        <uses-library android:name="android.test.runner" />
        <activity
            android:name=".AnomalyActivity"
            android:exported="true">
@@ -41,4 +43,10 @@
            android:exported="false"/>
    </application>

    <instrumentation
        android:name="android.support.test.runner.AndroidJUnitRunner"
        android:targetPackage="com.android.settings"
        android:label="Settings Test Cases">
    </instrumentation>

</manifest>
 No newline at end of file
+108 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.settings.anomaly.tests;

import static com.google.common.truth.Truth.assertWithMessage;

import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.Until;
import android.text.format.DateUtils;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Functional test for bluetooth unoptimized scanning anomaly detector
 *
 * @see com.android.settings.fuelgauge.anomaly.checker.BluetoothScanAnomalyDetector
 */
@RunWith(AndroidJUnit4.class)
public class BluetoothAnomalyTest {
    private static final String BATTERY_INTENT = "android.intent.action.POWER_USAGE_SUMMARY";
    private static final String RES_BT_EDITTEXT =
            "com.android.settings.anomaly.tester:id/bluetooth_run_time";
    private static final String RES_BT_BUTTON =
            "com.android.settings.anomaly.tester:id/bluetooth_button";
    private static final long TIME_OUT = 3000;
    private UiDevice mDevice;

    @Before
    public void setUp() {
        final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
        final Context context = instrumentation.getContext();
        mDevice = UiDevice.getInstance(instrumentation);

        // setup environment
        TestUtils.setUp(instrumentation);
        // start anomaly-tester app
        TestUtils.startAnomalyApp(context, mDevice);
    }

    @After
    public void tearDown() {
        TestUtils.tearDown(InstrumentationRegistry.getInstrumentation());
    }

    @Test
    public void testBluetoothAnomaly_longScanningTime_reportAnomaly() throws InterruptedException {
        // Set running time
        final long durationMs = DateUtils.SECOND_IN_MILLIS * 15;
        TestUtils.setEditTextWithValue(mDevice, RES_BT_EDITTEXT, durationMs);

        // Click start button
        TestUtils.clickButton(mDevice, RES_BT_BUTTON);

        // Wait for its running
        mDevice.pressHome();
        TestUtils.wait(mDevice, durationMs);

        // Check it in battery main page
        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
        instrumentation.startActivitySync(new Intent(BATTERY_INTENT));
        assertWithMessage("Doesn't have bluetooth anomaly").that(
                mDevice.wait(Until.findObject(By.text("AnomalyTester draining battery")),
                        TIME_OUT)).isNotNull();
    }

    @Test
    public void testBluetoothAnomaly_shortScanningTime_notReport() throws InterruptedException {
        // Set running time
        final long durationMs = DateUtils.SECOND_IN_MILLIS;
        TestUtils.setEditTextWithValue(mDevice, RES_BT_EDITTEXT, durationMs);

        // Click start button
        TestUtils.clickButton(mDevice, RES_BT_BUTTON);

        // Wait for its running
        mDevice.pressHome();
        TestUtils.wait(mDevice, durationMs);

        // Check it in battery main page
        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
        instrumentation.startActivitySync(new Intent(BATTERY_INTENT));
        assertWithMessage("Shouldn't have bluetooth anomaly").that(
                mDevice.wait(Until.findObject(By.text("AnomalyTester draining battery")),
                        TIME_OUT)).isNull();
    }

}
+91 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.settings.anomaly.tests;

import static com.google.common.truth.Truth.assertWithMessage;

import android.app.Instrumentation;
import android.app.UiAutomation;
import android.content.Context;
import android.content.Intent;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.Until;

public class TestUtils {
    private static final String PACKAGE_NAME = "com.android.settings.anomaly.tester";
    private static final long TIME_OUT = 3000;

    /**
     * This method set up the environment for anomaly test
     *
     * @param instrumentation to execute command
     */
    public static void setUp(Instrumentation instrumentation) {
        final UiAutomation uiAutomation = instrumentation.getUiAutomation();
        // pretend unplug and screen off, also reset the battery stats
        uiAutomation.executeShellCommand("dumpsys battery unplug");
        uiAutomation.executeShellCommand("dumpsys batterystats enable pretend-screen-off");
        uiAutomation.executeShellCommand("dumpsys batterystats --reset");
    }

    /**
     * This method cleans up all the commands in {@link #setUp(Instrumentation)}
     *
     * @param instrumentation to execute command
     */
    public static void tearDown(Instrumentation instrumentation) {
        final UiAutomation uiAutomation = instrumentation.getUiAutomation();
        // reset unplug and screen-off
        uiAutomation.executeShellCommand("dumpsys battery reset");
        uiAutomation.executeShellCommand("dumpsys batterystats disable pretend-screen-off");
    }

    public static void startAnomalyApp(Context context, UiDevice uiDevice) {
        final Intent intent = context.getPackageManager().getLaunchIntentForPackage(PACKAGE_NAME);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        context.startActivity(intent);
        uiDevice.wait(Until.hasObject(By.pkg(PACKAGE_NAME).depth(0)), TIME_OUT);
    }

    /**
     * Find {@link android.widget.EditText} with {@code res} and set its {@code value}
     */
    public static void setEditTextWithValue(UiDevice uiDevice, String res, long value) {
        final UiObject2 editText = uiDevice.findObject(By.res(res));
        assertWithMessage("Cannot find editText with res: " + res).that(editText).isNotNull();
        editText.setText(String.valueOf(value));
    }

    /**
     * Find {@link android.widget.Button} with {@code res} and click it
     */
    public static void clickButton(UiDevice uiDevice, String res) {
        final UiObject2 button = uiDevice.findObject(By.res(res));
        assertWithMessage("Cannot find button with res: " + res).that(button).isNotNull();
        button.click();
    }

    /**
     * Make {@link UiDevice} wait for {@code timeMs}
     *
     * @see Thread#sleep(long)
     */
    public static void wait(UiDevice uiDevice, long timeMs) throws InterruptedException {
        uiDevice.waitForIdle();
        Thread.sleep(timeMs);
    }
}