Merge "Fix failures of BYOD Managed Provisioning" into marshmallow-cts-dev
diff --git a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
index efeb665..53a7638 100644
--- a/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
+++ b/apps/CameraITS/tests/sensor_fusion/test_sensor_fusion.py
@@ -115,7 +115,7 @@
plot_rotations(cam_rots, gyro_rots)
# Pass/fail based on the offset and also the correlation distance.
- dist = scipy.spatial.distance.correlation(cam_rots,gyro_rots)
+ dist = scipy.spatial.distance.correlation(cam_rots, gyro_rots)
print "Best correlation of %f at shift of %.2fms"%(dist, offset*SEC_TO_MSEC)
assert(dist < THRESH_MAX_CORR_DIST)
assert(abs(offset) < THRESH_MAX_SHIFT_MS*MSEC_TO_SEC)
@@ -141,7 +141,7 @@
for shift in candidates:
times = cam_times + shift*MSEC_TO_NSEC
gyro_rots = get_gyro_rotations(gyro_events, times)
- dists.append(scipy.spatial.distance.correlation(cam_rots,gyro_rots))
+ dists.append(scipy.spatial.distance.correlation(cam_rots, gyro_rots))
best_corr_dist = min(dists)
best_shift = candidates[dists.index(best_corr_dist)]
@@ -181,9 +181,10 @@
gyro_rots: Array of N-1 gyro rotation measurements (rad).
"""
# For the plot, scale the rotations to be in degrees.
+ scale = 360/(2*math.pi)
fig = matplotlib.pyplot.figure()
- cam_rots = cam_rots * (360/(2*math.pi))
- gyro_rots = gyro_rots * (360/(2*math.pi))
+ cam_rots = cam_rots * scale
+ gyro_rots = gyro_rots * scale
pylab.plot(range(len(cam_rots)), cam_rots, 'r', label="camera")
pylab.plot(range(len(gyro_rots)), gyro_rots, 'b', label="gyro")
pylab.legend()
@@ -196,8 +197,7 @@
"""Get the rotation values of the gyro.
Integrates the gyro data between each camera frame to compute an angular
- displacement. Uses simple Euler approximation to implement the
- integration.
+ displacement.
Args:
gyro_events: List of gyro event objects.
@@ -219,20 +219,16 @@
sgyro = 0
# Integrate samples within the window.
for igyro in range(igyrowindow0, igyrowindow1):
- vgyro0 = all_rots[igyro]
- vgyro1 = all_rots[igyro+1]
+ vgyro = all_rots[igyro+1]
tgyro0 = all_times[igyro]
tgyro1 = all_times[igyro+1]
- vgyro = 0.5 * (vgyro0 + vgyro1)
deltatgyro = (tgyro1 - tgyro0) * NSEC_TO_SEC
sgyro += vgyro * deltatgyro
# Handle the fractional intervals at the sides of the window.
for side,igyro in enumerate([igyrowindow0-1, igyrowindow1]):
- vgyro0 = all_rots[igyro]
- vgyro1 = all_rots[igyro+1]
+ vgyro = all_rots[igyro+1]
tgyro0 = all_times[igyro]
tgyro1 = all_times[igyro+1]
- vgyro = 0.5 * (vgyro0 + vgyro1)
deltatgyro = (tgyro1 - tgyro0) * NSEC_TO_SEC
if side == 0:
f = (tcam0 - tgyro0) / (tgyro1 - tgyro0)
@@ -388,4 +384,3 @@
if __name__ == '__main__':
main()
-
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 7c43321..ea855e5 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -118,6 +118,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
+ <meta-data android:name="test_required_features"
+ android:value="android.software.device_admin" />
</activity>
<activity android:name=".admin.RedactedNotificationKeyguardDisabledFeaturesActivity"
@@ -128,6 +130,8 @@
<category android:name="android.cts.intent.category.MANUAL_TEST" />
</intent-filter>
<meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
+ <meta-data android:name="test_required_features"
+ android:value="android.software.device_admin" />
</activity>
<activity android:name=".admin.ScreenLockTestActivity"
diff --git a/apps/CtsVerifier/res/xml/device_admin_byod.xml b/apps/CtsVerifier/res/xml/device_admin_byod.xml
index ce44794..ff1eb95 100644
--- a/apps/CtsVerifier/res/xml/device_admin_byod.xml
+++ b/apps/CtsVerifier/res/xml/device_admin_byod.xml
@@ -17,6 +17,8 @@
<!-- BEGIN_INCLUDE(meta_data) -->
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
<uses-policies>
+ <limit-password />
+ <watch-login />
<encrypted-storage />
<wipe-data />
<reset-password />
diff --git a/common/device-side/device-info/Android.mk b/common/device-side/device-info/Android.mk
index 0f5e8d3..26b2cb8 100644
--- a/common/device-side/device-info/Android.mk
+++ b/common/device-side/device-info/Android.mk
@@ -20,6 +20,8 @@
LOCAL_MODULE_TAGS := optional
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util_v2
+
LOCAL_MODULE := compatibility-device-info
# uncomment when b/13282254 is fixed
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java
new file mode 100644
index 0000000..be44243
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfo.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2016 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.compatibility.common.deviceinfo;
+
+/**
+ * DeviceInfoActivity wrapper class. All EDI collectors should extend this
+ * class instead of DeviceInfoActivity.
+ */
+public abstract class DeviceInfo extends DeviceInfoActivity {
+}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java
index f9de6eb..1f1e287 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java
@@ -20,17 +20,13 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
-import android.text.TextUtils;
-import android.util.JsonWriter;
import android.util.Log;
import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStreamWriter;
-import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
+import com.android.compatibility.common.util.InfoStore;
+
/**
* Collect device information on target device and write to a JSON file.
*/
@@ -51,7 +47,6 @@
private static final String LOG_TAG = "DeviceInfoActivity";
private CountDownLatch mDone = new CountDownLatch(1);
- private JsonWriter mJsonWriter = null;
private String mResultFilePath = null;
private String mErrorMessage = "Collector has started.";
private int mResultCode = DEVICE_INFO_RESULT_STARTED;
@@ -59,17 +54,28 @@
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (createFilePath()) {
- createJsonWriter();
- startJsonWriter();
- collectDeviceInfo();
- closeJsonWriter();
- if (mResultCode == DEVICE_INFO_RESULT_STARTED) {
- mResultCode = DEVICE_INFO_RESULT_OK;
+ final File dir = new File(Environment.getExternalStorageDirectory(), "device-info-files");
+ if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ failed("External storage is not mounted");
+ } else if (!dir.mkdirs() && !dir.isDirectory()) {
+ failed("Cannot create directory for device info files");
+ } else {
+ try {
+ File jsonFile = new File(dir, getClass().getSimpleName() + ".deviceinfo.json");
+ jsonFile.createNewFile();
+ mResultFilePath = jsonFile.getAbsolutePath();
+ InfoStore store = new InfoStore(jsonFile);
+ store.open();
+ collectDeviceInfo(store);
+ store.close();
+ if (mResultCode == DEVICE_INFO_RESULT_STARTED) {
+ mResultCode = DEVICE_INFO_RESULT_OK;
+ }
+ } catch (Exception e) {
+ failed("Could not collect device info: " + e.getMessage());
}
}
-
Intent data = new Intent();
if (mResultCode == DEVICE_INFO_RESULT_OK) {
data.setData(Uri.parse(mResultFilePath));
@@ -86,7 +92,7 @@
/**
* Method to collect device information.
*/
- protected abstract void collectDeviceInfo();
+ protected abstract void collectDeviceInfo(InfoStore store) throws Exception;
void waitForActivityToFinish() {
try {
@@ -128,323 +134,5 @@
Log.e(LOG_TAG, message);
}
- private boolean createFilePath() {
- if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
- failed("External storage is not mounted");
- return false;
- }
- final File dir = new File(Environment.getExternalStorageDirectory(), "device-info-files");
- if (!dir.mkdirs() && !dir.isDirectory()) {
- failed("Cannot create directory for device info files");
- return false;
- }
-
- // Create file at /sdcard/device-info-files/<class_name>.deviceinfo.json
- final File jsonFile = new File(dir, getClass().getSimpleName() + ".deviceinfo.json");
- try {
- jsonFile.createNewFile();
- } catch (Exception e) {
- failed("Cannot create file to collect device info");
- return false;
- }
- mResultFilePath = jsonFile.getAbsolutePath();
- return true;
- }
-
- private void createJsonWriter() {
- try {
- FileOutputStream out = new FileOutputStream(mResultFilePath);
- mJsonWriter = new JsonWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
- // TODO(agathaman): remove to make json output less pretty
- mJsonWriter.setIndent(" ");
- } catch (Exception e) {
- failed("Failed to create JSON writer: " + e.getMessage());
- }
- }
-
- private void startJsonWriter() {
- try {
- mJsonWriter.beginObject();
- } catch (Exception e) {
- failed("Failed to begin JSON object: " + e.getMessage());
- }
- }
-
- private void closeJsonWriter() {
- try {
- mJsonWriter.endObject();
- mJsonWriter.close();
- } catch (Exception e) {
- failed("Failed to close JSON object: " + e.getMessage());
- }
- }
-
- /**
- * Start a new group of result.
- */
- public void startGroup() {
- try {
- mJsonWriter.beginObject();
- } catch (Exception e) {
- error("Failed to begin JSON group: " + e.getMessage());
- }
- }
-
- /**
- * Start a new group of result with specified name.
- */
- public void startGroup(String name) {
- try {
- mJsonWriter.name(name);
- mJsonWriter.beginObject();
- } catch (Exception e) {
- error("Failed to begin JSON group: " + e.getMessage());
- }
- }
-
- /**
- * Complete adding result to the last started group.
- */
- public void endGroup() {
- try {
- mJsonWriter.endObject();
- } catch (Exception e) {
- error("Failed to end JSON group: " + e.getMessage());
- }
- }
-
- /**
- * Start a new array of result.
- */
- public void startArray() {
- try {
- mJsonWriter.beginArray();
- } catch (Exception e) {
- error("Failed to begin JSON array: " + e.getMessage());
- }
- }
-
- /**
- * Start a new array of result with specified name.
- */
- public void startArray(String name) {
- checkName(name);
- try {
- mJsonWriter.name(name);
- mJsonWriter.beginArray();
- } catch (Exception e) {
- error("Failed to begin JSON array: " + e.getMessage());
- }
- }
-
- /**
- * Complete adding result to the last started array.
- */
- public void endArray() {
- try {
- mJsonWriter.endArray();
- } catch (Exception e) {
- error("Failed to end JSON group: " + e.getMessage());
- }
- }
-
- /**
- * Add a double value result.
- */
- public void addResult(String name, double value) {
- checkName(name);
- try {
- mJsonWriter.name(name).value(value);
- } catch (Exception e) {
- error("Failed to add result for type double: " + e.getMessage());
- }
- }
-
- /**
- * Add a long value result.
- */
- public void addResult(String name, long value) {
- checkName(name);
- try {
- mJsonWriter.name(name).value(value);
- } catch (Exception e) {
- error("Failed to add result for type long: " + e.getMessage());
- }
- }
-
- /**
- * Add an int value result.
- */
- public void addResult(String name, int value) {
- checkName(name);
- try {
- mJsonWriter.name(name).value((Number) value);
- } catch (Exception e) {
- error("Failed to add result for type int: " + e.getMessage());
- }
- }
-
- /**
- * Add a boolean value result.
- */
- public void addResult(String name, boolean value) {
- checkName(name);
- try {
- mJsonWriter.name(name).value(value);
- } catch (Exception e) {
- error("Failed to add result for type boolean: " + e.getMessage());
- }
- }
-
- /**
- * Add a String value result.
- */
- public void addResult(String name, String value) {
- checkName(name);
- try {
- mJsonWriter.name(name).value(checkString(value));
- } catch (Exception e) {
- error("Failed to add result for type String: " + e.getMessage());
- }
- }
-
- /**
- * Add a double array result.
- */
- public void addArray(String name, double[] list) {
- checkName(name);
- try {
- mJsonWriter.name(name);
- mJsonWriter.beginArray();
- for (double value : checkArray(list)) {
- mJsonWriter.value(value);
- }
- mJsonWriter.endArray();
- } catch (Exception e) {
- error("Failed to add result array for type double: " + e.getMessage());
- }
- }
-
- /**
- * Add a long array result.
- */
- public void addArray(String name, long[] list) {
- checkName(name);
- try {
- mJsonWriter.name(name);
- mJsonWriter.beginArray();
- for (long value : checkArray(list)) {
- mJsonWriter.value(value);
- }
- mJsonWriter.endArray();
- } catch (Exception e) {
- error("Failed to add result array for type long: " + e.getMessage());
- }
- }
-
- /**
- * Add an int array result.
- */
- public void addArray(String name, int[] list) {
- checkName(name);
- try {
- mJsonWriter.name(name);
- mJsonWriter.beginArray();
- for (int value : checkArray(list)) {
- mJsonWriter.value((Number) value);
- }
- mJsonWriter.endArray();
- } catch (Exception e) {
- error("Failed to add result array for type int: " + e.getMessage());
- }
- }
-
- /**
- * Add a boolean array result.
- */
- public void addArray(String name, boolean[] list) {
- checkName(name);
- try {
- mJsonWriter.name(name);
- mJsonWriter.beginArray();
- for (boolean value : checkArray(list)) {
- mJsonWriter.value(value);
- }
- mJsonWriter.endArray();
- } catch (Exception e) {
- error("Failed to add result array for type boolean: " + e.getMessage());
- }
- }
-
- /**
- * Add a String array result.
- */
- public void addArray(String name, String[] list) {
- checkName(name);
- try {
- mJsonWriter.name(name);
- mJsonWriter.beginArray();
- for (String value : checkArray(list)) {
- mJsonWriter.value(checkString(value));
- }
- mJsonWriter.endArray();
- } catch (Exception e) {
- error("Failed to add result array for type Sting: " + e.getMessage());
- }
- }
-
- private static boolean[] checkArray(boolean[] values) {
- if (values.length > MAX_ARRAY_LENGTH) {
- return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
- } else {
- return values;
- }
- }
-
- private static double[] checkArray(double[] values) {
- if (values.length > MAX_ARRAY_LENGTH) {
- return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
- } else {
- return values;
- }
- }
-
- private static int[] checkArray(int[] values) {
- if (values.length > MAX_ARRAY_LENGTH) {
- return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
- } else {
- return values;
- }
- }
-
- private static long[] checkArray(long[] values) {
- if (values.length > MAX_ARRAY_LENGTH) {
- return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
- } else {
- return values;
- }
- }
-
- private static String[] checkArray(String[] values) {
- if (values.length > MAX_ARRAY_LENGTH) {
- return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
- } else {
- return values;
- }
- }
-
- private static String checkString(String value) {
- if (value.length() > MAX_STRING_VALUE_LENGTH) {
- return value.substring(0, MAX_STRING_VALUE_LENGTH);
- }
- return value;
- }
-
- private static String checkName(String value) {
- if (TextUtils.isEmpty(value)) {
- throw new NullPointerException();
- }
- return value;
- }
}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java
index 7df3dae..304b74c 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java
@@ -45,12 +45,12 @@
import java.util.Scanner;
import java.util.Set;
-import com.android.compatibility.common.deviceinfo.DeviceInfoActivity;
+import com.android.compatibility.common.util.InfoStore;
/**
* Generic device info collector.
*/
-public class GenericDeviceInfo extends DeviceInfoActivity {
+public class GenericDeviceInfo extends DeviceInfo {
public static final String BUILD_ID = "build_id";
public static final String BUILD_PRODUCT = "build_product";
@@ -78,38 +78,38 @@
}
@Override
- protected void collectDeviceInfo() {
- addResult(BUILD_ID, Build.ID);
- addResult(BUILD_PRODUCT, Build.PRODUCT);
- addResult(BUILD_DEVICE, Build.DEVICE);
- addResult(BUILD_BOARD, Build.BOARD);
- addResult(BUILD_MANUFACTURER, Build.MANUFACTURER);
- addResult(BUILD_BRAND, Build.BRAND);
- addResult(BUILD_MODEL, Build.MODEL);
- addResult(BUILD_TYPE, Build.TYPE);
- addResult(BUILD_FINGERPRINT, Build.FINGERPRINT);
- addResult(BUILD_ABI, Build.CPU_ABI);
- addResult(BUILD_ABI2, Build.CPU_ABI2);
- addResult(BUILD_SERIAL, Build.SERIAL);
- addResult(BUILD_VERSION_RELEASE, Build.VERSION.RELEASE);
- addResult(BUILD_VERSION_SDK, Build.VERSION.SDK);
+ protected void collectDeviceInfo(InfoStore store) throws Exception {
+ store.addResult(BUILD_ID, Build.ID);
+ store.addResult(BUILD_PRODUCT, Build.PRODUCT);
+ store.addResult(BUILD_DEVICE, Build.DEVICE);
+ store.addResult(BUILD_BOARD, Build.BOARD);
+ store.addResult(BUILD_MANUFACTURER, Build.MANUFACTURER);
+ store.addResult(BUILD_BRAND, Build.BRAND);
+ store.addResult(BUILD_MODEL, Build.MODEL);
+ store.addResult(BUILD_TYPE, Build.TYPE);
+ store.addResult(BUILD_FINGERPRINT, Build.FINGERPRINT);
+ store.addResult(BUILD_ABI, Build.CPU_ABI);
+ store.addResult(BUILD_ABI2, Build.CPU_ABI2);
+ store.addResult(BUILD_SERIAL, Build.SERIAL);
+ store.addResult(BUILD_VERSION_RELEASE, Build.VERSION.RELEASE);
+ store.addResult(BUILD_VERSION_SDK, Build.VERSION.SDK);
// Collect build fields available in API level 21
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- addResult(BUILD_ABIS, TextUtils.join(",", Build.SUPPORTED_ABIS));
- addResult(BUILD_ABIS_32, TextUtils.join(",", Build.SUPPORTED_32_BIT_ABIS));
- addResult(BUILD_ABIS_64, TextUtils.join(",", Build.SUPPORTED_64_BIT_ABIS));
+ store.addResult(BUILD_ABIS, TextUtils.join(",", Build.SUPPORTED_ABIS));
+ store.addResult(BUILD_ABIS_32, TextUtils.join(",", Build.SUPPORTED_32_BIT_ABIS));
+ store.addResult(BUILD_ABIS_64, TextUtils.join(",", Build.SUPPORTED_64_BIT_ABIS));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- addResult(BUILD_VERSION_BASE_OS, Build.VERSION.BASE_OS);
- addResult(BUILD_VERSION_SECURITY_PATCH, Build.VERSION.SECURITY_PATCH);
+ store.addResult(BUILD_VERSION_BASE_OS, Build.VERSION.BASE_OS);
+ store.addResult(BUILD_VERSION_SECURITY_PATCH, Build.VERSION.SECURITY_PATCH);
} else {
// Access system properties directly because Build.Version.BASE_OS and
// Build.Version.SECURITY_PATCH are not defined pre-M.
- addResult(BUILD_VERSION_BASE_OS,
+ store.addResult(BUILD_VERSION_BASE_OS,
SystemProperties.get("ro.build.version.base_os", ""));
- addResult(BUILD_VERSION_SECURITY_PATCH,
+ store.addResult(BUILD_VERSION_SECURITY_PATCH,
SystemProperties.get("ro.build.version.security_patch", ""));
}
}
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
index 4d9ad46..1452040 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
@@ -19,12 +19,12 @@
import android.content.pm.PackageManager;
import android.os.Bundle;
-import com.android.compatibility.common.deviceinfo.DeviceInfoActivity;
+import com.android.compatibility.common.util.InfoStore;
/**
* PackageDeviceInfo collector.
*/
-public class PackageDeviceInfo extends DeviceInfoActivity {
+public class PackageDeviceInfo extends DeviceInfo {
private static final String PACKAGE = "package";
private static final String NAME = "name";
@@ -33,18 +33,18 @@
private static final String PRIV_APP_DIR = "/system/priv-app";
@Override
- protected void collectDeviceInfo() {
+ protected void collectDeviceInfo(InfoStore store) throws Exception {
PackageManager pm = this.getPackageManager();
- startArray(PACKAGE);
+ store.startArray(PACKAGE);
for (PackageInfo pkg : pm.getInstalledPackages(0)) {
- startGroup();
- addResult(NAME, pkg.packageName);
- addResult(VERSION_NAME, pkg.versionName);
+ store.startGroup();
+ store.addResult(NAME, pkg.packageName);
+ store.addResult(VERSION_NAME, pkg.versionName);
String dir = pkg.applicationInfo.sourceDir;
- addResult(SYSTEM_PRIV, dir != null && dir.startsWith(PRIV_APP_DIR));
- endGroup();
+ store.addResult(SYSTEM_PRIV, dir != null && dir.startsWith(PRIV_APP_DIR));
+ store.endGroup();
}
- endArray(); // Package
+ store.endArray(); // Package
}
}
diff --git a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/SampleDeviceInfo.java b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/SampleDeviceInfo.java
deleted file mode 100644
index 7da9951..0000000
--- a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/SampleDeviceInfo.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2015 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.compatibility.common.deviceinfo;
-
-import android.os.Bundle;
-
-import java.lang.StringBuilder;
-
-/**
- * Sample device info collector.
- */
-public class SampleDeviceInfo extends DeviceInfoActivity {
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-
- @Override
- protected void collectDeviceInfo() {
- boolean[] booleans = {Boolean.TRUE, Boolean.FALSE};
- double[] doubles = {Double.MAX_VALUE, Double.MIN_VALUE};
- int[] ints = {Integer.MAX_VALUE, Integer.MIN_VALUE};
- long[] longs = {Long.MAX_VALUE, Long.MIN_VALUE};
-
- // Group Foo
- startGroup("foo");
- addResult("foo_boolean", Boolean.TRUE);
-
- // Group Bar
- startGroup("bar");
- addArray("bar_string", new String[] {
- "bar-string-1",
- "bar-string-2",
- "bar-string-3"});
-
- addArray("bar_boolean", booleans);
- addArray("bar_double", doubles);
- addArray("bar_int", ints);
- addArray("bar_long", longs);
- endGroup(); // bar
-
- addResult("foo_double", Double.MAX_VALUE);
- addResult("foo_int", Integer.MAX_VALUE);
- addResult("foo_long", Long.MAX_VALUE);
- addResult("foo_string", "foo-string");
-
- StringBuilder sb = new StringBuilder();
- int[] arr = new int[1001];
- for (int i = 0; i < 1001; i++) {
- sb.append("a");
- arr[i] = i;
- }
- addResult("long_string", sb.toString());
- addArray("long_int_array", arr);
-
- endGroup(); // foo
- }
-}
-
diff --git a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/TestDeviceInfo.java b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/TestDeviceInfo.java
index 7f82942..96814f5 100644
--- a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/TestDeviceInfo.java
+++ b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/TestDeviceInfo.java
@@ -18,6 +18,11 @@
import android.os.Bundle;
import java.lang.StringBuilder;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+import com.android.compatibility.common.util.InfoStore;
/**
* Collector for testing DeviceInfoActivity
@@ -30,47 +35,47 @@
}
@Override
- protected void collectDeviceInfo() {
+ protected void collectDeviceInfo(InfoStore store) throws Exception {
// Test primitive results
- addResult("test_boolean", true);
- addResult("test_double", 1.23456789);
- addResult("test_int", 123456789);
- addResult("test_long", Long.MAX_VALUE);
- addResult("test_string", "test string");
- addArray("test_strings", new String[] {
- "test string 1",
- "test string 2",
- "test string 3",
- });
+ store.addResult("test_boolean", true);
+ store.addResult("test_double", 1.23456789);
+ store.addResult("test_int", 123456789);
+ store.addResult("test_long", Long.MAX_VALUE);
+ store.addResult("test_string", "test string");
+ List<String> list = new ArrayList<>();
+ list.add("test string 1");
+ list.add("test string 2");
+ list.add("test string 3");
+ store.addListResult("test_strings", list);
// Test group
- startGroup("test_group");
- addResult("test_boolean", false);
- addResult("test_double", 9.87654321);
- addResult("test_int", 987654321);
- addResult("test_long", Long.MAX_VALUE);
- addResult("test_string", "test group string");
- addArray("test_strings", new String[] {
- "test group string 1",
- "test group string 2",
- "test group string 3"
- });
- endGroup(); // test_group
+ store.startGroup("test_group");
+ store.addResult("test_boolean", false);
+ store.addResult("test_double", 9.87654321);
+ store.addResult("test_int", 987654321);
+ store.addResult("test_long", Long.MAX_VALUE);
+ store.addResult("test_string", "test group string");
+ list = new ArrayList<>();
+ list.add("test group string 1");
+ list.add("test group string 2");
+ list.add("test group string 3");
+ store.addListResult("test_strings", list);
+ store.endGroup(); // test_group
// Test array of groups
- startArray("test_groups");
+ store.startArray("test_groups");
for (int i = 1; i < 4; i++) {
- startGroup();
- addResult("test_string", "test groups string " + i);
- addArray("test_strings", new String[] {
- "test groups string " + i + "-1",
- "test groups string " + i + "-2",
- "test groups string " + i + "-3"
- });
- endGroup();
+ store.startGroup();
+ store.addResult("test_string", "test groups string " + i);
+ list = new ArrayList<>();
+ list.add("test groups string " + i + "-1");
+ list.add("test groups string " + i + "-2");
+ list.add("test groups string " + i + "-3");
+ store.addListResult("test_strings", list);
+ store.endGroup();
}
- endArray(); // test_groups
+ store.endArray(); // test_groups
// Test max
StringBuilder sb = new StringBuilder();
@@ -79,7 +84,7 @@
sb.append("a");
arr[i] = i;
}
- addResult("max_length_string", sb.toString());
- addArray("max_num_ints", arr);
+ store.addResult("max_length_string", sb.toString());
+ store.addArrayResult("max_num_ints", arr);
}
}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/InfoStore.java b/common/device-side/util/src/com/android/compatibility/common/util/InfoStore.java
new file mode 100644
index 0000000..62decdc
--- /dev/null
+++ b/common/device-side/util/src/com/android/compatibility/common/util/InfoStore.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2016 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.compatibility.common.util;
+
+import android.util.JsonWriter;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.List;
+
+public class InfoStore {
+
+ private static final int MAX_STRING_LENGTH = 1000;
+ private static final int MAX_ARRAY_LENGTH = 1000;
+ private static final int MAX_LIST_LENGTH = 1000;
+
+ private final File mJsonFile;
+ private JsonWriter mJsonWriter = null;
+
+ public InfoStore(File file) throws Exception {
+ mJsonFile = file;
+ }
+
+ /**
+ * Opens the file for storage and creates the writer.
+ */
+ public void open() throws IOException {
+ FileOutputStream out = new FileOutputStream(mJsonFile);
+ mJsonWriter = new JsonWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
+ // TODO(agathaman): remove to make json output less pretty
+ mJsonWriter.setIndent(" ");
+ mJsonWriter.beginObject();
+ }
+
+ /**
+ * Closes the writer.
+ */
+ public void close() throws IOException {
+ mJsonWriter.endObject();
+ mJsonWriter.close();
+ }
+
+ /**
+ * Start a new group of result.
+ */
+ public void startGroup() throws IOException {
+ mJsonWriter.beginObject();
+ }
+
+ /**
+ * Start a new group of result with specified name.
+ */
+ public void startGroup(String name) throws IOException {
+ mJsonWriter.name(name);
+ mJsonWriter.beginObject();
+ }
+
+ /**
+ * Complete adding result to the last started group.
+ */
+ public void endGroup() throws IOException {
+ mJsonWriter.endObject();
+ }
+
+ /**
+ * Start a new array of result.
+ */
+ public void startArray() throws IOException {
+ mJsonWriter.beginArray();
+ }
+
+ /**
+ * Start a new array of result with specified name.
+ */
+ public void startArray(String name) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.beginArray();
+ }
+
+ /**
+ * Complete adding result to the last started array.
+ */
+ public void endArray() throws IOException {
+ mJsonWriter.endArray();
+ }
+
+ /**
+ * Adds a int value to the InfoStore
+ */
+ public void addResult(String name, int value) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.value(value);
+ }
+
+ /**
+ * Adds a long value to the InfoStore
+ */
+ public void addResult(String name, long value) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.value(value);
+ }
+
+ /**
+ * Adds a float value to the InfoStore
+ */
+ public void addResult(String name, float value) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.value(value);
+ }
+
+ /**
+ * Adds a double value to the InfoStore
+ */
+ public void addResult(String name, double value) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.value(value);
+ }
+
+ /**
+ * Adds a boolean value to the InfoStore
+ */
+ public void addResult(String name, boolean value) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.value(value);
+ }
+
+ /**
+ * Adds a String value to the InfoStore
+ */
+ public void addResult(String name, String value) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.value(checkString(value));
+ }
+
+ /**
+ * Adds a int array to the InfoStore
+ */
+ public void addArrayResult(String name, int[] array) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.beginArray();
+ for (int value : checkArray(array)) {
+ mJsonWriter.value(value);
+ }
+ mJsonWriter.endArray();
+ }
+
+ /**
+ * Adds a long array to the InfoStore
+ */
+ public void addArrayResult(String name, long[] array) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.beginArray();
+ for (long value : checkArray(array)) {
+ mJsonWriter.value(value);
+ }
+ mJsonWriter.endArray();
+ }
+
+ /**
+ * Adds a float array to the InfoStore
+ */
+ public void addArrayResult(String name, float[] array) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.beginArray();
+ for (float value : checkArray(array)) {
+ mJsonWriter.value(value);
+ }
+ mJsonWriter.endArray();
+ }
+
+ /**
+ * Adds a double array to the InfoStore
+ */
+ public void addArrayResult(String name, double[] array) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.beginArray();
+ for (double value : checkArray(array)) {
+ mJsonWriter.value(value);
+ }
+ mJsonWriter.endArray();
+ }
+
+ /**
+ * Adds a boolean array to the InfoStore
+ */
+ public void addArrayResult(String name, boolean[] array) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.beginArray();
+ for (boolean value : checkArray(array)) {
+ mJsonWriter.value(value);
+ }
+ mJsonWriter.endArray();
+ }
+
+ /**
+ * Adds a List of String to the InfoStore
+ */
+ public void addListResult(String name, List<String> list) throws IOException {
+ checkName(name);
+ mJsonWriter.name(name);
+ mJsonWriter.beginArray();
+ for (String value : checkStringList(list)) {
+ mJsonWriter.value(checkString(value));
+ }
+ mJsonWriter.endArray();
+ }
+
+ private static int[] checkArray(int[] values) {
+ if (values.length > MAX_ARRAY_LENGTH) {
+ return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+ } else {
+ return values;
+ }
+ }
+
+ private static long[] checkArray(long[] values) {
+ if (values.length > MAX_ARRAY_LENGTH) {
+ return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+ } else {
+ return values;
+ }
+ }
+
+ private static float[] checkArray(float[] values) {
+ if (values.length > MAX_ARRAY_LENGTH) {
+ return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+ } else {
+ return values;
+ }
+ }
+
+ private static double[] checkArray(double[] values) {
+ if (values.length > MAX_ARRAY_LENGTH) {
+ return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+ } else {
+ return values;
+ }
+ }
+
+ private static boolean[] checkArray(boolean[] values) {
+ if (values.length > MAX_ARRAY_LENGTH) {
+ return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+ } else {
+ return values;
+ }
+ }
+
+ private static List<String> checkStringList(List<String> list) {
+ if (list.size() > MAX_LIST_LENGTH) {
+ return list.subList(0, MAX_LIST_LENGTH);
+ }
+ return list;
+ }
+
+ private static String checkString(String value) {
+ if (value == null || value.isEmpty()) {
+ return "null";
+ }
+ if (value.length() > MAX_STRING_LENGTH) {
+ return value.substring(0, MAX_STRING_LENGTH);
+ }
+ return value;
+ }
+
+ private static String checkName(String value) {
+ if (value == null || value.isEmpty()) {
+ throw new NullPointerException();
+ }
+ return value;
+ }
+}
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
index 547b205..a82c17c 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/ConnectivityConstraintTest.java
@@ -76,7 +76,20 @@
@Override
public void tearDown() throws Exception {
// Ensure that we leave WiFi in its previous state.
- mWifiManager.setWifiEnabled(mInitialWiFiState);
+ NetworkInfo.State expectedState = mInitialWiFiState ?
+ NetworkInfo.State.CONNECTED : NetworkInfo.State.DISCONNECTED;
+ ConnectivityActionReceiver receiver =
+ new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI,
+ expectedState);
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ mContext.registerReceiver(receiver, filter);
+
+ assertTrue(mWifiManager.setWifiEnabled(mInitialWiFiState));
+ assertTrue("Failure to restore previous WiFi state.",
+ receiver.waitForStateChange());
+
+ mContext.unregisterReceiver(receiver);
}
// --------------------------------------------------------------------------------------------
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
index dd4e3e3..ffbe432 100644
--- a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -41,6 +41,8 @@
import android.util.Rational;
import android.util.Size;
+import com.android.cts.util.TimeoutReq;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -303,6 +305,7 @@
* API specifications.
* </p>
*/
+ @TimeoutReq(minutes = 40)
public void testAeModeAndLock() throws Exception {
for (int i = 0; i < mCameraIds.length; i++) {
try {
diff --git a/tests/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/tests/app/src/android/app/cts/NotificationManagerTest.java
index fbb3060..c5a41c3 100644
--- a/tests/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -126,6 +126,8 @@
// we will check for it for up to 200ms before giving up
boolean found = false;
for (int tries=3; tries-->0;) {
+ // Need reset flag.
+ found = false;
final StatusBarNotification[] sbns = mNotificationManager.getActiveNotifications();
for (StatusBarNotification sbn : sbns) {
if (sbn.getId() == id) {
diff --git a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
index 14cd6d5..1ea6ff0 100644
--- a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
+++ b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
@@ -29,6 +29,7 @@
import android.os.Bundle;
import android.test.InstrumentationTestCase;
+import java.lang.Math;
import java.io.File;
import java.util.ArrayList;
import java.util.Random;
@@ -170,15 +171,28 @@
}
public void testOnMove() {
- mTestAbstractCursor.resetOnMoveRet();
assertFalse(mTestAbstractCursor.getOnMoveRet());
mTestAbstractCursor.moveToFirst();
+ assertTrue(mTestAbstractCursor.getOnMoveRet());
+ assertEquals(1, mTestAbstractCursor.getRowsMovedSum());
+
mTestAbstractCursor.moveToPosition(5);
assertTrue(mTestAbstractCursor.getOnMoveRet());
+ assertEquals(6, mTestAbstractCursor.getRowsMovedSum());
assertEquals(0, mTestAbstractCursor.getOldPos());
assertEquals(5, mTestAbstractCursor.getNewPos());
}
+ public void testOnMove_samePosition() {
+ mTestAbstractCursor.moveToFirst();
+ mTestAbstractCursor.moveToPosition(5);
+ assertEquals(6, mTestAbstractCursor.getRowsMovedSum());
+ mTestAbstractCursor.moveToPosition(5);
+ // Moving to the same position should either call onMove(5, 5)
+ // or be a no-op. It should no change the RowsMovedSum.
+ assertEquals(6, mTestAbstractCursor.getRowsMovedSum());
+ }
+
public void testMoveToPrevious() {
// Test moveToFirst, isFirst, moveToNext, getPosition
assertTrue(mDatabaseCursor.moveToFirst());
@@ -426,6 +440,8 @@
private boolean mOnMoveReturnValue;
private int mOldPosition;
private int mNewPosition;
+ /** The accumulated number of rows this cursor has moved over. */
+ private int mRowsMovedSum;
private String[] mColumnNames;
private ArrayList<Object>[] mRows;
private boolean mHadCalledOnChange = false;
@@ -481,11 +497,16 @@
return mNewPosition;
}
+ public int getRowsMovedSum() {
+ return mRowsMovedSum;
+ }
+
@Override
public boolean onMove(int oldPosition, int newPosition) {
mOnMoveReturnValue = super.onMove(oldPosition, newPosition);
mOldPosition = oldPosition;
mNewPosition = newPosition;
+ mRowsMovedSum += Math.abs(newPosition - oldPosition);
return mOnMoveReturnValue;
}
@@ -618,3 +639,4 @@
}
}
}
+
diff --git a/tests/tests/os/src/android/os/cts/SecurityPatchTest.java b/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
new file mode 100644
index 0000000..7b3ac14
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/SecurityPatchTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2016 Google Inc.
+ *
+ * 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.os.cts;
+
+import android.os.Build;
+import android.os.SystemProperties;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+/**
+ * Tests for Security Patch String settings
+ */
+public class SecurityPatchTest extends InstrumentationTestCase {
+
+ private static final String TAG = SecurityPatchTest.class.getSimpleName();
+ private static final String SECURITY_PATCH_ERROR =
+ "ro.build.version.security_patch should be in the format \"YYYY-MM-DD\". Found \"%s\"";
+ private static final String SECURITY_PATCH_DATE_ERROR =
+ "ro.build.version.security_patch should be \"%d-%02d\" or later. Found \"%s\"";
+ private static final int SECURITY_PATCH_YEAR = 2016;
+ private static final int SECURITY_PATCH_MONTH = 02;
+
+ private boolean mSkipTests = false;
+
+ @Override
+ protected void setUp() {
+ mSkipTests = (Build.VERSION.SDK_INT < Build.VERSION_CODES.M);
+ }
+
+ /** Security patch string must exist in M or higher **/
+ public void testSecurityPatchFound() {
+ if (mSkipTests) {
+ Log.w(TAG, "Skipping M+ Test.");
+ return;
+ }
+
+ String buildSecurityPatch = SystemProperties.get("ro.build.version.security_patch", "");
+ String error = String.format(SECURITY_PATCH_ERROR, buildSecurityPatch);
+ assertTrue(error, !buildSecurityPatch.isEmpty());
+ }
+
+ /** Security patch should be of the form YYYY-MM-DD in M or higher */
+ public void testSecurityPatchFormat() {
+ if (mSkipTests) {
+ Log.w(TAG, "Skipping M+ Test.");
+ return;
+ }
+
+ String buildSecurityPatch = SystemProperties.get("ro.build.version.security_patch", "");
+ String error = String.format(SECURITY_PATCH_ERROR, buildSecurityPatch);
+
+ assertEquals(error, 10, buildSecurityPatch.length());
+ assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(0)));
+ assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(1)));
+ assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(2)));
+ assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(3)));
+ assertEquals(error, '-', buildSecurityPatch.charAt(4));
+ assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(5)));
+ assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(6)));
+ assertEquals(error, '-', buildSecurityPatch.charAt(7));
+ assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(8)));
+ assertTrue(error, Character.isDigit(buildSecurityPatch.charAt(9)));
+ }
+
+ /** Security patch should no older than the month this test was updated in M or higher **/
+ public void testSecurityPatchDate() {
+ if (mSkipTests) {
+ Log.w(TAG, "Skipping M+ Test.");
+ return;
+ }
+
+ String buildSecurityPatch = SystemProperties.get("ro.build.version.security_patch", "");
+ String error = String.format(SECURITY_PATCH_DATE_ERROR,
+ SECURITY_PATCH_YEAR,
+ SECURITY_PATCH_MONTH,
+ buildSecurityPatch);
+
+ int declaredYear = 0;
+ int declaredMonth = 0;
+
+ try {
+ declaredYear = Integer.parseInt(buildSecurityPatch.substring(0,4));
+ declaredMonth = Integer.parseInt(buildSecurityPatch.substring(5,7));
+ } catch (Exception e) {
+ assertTrue(error, false);
+ }
+
+ assertTrue(error, declaredYear >= SECURITY_PATCH_YEAR);
+ assertTrue(error, (declaredYear > SECURITY_PATCH_YEAR) ||
+ (declaredMonth >= SECURITY_PATCH_MONTH));
+ }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
index 5a80802..6b72b82 100755
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
@@ -101,6 +101,7 @@
"311230", // C SPire Wireless + Celluar South
"310600", // Cellcom
"31000", // Republic Wireless US
+ "310260", // Republic Wireless US
"310026", // T-Mobile US
"330120", // OpenMobile communication
// Verizon
@@ -142,6 +143,7 @@
"45005", // SKT Mobility
"45002", // SKT Mobility
"45006", // LGT
+ "310260", // Republic Wireless US
// Verizon
"310004",
"310012",
diff --git a/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java b/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java
index 886193c..b8dbb6e 100644
--- a/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java
+++ b/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.java
@@ -17,47 +17,45 @@
import android.os.Bundle;
-import com.android.compatibility.common.deviceinfo.DeviceInfoActivity;
+import com.android.compatibility.common.deviceinfo.DeviceInfo;
+import com.android.compatibility.common.util.InfoStore;
+
+import java.util.Arrays;
/**
* Sample device info collector.
*/
-public class SampleDeviceInfo extends DeviceInfoActivity {
+public class SampleDeviceInfo extends DeviceInfo {
@Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- }
-
- @Override
- protected void collectDeviceInfo() {
+ protected void collectDeviceInfo(InfoStore store) throws Exception {
boolean[] booleans = {Boolean.TRUE, Boolean.FALSE};
double[] doubles = {Double.MAX_VALUE, Double.MIN_VALUE};
int[] ints = {Integer.MAX_VALUE, Integer.MIN_VALUE};
long[] longs = {Long.MAX_VALUE, Long.MIN_VALUE};
// Group Foo
- startGroup("foo");
- addResult("foo_boolean", Boolean.TRUE);
+ store.startGroup("foo");
+ store.addResult("foo_boolean", Boolean.TRUE);
// Group Bar
- startGroup("bar");
- addArray("bar_string", new String[] {
+ store.startGroup("bar");
+ store.addListResult("bar_string", Arrays.asList(new String[] {
"bar-string-1",
"bar-string-2",
- "bar-string-3"});
+ "bar-string-3"}));
- addArray("bar_boolean", booleans);
- addArray("bar_double", doubles);
- addArray("bar_int", ints);
- addArray("bar_long", longs);
- endGroup(); // bar
+ store.addArrayResult("bar_boolean", booleans);
+ store.addArrayResult("bar_double", doubles);
+ store.addArrayResult("bar_int", ints);
+ store.addArrayResult("bar_long", longs);
+ store.endGroup(); // bar
- addResult("foo_double", Double.MAX_VALUE);
- addResult("foo_int", Integer.MAX_VALUE);
- addResult("foo_long", Long.MAX_VALUE);
- addResult("foo_string", "foo-string");
- endGroup(); // foo
+ store.addResult("foo_double", Double.MAX_VALUE);
+ store.addResult("foo_int", Integer.MAX_VALUE);
+ store.addResult("foo_long", Long.MAX_VALUE);
+ store.addResult("foo_string", "foo-string");
+ store.endGroup(); // foo
}
}
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
index c336d3c..24cff32 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
@@ -78,4 +78,5 @@
public static final String TOTAL_MEMORY = "total_memory";
public static final String REFERENCE_BUILD_FINGERPRINT =
"reference_build_fingerprint";
+ public static final String AVAILABLE_PROCESSORS = "available_processors";
}
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
index 37f8558..b752c91 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
@@ -169,6 +169,9 @@
addResult(LARGE_MEMORY_CLASS, getLargeMemoryClass());
addResult(TOTAL_MEMORY, getTotalMemory());
+ // CPU Info
+ addResult(AVAILABLE_PROCESSORS, Runtime.getRuntime().availableProcessors());
+
finish(Activity.RESULT_OK, mResults);
}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
index 6f4d42d..885f267 100644
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DeqpTestRunner.java
@@ -311,6 +311,8 @@
final Map<String, String> emptyMap = Collections.emptyMap();
mSink.testEnded(testId, emptyMap);
+ } else {
+ CLog.w("Finalization for non-pending case %s", testId);
}
}
@@ -372,6 +374,8 @@
public void abortTest(TestIdentifier testId, String errorMessage) {
final PendingResult result = mPendingResults.get(testId);
+ CLog.i("Test %s aborted with message %s", testId, errorMessage);
+
// Mark as executed
result.allInstancesPassed = false;
result.errorMessages.put(mRunConfig, errorMessage);
@@ -390,37 +394,57 @@
/**
* Handles beginning of dEQP session.
*/
- private void handleBeginSession(Map<String, String> values) {
+ private boolean handleBeginSession(Map<String, String> values) {
// ignore
+ return true;
+ }
+
+ /**
+ * Handle session info
+ */
+ private boolean handleSessionInfo(Map<String, String> values) {
+ // ignore
+ return true;
}
/**
* Handles end of dEQP session.
*/
- private void handleEndSession(Map<String, String> values) {
+ private boolean handleEndSession(Map<String, String> values) {
// ignore
+ return true;
}
/**
* Handles beginning of dEQP testcase.
*/
- private void handleBeginTestCase(Map<String, String> values) {
- mCurrentTestId = pathToIdentifier(values.get("dEQP-BeginTestCase-TestCasePath"));
+ private boolean handleBeginTestCase(Map<String, String> values) {
+ String casePath = values.get("dEQP-BeginTestCase-TestCasePath");
+
mCurrentTestLog = "";
mGotTestResult = false;
+ if (casePath == null) {
+ CLog.w("Got null case path for test case begin event. Current test ID: %s", mCurrentTestId);
+ mCurrentTestId = null;
+ return false;
+ }
+
+ mCurrentTestId = pathToIdentifier(casePath);
+
// mark instance as started
if (mPendingResults.get(mCurrentTestId) != null) {
mPendingResults.get(mCurrentTestId).remainingConfigs.remove(mRunConfig);
} else {
CLog.w("Got unexpected start of %s", mCurrentTestId);
}
+ return true;
}
/**
* Handles end of dEQP testcase.
*/
- private void handleEndTestCase(Map<String, String> values) {
+ private boolean handleEndTestCase(Map<String, String> values) {
final PendingResult result = mPendingResults.get(mCurrentTestId);
if (result != null) {
@@ -442,19 +466,24 @@
CLog.w("Got unexpected end of %s", mCurrentTestId);
}
mCurrentTestId = null;
+ return true;
}
/**
* Handles dEQP testcase result.
*/
- private void handleTestCaseResult(Map<String, String> values) {
+ private boolean handleTestCaseResult(Map<String, String> values) {
String code = values.get("dEQP-TestCaseResult-Code");
+ if (code == null) {
+ return false;
+ }
+
String details = values.get("dEQP-TestCaseResult-Details");
if (mPendingResults.get(mCurrentTestId) == null) {
CLog.w("Got unexpected result for %s", mCurrentTestId);
mGotTestResult = true;
- return;
+ return true;
}
if (code.compareTo("Pass") == 0) {
@@ -480,12 +509,13 @@
mGotTestResult = true;
CLog.e("Got invalid result code '%s' for test %s", code, mCurrentTestId);
}
+ return true;
}
/**
* Handles terminated dEQP testcase.
*/
- private void handleTestCaseTerminate(Map<String, String> values) {
+ private boolean handleTestCaseTerminate(Map<String, String> values) {
final PendingResult result = mPendingResults.get(mCurrentTestId);
if (result != null) {
@@ -504,40 +534,52 @@
mCurrentTestId = null;
mGotTestResult = true;
+ return true;
}
/**
* Handles dEQP testlog data.
*/
- private void handleTestLogData(Map<String, String> values) {
- mCurrentTestLog = mCurrentTestLog + values.get("dEQP-TestLogData-Log");
+ private boolean handleTestLogData(Map<String, String> values) {
+ String newLog = values.get("dEQP-TestLogData-Log");
+ if (newLog == null) {
+ return false;
+ }
+ mCurrentTestLog = mCurrentTestLog + newLog;
+ return true;
}
/**
* Handles new instrumentation status message.
+ * @return true if handled correctly, false if missing values.
*/
- public void handleStatus(Map<String, String> values) {
+ public boolean handleStatus(Map<String, String> values) {
String eventType = values.get("dEQP-EventType");
if (eventType == null) {
- return;
+ // Not an event, but some other line
+ return true;
}
if (eventType.compareTo("BeginSession") == 0) {
- handleBeginSession(values);
+ return handleBeginSession(values);
+ } else if (eventType.compareTo("SessionInfo") == 0) {
+ return handleSessionInfo(values);
} else if (eventType.compareTo("EndSession") == 0) {
- handleEndSession(values);
+ return handleEndSession(values);
} else if (eventType.compareTo("BeginTestCase") == 0) {
- handleBeginTestCase(values);
+ return handleBeginTestCase(values);
} else if (eventType.compareTo("EndTestCase") == 0) {
- handleEndTestCase(values);
+ return handleEndTestCase(values);
} else if (eventType.compareTo("TestCaseResult") == 0) {
- handleTestCaseResult(values);
+ return handleTestCaseResult(values);
} else if (eventType.compareTo("TerminateTestCase") == 0) {
- handleTestCaseTerminate(values);
+ return handleTestCaseTerminate(values);
} else if (eventType.compareTo("TestLogData") == 0) {
- handleTestLogData(values);
+ return handleTestLogData(values);
}
+ CLog.e("Unknown event type (%s)", eventType);
+ return false;
}
/**
@@ -548,6 +590,7 @@
if (mCurrentTestId != null) {
// Current instance was removed from remainingConfigs when case
// started. Mark current instance as pending.
+ CLog.i("Batch ended with test '%s' current", mCurrentTestId);
if (mPendingResults.get(mCurrentTestId) != null) {
mPendingResults.get(mCurrentTestId).remainingConfigs.add(mRunConfig);
} else {
@@ -569,6 +612,7 @@
private String mCurrentValue;
private int mResultCode;
private boolean mGotExitValue = false;
+ private boolean mParseSuccessful = true;
public InstrumentationParser(TestInstanceResultListener listener) {
@@ -591,7 +635,7 @@
mCurrentValue = null;
}
- mListener.handleStatus(mValues);
+ mParseSuccessful &= mListener.handleStatus(mValues);
mValues = null;
} else if (line.startsWith("INSTRUMENTATION_STATUS: dEQP-")) {
if (mCurrentName != null) {
@@ -604,16 +648,25 @@
String prefix = "INSTRUMENTATION_STATUS: ";
int nameBegin = prefix.length();
int nameEnd = line.indexOf('=');
- int valueBegin = nameEnd + 1;
-
- mCurrentName = line.substring(nameBegin, nameEnd);
- mCurrentValue = line.substring(valueBegin);
+ if (nameEnd < 0) {
+ CLog.e("Line does not contain value. Logcat interrupted? (%s)", line);
+ mCurrentValue = null;
+ mCurrentName = null;
+ mParseSuccessful = false;
+ return;
+ } else {
+ int valueBegin = nameEnd + 1;
+ mCurrentName = line.substring(nameBegin, nameEnd);
+ mCurrentValue = line.substring(valueBegin);
+ }
} else if (line.startsWith("INSTRUMENTATION_CODE: ")) {
try {
mResultCode = Integer.parseInt(line.substring(22));
mGotExitValue = true;
} catch (NumberFormatException ex) {
- CLog.w("Instrumentation code format unexpected");
+ CLog.e("Instrumentation code format unexpected");
+ mParseSuccessful = false;
+ return;
}
} else if (mCurrentValue != null) {
mCurrentValue = mCurrentValue + line;
@@ -634,7 +687,7 @@
}
if (mValues != null) {
- mListener.handleStatus(mValues);
+ mParseSuccessful &= mListener.handleStatus(mValues);
mValues = null;
}
}
@@ -651,7 +704,7 @@
* Returns whether target instrumentation exited normally.
*/
public boolean wasSuccessful() {
- return mGotExitValue;
+ return mGotExitValue && mParseSuccessful;
}
/**
@@ -1451,11 +1504,12 @@
Throwable interruptingError = null;
try {
+ CLog.d("Running command '%s'", command);
executeShellCommandAndReadOutput(command, parser);
- } catch (Throwable ex) {
- interruptingError = ex;
- } finally {
parser.flush();
+ } catch (Throwable ex) {
+ CLog.w("Instrumented call threw '%s'", ex.getMessage());
+ interruptingError = ex;
}
final boolean progressedSinceLastCall = mInstanceListerner.getCurrentTestId() != null ||
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
index 7ec09c9..a22634f 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/DeqpTestRunnerTest.java
@@ -1165,6 +1165,735 @@
EasyMock.verify(mockDevice);
}
+ public void testRun_sessionInfoValueMissing() throws Exception {
+ final String instrumentationAnswerOk =
+ "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.test1\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_CODE: 0\r\n";
+
+ final String instrumentationAnswerBroken =
+ "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n";
+
+ final TestIdentifier[] testIds = {
+ new TestIdentifier("dEQP-GLES3.instances", "test1"),
+ };
+
+ final String[] testPaths = {
+ "dEQP-GLES3.instances.test1",
+ };
+
+ Map<String,String> config = new HashMap<>();
+ config.put("glconfig", "rgba8888d24s8");
+ config.put("rotation", "unspecified");
+ config.put("surfacetype", "window");
+
+ Map<TestIdentifier, List<Map<String, String>>> instances = new HashMap<>();
+
+ instances.put(testIds[0], new ArrayList<Map<String,String>>());
+ instances.get(testIds[0]).add(config);
+
+ Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+ for (TestIdentifier id : testIds) {
+ tests.add(id);
+ }
+
+ ITestInvocationListener mockListener
+ = EasyMock.createStrictMock(ITestInvocationListener.class);
+ IMocksControl orderedControl = EasyMock.createStrictControl();
+ ITestDevice mockDevice = orderedControl.createMock(ITestDevice.class);
+ IDevice mockIDevice = orderedControl.createMock(IDevice.class);
+
+ DeqpTestRunner.IRecovery mockRecovery = EasyMock.createMock(DeqpTestRunner.IRecovery.class);
+
+ DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instances);
+ deqpTest.setAbi(UnitTests.ABI);
+ deqpTest.setDevice(mockDevice);
+ deqpTest.setBuildHelper(new StubCtsBuildHelper());
+ deqpTest.setRecovery(mockRecovery);
+
+ int version = 3 << 16;
+ EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+ .andReturn(Integer.toString(version)).atLeastOnce();
+
+ mockRecovery.onExecutionProgressed();
+ EasyMock.expectLastCall().atLeastOnce();
+
+ mockRecovery.setDevice(mockDevice);
+ EasyMock.expectLastCall().atLeastOnce();
+
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+ andReturn("").once();
+
+ EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+ EasyMock.eq(true),
+ EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+ .once();
+
+ // query config
+ expectRenderConfigQueryAndReturn(mockDevice,
+ "--deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-gl-major-version=3 "
+ + "--deqp-gl-minor-version=0", "Yes");
+
+ // run config and fail
+ runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+ "{dEQP-GLES3{instances{test1}}}",
+ "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+ + " --deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-log-images=disable "
+ + "--deqp-watchdog=enable", instrumentationAnswerBroken);
+
+ mockRecovery.recoverComLinkKilled();
+ EasyMock.expectLastCall().once();
+
+ // Re-try
+ runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+ "{dEQP-GLES3{instances{test1}}}",
+ "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+ + " --deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-log-images=disable "
+ + "--deqp-watchdog=enable", instrumentationAnswerOk);
+
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
+ .andReturn("").once();
+
+ mockListener.testRunStarted(ID, 1);
+ EasyMock.expectLastCall().once();
+
+ // test1
+ mockListener.testStarted(EasyMock.eq(testIds[0]));
+ EasyMock.expectLastCall().once();
+
+ mockListener.testEnded(EasyMock.eq(testIds[0]), EasyMock.<Map<String, String>>notNull());
+ EasyMock.expectLastCall().once();
+
+ mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
+ EasyMock.expectLastCall().once();
+
+ orderedControl.replay();
+ EasyMock.replay(mockListener);
+ EasyMock.replay(mockRecovery);
+ deqpTest.run(mockListener);
+
+ EasyMock.verify(mockListener);
+ orderedControl.verify();
+ EasyMock.verify(mockRecovery);
+ }
+
+ public void testRun_resultEventTypeMissing() throws Exception {
+ final String instrumentationAnswerOk =
+ "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.test1\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_CODE: 0\r\n";
+
+ final String instrumentationAnswerBroken =
+ "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.test1\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n";
+
+ final TestIdentifier[] testIds = {
+ new TestIdentifier("dEQP-GLES3.instances", "test1"),
+ };
+
+ final String[] testPaths = {
+ "dEQP-GLES3.instances.test1",
+ };
+
+ Map<String,String> config = new HashMap<>();
+ config.put("glconfig", "rgba8888d24s8");
+ config.put("rotation", "unspecified");
+ config.put("surfacetype", "window");
+
+ Map<TestIdentifier, List<Map<String, String>>> instances = new HashMap<>();
+
+ instances.put(testIds[0], new ArrayList<Map<String,String>>());
+ instances.get(testIds[0]).add(config);
+
+ Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+ for (TestIdentifier id : testIds) {
+ tests.add(id);
+ }
+
+ ITestInvocationListener mockListener
+ = EasyMock.createStrictMock(ITestInvocationListener.class);
+ IMocksControl orderedControl = EasyMock.createStrictControl();
+ ITestDevice mockDevice = orderedControl.createMock(ITestDevice.class);
+ IDevice mockIDevice = orderedControl.createMock(IDevice.class);
+
+ DeqpTestRunner.IRecovery mockRecovery = EasyMock.createMock(DeqpTestRunner.IRecovery.class);
+
+ DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instances);
+ deqpTest.setAbi(UnitTests.ABI);
+ deqpTest.setDevice(mockDevice);
+ deqpTest.setBuildHelper(new StubCtsBuildHelper());
+ deqpTest.setRecovery(mockRecovery);
+
+ int version = 3 << 16;
+ EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+ .andReturn(Integer.toString(version)).atLeastOnce();
+
+ mockRecovery.onExecutionProgressed();
+ EasyMock.expectLastCall().atLeastOnce();
+
+ mockRecovery.setDevice(mockDevice);
+ EasyMock.expectLastCall().atLeastOnce();
+
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+ andReturn("").once();
+
+ EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+ EasyMock.eq(true),
+ EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+ .once();
+
+ // query config
+ expectRenderConfigQueryAndReturn(mockDevice,
+ "--deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-gl-major-version=3 "
+ + "--deqp-gl-minor-version=0", "Yes");
+
+ // run config and fail
+ runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+ "{dEQP-GLES3{instances{test1}}}",
+ "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+ + " --deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-log-images=disable "
+ + "--deqp-watchdog=enable", instrumentationAnswerBroken);
+
+ mockRecovery.recoverComLinkKilled();
+ EasyMock.expectLastCall().once();
+
+ // Re-try
+ runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+ "{dEQP-GLES3{instances{test1}}}",
+ "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+ + " --deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-log-images=disable "
+ + "--deqp-watchdog=enable", instrumentationAnswerOk);
+
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
+ .andReturn("").once();
+
+ mockListener.testRunStarted(ID, 1);
+ EasyMock.expectLastCall().once();
+
+ // test1
+ mockListener.testStarted(EasyMock.eq(testIds[0]));
+ EasyMock.expectLastCall().once();
+
+ mockListener.testEnded(EasyMock.eq(testIds[0]), EasyMock.<Map<String, String>>notNull());
+ EasyMock.expectLastCall().once();
+
+ mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
+ EasyMock.expectLastCall().once();
+
+ orderedControl.replay();
+ EasyMock.replay(mockListener);
+ EasyMock.replay(mockRecovery);
+ deqpTest.run(mockListener);
+
+ EasyMock.verify(mockListener);
+ orderedControl.verify();
+ EasyMock.verify(mockRecovery);
+ }
+
+ /**
+ * Test handling of interrupted line in the instrumentation output
+ * and recovery from the error.
+ */
+ public void testRun_testCasePathInterrupted() throws Exception {
+ final String instrumentationAnswerOk1 =
+ "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.test1\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_CODE: 0\r\n";
+ final String instrumentationAnswerOk2 =
+ "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.test2\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_CODE: 0\r\n";
+ final String instrumentationAnswerBroken =
+ "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePat";
+
+ final TestIdentifier[] testIds = {
+ new TestIdentifier("dEQP-GLES3.instances", "test1"),
+ new TestIdentifier("dEQP-GLES3.instances", "test2"),
+ };
+
+ final String[] testPaths = {
+ "dEQP-GLES3.instances.test1",
+ "dEQP-GLES3.instances.test2",
+ };
+
+ Map<String,String> config = new HashMap<>();
+ config.put("glconfig", "rgba8888d24s8");
+ config.put("rotation", "unspecified");
+ config.put("surfacetype", "window");
+
+ Map<TestIdentifier, List<Map<String, String>>> instances = new HashMap<>();
+
+ instances.put(testIds[0], new ArrayList<Map<String,String>>());
+ instances.get(testIds[0]).add(config);
+ instances.put(testIds[1], new ArrayList<Map<String,String>>());
+ instances.get(testIds[1]).add(config);
+
+ Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+ for (TestIdentifier id : testIds) {
+ tests.add(id);
+ }
+
+ ITestInvocationListener mockListener
+ = EasyMock.createStrictMock(ITestInvocationListener.class);
+ IMocksControl orderedControl = EasyMock.createStrictControl();
+ ITestDevice mockDevice = orderedControl.createMock(ITestDevice.class);
+ IDevice mockIDevice = orderedControl.createMock(IDevice.class);
+
+ DeqpTestRunner.IRecovery mockRecovery = EasyMock.createMock(DeqpTestRunner.IRecovery.class);
+
+ DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instances);
+ deqpTest.setAbi(UnitTests.ABI);
+ deqpTest.setDevice(mockDevice);
+ deqpTest.setBuildHelper(new StubCtsBuildHelper());
+ deqpTest.setRecovery(mockRecovery);
+
+ int version = 3 << 16;
+ EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+ .andReturn(Integer.toString(version)).atLeastOnce();
+
+ mockRecovery.onExecutionProgressed();
+ EasyMock.expectLastCall().atLeastOnce();
+
+ mockRecovery.setDevice(mockDevice);
+ EasyMock.expectLastCall().atLeastOnce();
+
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+ andReturn("").once();
+
+ EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+ EasyMock.eq(true),
+ EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+ .once();
+
+ // query config
+ expectRenderConfigQueryAndReturn(mockDevice,
+ "--deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-gl-major-version=3 "
+ + "--deqp-gl-minor-version=0", "Yes");
+
+ // run config and fail
+ runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+ "{dEQP-GLES3{instances{test1,test2}}}",
+ "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+ + " --deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-log-images=disable "
+ + "--deqp-watchdog=enable", instrumentationAnswerBroken);
+
+ mockRecovery.recoverComLinkKilled();
+ EasyMock.expectLastCall().once();
+
+ // Re-try
+ runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+ "{dEQP-GLES3{instances{test1}}}",
+ "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+ + " --deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-log-images=disable "
+ + "--deqp-watchdog=enable", instrumentationAnswerOk1);
+
+ runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+ "{dEQP-GLES3{instances{test2}}}",
+ "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+ + " --deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-log-images=disable "
+ + "--deqp-watchdog=enable", instrumentationAnswerOk2);
+
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
+ .andReturn("").once();
+
+ mockListener.testRunStarted(ID, 2);
+ EasyMock.expectLastCall().once();
+
+ // test1
+ mockListener.testStarted(EasyMock.eq(testIds[0]));
+ EasyMock.expectLastCall().once();
+
+ mockListener.testEnded(EasyMock.eq(testIds[0]), EasyMock.<Map<String, String>>notNull());
+ EasyMock.expectLastCall().once();
+
+ // test2
+ mockListener.testStarted(EasyMock.eq(testIds[1]));
+ EasyMock.expectLastCall().once();
+
+ mockListener.testEnded(EasyMock.eq(testIds[1]), EasyMock.<Map<String, String>>notNull());
+ EasyMock.expectLastCall().once();
+
+ mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
+ EasyMock.expectLastCall().once();
+
+ orderedControl.replay();
+ EasyMock.replay(mockListener);
+ EasyMock.replay(mockRecovery);
+ deqpTest.run(mockListener);
+
+ EasyMock.verify(mockListener);
+ orderedControl.verify();
+ EasyMock.verify(mockRecovery);
+ }
+
+ /**
+ * Test handling of interrupted line in the instrumentation output
+ * and recovery from the error.
+ */
+ public void testRun_testCasePathMissing() throws Exception {
+ final String instrumentationAnswerOk1 =
+ "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.test1\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_CODE: 0\r\n";
+ final String instrumentationAnswerOk2 =
+ "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.test2\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_CODE: 0\r\n";
+ final String instrumentationAnswerBroken =
+ "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+ + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+ + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n";
+
+
+ final TestIdentifier[] testIds = {
+ new TestIdentifier("dEQP-GLES3.instances", "test1"),
+ new TestIdentifier("dEQP-GLES3.instances", "test2"),
+ };
+
+ final String[] testPaths = {
+ "dEQP-GLES3.instances.test1",
+ "dEQP-GLES3.instances.test2",
+ };
+
+ Map<String,String> config = new HashMap<>();
+ config.put("glconfig", "rgba8888d24s8");
+ config.put("rotation", "unspecified");
+ config.put("surfacetype", "window");
+
+ Map<TestIdentifier, List<Map<String, String>>> instances = new HashMap<>();
+
+ instances.put(testIds[0], new ArrayList<Map<String,String>>());
+ instances.get(testIds[0]).add(config);
+ instances.put(testIds[1], new ArrayList<Map<String,String>>());
+ instances.get(testIds[1]).add(config);
+
+ Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+ for (TestIdentifier id : testIds) {
+ tests.add(id);
+ }
+
+ ITestInvocationListener mockListener
+ = EasyMock.createStrictMock(ITestInvocationListener.class);
+ IMocksControl orderedControl = EasyMock.createStrictControl();
+ ITestDevice mockDevice = orderedControl.createMock(ITestDevice.class);
+ IDevice mockIDevice = orderedControl.createMock(IDevice.class);
+
+ DeqpTestRunner.IRecovery mockRecovery = EasyMock.createMock(DeqpTestRunner.IRecovery.class);
+
+ DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instances);
+ deqpTest.setAbi(UnitTests.ABI);
+ deqpTest.setDevice(mockDevice);
+ deqpTest.setBuildHelper(new StubCtsBuildHelper());
+ deqpTest.setRecovery(mockRecovery);
+
+ int version = 3 << 16;
+ EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+ .andReturn(Integer.toString(version)).atLeastOnce();
+
+ mockRecovery.onExecutionProgressed();
+ EasyMock.expectLastCall().atLeastOnce();
+
+ mockRecovery.setDevice(mockDevice);
+ EasyMock.expectLastCall().atLeastOnce();
+
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+ andReturn("").once();
+
+ EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+ EasyMock.eq(true),
+ EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+ .once();
+
+ // query config
+ expectRenderConfigQueryAndReturn(mockDevice,
+ "--deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-gl-major-version=3 "
+ + "--deqp-gl-minor-version=0", "Yes");
+
+ // run config and fail
+ runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+ "{dEQP-GLES3{instances{test1,test2}}}",
+ "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+ + " --deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-log-images=disable "
+ + "--deqp-watchdog=enable", instrumentationAnswerBroken);
+
+ mockRecovery.recoverComLinkKilled();
+ EasyMock.expectLastCall().once();
+
+ // Re-try
+ runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+ "{dEQP-GLES3{instances{test1}}}",
+ "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+ + " --deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-log-images=disable "
+ + "--deqp-watchdog=enable", instrumentationAnswerOk1);
+
+ runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+ "{dEQP-GLES3{instances{test2}}}",
+ "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+ + " --deqp-gl-config-name=rgba8888d24s8 "
+ + "--deqp-screen-rotation=unspecified "
+ + "--deqp-surface-type=window "
+ + "--deqp-log-images=disable "
+ + "--deqp-watchdog=enable", instrumentationAnswerOk2);
+
+ EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
+ .andReturn("").once();
+
+ mockListener.testRunStarted(ID, 2);
+ EasyMock.expectLastCall().once();
+
+ // test1
+ mockListener.testStarted(EasyMock.eq(testIds[0]));
+ EasyMock.expectLastCall().once();
+
+ mockListener.testEnded(EasyMock.eq(testIds[0]), EasyMock.<Map<String, String>>notNull());
+ EasyMock.expectLastCall().once();
+
+ // test2
+ mockListener.testStarted(EasyMock.eq(testIds[1]));
+ EasyMock.expectLastCall().once();
+
+ mockListener.testEnded(EasyMock.eq(testIds[1]), EasyMock.<Map<String, String>>notNull());
+ EasyMock.expectLastCall().once();
+
+ mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
+ EasyMock.expectLastCall().once();
+
+ orderedControl.replay();
+ EasyMock.replay(mockListener);
+ EasyMock.replay(mockRecovery);
+ deqpTest.run(mockListener);
+
+ EasyMock.verify(mockListener);
+ orderedControl.verify();
+ EasyMock.verify(mockRecovery);
+ }
+
/**
* Test dEQP with multiple instances
*/