Merge changes from topic "bugreporting-aosp-sync"
* changes: Fix consent timed out to sharing bugreport data Add BugreportManagerTestCases to bugreport presubmit Enable bug report tests in pre/postsubmit Run bugreport unit test without script
This commit is contained in:
48
core/java/android/os/TEST_MAPPING
Normal file
48
core/java/android/os/TEST_MAPPING
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "BugreportManagerTestCases",
|
||||
"options": [
|
||||
{
|
||||
"exclude-annotation": "androidx.test.filters.LargeTest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "CtsBugreportTestCases",
|
||||
"options": [
|
||||
{
|
||||
"exclude-annotation": "androidx.test.filters.LargeTest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "ShellTests",
|
||||
"options": [
|
||||
{
|
||||
"exclude-annotation": "androidx.test.filters.LargeTest"
|
||||
},
|
||||
{
|
||||
"exclude-annotation": "androidx.test.filters.FlakyTest"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"postsubmit": [
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "BugreportManagerTestCases"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "CtsBugreportTestCases"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "ShellTests"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -15,12 +15,22 @@
|
||||
android_test {
|
||||
name: "BugreportManagerTestCases",
|
||||
srcs: ["src/**/*.java"],
|
||||
data: [":bugreport_artifacts"],
|
||||
libs: [
|
||||
"android.test.runner",
|
||||
"android.test.base",
|
||||
],
|
||||
static_libs: ["androidx.test.rules", "truth-prebuilt"],
|
||||
static_libs: [
|
||||
"androidx.test.rules",
|
||||
"androidx.test.uiautomator_uiautomator",
|
||||
"truth-prebuilt",
|
||||
],
|
||||
test_suites: ["general-tests"],
|
||||
sdk_version: "test_current",
|
||||
platform_apis: true,
|
||||
}
|
||||
|
||||
filegroup {
|
||||
name: "bugreport_artifacts",
|
||||
srcs: ["config/test-sysconfig.xml"],
|
||||
}
|
||||
|
||||
@@ -21,11 +21,16 @@
|
||||
<option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
|
||||
<option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
|
||||
<option name="cleanup-apks" value="true"/>
|
||||
<option name="test-file-name" value="BugreportManagerTestCases.apk"/>
|
||||
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
|
||||
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
|
||||
<option name="push-file" key="test-sysconfig.xml" value="/system/etc/sysconfig/allow-br-from-tests.xml" />
|
||||
<option name="push-file" key="BugreportManagerTestCases.apk" value="/system/priv-app/BugreportManagerTestCases.apk" />
|
||||
<option name="abort-on-push-failure" value="true" />
|
||||
<option name="cleanup" value="true" />
|
||||
<option name="remount-system" value="true" />
|
||||
</target_preparer>
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.RebootTargetPreparer" />
|
||||

|
||||
<test class="com.android.tradefed.testtype.AndroidJUnitTest">
|
||||
<option name="package" value="com.android.os.bugreports.tests"/>
|
||||
<!-- test-timeout unit is ms, value = 30 min -->
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (C) 2019 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.
|
||||
|
||||
# Script to run bugreport unitests
|
||||
# Must run on a rooted device.
|
||||
# Must run lunch before running the script
|
||||
# Usage: ${ANDROID_BUILD_TOP}/frameworks/base/core/tests/bugreports/run.sh
|
||||
|
||||
# NOTE: This script replaces the framework-sysconfig.xml on your device, so use with caution.
|
||||
# It tries to replace it when done, but if the script does not finish cleanly
|
||||
# (for e.g. force stopped mid-way) your device will be left in an inconsistent state.
|
||||
# Reflashing will restore the right config.
|
||||
|
||||
TMP_SYS_CONFIG=/var/tmp/framework-sysconfig.xml
|
||||
|
||||
if [[ -z $ANDROID_PRODUCT_OUT ]]; then
|
||||
echo "Please lunch before running this test."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Print every command to console.
|
||||
set -x
|
||||
|
||||
make -j BugreportManagerTestCases &&
|
||||
adb root &&
|
||||
adb remount &&
|
||||
adb wait-for-device &&
|
||||
# Save the sysconfig file in a tmp location and push the test config in
|
||||
adb pull /system/etc/sysconfig/framework-sysconfig.xml "${TMP_SYS_CONFIG}" &&
|
||||
adb push $ANDROID_BUILD_TOP/frameworks/base/core/tests/bugreports/config/test-sysconfig.xml /system/etc/sysconfig/framework-sysconfig.xml &&
|
||||
# The test app needs to be a priv-app.
|
||||
adb push $OUT/testcases/BugreportManagerTestCases/*/BugreportManagerTestCases.apk /system/priv-app ||
|
||||
exit 1
|
||||
|
||||
adb reboot &&
|
||||
adb wait-for-device &&
|
||||
atest BugreportManagerTest || echo "Tests FAILED!"
|
||||
|
||||
# Restore the saved config file
|
||||
if [ -f "${TMP_SYS_CONFIG}" ]; then
|
||||
SIZE=$(stat --printf="%s" "${TMP_SYS_CONFIG}")
|
||||
if [ SIZE > 0 ]; then
|
||||
adb remount &&
|
||||
adb wait-for-device &&
|
||||
adb push "${TMP_SYS_CONFIG}" /system/etc/sysconfig/framework-sysconfig.xml &&
|
||||
rm "${TMP_SYS_CONFIG}"
|
||||
fi
|
||||
fi
|
||||
@@ -18,6 +18,8 @@ package com.android.os.bugreports.tests;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.Manifest;
|
||||
@@ -25,17 +27,27 @@ import android.content.Context;
|
||||
import android.os.BugreportManager;
|
||||
import android.os.BugreportManager.BugreportCallback;
|
||||
import android.os.BugreportParams;
|
||||
import android.os.FileUtils;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.StrictMode;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.uiautomator.By;
|
||||
import androidx.test.uiautomator.BySelector;
|
||||
import androidx.test.uiautomator.UiDevice;
|
||||
import androidx.test.uiautomator.UiObject2;
|
||||
import androidx.test.uiautomator.Until;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExternalResource;
|
||||
import org.junit.rules.TestName;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
@@ -51,9 +63,11 @@ import java.util.concurrent.TimeUnit;
|
||||
@RunWith(JUnit4.class)
|
||||
public class BugreportManagerTest {
|
||||
@Rule public TestName name = new TestName();
|
||||
@Rule public ExtendedStrictModeVmPolicy mTemporaryVmPolicy = new ExtendedStrictModeVmPolicy();
|
||||
|
||||
private static final String TAG = "BugreportManagerTest";
|
||||
private static final long BUGREPORT_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(10);
|
||||
private static final long UIAUTOMATOR_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10);
|
||||
|
||||
private Handler mHandler;
|
||||
private Executor mExecutor;
|
||||
@@ -86,6 +100,8 @@ public class BugreportManagerTest {
|
||||
@After
|
||||
public void teardown() throws Exception {
|
||||
dropPermissions();
|
||||
FileUtils.closeQuietly(mBugreportFd);
|
||||
FileUtils.closeQuietly(mScreenshotFd);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,47 +111,45 @@ public class BugreportManagerTest {
|
||||
// wifi bugreport does not take screenshot
|
||||
mBrm.startBugreport(mBugreportFd, null /*screenshotFd = null*/, wifi(),
|
||||
mExecutor, callback);
|
||||
shareConsentDialog(ConsentReply.ALLOW);
|
||||
waitTillDoneOrTimeout(callback);
|
||||
|
||||
assertThat(callback.isDone()).isTrue();
|
||||
// Wifi bugreports should not receive any progress.
|
||||
assertThat(callback.hasReceivedProgress()).isFalse();
|
||||
// TODO: Because of b/130234145, consent dialog is not shown; so we get a timeout error.
|
||||
// When the bug is fixed, accept consent via UIAutomator and verify contents
|
||||
// of mBugreportFd.
|
||||
assertThat(callback.getErrorCode()).isEqualTo(
|
||||
BugreportCallback.BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT);
|
||||
assertThat(mBugreportFile.length()).isGreaterThan(0L);
|
||||
assertFdsAreClosed(mBugreportFd);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@Test
|
||||
public void normalFlow_interactive() throws Exception {
|
||||
BugreportCallbackImpl callback = new BugreportCallbackImpl();
|
||||
// interactive bugreport does not take screenshot
|
||||
mBrm.startBugreport(mBugreportFd, null /*screenshotFd = null*/, interactive(),
|
||||
mExecutor, callback);
|
||||
|
||||
shareConsentDialog(ConsentReply.ALLOW);
|
||||
waitTillDoneOrTimeout(callback);
|
||||
|
||||
assertThat(callback.isDone()).isTrue();
|
||||
// Interactive bugreports show progress updates.
|
||||
assertThat(callback.hasReceivedProgress()).isTrue();
|
||||
assertThat(callback.getErrorCode()).isEqualTo(
|
||||
BugreportCallback.BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT);
|
||||
assertThat(mBugreportFile.length()).isGreaterThan(0L);
|
||||
assertFdsAreClosed(mBugreportFd);
|
||||
}
|
||||
|
||||
@LargeTest
|
||||
@Test
|
||||
public void normalFlow_full() throws Exception {
|
||||
BugreportCallbackImpl callback = new BugreportCallbackImpl();
|
||||
mBrm.startBugreport(mBugreportFd, mScreenshotFd, full(), mExecutor, callback);
|
||||
|
||||
shareConsentDialog(ConsentReply.ALLOW);
|
||||
waitTillDoneOrTimeout(callback);
|
||||
|
||||
assertThat(callback.isDone()).isTrue();
|
||||
assertThat(callback.getErrorCode()).isEqualTo(
|
||||
BugreportCallback.BUGREPORT_ERROR_USER_CONSENT_TIMED_OUT);
|
||||
// bugreport and screenshot files should be empty when user consent timed out.
|
||||
assertThat(mBugreportFile.length()).isEqualTo(0);
|
||||
assertThat(mScreenshotFile.length()).isEqualTo(0);
|
||||
// bugreport and screenshot files shouldn't be empty when user consents.
|
||||
assertThat(mBugreportFile.length()).isGreaterThan(0L);
|
||||
assertThat(mScreenshotFile.length()).isGreaterThan(0L);
|
||||
assertFdsAreClosed(mBugreportFd, mScreenshotFd);
|
||||
}
|
||||
|
||||
@@ -144,6 +158,8 @@ public class BugreportManagerTest {
|
||||
// Start bugreport #1
|
||||
BugreportCallbackImpl callback = new BugreportCallbackImpl();
|
||||
mBrm.startBugreport(mBugreportFd, mScreenshotFd, wifi(), mExecutor, callback);
|
||||
// TODO(b/162389762) Make sure the wait time is reasonable
|
||||
shareConsentDialog(ConsentReply.ALLOW);
|
||||
|
||||
// Before #1 is done, try to start #2.
|
||||
assertThat(callback.isDone()).isFalse();
|
||||
@@ -375,4 +391,88 @@ public class BugreportManagerTest {
|
||||
private static BugreportParams full() {
|
||||
return new BugreportParams(BugreportParams.BUGREPORT_MODE_FULL);
|
||||
}
|
||||
|
||||
/* Allow/deny the consent dialog to sharing bugreport data or check existence only. */
|
||||
private enum ConsentReply {
|
||||
ALLOW,
|
||||
DENY,
|
||||
TIMEOUT
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure the consent dialog is shown and take action according to <code>consentReply<code/>.
|
||||
* It will fail if the dialog is not shown when <code>ignoreNotFound<code/> is false.
|
||||
*/
|
||||
private void shareConsentDialog(@NonNull ConsentReply consentReply) throws Exception {
|
||||
mTemporaryVmPolicy.permitIncorrectContextUse();
|
||||
final UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
|
||||
|
||||
// Unlock before finding/clicking an object.
|
||||
device.wakeUp();
|
||||
device.executeShellCommand("wm dismiss-keyguard");
|
||||
|
||||
final BySelector consentTitleObj = By.res("android", "alertTitle");
|
||||
if (!device.wait(Until.hasObject(consentTitleObj), UIAUTOMATOR_TIMEOUT_MS)) {
|
||||
fail("The consent dialog is not found");
|
||||
}
|
||||
if (consentReply.equals(ConsentReply.TIMEOUT)) {
|
||||
return;
|
||||
}
|
||||
final BySelector selector;
|
||||
if (consentReply.equals(ConsentReply.ALLOW)) {
|
||||
selector = By.res("android", "button1");
|
||||
Log.d(TAG, "Allow the consent dialog");
|
||||
} else { // ConsentReply.DENY
|
||||
selector = By.res("android", "button2");
|
||||
Log.d(TAG, "Deny the consent dialog");
|
||||
}
|
||||
final UiObject2 btnObj = device.findObject(selector);
|
||||
assertNotNull("The button of consent dialog is not found", btnObj);
|
||||
btnObj.click();
|
||||
|
||||
Log.d(TAG, "Wait for the dialog to be dismissed");
|
||||
assertTrue(device.wait(Until.gone(consentTitleObj), UIAUTOMATOR_TIMEOUT_MS));
|
||||
}
|
||||
|
||||
/**
|
||||
* A rule to change strict mode vm policy temporarily till test method finished.
|
||||
*
|
||||
* To permit the non-visual context usage in tests while taking bugreports need user consent,
|
||||
* or UiAutomator/BugreportManager.DumpstateListener would run into error.
|
||||
* UiDevice#findObject creates UiObject2, its Gesture object and ViewConfiguration and
|
||||
* UiObject2#click need to know bounds. Both of them access to WindowManager internally without
|
||||
* visual context comes from InstrumentationRegistry and violate the policy.
|
||||
* Also <code>DumpstateListener<code/> violate the policy when onScreenshotTaken is called.
|
||||
*
|
||||
* TODO(b/161201609) Remove this class once violations fixed.
|
||||
*/
|
||||
static class ExtendedStrictModeVmPolicy extends ExternalResource {
|
||||
private boolean mWasVmPolicyChanged = false;
|
||||
private StrictMode.VmPolicy mOldVmPolicy;
|
||||
|
||||
@Override
|
||||
protected void after() {
|
||||
restoreVmPolicyIfNeeded();
|
||||
}
|
||||
|
||||
public void permitIncorrectContextUse() {
|
||||
// Allow to call multiple times without losing old policy.
|
||||
if (mOldVmPolicy == null) {
|
||||
mOldVmPolicy = StrictMode.getVmPolicy();
|
||||
}
|
||||
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
|
||||
.detectAll()
|
||||
.permitIncorrectContextUse()
|
||||
.penaltyLog()
|
||||
.build());
|
||||
mWasVmPolicyChanged = true;
|
||||
}
|
||||
|
||||
private void restoreVmPolicyIfNeeded() {
|
||||
if (mWasVmPolicyChanged && mOldVmPolicy != null) {
|
||||
StrictMode.setVmPolicy(mOldVmPolicy);
|
||||
mOldVmPolicy = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
31
packages/Shell/TEST_MAPPING
Normal file
31
packages/Shell/TEST_MAPPING
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"name": "CtsBugreportTestCases",
|
||||
"options": [
|
||||
{
|
||||
"exclude-annotation": "androidx.test.filters.LargeTest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ShellTests",
|
||||
"options": [
|
||||
{
|
||||
"exclude-annotation": "androidx.test.filters.LargeTest"
|
||||
},
|
||||
{
|
||||
"exclude-annotation": "androidx.test.filters.FlakyTest"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"postsubmit": [
|
||||
{
|
||||
"name": "CtsBugreportTestCases"
|
||||
},
|
||||
{
|
||||
"name": "ShellTests"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,7 +1,51 @@
|
||||
{
|
||||
"presubmit": [
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "BugreportManagerTestCases",
|
||||
"options": [
|
||||
{
|
||||
"exclude-annotation": "androidx.test.filters.LargeTest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "CtsBugreportTestCases",
|
||||
"options": [
|
||||
{
|
||||
"exclude-annotation": "androidx.test.filters.LargeTest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "CtsUsbTests"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "ShellTests",
|
||||
"options": [
|
||||
{
|
||||
"exclude-annotation": "androidx.test.filters.LargeTest"
|
||||
},
|
||||
{
|
||||
"exclude-annotation": "androidx.test.filters.FlakyTest"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"postsubmit": [
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "BugreportManagerTestCases"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "CtsBugreportTestCases"
|
||||
},
|
||||
{
|
||||
"file_patterns": ["Bugreport[^/]*\\.java"],
|
||||
"name": "ShellTests"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user