Skip to content
Snippets Groups Projects
Commit b7d653f5 authored by Android Build Role Account android-build-prod's avatar Android Build Role Account android-build-prod
Browse files

Snap for 6665474 from b94177df to q-keystone-qcom-release

Change-Id: Iaefd7100899061bbbc9b1719dc68cadaf52f8a3f
parents b339586f b94177df
Branches
No related tags found
No related merge requests found
......@@ -45,7 +45,8 @@ public class PreviousSessionFileCopier implements ITestInvocationListener {
CertificationSuiteResultReporter.FAILURE_REPORT_NAME,
CertificationSuiteResultReporter.SUMMARY_FILE,
CertificationChecksumHelper.NAME,
"diffs");
"diffs",
"proto");
private CompatibilityBuildHelper mBuildHelper;
private File mPreviousSessionDir = null;
......
......@@ -19,6 +19,8 @@ package com.android.compatibility.common.tradefed.targetprep;
import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
import com.android.ddmlib.testrunner.TestResult.TestStatus;
import com.android.tradefed.build.IBuildInfo;
import com.android.tradefed.config.IConfiguration;
import com.android.tradefed.config.IConfigurationReceiver;
import com.android.tradefed.config.Option;
import com.android.tradefed.config.OptionClass;
import com.android.tradefed.device.DeviceNotAvailableException;
......@@ -37,11 +39,10 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.util.Map.Entry;
/**
* Target preparer that instruments an APK.
*/
/** Target preparer that instruments an APK. */
@OptionClass(alias = "apk-instrumentation-preparer")
public class ApkInstrumentationPreparer extends PreconditionPreparer implements ITargetCleaner {
public class ApkInstrumentationPreparer extends PreconditionPreparer
implements IConfigurationReceiver, ITargetCleaner {
@Option(name = "apk", description = "Name of the apk to instrument", mandatory = true)
protected String mApkFileName = null;
......@@ -59,6 +60,14 @@ public class ApkInstrumentationPreparer extends PreconditionPreparer implements
@Option(name = "throw-error", description = "Whether to throw error for device test failure")
protected boolean mThrowError = true;
private IConfiguration mConfiguration = null;
/** {@inheritDoc} */
@Override
public void setConfiguration(IConfiguration configuration) {
mConfiguration = configuration;
}
/**
* {@inheritDoc}
*/
......@@ -118,6 +127,7 @@ public class ApkInstrumentationPreparer extends PreconditionPreparer implements
CLog.i("Instrumenting package: %s", mPackageName);
CollectingTestListener listener = new CollectingTestListener();
AndroidJUnitTest instrTest = new AndroidJUnitTest();
instrTest.setConfiguration(mConfiguration);
instrTest.setDevice(device);
instrTest.setInstallFile(apkFile);
instrTest.setPackageName(mPackageName);
......
......@@ -95,4 +95,13 @@ public class PreviousSessionFileCopierTest {
// File are not overriden
assertEquals("CURRENT", FileUtil.readStringFromFile(original));
}
@Test
public void testCopy_fileExcluded() throws Exception {
new File(mPreviousDir, "proto").mkdir();
mCopier.invocationStarted(mContext);
mCopier.invocationEnded(500L);
// Nothing was copied
assertEquals(0, mCurrentDir.listFiles().length);
}
}
......@@ -17,6 +17,10 @@
package com.android.compatibility.common.util;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.math.BigInteger;
......@@ -60,12 +64,9 @@ public class CrashUtils {
private static Pattern sAbortMessageCheckPattern =
Pattern.compile("(?i)Abort message.*?CHECK_");
/**
* returns true if the signal is a segmentation fault or bus error.
*/
public static boolean isSecuritySignal(JSONObject crash) throws JSONException {
return crash.getString(SIGNAL).toLowerCase().matches("sig(segv|bus)");
}
public static final String SIGSEGV = "SIGSEGV";
public static final String SIGBUS = "SIGBUS";
public static final String SIGABRT = "SIGABRT";
/**
* returns the filename of the process.
......@@ -79,14 +80,12 @@ public class CrashUtils {
* Determines if the given input has a {@link com.android.compatibility.common.util.Crash} that
* should fail an sts test
*
* @param processPatterns list of patterns that match applicable process names
* @param checkMinAddr if the minimum fault address should be respected
* @param crashes list of crashes to check
* @param config crash detection configuration object
* @return if a crash is serious enough to fail an sts test
*/
public static boolean securityCrashDetected(
JSONArray crashes, boolean checkMinAddr, Pattern... processPatterns) {
return matchSecurityCrashes(crashes, checkMinAddr, processPatterns).length() > 0;
public static boolean securityCrashDetected(JSONArray crashes, Config config) {
return matchSecurityCrashes(crashes, config).length() > 0;
}
public static BigInteger getBigInteger(JSONObject source, String name) throws JSONException {
......@@ -105,28 +104,35 @@ public class CrashUtils {
* Determines which given inputs have a {@link com.android.compatibility.common.util.Crash} that
* should fail an sts test
*
* @param processPatterns list of patterns that match applicable process names
* @param checkMinAddr if the minimum fault address should be respected
* @param crashes list of crashes to check
* @param config crash detection configuration object
* @return the list of crashes serious enough to fail an sts test
*/
public static JSONArray matchSecurityCrashes(
JSONArray crashes, boolean checkMinAddr, Pattern... processPatterns) {
public static JSONArray matchSecurityCrashes(JSONArray crashes, Config config) {
JSONArray securityCrashes = new JSONArray();
for (int i = 0; i < crashes.length(); i++) {
try {
JSONObject crash = crashes.getJSONObject(i);
if (!matchesAny(getProcessFileName(crash), processPatterns)) {
// match process patterns
if (!matchesAny(getProcessFileName(crash), config.processPatterns)) {
continue;
}
if (!isSecuritySignal(crash)) {
// match signal
String crashSignal = crash.getString(SIGNAL);
if (!config.signals.contains(crashSignal)) {
continue;
}
// if check specified, reject crash if address is unlikely to be security-related
if (config.checkMinAddress) {
BigInteger faultAddress = getBigInteger(crash, FAULT_ADDRESS);
if (checkMinAddr && faultAddress != null
&& faultAddress.compareTo(MIN_CRASH_ADDR) < 0) {
if (faultAddress != null
&& faultAddress.compareTo(config.minCrashAddress) < 0) {
continue;
}
}
securityCrashes.put(crash);
} catch (JSONException | NullPointerException e) {}
}
......@@ -136,7 +142,7 @@ public class CrashUtils {
/**
* returns true if the input matches any of the patterns.
*/
private static boolean matchesAny(String input, Pattern... patterns) {
private static boolean matchesAny(String input, Collection<Pattern> patterns) {
for (Pattern p : patterns) {
if (p.matcher(input).matches()) {
return true;
......@@ -195,4 +201,53 @@ public class CrashUtils {
}
return crashes;
}
public static class Config {
private boolean checkMinAddress = true;
private BigInteger minCrashAddress = MIN_CRASH_ADDR;
private List<String> signals = Arrays.asList(SIGSEGV, SIGBUS);
private List<Pattern> processPatterns = Collections.emptyList();
public Config setMinAddress(BigInteger minCrashAddress) {
this.minCrashAddress = minCrashAddress;
return this;
}
public Config checkMinAddress(boolean checkMinAddress) {
this.checkMinAddress = checkMinAddress;
return this;
}
public Config setSignals(String... signals) {
this.signals = Arrays.asList(signals);
return this;
}
public Config appendSignals(String... signals) {
Collections.addAll(this.signals, signals);
return this;
}
public Config setProcessPatterns(String... processPatternStrings) {
Pattern[] processPatterns = new Pattern[processPatternStrings.length];
for (int i = 0; i < processPatternStrings.length; i++) {
processPatterns[i] = Pattern.compile(processPatternStrings[i]);
}
return setProcessPatterns(processPatterns);
}
public Config setProcessPatterns(Pattern... processPatterns) {
this.processPatterns = Arrays.asList(processPatterns);
return this;
}
public List<Pattern> getProcessPatterns() {
return Collections.unmodifiableList(processPatterns);
}
public Config appendProcessPatterns(Pattern... processPatterns) {
Collections.addAll(this.processPatterns, processPatterns);
return this;
}
}
}
......@@ -91,51 +91,61 @@ public class CrashUtilsTest {
@Test
public void testValidCrash() throws Exception {
Assert.assertTrue(CrashUtils.securityCrashDetected(mCrashes, true,
Pattern.compile("synthetic_process_0")));
Assert.assertTrue(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
.checkMinAddress(true)
.setProcessPatterns(Pattern.compile("synthetic_process_0"))));
}
@Test
public void testMissingName() throws Exception {
Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, true,
Pattern.compile("")));
Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
.checkMinAddress(true)
.setProcessPatterns(Pattern.compile(""))));
}
@Test
public void testSIGABRT() throws Exception {
Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, true,
Pattern.compile("installd")));
Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
.checkMinAddress(true)
.setProcessPatterns(Pattern.compile("installd"))));
}
@Test
public void testFaultAddressBelowMin() throws Exception {
Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, true,
Pattern.compile("synthetic_process_1")));
Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
.checkMinAddress(true)
.setProcessPatterns(Pattern.compile("synthetic_process_1"))));
}
@Test
public void testIgnoreMinAddressCheck() throws Exception {
Assert.assertTrue(CrashUtils.securityCrashDetected(mCrashes, false,
Pattern.compile("synthetic_process_1")));
Assert.assertTrue(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
.checkMinAddress(false)
.setProcessPatterns(Pattern.compile("synthetic_process_1"))));
}
@Test
public void testBadAbortMessage() throws Exception {
Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, true,
Pattern.compile("generic")));
Assert.assertFalse(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
.checkMinAddress(true)
.setProcessPatterns(Pattern.compile("generic"))));
}
@Test
public void testGoodAndBadCrashes() throws Exception {
Assert.assertTrue(CrashUtils.securityCrashDetected(mCrashes, true,
Pattern.compile("synthetic_process_0"), Pattern.compile("generic")));
Assert.assertTrue(CrashUtils.securityCrashDetected(mCrashes, new CrashUtils.Config()
.checkMinAddress(true)
.setProcessPatterns(
Pattern.compile("synthetic_process_0"),
Pattern.compile("generic"))));
}
@Test
public void testNullFaultAddress() throws Exception {
JSONArray crashes = new JSONArray();
crashes.put(createCrashJson(8373, 8414, "loo", "com.android.bluetooth", null, "SIGSEGV"));
Assert.assertTrue(CrashUtils.securityCrashDetected(crashes, true,
Pattern.compile("com\\.android\\.bluetooth")));
Assert.assertTrue(CrashUtils.securityCrashDetected(crashes, new CrashUtils.Config()
.checkMinAddress(true)
.setProcessPatterns(Pattern.compile("com\\.android\\.bluetooth"))));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment