Merge "ATest: Add atest as a build target"
diff --git a/Android.mk b/Android.mk
index 5b3b76a..1437ab1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,7 +14,7 @@
LOCAL_PATH := $(call my-dir)
COMPATIBILITY.tradefed_tests_dir := \
- $(COMPATIBILITY.tradefed_tests_dir) $(LOCAL_PATH)/res/config $(LOCAL_PATH)/tests/res/config $(LOCAL_PATH)/prod-tests/res/config
+ $(COMPATIBILITY.tradefed_tests_dir) $(LOCAL_PATH)/res/config $(LOCAL_PATH)/tests/res/config
include $(CLEAR_VARS)
@@ -36,7 +36,7 @@
# Note that this is incompatible with `make dist`. If you want to make
# the distribution, you must run `tapas` with the individual target names.
.PHONY: tradefed-core
-tradefed-core: tradefed atest_tradefed tf-prod-tests tf-prod-metatests tradefed-contrib script_help
+tradefed-core: tradefed atest_tradefed tradefed-contrib tf-contrib-tests script_help
.PHONY: tradefed-all
tradefed-all: tradefed-core tradefed-tests tradefed_win verify loganalysis-tests
@@ -56,7 +56,7 @@
########################################################
# Zip up the built files and dist it as tradefed.zip
-tradefed_dist_host_jars := tradefed tradefed-tests tf-prod-tests tf-prod-metatests emmalib jack-jacoco-reporter loganalysis loganalysis-tests tf-remote-client tradefed-contrib tools-common-prebuilt
+tradefed_dist_host_jars := tradefed tradefed-tests emmalib jack-jacoco-reporter loganalysis loganalysis-tests tf-remote-client tradefed-contrib tf-contrib-tests tools-common-prebuilt
tradefed_dist_host_jar_files := $(foreach m, $(tradefed_dist_host_jars), $(HOST_OUT_JAVA_LIBRARIES)/$(m).jar)
tradefed_dist_host_exes := tradefed.sh tradefed_win.bat script_help.sh verify.sh run_tf_cmd.sh atest_tradefed.sh
diff --git a/atest/Android.bp b/atest/Android.bp
index 3891566..a53d3f9 100644
--- a/atest/Android.bp
+++ b/atest/Android.bp
@@ -66,3 +66,28 @@
"constants_default.py"
],
}
+
+// Move asuite_default and asuite_metrics to //tools/asuite when atest is
+// running as a prebuilt.
+python_defaults {
+ name: "asuite_default",
+ pkg_path: "asuite",
+ version: {
+ py2: {
+ enabled: true,
+ embedded_launcher: false,
+ },
+ py3: {
+ enabled: true,
+ embedded_launcher: false,
+ },
+ },
+}
+
+python_library_host {
+ name: "asuite_metrics",
+ defaults: ["asuite_default"],
+ srcs: [
+ "asuite_metrics.py",
+ ],
+}
diff --git a/atest/asuite_metrics.py b/atest/asuite_metrics.py
new file mode 100644
index 0000000..78bfff9
--- /dev/null
+++ b/atest/asuite_metrics.py
@@ -0,0 +1,101 @@
+# Copyright 2018, 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.
+
+"""Asuite simple Metrics Functions"""
+
+import json
+import logging
+import os
+import urllib2
+import uuid
+
+_JSON_HEADERS = {'Content-Type': 'application/json'}
+_METRICS_RESPONSE = 'done'
+_DUMMY_UUID = '00000000-0000-4000-8000-000000000000'
+_METRICS_TIMEOUT = 2 #seconds
+_META_FILE = os.path.join(os.path.expanduser('~'),
+ '.config', 'asuite', '.metadata')
+_ANDROID_BUILD_TOP = 'ANDROID_BUILD_TOP'
+
+
+#pylint: disable=broad-except
+def log_event(metrics_url, dummy_key_fallback=True, **kwargs):
+ """Base log event function for asuite backend.
+
+ Args:
+ metrics_url: String, URL to report metrics to.
+ dummy_key_fallback: Boolean, If True and unable to get grouping key,
+ use a dummy key otherwise return out. Sometimes we
+ don't want to return metrics for users we are
+ unable to identify. Default True.
+ kwargs: Dict, additional fields we want to return metrics for.
+ """
+ try:
+ try:
+ key = str(_get_grouping_key())
+ except Exception:
+ if not dummy_key_fallback:
+ return
+ key = _DUMMY_UUID
+ data = {'grouping_key': key,
+ 'run_id': str(uuid.uuid4())}
+ if kwargs:
+ data.update(kwargs)
+ data = json.dumps(data)
+ request = urllib2.Request(metrics_url, data=data,
+ headers=_JSON_HEADERS)
+ response = urllib2.urlopen(request, timeout=_METRICS_TIMEOUT)
+ content = response.read()
+ if content != _METRICS_RESPONSE:
+ raise Exception('Unexpected metrics response: %s' % content)
+ except Exception as e:
+ logging.debug('Exception sending metrics: %s', e)
+
+
+def _get_grouping_key():
+ """Get grouping key. Returns UUID.uuid4."""
+ if os.path.isfile(_META_FILE):
+ with open(_META_FILE) as f:
+ try:
+ return uuid.UUID(f.read(), version=4)
+ except ValueError:
+ logging.debug('malformed group_key in file, rewriting')
+ # TODO: Delete get_old_key() on 11/17/2018
+ key = _get_old_key() or uuid.uuid4()
+ dir_path = os.path.dirname(_META_FILE)
+ if os.path.isfile(dir_path):
+ os.remove(dir_path)
+ try:
+ os.makedirs(dir_path)
+ except OSError as e:
+ if not os.path.isdir(dir_path):
+ raise e
+ with open(_META_FILE, 'w+') as f:
+ f.write(str(key))
+ return key
+
+
+def _get_old_key():
+ """Get key from old meta data file if exists, else return None."""
+ old_file = os.path.join(os.environ[_ANDROID_BUILD_TOP],
+ 'tools/tradefederation/core/atest', '.metadata')
+ key = None
+ if os.path.isfile(old_file):
+ with open(old_file) as f:
+ try:
+ key = uuid.UUID(f.read(), version=4)
+ except ValueError:
+ logging.debug('error reading old key')
+ os.remove(old_file)
+ return key
diff --git a/atest/atest_metrics.py b/atest/atest_metrics.py
index 818fa9c..d2ac3ad 100755
--- a/atest/atest_metrics.py
+++ b/atest/atest_metrics.py
@@ -16,67 +16,11 @@
"""Simple Metrics Functions"""
-import json
-import logging
-import os
-import urllib2
-import uuid
-
import constants
+import asuite_metrics
-JSON_HEADERS = {'Content-Type': 'application/json'}
#pylint: disable=broad-except
def log_start_event():
"""Log that atest started."""
- try:
- try:
- key = str(get_grouping_key())
- except Exception:
- key = constants.DUMMY_UUID
- data = {'grouping_key': key,
- 'run_id': str(uuid.uuid4())}
- data = json.dumps(data)
- request = urllib2.Request(constants.METRICS_URL, data=data, headers=JSON_HEADERS)
- response = urllib2.urlopen(request, timeout=constants.METRICS_TIMEOUT)
- content = response.read()
- if content != constants.METRICS_RESPONSE:
- raise Exception('Unexpected metrics response: %s' % content)
- except Exception as e:
- logging.debug('Exception sending metrics: %s', e)
-
-def get_grouping_key():
- """Get grouping key. Returns UUID."""
- if os.path.isfile(constants.META_FILE):
- with open(constants.META_FILE) as f:
- try:
- return uuid.UUID(f.read(), version=4)
- except ValueError:
- logging.debug('malformed group_key in file, rewriting')
- # TODO: Delete get_old_key() on 11/17/2018
- key = get_old_key() or uuid.uuid4()
- dir_path = os.path.dirname(constants.META_FILE)
- if os.path.isfile(dir_path):
- os.remove(dir_path)
- try:
- os.makedirs(dir_path)
- except OSError as e:
- if not os.path.isdir(dir_path):
- raise e
- with open(constants.META_FILE, 'w+') as f:
- f.write(str(key))
- return key
-
-def get_old_key():
- """Get key from old meta data file if exists, else return None."""
- old_file = os.path.join(os.environ[constants.ANDROID_BUILD_TOP],
- 'tools/tradefederation/core/atest', '.metadata')
- key = None
- if os.path.isfile(old_file):
- with open(old_file) as f:
- try:
- key = uuid.UUID(f.read(), version=4)
- except ValueError:
- logging.debug('error reading old key')
- os.remove(old_file)
- return key
+ asuite_metrics.log_event(constants.METRICS_URL)
diff --git a/atest/constants_default.py b/atest/constants_default.py
index ee1eb85..ce0dc15 100644
--- a/atest/constants_default.py
+++ b/atest/constants_default.py
@@ -16,7 +16,6 @@
Various globals used by atest.
"""
-import os
MODE = 'DEFAULT'
@@ -112,12 +111,7 @@
BOTH_TEST = 'both'
# Metrics
-META_FILE = os.path.join(os.path.expanduser('~'),
- '.config', 'asuite', '.metadata')
METRICS_URL = 'http://asuite-218222.appspot.com/atest/metrics'
-METRICS_TIMEOUT = 2 #seconds
-METRICS_RESPONSE = 'done'
-DUMMY_UUID = '00000000-0000-4000-8000-000000000000'
# VTS plans
VTS_STAGING_PLAN = 'vts-staging-default'
diff --git a/prod-tests/.classpath b/prod-tests/.classpath
deleted file mode 100644
index d3c1487..0000000
--- a/prod-tests/.classpath
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="src" path="junit"/>
- <classpathentry kind="src" path="res"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry combineaccessrules="false" kind="src" path="/tradefederation"/>
- <classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
- <classpathentry combineaccessrules="false" kind="src" path="/loganalysis"/>
- <classpathentry kind="var" path="TRADEFED_ROOT/out/host/common/obj/JAVA_LIBRARIES/host-libprotobuf-java-full_intermediates/classes.jar"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/prod-tests/.project b/prod-tests/.project
deleted file mode 100644
index ce64e84..0000000
--- a/prod-tests/.project
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>tf-prod-tests</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
- <linkedResources>
- <link>
- <name>junit</name>
- <type>2</type>
- <locationURI>TRADEFED_ROOT/external/junit/src/main/java</locationURI>
- </link>
- </linkedResources>
-</projectDescription>
diff --git a/prod-tests/Android.mk b/prod-tests/Android.mk
deleted file mode 100644
index 00abe3b..0000000
--- a/prod-tests/Android.mk
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright (C) 2011 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_RESOURCE_DIRS := res
-
-LOCAL_JAVACFLAGS += -g -Xlint
--include tools/tradefederation/core/error_prone_rules.mk
-
-LOCAL_MODULE := tf-prod-tests
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_JAVA_LIBRARIES := tradefed loganalysis
-
-LOCAL_JAR_MANIFEST := MANIFEST.mf
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# makefile rules to copy jars to HOST_OUT/tradefed
-# so tradefed.sh can automatically add to classpath
-DEST_JAR := $(HOST_OUT)/tradefed/$(LOCAL_MODULE).jar
-$(DEST_JAR): $(LOCAL_BUILT_MODULE)
- $(copy-file-to-new-target)
-
-# this dependency ensure the above rule will be executed if jar is built
-$(LOCAL_INSTALLED_MODULE) : $(DEST_JAR)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/prod-tests/MANIFEST.mf b/prod-tests/MANIFEST.mf
deleted file mode 100644
index 19d17b0..0000000
--- a/prod-tests/MANIFEST.mf
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Implementation-Version: default
diff --git a/prod-tests/README b/prod-tests/README
deleted file mode 100644
index 4da837c..0000000
--- a/prod-tests/README
+++ /dev/null
@@ -1,5 +0,0 @@
-This directory contains test harness code that make use of the tradefed
-framework to run tests on Android platform.
-
-They are distinct from code in the 'tests' directory, which are unit tests for
-the tradefed framework itself.
diff --git a/prod-tests/res/config/app/launch.xml b/prod-tests/res/config/app/launch.xml
deleted file mode 100644
index 684aad6..0000000
--- a/prod-tests/res/config/app/launch.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<configuration description="Runs app install and launch test with given apk">
- <option name="enable-root" value="false" />
- <build_provider class="com.android.tradefed.build.LocalAppBuildProvider" />
- <!-- to install AppLaunch.apk -->
- <target_preparer class="com.android.tradefed.targetprep.InstallApkSetup" />
- <test class="com.android.app.tests.AppLaunchTest" />
- <logger class="com.android.tradefed.log.FileLogger"/>
-</configuration>
diff --git a/prod-tests/res/config/build/image-stats.xml b/prod-tests/res/config/build/image-stats.xml
deleted file mode 100644
index 2cdaa93..0000000
--- a/prod-tests/res/config/build/image-stats.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<configuration description="Runs download manager host-based tests">
- <option name="null-device" value="true" />
- <test class="com.android.build.tests.ImageStats" />
-</configuration>
diff --git a/prod-tests/res/config/framework/download-mgr.xml b/prod-tests/res/config/framework/download-mgr.xml
deleted file mode 100644
index 5df3b6e..0000000
--- a/prod-tests/res/config/framework/download-mgr.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<configuration description="Runs download manager host-based tests">
- <test class="com.android.framework.tests.DownloadManagerHostTests" />
- <logger class="com.android.tradefed.log.FileLogger">
- <option name="log-level-display" value="debug" />
- </logger>
-</configuration>
diff --git a/prod-tests/res/config/framework/package-mgr-ota.xml b/prod-tests/res/config/framework/package-mgr-ota.xml
deleted file mode 100644
index b8b3b3d..0000000
--- a/prod-tests/res/config/framework/package-mgr-ota.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
- <!-- Copyright 2012 Google Inc. All Rights Reserved -->
-<configuration description="Runs package manager ota host-based tests">
-
- <test class="com.android.framework.tests.PackageManagerOTATests">
- </test>
- <logger class="com.android.tradefed.log.FileLogger" />
- <result_reporter class="com.android.tradefed.result.XmlResultReporter" />
-</configuration>
diff --git a/prod-tests/res/config/framework/package-mgr-stress.xml b/prod-tests/res/config/framework/package-mgr-stress.xml
deleted file mode 100644
index 92de5df..0000000
--- a/prod-tests/res/config/framework/package-mgr-stress.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<configuration description="Runs package manager host-based stress tests">
- <test class="com.android.framework.tests.PackageManagerStressHostTests" />
- <logger class="com.android.tradefed.log.FileLogger">
- <option name="log-level-display" value="debug" />
- </logger>
-</configuration>
diff --git a/prod-tests/res/config/framework/package-mgr.xml b/prod-tests/res/config/framework/package-mgr.xml
deleted file mode 100644
index 9fd19f6..0000000
--- a/prod-tests/res/config/framework/package-mgr.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<configuration description="Runs download manager host-based tests">
- <test class="com.android.framework.tests.PackageManagerHostTests" />
- <logger class="com.android.tradefed.log.FileLogger">
- <option name="log-level-display" value="debug" />
- </logger>
-</configuration>
diff --git a/prod-tests/res/config/framework/preloaded-classes.xml b/prod-tests/res/config/framework/preloaded-classes.xml
deleted file mode 100644
index 38332d3..0000000
--- a/prod-tests/res/config/framework/preloaded-classes.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Runs tests to report preloaded classes information">
- <!-- Download preload tool -->
- <option name="device-launch-control:additional-files-filter" value=".*preload2.jar" />
- <!-- Install test apps -->
- <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup" />
- <!-- Preload test configuration -->
- <option name="test-tag" value="preloaded-classes" />
- <test class="com.android.framework.tests.PreloadedClassesTest" />
-</configuration>
diff --git a/prod-tests/res/config/google/example/hello-world-multi.xml b/prod-tests/res/config/google/example/hello-world-multi.xml
deleted file mode 100644
index a9af98e..0000000
--- a/prod-tests/res/config/google/example/hello-world-multi.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<configuration description="Multi device Hello World Example">
- <!-- Some option for the whole configuration-->
- <option name="test-tag" value="multi-device-hello-world" />
-
- <!-- Each device configuration -->
- <device name="device1">
- <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
- <option name="disable" value="true" />
- </target_preparer>
- </device>
-
- <!-- A device tag can be completely empty if it doesn't require any setup -->
- <device name="device2" />
-
- <!-- preparer that affects all the devices, called after the individual target_preparer -->
- <!-- Not required: If you have none, you can remove all the 'multi_target_preparer' -->
- <multi_target_preparer class="com.android.tradefed.targetprep.multi.StubMultiTargetPreparer" />
- <multi_target_preparer class="com.android.tradefed.targetprep.multi.HelloWorldMultiTargetPreparer" />
-
- <!-- logger in verbose for the example -->
- <logger class="com.android.tradefed.log.FileLogger">
- <option name="log-level" value="VERBOSE" />
- <option name="log-level-display" value="VERBOSE" />
- </logger>
-
- <!-- tests that will be ran -->
- <test class="com.android.tradefed.HelloWorldMultiDevices" />
-
- <!-- result reporters -->
- <result_reporter class="com.android.tradefed.result.ConsoleResultReporter" />
-
-</configuration>
-
diff --git a/prod-tests/res/config/longevity/metrics-collectors.xml b/prod-tests/res/config/longevity/metrics-collectors.xml
deleted file mode 100644
index 3c328b7..0000000
--- a/prod-tests/res/config/longevity/metrics-collectors.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<!-- Metric collectors for longevity runs. -->
-<configuration description="Metric collectors for longevity runs.">
- <metrics_collector class="com.android.tradefed.device.metric.ScheduleMultipleDeviceMetricCollector">
- <!-- Collect fragmentation info every 2 minutes. -->
- <option name="metric-collection-intervals" key="fragmentation" value="120000" />
- <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.BuddyInfoMetricCollector" />
-
- <!-- Collect compact memory dump every 3 minutes. -->
- <option name="metric-collection-intervals" key="compact-meminfo" value="180000" />
- <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.MemInfoMetricCollector" />
-
- <!-- Collect graphicsstats dump every 4 minutes. -->
- <option name="metric-collection-intervals" key="jank" value="240000" />
- <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.GraphicsStatsMetricCollector" />
-
- <!-- Collect bugreport every 1 hour. -->
- <option name="metric-collection-intervals" key="bugreportz" value="3600000" />
- <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.BugreportzMetricCollector" />
-
- <!-- Collect ion audio and system heap info every 15 minutes. -->
- <option name="metric-collection-intervals" key="ion" value="900000" />
- <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.IonHeapInfoMetricCollector" />
-
- <!-- Collect pagetype info every 10 minutes. -->
- <option name="metric-collection-intervals" key="pagetypeinfo" value="600000" />
- <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.PagetypeInfoMetricCollector" />
-
- <!-- Collect trace every 20 minutes. -->
- <option name="metric-collection-intervals" key="trace" value="1200000" />
- <option name="metric-collector-command-classes" value="com.android.tradefed.device.metric.TraceMetricCollector" />
- <!-- Add more if there are requests. -->
- </metrics_collector>
-</configuration>
diff --git a/prod-tests/res/config/longevity/preparers.xml b/prod-tests/res/config/longevity/preparers.xml
deleted file mode 100644
index 5168a62..0000000
--- a/prod-tests/res/config/longevity/preparers.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<!-- Preparer configuration for longevity runs. -->
-<configuration description="Preparer configuration for longevity runs.">
- <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
- <option name="test-file-name" value="PhoneLongevityTests.apk" />
- </target_preparer>
-</configuration>
diff --git a/prod-tests/res/config/longevity/test.xml b/prod-tests/res/config/longevity/test.xml
deleted file mode 100644
index 754ea35..0000000
--- a/prod-tests/res/config/longevity/test.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<!-- Test configuration for longevity runs. -->
-<configuration description="Test configuration for longevity runs.">
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <!-- Test run setup and configuration. -->
- <option name="package" value="android.longevity.platform" />
- <option name="class" value="android.longevity.platform.PhoneSuite" />
- <option name="instrumentation-arg" key="iterations" value="100" />
- <option name="instrumentation-arg" key="shuffle" value="true" />
-
- <!-- Timeout configurations. Test: 5m. Suite: 10h. Battery: 5%. -->
- <option name="instrumentation-arg" key="timeout_msec" value="300000" />
- <option name="instrumentation-arg" key="suite-timeout_msec" value="36000000" />
- <option name="instrumentation-arg" key="min-battery" value="0.05" />
-
- <!-- Override or negate instrumentation defaults. -->
- <option name="shell-timeout" value="0" />
- <option name="test-timeout" value="0" />
- </test>
-</configuration>
diff --git a/prod-tests/res/config/monkey/app-metrics.xml b/prod-tests/res/config/monkey/app-metrics.xml
deleted file mode 100644
index 76b8cee..0000000
--- a/prod-tests/res/config/monkey/app-metrics.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<configuration description="Run monkey using existing pre-prepared device with defaults appropriate for a single application being targeted. Use --package to specify application.">
- <option name = "enable-root" value="false" />
- <option name = "reboot-device" value="false" />
- <test class="com.android.monkey.MonkeyMetricsTest">
- <option name="category" value="android.intent.category.CAR_DOCK" />
- <option name="category" value="android.intent.category.INFO" />
- <option name="category" value="android.intent.category.LAUNCHER" />
- <option name="category" value="android.intent.category.MONKEY" />
- <option name="category" value="android.intent.category.SAMPLE_CODE" />
- <option name="target-count" value="10000" />
- <option name="throttle" value="100" />
- <option name="idle-time" value="0" />
- <!-- 30 minute timeout for the monkey -->
- <option name="monkey-timeout" value="30" />
- <option name="retry-on-failure" value="true" />
- </test>
-</configuration>
\ No newline at end of file
diff --git a/prod-tests/res/config/monkey/application.xml b/prod-tests/res/config/monkey/application.xml
deleted file mode 100644
index 711538d..0000000
--- a/prod-tests/res/config/monkey/application.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<configuration description="Run monkey using existing pre-prepared device with defaults appropriate for a single application being targeted. Use --package to specify application.">
- <option name = "enable-root" value="false" />
- <option name = "reboot-device" value="false" />
- <test class="com.android.monkey.MonkeyBase">
- <option name="category" value="android.intent.category.CAR_DOCK" />
- <option name="category" value="android.intent.category.INFO" />
- <option name="category" value="android.intent.category.LAUNCHER" />
- <option name="category" value="android.intent.category.MONKEY" />
- <option name="category" value="android.intent.category.SAMPLE_CODE" />
- <option name="target-count" value="10000" />
- <option name="throttle" value="100" />
- <option name="idle-time" value="30" />
- <!-- 30 minute timeout for the monkey -->
- <option name="monkey-timeout" value="30" />
- <option name="retry-on-failure" value="true" />
- </test>
- <logger class="com.android.tradefed.log.FileLogger" />
-</configuration>
\ No newline at end of file
diff --git a/prod-tests/res/config/monkey/system.xml b/prod-tests/res/config/monkey/system.xml
deleted file mode 100644
index fb5463b..0000000
--- a/prod-tests/res/config/monkey/system.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<configuration description="Run monkey using existing pre-prepared device with defaults appropriate for the entire system being targeted. Use --package to restrict run to specified applications.">
- <option name = "enable-root" value="false" />
- <option name = "reboot-device" value="false" />
- <test class="com.android.monkey.MonkeyBase">
- <option name="category" value="android.intent.category.LAUNCHER" />
- <option name="target-count" value="125000" />
- <option name="idle-time" value="0" />
- </test>
- <logger class="com.android.tradefed.log.FileLogger" />
-</configuration>
diff --git a/prod-tests/res/config/performance/app-transitions.xml b/prod-tests/res/config/performance/app-transitions.xml
deleted file mode 100644
index 9816f1e..0000000
--- a/prod-tests/res/config/performance/app-transitions.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Testing the transition delay performance" >
-
- <option name="test-tag" value="AppTransitionTests" />
-
- <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup" >
- <option name="test-file-name" value="AppTransitionTests.apk" />
- </target_preparer>
-
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer" />
-
- <test class="com.android.performance.tests.AppTransitionTests" />
-
-</configuration>
diff --git a/prod-tests/res/config/performance/hermetic-launch.xml b/prod-tests/res/config/performance/hermetic-launch.xml
deleted file mode 100644
index dc74149..0000000
--- a/prod-tests/res/config/performance/hermetic-launch.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<configuration description="Testing the app launch performance" >
-
- <option
- name="test-tag"
- value="HermeticLaunchTest" />
-
- <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup" >
- <option
- name="test-file-name"
- value="PerformanceLaunch.apk" />
- <option
- name="test-file-name"
- value="PerformanceAppTest.apk" />
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.InstallApkSetup" />
-
- <target_preparer class="com.android.tradefed.targetprep.CpuThrottlingWaiter" />
- <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer" />
-
- <test class="com.android.performance.tests.HermeticLaunchTest" >
- <option
- name="package"
- value="com.android.performanceapp.tests" />
- <option
- name="target-package"
- value="com.android.performanceLaunch" />
- <option
- name="launch-count"
- value="15" />
- <option
- name="save-atrace"
- value="true" />
- </test>
-
-</configuration>
diff --git a/prod-tests/res/config/performance/hermetic-memory.xml b/prod-tests/res/config/performance/hermetic-memory.xml
deleted file mode 100644
index d6dbfab..0000000
--- a/prod-tests/res/config/performance/hermetic-memory.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2016 Google Inc. All Rights Reserved -->
-<configuration description="Testing system memory and app memory usage after launching app">
- <!--apk-path option should point to the location of the test apk path-->
- <target_preparer class="com.android.tradefed.targetprep.InstallApkSetup" >
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.TimeWaster" >
- <option name="delay" value="60000" />
- </target_preparer>
- <test class="com.android.performance.tests.HermeticMemoryTest"/>
-</configuration>
diff --git a/prod-tests/res/config/stability/reboot-stress.xml b/prod-tests/res/config/stability/reboot-stress.xml
deleted file mode 100644
index a858174..0000000
--- a/prod-tests/res/config/stability/reboot-stress.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-<configuration description="Runs reboot stress test">
- <test class="com.android.stability.tests.RebootStressTest" />
- <logger class="com.android.tradefed.log.FileLogger">
- <option name="log-level-display" value="debug" />
- </logger>
- <result_reporter class="com.android.tradefed.result.XmlResultReporter" />
-</configuration>
diff --git a/prod-tests/res/config/template/android-junit.xml b/prod-tests/res/config/template/android-junit.xml
deleted file mode 100644
index 0065e94..0000000
--- a/prod-tests/res/config/template/android-junit.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 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.
--->
-<!-- A template for running non-custom, Android JUnit-style tests. -->
-<configuration description="Android JUnit Google Tradefed XML">
- <!-- Required: specify the package to run. -->
- <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
- <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
- </test>
-</configuration>
diff --git a/prod-tests/res/config/template/local.xml b/prod-tests/res/config/template/local.xml
deleted file mode 100644
index 6520e72..0000000
--- a/prod-tests/res/config/template/local.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<!-- Common base configuration for local runs. -->
-<configuration description="Common base configuration for local runs">
- <option name="bugreport-on-invocation-ended" value="true" />
- <build_provider class="com.android.tradefed.build.BootstrapBuildProvider" />
- <!-- Provides a mechanism for overwriting the preloaded classes that is disabled by default. -->
- <target_preparer class="com.android.tradefed.targetprep.PreloadedClassesPreparer">
- <option name="disable" value="true" />
- </target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
- <option name="screen-always-on" value="on" />
- <option name="screen-adaptive-brightness" value="off" />
- <option name="screen-brightness" value="30" />
- </target_preparer>
-
- <template-include name="preparers" default="empty" />
-
- <template-include name="test" />
-
- <logger class="com.android.tradefed.log.FileLogger">
- <option name="log-level" value="VERBOSE" />
- <option name="log-level-display" value="VERBOSE" />
- </logger>
- <log_saver class="com.android.tradefed.result.FileSystemLogSaver" />
- <result_reporter class="com.android.tradefed.result.ConsoleResultReporter" />
- <result_reporter class="com.android.tradefed.result.InvocationFailureEmailResultReporter" />
- <result_reporter class="com.android.tradefed.result.DeviceUnavailEmailResultReporter" />
- <template-include name="reporters" default="empty" />
-</configuration>
diff --git a/prod-tests/res/config/template/local_min.xml b/prod-tests/res/config/template/local_min.xml
deleted file mode 100644
index 2707eb2..0000000
--- a/prod-tests/res/config/template/local_min.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<!-- Common base configuration for local runs with minimum overhead. -->
-<configuration description="Common base configuration for local runs with minimum overhead">
- <build_provider class="com.android.tradefed.build.BootstrapBuildProvider" />
- <target_preparer class="com.android.tradefed.targetprep.PreloadedClassesPreparer">
- <option name="disable" value="true" />
- </target_preparer>
-
- <template-include name="preparers" default="empty" />
-
- <template-include name="test" default="empty" />
-
- <logger class="com.android.tradefed.log.FileLogger">
- <option name="log-level" value="VERBOSE" />
- <option name="log-level-display" value="VERBOSE" />
- </logger>
- <log_saver class="com.android.tradefed.result.FileSystemLogSaver" />
- <result_reporter class="com.android.tradefed.result.ConsoleResultReporter" />
- <result_reporter class="com.android.tradefed.result.suite.SuiteResultReporter" />
- <result_reporter class="com.android.tradefed.result.MetricsXMLResultReporter"/>
- <template-include name="reporters" default="empty" />
- <template-include name="metrics_collector" default="empty" />
-</configuration>
diff --git a/prod-tests/res/config/uiautomator/uiautomator-demo.xml b/prod-tests/res/config/uiautomator/uiautomator-demo.xml
deleted file mode 100644
index 4e0d610..0000000
--- a/prod-tests/res/config/uiautomator/uiautomator-demo.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<configuration description="Runs the UI Automator Demo Test">
- <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
- <!--
- This test requires deploying the UI Automator demo test onto device.
- The demo test is located under Android source tree:
- frameworks/testing/uiautomator/samples/SkeletonTest
- After the uiautomator.skeletontest.jar is built, insert "__push"
- parameter to this TradFed test to deploy:
- __push /path/to/uiautomator.skeletontest.jar->/data/local/tmp/uiautomator.skeletontest.jar
- -->
- <test class="com.android.tradefed.testtype.UiAutomatorTest">
- <option name="jar-path" value="uiautomator.skeletontest.jar" />
- <option name="class" value="com.android.uiautomator.samples.skeleton.DemoTestCase" />
- </test>
- <logger class="com.android.tradefed.log.FileLogger">
- <option name="log-level-display" value="debug" />
- </logger>
-</configuration>
diff --git a/prod-tests/src/com/android/app/tests/AppLaunchTest.java b/prod-tests/src/com/android/app/tests/AppLaunchTest.java
deleted file mode 100644
index 051979c..0000000
--- a/prod-tests/src/com/android/app/tests/AppLaunchTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2012 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.app.tests;
-
-import com.android.tradefed.build.IAppBuildInfo;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.VersionedFile;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.testtype.InstrumentationTest;
-import com.android.tradefed.util.AaptParser;
-import com.android.tradefed.util.FileUtil;
-
-import org.junit.Assert;
-
-import java.io.File;
-import java.util.HashMap;
-
-/**
- * A harness that installs and launches an app on device and verifies it doesn't crash.
- * <p/>
- * Requires a {@link IAppBuildInfo} and 'aapt' being present in path. Assume the AppLaunch
- * test app is already present on device.
- */
-public class AppLaunchTest implements IDeviceTest, IRemoteTest, IBuildReceiver {
-
- private static final String RUN_NAME = "AppLaunch";
- private ITestDevice mDevice;
- private IBuildInfo mBuild;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setBuild(IBuildInfo buildInfo) {
- mBuild = buildInfo;
- }
-
- /**
- * Installs all apks listed in {@link IAppBuildInfo}, then attempts to run the package in the
- * first apk. Note that this does <emph>not</emph> attempt to uninstall the apks, and requires
- * external cleanup.
- * <p />
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- long startTime = System.currentTimeMillis();
- listener.testRunStarted(RUN_NAME, 2);
- try {
- Assert.assertTrue(mBuild instanceof IAppBuildInfo);
- IAppBuildInfo appBuild = (IAppBuildInfo)mBuild;
- Assert.assertFalse(appBuild.getAppPackageFiles().isEmpty());
-
- // We assume that the first apk is the one to be executed, and any others are to be
- // installed and uninstalled.
- File appApkFile = appBuild.getAppPackageFiles().get(0).getFile();
- AaptParser p = AaptParser.parse(appApkFile);
- Assert.assertNotNull(p);
- String packageName = p.getPackageName();
- Assert.assertNotNull(String.format("Failed to parse package name from %s",
- appApkFile.getAbsolutePath()), packageName);
-
- for (final VersionedFile apkVersionedFile : appBuild.getAppPackageFiles()) {
- final File apkFile = apkVersionedFile.getFile();
- performInstallTest(apkFile, listener);
- }
-
- performLaunchTest(packageName, listener);
- } catch (AssertionError e) {
- listener.testRunFailed(e.toString());
- } finally {
- listener.testRunEnded(
- System.currentTimeMillis() - startTime, new HashMap<String, Metric>());
- }
-
- }
-
- private void performInstallTest(File apkFile, ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- TestDescription installTest =
- new TestDescription(
- "com.android.app.tests.InstallTest",
- FileUtil.getBaseName(apkFile.getName()));
- listener.testStarted(installTest);
- String result = getDevice().installPackage(apkFile, true);
- if (result != null) {
- listener.testFailed(installTest, result);
- }
- listener.testEnded(installTest, new HashMap<String, Metric>());
- }
-
- private void performLaunchTest(String packageName, ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- InstrumentationTest i = new InstrumentationTest();
- i.setRunName(RUN_NAME);
- i.setPackageName("com.android.applaunchtest");
- i.setRunnerName("com.android.applaunchtest.AppLaunchRunner");
- i.setDevice(getDevice());
- i.addInstrumentationArg("packageName", packageName);
- i.run(listener);
- try (InputStreamSource s = getDevice().getScreenshot()) {
- listener.testLog("screenshot", LogDataType.PNG, s);
- }
- }
-}
diff --git a/prod-tests/src/com/android/build/tests/ImageStats.java b/prod-tests/src/com/android/build/tests/ImageStats.java
deleted file mode 100644
index 9d9c6ef..0000000
--- a/prod-tests/src/com/android/build/tests/ImageStats.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2018 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.build.tests;
-
-import com.android.ddmlib.Log;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * A device-less test that parses standard Android build image stats file and performs aggregation
- */
-@OptionClass(alias = "image-stats")
-public class ImageStats implements IRemoteTest, IBuildReceiver {
-
- // built-in aggregation labels
- private static final String LABEL_TOTAL = "total";
- private static final String LABEL_CATEGORIZED = "categorized";
- private static final String LABEL_UNCATEGORIZED = "uncategorized";
-
- private static final String FILE_SIZES = "fileSizes";
-
- @Option(name = "size-stats-file", description = "Specify the name of the file containing image "
- + "stats; when \"file-from-build-info\" is set to true, the name refers to a file that "
- + "can be found in build info (note that build provider must be properly configured to "
- + "download it), otherwise it refers to a local file, typically used for debugging "
- + "purposes", mandatory = true)
- private String mStatsFileName = null;
-
- @Option(name = "file-from-build-info", description = "If the \"size-stats-file\" references a "
- + "file from build info, or local; use local file for debugging purposes.")
- private boolean mFileFromBuildInfo = false;
-
- @Option(name = "aggregation-pattern", description = "A key value pair consists of a regex as "
- + "key and a string label as value. The regex is used to scan and group file size "
- + "entries together for aggregation; that is, all files with names matching the "
- + "pattern are grouped together for summing; this also means that a file could be "
- + "counted multiple times; note that the regex must be a full match, not substring. "
- + "The string label is used for identifying the summed group of file sizes when "
- + "reporting; the regex may contain unnamed capturing groups, and values may contain "
- + "numerical \"back references\" as place holders to be replaced with content of "
- + "corresponding capturing group, example: ^.+\\.(.+)$ -> group-by-extension-\\1; back "
- + "references are 1-indexed and there maybe up to 9 capturing groups; no strict checks "
- + "are performed to ensure that capturing groups and place holders are 1:1 mapping. "
- + "There are 3 built-in aggregations: total, categorized and uncategorized.")
- private Map<String, String> mAggregationPattern = new HashMap<>();
-
- @Option(name = "min-report-size", description = "Minimum size in bytes that an aggregated "
- + "category needs to reach before being included in reported metrics. 0 for no limit. "
- + "Note that built-in categories are always reported.")
- private long mMinReportSize = 0;
-
- private IBuildInfo mBuildInfo;
-
- @Override
- public void setBuild(IBuildInfo buildInfo) {
- mBuildInfo = buildInfo;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- File statsFile;
- if (mFileFromBuildInfo) {
- statsFile = mBuildInfo.getFile(mStatsFileName);
- } else {
- statsFile = new File(mStatsFileName);
- }
- long start = System.currentTimeMillis();
- Map<String, String> fileSizes = null;
- // fixed run name, 1 test to run
- listener.testRunStarted("image-stats", 1);
- if (statsFile == null || !statsFile.exists()) {
- throw new RuntimeException(
- "Invalid image stats file (<null>) specified or it does not exist.");
- } else {
- TestDescription td = new TestDescription(ImageStats.class.getName(), FILE_SIZES);
- listener.testStarted(td);
- try (InputStream in = new FileInputStream(statsFile)) {
- fileSizes = performAggregation(parseFileSizes(in),
- processAggregationPatterns(mAggregationPattern));
- } catch (IOException ioe) {
- String message = String.format("Failed to parse image stats file: %s",
- statsFile.getAbsolutePath());
- CLog.e(message);
- CLog.e(ioe);
- listener.testFailed(td, ioe.toString());
- listener.testEnded(td, new HashMap<String, Metric>());
- listener.testRunFailed(message);
- listener.testRunEnded(
- System.currentTimeMillis() - start, new HashMap<String, Metric>());
- throw new RuntimeException(message, ioe);
- }
- String logOutput = String.format("File sizes: %s", fileSizes.toString());
- if (mFileFromBuildInfo) {
- CLog.v(logOutput);
- } else {
- // assume local debug, print outloud
- CLog.logAndDisplay(Log.LogLevel.VERBOSE, logOutput);
- }
- listener.testEnded(td, TfMetricProtoUtil.upgradeConvert(fileSizes));
- }
- listener.testRunEnded(System.currentTimeMillis() - start, new HashMap<String, Metric>());
- }
-
- /**
- * Processes text files like 'installed-files.txt' (as built by standard Android build rules for
- * device targets) into a map of file path to file sizes
- * @param in an unread {@link InputStream} for the content of the file sizes; the stream will be
- * fully read after executing the method
- * @return
- */
- protected Map<String, Long> parseFileSizes(InputStream in) throws IOException {
- Map<String, Long> ret = new HashMap<>();
- try (BufferedReader br = new BufferedReader(new InputStreamReader(in))) {
- String line;
- while ((line = br.readLine()) != null) {
- // trim both ends of the raw line and make a split by whitespaces
- // e.g. trying to match a line like this:
- // 96992106 /system/app/Chrome/Chrome.apk
- String[] fields = line.trim().split("\\s+");
- if (fields.length != 2) {
- CLog.w("Unable to split line to file size and name: %s", line);
- continue;
- }
- long size = 0;
- try {
- size = Long.parseLong(fields[0]);
- } catch (NumberFormatException nfe) {
- CLog.w("Failed to parse file size from field '%s', ignored", fields[0]);
- continue;
- }
- ret.put(fields[1], size);
- }
- }
- return ret;
- }
-
- /** Compiles the supplied aggregation regex's */
- protected Map<Pattern, String> processAggregationPatterns(Map<String, String> rawPatterns) {
- Map<Pattern, String> ret = new HashMap<>();
- for (Map.Entry<String, String> e : rawPatterns.entrySet()) {
- Pattern p = Pattern.compile(e.getKey());
- ret.put(p, e.getValue());
- }
- return ret;
- }
-
- /**
- * Converts a matched file entry to the final aggregation label name.
- * <p>
- * The main thing being converted here is that capturing groups in the regex (used to match the
- * filenames) are extracted, and used to replace the corresponding placeholders in raw label.
- * For each 1-indexed capturing group, the captured content is used to replace the "\x"
- * placeholders in raw label, with x being a number between 1-9, corresponding to the index of
- * the capturing group.
- *
- * @param matcher the {@link Matcher} representing the matched result from the regex and input
- * @param rawLabel the corresponding aggregation label
- * @return
- */
- protected String getAggregationLabel(Matcher matcher, String rawLabel) {
- if (matcher.groupCount() == 0) {
- // no capturing groups, return label as is
- return rawLabel;
- }
- if (matcher.groupCount() > 9) {
- // since we are doing replacement of back references to capturing groups manually,
- // artificially limiting this to avoid overly complex code to handle \1 vs \10
- // in other words, "9 capturing groups ought to be enough for anybody"
- throw new RuntimeException("too many capturing groups");
- }
- String label = rawLabel;
- for (int i = 1; i <= matcher.groupCount(); i++) {
- String marker = String.format("\\%d", i); // e.g. "\1"
- if (label.indexOf(marker) == -1) {
- CLog.w("Capturing groups were defined in regex '%s', but corresponding "
- + "back-reference placeholder '%s' not found in label '%s'",
- matcher.pattern(), marker, rawLabel);
- continue;
- }
- label = label.replace(marker, matcher.group(i));
- }
- // ensure that the resulting label is not the same as the fixed "uncategorized" label
- if (LABEL_UNCATEGORIZED.equals(label)) {
- throw new IllegalArgumentException(String.format("Use of aggregation label '%s' "
- + "conflicts with built-in default.", LABEL_UNCATEGORIZED));
- }
- return label;
- }
-
- /**
- * Performs aggregation by adding raw file size entries together based on the regex's the full
- * path names are matched. Note that this means a file entry could get aggregated multiple
- * times. The returned map will also include a fixed entry called "uncategorized" that adds the
- * sizes of all file entries that were never matched together.
- * @param stats the map of raw stats: full path name -> file size
- * @param patterns the map of aggregation patterns: a regex that could match file names -> the
- * name of the aggregated result category (e.g. all apks)
- * @return
- */
- protected Map<String, String> performAggregation(Map<String, Long> stats,
- Map<Pattern, String> patterns) {
- Set<String> uncategorizedFiles = new HashSet<>(stats.keySet());
- Map<String, Long> result = new HashMap<>();
- long total = 0;
-
- for (Map.Entry<String, Long> stat : stats.entrySet()) {
- // aggregate for total first
- total += stat.getValue();
- for (Map.Entry<Pattern, String> pattern : patterns.entrySet()) {
- Matcher m = pattern.getKey().matcher(stat.getKey());
- if (m.matches()) {
- // the file entry being looked at matches one of the preconfigured rules
- String label = getAggregationLabel(m, pattern.getValue());
- Long size = result.get(label);
- if (size == null) {
- size = 0L;
- }
- size += stat.getValue();
- result.put(label, size);
- // keep track of files that we've already aggregated at least once
- if (uncategorizedFiles.contains(stat.getKey())) {
- uncategorizedFiles.remove(stat.getKey());
- }
- }
- }
- }
- // final pass for uncategorized files
- long uncategorized = 0;
- for (String file : uncategorizedFiles) {
- uncategorized += stats.get(file);
- }
- Map<String, String> ret = new HashMap<>();
- for (Map.Entry<String, Long> e : result.entrySet()) {
- if (mMinReportSize > 0 && e.getValue() < mMinReportSize) {
- // has a min report size requirement and current category does not meet it
- CLog.v("Skipped reporting for %s (value %d): it's below threshold %d",
- e.getKey(), e.getValue(), mMinReportSize);
- continue;
- }
- ret.put(e.getKey(), Long.toString(e.getValue()));
- }
- ret.put(LABEL_UNCATEGORIZED, Long.toString(uncategorized));
- ret.put(LABEL_TOTAL, Long.toString(total));
- ret.put(LABEL_CATEGORIZED, Long.toString(total - uncategorized));
- return ret;
- }
-}
diff --git a/prod-tests/src/com/android/continuous/SmokeTest.java b/prod-tests/src/com/android/continuous/SmokeTest.java
deleted file mode 100644
index 93f221f..0000000
--- a/prod-tests/src/com/android/continuous/SmokeTest.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2012 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.continuous;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.result.BugreportCollector;
-import com.android.tradefed.result.DeviceFileReporter;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.NameMangleListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.InstrumentationTest;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * A test that runs the smoke tests
- * <p />
- * Simply {@link InstrumentationTest} with extra reporting. Should be re-integrated with
- * {@link InstrumentationTest} after it's clear that it works as expected.
- */
-@OptionClass(alias = "smoke")
-public class SmokeTest extends InstrumentationTest {
- @Option(name = "capture-file-pattern", description = "File glob of on-device files to log " +
- "if found. Takes two arguments: the glob, and the file type " +
- "(text/xml/zip/gzip/png/unknown). May be repeated.", importance = Importance.IF_UNSET)
- private Map<String, LogDataType> mUploadFilePatterns = new LinkedHashMap<String, LogDataType>();
-
- @Option(name = "bugreport-device-wait-time", description = "How many seconds to wait for the " +
- "device to become available so we can capture a bugreport. Useful in case the smoke " +
- "tests fail due to a device reboot.")
- private int mDeviceWaitTime = 60;
-
- /**
- * Simple constructor that disables an incompatible runmode from the superclass
- */
- public SmokeTest() {
- super();
- // Re-run mode doesn't work properly with Smoke
- setRerunMode(false);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(final ITestInvocationListener listener) throws DeviceNotAvailableException {
- // trimListener should be the first thing to receive any results. It will pass the results
- // through to the bugListener, which will forward them (after collecting any necessary
- // bugreports) to the real Listener(s).
- final BugreportCollector bugListener = new BugreportCollector(listener, getDevice());
- bugListener.setDeviceWaitTime(mDeviceWaitTime);
- bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
- final ITestInvocationListener trimListener = new TrimListener(bugListener);
-
- super.run(trimListener);
-
- final DeviceFileReporter dfr = new DeviceFileReporter(getDevice(), trimListener);
- dfr.addPatterns(mUploadFilePatterns);
- dfr.run();
- }
-
- /**
- * A class to adjust the test identifiers from something like this:
- * com.android.smoketest.SmokeTestRunner$3#com.android.voicedialer.VoiceDialerActivity
- * To this:
- * SmokeFAST#com.android.voicedialer.VoiceDialerActivity
- */
- static class TrimListener extends NameMangleListener {
- public TrimListener(ITestInvocationListener listener) {
- super(listener);
- }
-
- /** {@inheritDoc} */
- @Override
- protected TestDescription mangleTestId(TestDescription test) {
- final String method = test.getTestName();
- final String klass = test.getClassName().replaceFirst(
- "com.android.smoketest.SmokeTestRunner(?:\\$\\d+)?", "SmokeFAST");
- return new TestDescription(klass, method);
- }
- }
-}
-
diff --git a/prod-tests/src/com/android/continuous/SmokeTestFailureReporter.java b/prod-tests/src/com/android/continuous/SmokeTestFailureReporter.java
deleted file mode 100644
index dfc66228..0000000
--- a/prod-tests/src/com/android/continuous/SmokeTestFailureReporter.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2012 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.continuous;
-
-import com.android.ddmlib.testrunner.TestResult.TestStatus;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.invoker.IInvocationContext;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.result.TestFailureEmailResultReporter;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.result.TestRunResult;
-import com.android.tradefed.util.Email;
-import com.android.tradefed.util.IEmail;
-
-import java.util.Map;
-
-/**
- * A customized failure reporter that sends emails in a specific format
- */
-@OptionClass(alias = "smoke-failure-email")
-public class SmokeTestFailureReporter extends TestFailureEmailResultReporter {
- /**
- * Default constructor
- */
- public SmokeTestFailureReporter() {
- this(new Email());
- }
-
- /**
- * Create a {@link SmokeTestFailureReporter} with a custom {@link IEmail} instance to use.
- *
- * <p>Exposed for unit testing.
- *
- * @param mailer the {@link IEmail} instance to use.
- */
- protected SmokeTestFailureReporter(IEmail mailer) {
- super(mailer);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected String generateEmailSubject() {
- final IInvocationContext context = getInvocationContext();
- StringBuilder sb = new StringBuilder();
- sb.append(context.getTestTag());
- sb.append(" SmokeFAST failed on: ");
- for (IBuildInfo build : context.getBuildInfos()) {
- sb.append(build.toString());
- }
- return sb.toString();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- protected String generateEmailBody() {
- StringBuilder sb = new StringBuilder();
-
- for (TestRunResult run : getMergedTestRunResults()) {
- if (run.hasFailedTests()) {
- final Map<TestDescription, TestResult> tests = run.getTestResults();
- for (Map.Entry<TestDescription, TestResult> test : tests.entrySet()) {
- final TestDescription id = test.getKey();
- final TestResult result = test.getValue();
-
- if (result.getStatus() == TestStatus.PASSED) continue;
-
- sb.append(String.format("%s#%s %s\n",
- id.getClassName(), id.getTestName(),
- describeStatus(result.getStatus())));
-
- final String trace = result.getStackTrace();
- if (trace != null) {
- sb.append("Stack trace:\n");
- sb.append(trace);
- sb.append("\n");
- }
- }
- }
- }
-
- sb.append("\n");
- sb.append(super.generateEmailBody());
- return sb.toString();
- }
-
- private String describeStatus(TestStatus status) {
- switch (status) {
- case FAILURE:
- return "failed";
- case PASSED:
- return "passed";
- case INCOMPLETE:
- return "did not complete";
- case ASSUMPTION_FAILURE:
- return "assumption failed";
- case IGNORED:
- return "ignored";
- }
- return "had an unknown result";
- }
-}
diff --git a/prod-tests/src/com/android/fastboot/tests/FastbootTest.java b/prod-tests/src/com/android/fastboot/tests/FastbootTest.java
deleted file mode 100644
index 8159314..0000000
--- a/prod-tests/src/com/android/fastboot/tests/FastbootTest.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * 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.fastboot.tests;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.OptionSetter;
-import com.android.tradefed.device.DeviceDisconnectedException;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.IManagedTestDevice;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.ITestDevice.RecoveryMode;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.DeviceFlashPreparer;
-import com.android.tradefed.targetprep.IDeviceFlasher.UserDataFlashOption;
-import com.android.tradefed.targetprep.TargetSetupError;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Flashes the device as part of the test, report device post-flash status as test results.
- * TODO: Add more fastboot test validation step.
- */
-public class FastbootTest implements IRemoteTest, IDeviceTest, IBuildReceiver {
-
- private static final String FASTBOOT_TEST = FastbootTest.class.getName();
- /** the desired recentness of battery level **/
- private static final long BATTERY_FRESHNESS_MS = 30 * 1000;
- private static final long INVALID_TIME_DURATION = -1;
- private static final String INITIAL_BOOT_TIME = "initial-boot";
- private static final String ONLINE_TIME = "online";
-
- @Option(name = "device-boot-time", description = "Max time in ms to wait for"
- + " device to boot.", isTimeVal = true)
- private long mDeviceBootTimeMs = 5 * 60 * 1000;
-
- @Option(name = "userdata-flash", description = "Specify handling of userdata partition.")
- private UserDataFlashOption mUserDataFlashOption = UserDataFlashOption.WIPE;
-
- @Option(name = "concurrent-flasher-limit", description = "The maximum number of concurrent"
- + " flashers (may be useful to avoid memory constraints)")
- private Integer mConcurrentFlasherLimit = null;
-
- @Option(name = "skip-battery-check", description = "If true, the battery reading test will"
- + " be skipped.")
- private boolean mSkipBatteryCheck = false;
-
- @Option(name = "flasher-class", description = "The Flasher class (implementing "
- + "DeviceFlashPreparer) to be used for the fastboot test", mandatory = true)
- private String mFlasherClass;
-
- private IBuildInfo mBuildInfo;
- private ITestDevice mDevice;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setBuild(IBuildInfo buildInfo) {
- mBuildInfo = buildInfo;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- long start = System.currentTimeMillis();
- listener.testRunStarted(FASTBOOT_TEST, 1);
- String originalFastbootpath = ((IManagedTestDevice)mDevice).getFastbootPath();
- try {
- testFastboot(listener);
- } finally {
- // reset fastboot path
- ((IManagedTestDevice)mDevice).setFastbootPath(originalFastbootpath);
- listener.testRunEnded(
- System.currentTimeMillis() - start, new HashMap<String, Metric>());
- }
- }
-
- /**
- * Flash the device and calculate the time to bring the device online and first boot.
- * @param listener
- * @throws DeviceNotAvailableException
- */
- private void testFastboot(ITestInvocationListener listener) throws DeviceNotAvailableException {
- HashMap<String, Metric> result = new HashMap<>();
- TestDescription firstBootTestId =
- new TestDescription(
- String.format("%s.%s", FASTBOOT_TEST, FASTBOOT_TEST), FASTBOOT_TEST);
- listener.testStarted(firstBootTestId);
- DeviceFlashPreparer flasher = loadFlashPreparerClass();
- long bootStart = INVALID_TIME_DURATION;
- long onlineTime = INVALID_TIME_DURATION;
- long bootTime = INVALID_TIME_DURATION;
- try {
- if (flasher == null) {
- throw new RuntimeException(String.format("Could not find flasher %s",
- mFlasherClass));
- }
- try {
- OptionSetter setter = new OptionSetter(flasher);
- // duping and passing parameters down to flasher
- setter.setOptionValue("device-boot-time", Long.toString(mDeviceBootTimeMs));
- setter.setOptionValue("userdata-flash", mUserDataFlashOption.toString());
- if (mConcurrentFlasherLimit != null) {
- setter.setOptionValue("concurrent-flasher-limit",
- mConcurrentFlasherLimit.toString());
- }
- // always to skip because the test needs to detect device online
- // and available state individually
- setter.setOptionValue("skip-post-flashing-setup", "true");
- setter.setOptionValue("force-system-flash", "true");
- } catch (ConfigurationException ce) {
- // this really shouldn't happen, but if it does, it'll indicate a setup problem
- // so this should be exposed, even at the expense of categorizing the build as
- // having a critical failure
- throw new RuntimeException("failed to set options for flasher", ce);
- }
-
- File fastboot = getFastbootFile(mBuildInfo);
- if (fastboot == null) {
- listener.testFailed(firstBootTestId,
- "Couldn't find the fastboot binary in build info.");
- return;
- }
- // Set the fastboot path for device
- ((IManagedTestDevice)mDevice).setFastbootPath(fastboot.getAbsolutePath());
-
- // flash it!
- CLog.v("Flashing device %s", mDevice.getSerialNumber());
- try {
- flasher.setUp(mDevice, mBuildInfo);
- // we are skipping post boot setup so this is the start of boot process
- bootStart = System.currentTimeMillis();
- } catch (TargetSetupError | BuildError e) {
- // setUp() may throw DeviceNotAvailableException, TargetSetupError and BuildError.
- // DNAE is allowed to get thrown here so that a tool failure is triggered and build
- // maybe retried; the other 2x types are also rethrown as RuntimeException's for
- // the same purpose. In general, these exceptions reflect flashing or infra related
- // flakiness, so retrying is a reasonable mitigation.
- throw new RuntimeException("Exception during device flashing", e);
- }
- // check if device is online after flash, i.e. if adb is broken
- CLog.v("Waiting for device %s online", mDevice.getSerialNumber());
- mDevice.setRecoveryMode(RecoveryMode.ONLINE);
- try {
- mDevice.waitForDeviceOnline();
- onlineTime = System.currentTimeMillis() - bootStart;
- } catch (DeviceNotAvailableException dnae) {
- CLog.e("Device not online after flashing");
- CLog.e(dnae);
- listener.testRunFailed("Device not online after flashing");
- throw new DeviceDisconnectedException("Device not online after flashing",
- mDevice.getSerialNumber());
- }
- // check if device can be fully booted, i.e. if application framework won't boot
- CLog.v("Waiting for device %s boot complete", mDevice.getSerialNumber());
- mDevice.setRecoveryMode(RecoveryMode.AVAILABLE);
- try {
- mDevice.waitForDeviceAvailable(mDeviceBootTimeMs);
- bootTime = System.currentTimeMillis() - bootStart;
- } catch (DeviceNotAvailableException dnae) {
- CLog.e("Device %s not available after flashing", mDevice.getSerialNumber());
- CLog.e(dnae);
- // only report as test failure, not test run failure because we were able to run the
- // test until the end, despite the failure verdict, and the device is returned to
- // the pool in a useable state
- listener.testFailed(firstBootTestId, "Device not available after flashing");
- return;
- }
- CLog.v("Device %s boot complete", mDevice.getSerialNumber());
- if (mSkipBatteryCheck) {
- // If we skip the battery Check, we can return directly after boot complete.
- return;
- }
- // We check if battery level are readable as non root to ensure that device is usable.
- mDevice.disableAdbRoot();
- try {
- Future<Integer> batteryFuture = mDevice.getIDevice()
- .getBattery(BATTERY_FRESHNESS_MS, TimeUnit.MILLISECONDS);
- // get cached value or wait up to 500ms for battery level query
- Integer level = batteryFuture.get(500, TimeUnit.MILLISECONDS);
- CLog.d("Battery level value reading is: '%s'", level);
- if (level == null) {
- listener.testFailed(firstBootTestId, "Reading of battery level is wrong.");
- return;
- }
- } catch (InterruptedException | ExecutionException |
- java.util.concurrent.TimeoutException e) {
- CLog.e("Failed to query battery level for %s", mDevice.getSerialNumber());
- CLog.e(e);
- listener.testFailed(firstBootTestId, "Failed to query battery level.");
- return;
- } finally {
- mDevice.enableAdbRoot();
- }
- } finally {
- CLog.d("Device online time: %dms, initial boot time: %dms", onlineTime, bootTime);
- if (onlineTime != INVALID_TIME_DURATION) {
- result.put(
- ONLINE_TIME, TfMetricProtoUtil.stringToMetric(Long.toString(onlineTime)));
- }
- if (bootTime != INVALID_TIME_DURATION) {
- result.put(
- INITIAL_BOOT_TIME,
- TfMetricProtoUtil.stringToMetric(Long.toString(bootTime)));
- }
- listener.testEnded(firstBootTestId, result);
- }
- }
-
- /**
- * Attempt to load the class implementing {@link DeviceFlashPreparer} based on the option
- * flasher-class, allows anybody to tests fastboot using their own implementation of it.
- */
- private DeviceFlashPreparer loadFlashPreparerClass() {
- try {
- Class<?> flasherClass = Class.forName(mFlasherClass);
- Object flasherObject = flasherClass.newInstance();
- if (flasherObject instanceof DeviceFlashPreparer) {
- return (DeviceFlashPreparer)flasherObject;
- } else {
- CLog.e("Loaded class '%s' is not an instance of DeviceFlashPreparer.",
- flasherObject);
- return null;
- }
- } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
- CLog.e(e);
- return null;
- }
- }
-
- /**
- * Helper to find the fastboot file as part of the buildinfo file list.
- */
- private File getFastbootFile(IBuildInfo buildInfo) {
- File fastboot = buildInfo.getFile("fastboot");
- if (fastboot == null) {
- return null;
- }
- FileUtil.chmodGroupRWX(fastboot);
- return fastboot;
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTest.java b/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTest.java
deleted file mode 100644
index 3b999a1..0000000
--- a/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTest.java
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * Copyright (C) 2011 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.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.framework.tests.BandwidthStats.CompareResult;
-import com.android.framework.tests.BandwidthStats.ComparisonRecord;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.IRunUtil.IRunnableResult;
-import com.android.tradefed.util.MultiMap;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.net.HttpHelper;
-import com.android.tradefed.util.net.IHttpHelper;
-import com.android.tradefed.util.net.IHttpHelper.DataSizeException;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Test that instruments a bandwidth test, gathers bandwidth metrics, and posts
- * the results to the Release Dashboard.
- */
-public class BandwidthMicroBenchMarkTest implements IDeviceTest, IRemoteTest {
-
- ITestDevice mTestDevice = null;
-
- @Option(name = "test-package-name", description = "Android test package name.")
- private String mTestPackageName;
-
- @Option(name = "test-class-name", description = "Test class name.")
- private String mTestClassName;
-
- @Option(name = "test-method-name", description = "Test method name.")
- private String mTestMethodName;
-
- @Option(name = "test-label",
- description = "Test label to identify the test run.")
- private String mTestLabel;
-
- @Option(name = "bandwidth-test-server",
- description = "Test label to use when posting to dashboard.",
- importance=Option.Importance.IF_UNSET)
- private String mTestServer;
-
- @Option(name = "ssid",
- description = "The ssid to use for the wifi connection.")
- private String mSsid;
-
- @Option(name = "initial-server-poll-interval-ms",
- description = "The initial poll interval in msecs for querying the test server.")
- private int mInitialPollIntervalMs = 1 * 1000;
-
- @Option(name = "server-total-timeout-ms",
- description = "The total timeout in msecs for querying the test server.")
- private int mTotalTimeoutMs = 40 * 60 * 1000;
-
- @Option(name = "server-query-op-timeout-ms",
- description = "The timeout in msecs for a single operation to query the test server.")
- private int mQueryOpTimeoutMs = 2 * 60 * 1000;
-
- @Option(name="difference-threshold",
- description="The maximum allowed difference between network stats in percent")
- private int mDifferenceThreshold = 5;
-
- @Option(name="server-difference-threshold",
- description="The maximum difference between the stats reported by the " +
- "server and the device in percent")
- private int mServerDifferenceThreshold = 6;
-
- @Option(name = "compact-ru-key",
- description = "Name of the reporting unit for pass/fail results")
- private String mCompactRuKey;
-
- @Option(name = "iface", description="Network interface on the device to use for stats",
- importance = Option.Importance.ALWAYS)
- private String mIface;
-
- private static final String TEST_RUNNER = "com.android.bandwidthtest.BandwidthTestRunner";
- private static final String TEST_SERVER_QUERY = "query";
- private static final String DEVICE_ID_LABEL = "device_id";
- private static final String TIMESTAMP_LABEL = "timestamp";
-
-
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- Assert.assertNotNull(mTestDevice);
-
- Assert.assertNotNull("Need a test server, specify it using --bandwidth-test-server",
- mTestServer);
-
- // Run test
- IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mTestPackageName,
- TEST_RUNNER, mTestDevice.getIDevice());
- runner.setMethodName(mTestClassName, mTestMethodName);
- if (mSsid != null) {
- runner.addInstrumentationArg("ssid", mSsid);
- }
- runner.addInstrumentationArg("server", mTestServer);
-
- CollectingTestListener collectingListener = new CollectingTestListener();
- Assert.assertTrue(
- mTestDevice.runInstrumentationTests(runner, collectingListener, listener));
-
- // Collect bandwidth metrics from the instrumentation test out.
- Map<String, String> bandwidthTestMetrics = new HashMap<String, String>();
- Collection<TestResult> testResults =
- collectingListener.getCurrentRunResults().getTestResults().values();
- if (testResults != null && testResults.iterator().hasNext()) {
- Map<String, String> testMetrics = testResults.iterator().next().getMetrics();
- if (testMetrics != null) {
- bandwidthTestMetrics.putAll(testMetrics);
- }
- }
-
- // Fetch the data from the test server.
- String deviceId = bandwidthTestMetrics.get(DEVICE_ID_LABEL);
- String timestamp = bandwidthTestMetrics.get(TIMESTAMP_LABEL);
- Assert.assertNotNull("Failed to fetch deviceId from server", deviceId);
- Assert.assertNotNull("Failed to fetch timestamp from server", timestamp);
- Map<String, String> serverData = fetchDataFromTestServer(deviceId, timestamp);
-
- // Calculate additional network sanity stats - pre-framework logic network stats
- BandwidthUtils bw = new BandwidthUtils(mTestDevice, mIface);
- reportPassFail(listener, mCompactRuKey, bw, serverData, bandwidthTestMetrics);
-
- saveFile("/proc/net/dev", "proc_net_dev", listener);
- saveFile("/proc/net/xt_qtaguid/stats", "qtaguid_stats", listener);
-
- }
-
- private void saveFile(String remoteFilename, String spongeName,
- ITestInvocationListener listener) throws DeviceNotAvailableException {
- File f = mTestDevice.pullFile(remoteFilename);
- if (f == null) {
- CLog.w("Failed to pull %s", remoteFilename);
- return;
- }
-
- saveFile(spongeName, listener, f);
- }
-
- private void saveFile(String spongeName, ITestInvocationListener listener, File file) {
- try (InputStreamSource stream = new FileInputStreamSource(file)) {
- listener.testLog(spongeName, LogDataType.TEXT, stream);
- }
- }
-
- /**
- * Fetch the bandwidth test data recorded on the test server.
- *
- * @param deviceId
- * @param timestamp
- * @return a map of the data that was recorded by the test server.
- */
- private Map<String, String> fetchDataFromTestServer(String deviceId, String timestamp) {
- IHttpHelper httphelper = new HttpHelper();
- MultiMap<String,String> params = new MultiMap<String,String> ();
- params.put("device_id", deviceId);
- params.put("timestamp", timestamp);
- String queryUrl = mTestServer;
- if (!queryUrl.endsWith("/")) {
- queryUrl += "/";
- }
- queryUrl += TEST_SERVER_QUERY;
- QueryRunnable runnable = new QueryRunnable(httphelper, queryUrl, params);
- if (RunUtil.getDefault().runEscalatingTimedRetry(mQueryOpTimeoutMs, mInitialPollIntervalMs,
- mQueryOpTimeoutMs, mTotalTimeoutMs, runnable)) {
- return runnable.getServerResponse();
- } else {
- CLog.w("Failed to query test server", runnable.getException());
- }
- return null;
- }
-
- private static class QueryRunnable implements IRunnableResult {
- private final IHttpHelper mHttpHelper;
- private final String mBaseUrl;
- private final MultiMap<String,String> mParams;
- private Map<String, String> mServerResponse = null;
- private Exception mException = null;
-
- public QueryRunnable(IHttpHelper helper, String testServerUrl,
- MultiMap<String,String> params) {
- mHttpHelper = helper;
- mBaseUrl = testServerUrl;
- mParams = params;
- }
-
- /**
- * Perform a single bandwidth test server query, storing the response or
- * the associated exception in case of error.
- */
- @Override
- public boolean run() {
- try {
- String serverResponse = mHttpHelper.doGet(mHttpHelper.buildUrl(mBaseUrl, mParams));
- mServerResponse = parseServerResponse(serverResponse);
- return true;
- } catch (IOException e) {
- CLog.i("IOException %s when contacting test server", e.getMessage());
- mException = e;
- } catch (DataSizeException e) {
- CLog.i("Unexpected oversized response when contacting test server");
- mException = e;
- }
- return false;
- }
-
- /**
- * Returns exception.
- *
- * @return the last {@link Exception} that occurred when performing
- * run().
- */
- public Exception getException() {
- return mException;
- }
-
- /**
- * Returns the server response.
- *
- * @return a map of the server response.
- */
- public Map<String, String> getServerResponse() {
- return mServerResponse;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void cancel() {
- // ignore
- }
- }
-
- /**
- * Helper to parse test server's response into a map
- * <p>
- * Exposed for unit testing.
- *
- * @param serverResponse {@link String} for the test server http request
- * @return a map representation of the server response
- */
- public static Map<String, String> parseServerResponse(String serverResponse) {
- // No such test run was recorded.
- if (serverResponse == null || serverResponse.trim().length() == 0) {
- return null;
- }
- final String[] responseLines = serverResponse.split("\n");
- Map<String, String> results = new HashMap<String, String>();
- for (String responseLine : responseLines) {
- final String[] responsePairs = responseLine.split(" ");
- for (String responsePair : responsePairs) {
- final String[] pair = responsePair.split(":", 2);
- if (pair.length >= 2) {
- results.put(pair[0], pair[1]);
- } else {
- CLog.w("Invalid server response: %s", responsePair);
- }
- }
- }
- return results;
- }
-
- /**
- * Fetch the last stats from event log and calculate the differences.
- *
- * @throws DeviceNotAvailableException
- */
- private boolean evaluateEventLog(ITestInvocationListener listener) throws DeviceNotAvailableException {
- // issue a force update of stats
- String res = mTestDevice.executeShellCommand("dumpsys netstats poll");
- if (!res.contains("Forced poll")) {
- CLog.w("Failed to force a poll on the device.");
- }
- // fetch events log
- String log = mTestDevice.executeShellCommand("logcat -d -b events");
- if (log != null) {
- return evaluateStats("netstats_mobile_sample", log, listener);
- }
- return false;
- }
-
- /**
- * Parse a log output for a given key and calculate the network stats.
- *
- * @param key {@link String} to search for in the log
- * @param log obtained from adb logcat -b events
- * @param listener the {@link ITestInvocationListener} where to report results.
- */
- private boolean evaluateStats(String key, String log, ITestInvocationListener listener) {
- File filteredEventLog = null;
- BufferedWriter out = null;
- boolean passed = true;
-
- try {
- filteredEventLog = File.createTempFile(String.format("%s_event_log", key), ".txt");
- out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filteredEventLog)));
- String[] parts = log.split("\n");
- for (int i = parts.length - 1; i > 0; i--) {
- String str = parts[i];
- if (str.contains(key)) {
- out.write(str);
- passed = passed && evaluateEventLogLine(str);
- }
- }
- out.flush();
- saveFile(key + "_event_log", listener, filteredEventLog);
- return passed;
- } catch (FileNotFoundException e) {
- CLog.w("Could not create file to save event log: %s", e.getMessage());
- return false;
- } catch (IOException e) {
- CLog.w("Could not save event log file: %s", e.getMessage());
- } finally {
- StreamUtil.close(out);
- FileUtil.deleteFile(filteredEventLog);
- }
- return false;
- }
-
- private boolean evaluateEventLogLine(String line) {
- int start = line.lastIndexOf("[");
- int end = line.lastIndexOf("]");
- String subStr = line.substring(start + 1, end);
- String[] statsStrArray = subStr.split(",");
- if (statsStrArray.length != 13) {
- CLog.e("Failed to parse for \"%s\" in log.", line);
- return false;
- }
- long xtRb = Long.parseLong(statsStrArray[4].trim());
- long xtTb = Long.parseLong(statsStrArray[5].trim());
- long xtRp = Long.parseLong(statsStrArray[6].trim());
- long xtTp = Long.parseLong(statsStrArray[7].trim());
- long uidRb = Long.parseLong(statsStrArray[8].trim());
- long uidTb = Long.parseLong(statsStrArray[9].trim());
- long uidRp = Long.parseLong(statsStrArray[10].trim());
- long uidTp = Long.parseLong(statsStrArray[11].trim());
-
- BandwidthStats xtStats = new BandwidthStats(xtRb, xtRp, xtTb, xtTp);
- BandwidthStats uidStats = new BandwidthStats(uidRb, uidRp, uidTb, uidTp);
- boolean result = true;
- CompareResult compareResult = xtStats.compareAll(uidStats, mDifferenceThreshold);
- result &= compareResult.getResult();
- if (!compareResult.getResult()) {
- CLog.i("Failure comparing netstats_mobile_sample xt and uid");
- printFailures(compareResult);
- }
- if (!result) {
- CLog.i("Failed line: %s", line);
- }
- return result;
- }
-
- /**
- * Compare the data reported by instrumentation to uid breakdown reported by the kernel,
- * the sum of uid breakdown and the total reported by the kernel and the data reported by
- * instrumentation to the data reported by the server.
- * @param listener result reporter
- * @param compactRuKey key to use when posting to rdb.
- * @param utils data parsed from the kernel.
- * @param instrumentationData data reported by the test.
- * @param serverData data reported by the server.
- * @throws DeviceNotAvailableException
- */
- private void reportPassFail(ITestInvocationListener listener, String compactRuKey,
- BandwidthUtils utils, Map<String, String> serverData,
- Map<String, String> instrumentationData) throws DeviceNotAvailableException {
- if (compactRuKey == null) return;
-
- int passCount = 0;
- int failCount = 0;
-
- // Calculate the difference between what framework reports and what the kernel reports
- boolean download = Boolean.parseBoolean(serverData.get("download"));
- long frameworkUidBytes = 0;
- if (download) {
- frameworkUidBytes = Long.parseLong(instrumentationData.get("PROF_rx"));
- } else {
- frameworkUidBytes = Long.parseLong(instrumentationData.get("PROF_tx"));
- }
-
- // Compare data reported by the server and the instrumentation
- long serverBytes = Long.parseLong(serverData.get("size"));
- float diff = Math.abs(BandwidthStats.computePercentDifference(
- serverBytes, frameworkUidBytes));
- if (diff < mServerDifferenceThreshold) {
- passCount += 1;
- } else {
- CLog.i("Comparing between server and instrumentation failed expected %d got %d",
- serverBytes, frameworkUidBytes);
- failCount += 1;
- }
-
- if (evaluateEventLog(listener)) {
- passCount += 1;
- } else {
- failCount += 1;
- }
-
- Map<String, String> postMetrics = new HashMap<String, String>();
- postMetrics.put("Pass", String.valueOf(passCount));
- postMetrics.put("Fail", String.valueOf(failCount));
-
- listener.testRunStarted(compactRuKey, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(postMetrics));
- }
-
- private void printFailures(CompareResult result) {
- for (ComparisonRecord failure : result.getFailures()) {
- CLog.i(failure.toString());
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mTestDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTestTest.java b/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTestTest.java
deleted file mode 100644
index f39a632..0000000
--- a/prod-tests/src/com/android/framework/tests/BandwidthMicroBenchMarkTestTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 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.framework.tests;
-
-import junit.framework.TestCase;
-
-import java.util.Map;
-
-public class BandwidthMicroBenchMarkTestTest extends TestCase {
-
- /**
- * Test method for {@link BandwidthMicroBenchMarkTest#parseServerResponse(String)} on empty
- * response.
- */
- public void testParseNullResponse() throws Exception {
- assertNull(BandwidthMicroBenchMarkTest.parseServerResponse(""));
- assertNull(BandwidthMicroBenchMarkTest.parseServerResponse(null));
- }
-
- /**
- * Test method for {@link BandwidthMicroBenchMarkTest#parseServerResponse(String)} on standard
- * response.
- */
- public void testParseCorrectResponse() throws Exception {
- Map<String, String> result = BandwidthMicroBenchMarkTest.parseServerResponse(
- "foo:bar blue:red\nandroid:google\n");
- assertNotNull(result);
- assertEquals(3, result.size());
- assertTrue(result.containsKey("foo"));
- assertEquals("bar", result.get("foo"));
- assertEquals("red", result.get("blue"));
- assertEquals("google", result.get("android"));
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/BandwidthStats.java b/prod-tests/src/com/android/framework/tests/BandwidthStats.java
deleted file mode 100644
index 21e5f8b..0000000
--- a/prod-tests/src/com/android/framework/tests/BandwidthStats.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2011 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.framework.tests;
-
-import com.android.tradefed.log.LogUtil.CLog;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Simple container class used to store network Stats.
- */
-public class BandwidthStats {
- private long mRxBytes = 0;
- private long mRxPackets = 0;
- private long mTxBytes = 0;
- private long mTxPackets = 0;
-
- public BandwidthStats (long rxBytes, long rxPackets, long txBytes, long txPackets) {
- mRxBytes = rxBytes;
- mRxPackets = rxPackets;
- mTxBytes = txBytes;
- mTxPackets = txPackets;
- }
-
- public BandwidthStats() {
- }
-
- /**
- * Compute percent difference between a and b.
- * @param a
- * @param b
- * @return % difference of a and b.
- */
- static float computePercentDifference(float a, float b) {
- if (a == b) {
- return 0;
- }
- if (a == 0) {
- CLog.d("Invalid value for a: %f", a);
- return Float.MIN_VALUE;
- }
- return ( a - b) / a * 100;
- }
-
- public long getRxBytes() {
- return mRxBytes;
- }
-
- public void setRxBytes(long rxBytes) {
- this.mRxBytes = rxBytes;
- }
-
- public long getRxPackets() {
- return mRxPackets;
- }
-
- public void setRxPackets(long rxPackets) {
- this.mRxPackets = rxPackets;
- }
-
- public long getTxBytes() {
- return mTxBytes;
- }
-
- public void setTxBytes(long txBytes) {
- this.mTxBytes = txBytes;
- }
-
- public long getTxPackets() {
- return mTxPackets;
- }
-
- public void setTxPackets(long txPackets) {
- this.mTxPackets = txPackets;
- }
-
- public CompareResult compareAll(BandwidthStats stats, float mDifferenceThreshold) {
- CompareResult result = new CompareResult();
- result.addRecord(this.compareRb(stats), mDifferenceThreshold);
- result.addRecord(this.compareRp(stats), mDifferenceThreshold);
- result.addRecord(this.compareTb(stats), mDifferenceThreshold);
- result.addRecord(this.compareTp(stats), mDifferenceThreshold);
- return result;
- }
-
- private ComparisonRecord compareTp(BandwidthStats stats) {
- float difference = BandwidthStats.computePercentDifference(
- this.mTxPackets, stats.mTxPackets);
-
- ComparisonRecord result = new ComparisonRecord("Tp", this.mTxPackets, stats.mTxPackets,
- difference);
-
- return result;
- }
-
- private ComparisonRecord compareTb(BandwidthStats stats) {
- float difference = BandwidthStats.computePercentDifference(
- this.mTxBytes, stats.mTxBytes);
-
- ComparisonRecord result = new ComparisonRecord("Tb", this.mTxBytes, stats.mTxBytes,
- difference);
-
- return result;
- }
-
- private ComparisonRecord compareRp(BandwidthStats stats) {
- float difference = BandwidthStats.computePercentDifference(
- this.mRxPackets, stats.mRxPackets);
-
- ComparisonRecord result = new ComparisonRecord("Rp", this.mRxPackets, stats.mRxPackets,
- difference);
-
- return result;
- }
-
- private ComparisonRecord compareRb(BandwidthStats stats) {
- float difference = BandwidthStats.computePercentDifference(
- this.mRxBytes, stats.mRxBytes);
-
- ComparisonRecord result = new ComparisonRecord("Rb", this.mRxBytes, stats.mRxBytes,
- difference);
-
- return result;
- }
-
- /**
- * Holds the record of comparing a single stat like transmitted packets. All comparisons are
- * recorded so it is easier to see which one failed later.
- */
- public static class ComparisonRecord {
- private String mStatName;
- private long mFirst;
- private long mSecond;
- private float mDifference;
-
- public ComparisonRecord(String statName, long first, long second, float difference) {
- this.mStatName = statName;
- this.mFirst = first;
- this.mSecond = second;
- this.mDifference = difference;
- }
-
- public String getStatName() {
- return mStatName;
- }
-
- public long getFirst() {
- return mFirst;
- }
-
- public long getSecond() {
- return mSecond;
- }
-
- public float getDifference() {
- return mDifference;
- }
-
- @Override
- public String toString() {
- return String.format("%s expected %d actual %d difference is %f%%",
- mStatName, mFirst, mSecond, mDifference);
- }
- }
-
- /**
- * Holds the result of comparing bandwidth stats from different sources. The result is passed
- * if all individual stats are within a threshold. Also keeps track of which individual stats
- * failed the comparison for debugging purposes.
- *
- */
- public static class CompareResult {
- private boolean mPassed;
- private List<ComparisonRecord> mFailures;
-
- public CompareResult() {
- mPassed = true;
- mFailures = new ArrayList<ComparisonRecord>();
- }
-
- public void addRecord(ComparisonRecord record, float threshold) {
- if (record.getDifference() < threshold) {
- mPassed &= true;
- } else {
- mPassed = false;
- mFailures.add(record);
- }
- }
-
- public boolean getResult() {
- return mPassed;
- }
-
- public Collection<ComparisonRecord> getFailures() {
- return mFailures;
- }
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/BandwidthUtils.java b/prod-tests/src/com/android/framework/tests/BandwidthUtils.java
deleted file mode 100644
index af48baa..0000000
--- a/prod-tests/src/com/android/framework/tests/BandwidthUtils.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2011 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.framework.tests;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.util.StreamUtil;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-public class BandwidthUtils {
-
- private BandwidthStats mDevStats;
- private Map<Integer, BandwidthStats> mUidStats = new HashMap<Integer, BandwidthStats>();
- private String mIface;
- ITestDevice mTestDevice = null;
-
- BandwidthUtils(ITestDevice device, String iface) throws DeviceNotAvailableException {
- mTestDevice = device;
- mIface = iface;
- parseUidStats();
- parseNetDevStats();
- }
-
- public BandwidthStats getStatsForUid(int uid) {
- return mUidStats.get(uid);
- }
-
- public BandwidthStats getDevStats() {
- return mDevStats;
- }
-
- public BandwidthStats getSumOfUidStats() {
- long rb = 0, rp = 0, tb = 0, tp = 0;
- for (BandwidthStats stats : mUidStats.values()) {
- rb += stats.getRxBytes();
- rp += stats.getRxPackets();
- tb += stats.getTxBytes();
- tp += stats.getTxPackets();
- }
- return new BandwidthStats(rb, rp, tb, tp);
- }
-
- /**
- * Parses the uid stats from /proc/net/xt_qtaguid/stats
- * @throws DeviceNotAvailableException
- */
- private void parseUidStats() throws DeviceNotAvailableException {
- File statsFile = mTestDevice.pullFile("/proc/net/xt_qtaguid/stats");
- FileInputStream fStream = null;
- try {
- fStream = new FileInputStream(statsFile);
- String tmp = StreamUtil.getStringFromStream(fStream);
- String[] lines = tmp.split("\n");
- for (String line : lines) {
- if (line.contains("idx")) {
- continue;
- }
- String[] parts = line.trim().split(" ");
- String iface = parts[1];
- if (!mIface.equals(iface)) { // skip if its not iface we need
- continue;
- }
- String foreground = parts[4];
- if (!"0".equals(foreground)) { // test uses background data, skip foreground
- continue;
- }
- String tag = parts[2];
- int uid = Integer.parseInt(parts[3]);
- int rb = Integer.parseInt(parts[5]);
- int rp = Integer.parseInt(parts[6]);
- int tb = Integer.parseInt(parts[7]);
- int tp = Integer.parseInt(parts[8]);
- if ("0x0".equals(tag)) {
- CLog.v("qtag iface %s pid %d rb %d rp %d tb %d tp %d",
- iface, uid, rb, rp, tb, tp);
- mUidStats.put(uid, new BandwidthStats(rb, rp, tb, tp));
- }
- }
- } catch (IOException e) {
- CLog.d("Failed to read file %s: %s", statsFile.toString(), e.getMessage());
- } finally {
- StreamUtil.close(fStream);
- }
- }
-
- /**
- * Add stats, if the iface is currently active or it is an unknown iface found in /proc/net/dev.
- * @throws DeviceNotAvailableException
- */
- private void parseNetDevStats() throws DeviceNotAvailableException {
- File file = mTestDevice.pullFile("/proc/net/dev");
- FileInputStream fStream = null;
- try {
- fStream = new FileInputStream(file);
- String tmp = StreamUtil.getStringFromStream(fStream);
- String[] lines = tmp.split("\n");
- for (String line : lines) {
- if (line.contains("Receive") || line.contains("multicast")) {
- continue;
- }
- String[] parts = line.trim().split("[ :]+");
- String iface = parts[0].replace(":", "").trim();
- if (mIface.equals(iface)) {
- int rb = Integer.parseInt(parts[1]);
- int rp = Integer.parseInt(parts[2]);
- int tb = Integer.parseInt(parts[9]);
- int tp = Integer.parseInt(parts[10]);
- CLog.v("net iface %s rb %d rp %d tb %d tp %d", iface, rb, rp, tb, tp);
- mDevStats = new BandwidthStats(rb, rp, tb, tp);
- break;
- }
- }
- } catch (IOException e) {
- CLog.d("Failed to read file %s: %s", file.toString(), e.getMessage());
- } finally {
- StreamUtil.close(fStream);
- }
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/DataIdleTest.java b/prod-tests/src/com/android/framework/tests/DataIdleTest.java
deleted file mode 100644
index 38ecdd3..0000000
--- a/prod-tests/src/com/android/framework/tests/DataIdleTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2011 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.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ByteArrayInputStreamSource;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Test that measures the data usage for an idle device and reports it to the result listener.
- */
-public class DataIdleTest implements IDeviceTest, IRemoteTest {
-
- ITestDevice mTestDevice = null;
- DataIdleTestHelper mTestHelper = null;
-
- @Option(name = "test-package-name", description = "Android test package name.")
- private String mTestPackageName;
-
- @Option(name = "test-class-name", description = "Optional test class name to test.")
- private String mTestClassName;
-
- @Option(name = "test-method-name", description = "Optional test method name to run.")
- private String mTestMethodName;
-
- @Option(name = "test-label",
- description = "Test label to identify the test run.")
- private String mTestLabel;
-
- @Option(name = "mobile-data-only",
- description = "If this test is to use mobile data or not.")
- private boolean mMobileDataOnly;
-
- @Option(name = "idle-time-msecs", description = "Time in msecs to wait for data to propagate.")
- private int mIdleTime = 60 * 60 * 1000;
-
- private static final String BUG_REPORT_LABEL = "bugreport";
- private static final String DUMPSYS_REPORT_LABEL = "dumpsys";
-
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- Assert.assertNotNull(mTestDevice);
- mTestHelper = new DataIdleTestHelper(mTestDevice);
- // if mobile data only, then wifi should be disabled, or vice versa
- Assert.assertEquals("incorrect wifi status for current test parameters",
- mMobileDataOnly, !mTestDevice.isWifiEnabled());
- // Test the Internet connection.
- Assert.assertTrue("Failed to connect to get data.", mTestHelper.pingTest());
-
- CLog.v("Sleeping for %d", mIdleTime);
- RunUtil.getDefault().sleep(mIdleTime);
-
-
- // Run test to dump all the data stats gathered by the system.
- IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mTestPackageName,
- mTestDevice.getIDevice());
-
- if (mTestClassName != null) {
- runner.setClassName(mTestClassName);
- }
- if (mTestClassName != null && mTestMethodName != null) {
- runner.setMethodName(mTestClassName, mTestMethodName);
- }
-
- CollectingTestListener collectingListener = new CollectingTestListener();
- Assert.assertTrue(mTestDevice.runInstrumentationTests(runner, collectingListener));
-
- // Collect bandwidth metrics from the instrumentation test out.
- Map<String, String> idleTestMetrics = new HashMap<String, String>();
- Collection<TestResult> testResults =
- collectingListener.getCurrentRunResults().getTestResults().values();
- if (testResults != null && testResults.iterator().hasNext()) {
- Map<String, String> testMetrics = testResults.iterator().next().getMetrics();
- if (testMetrics != null) {
- idleTestMetrics.putAll(testMetrics);
- idleTestMetrics.put("Idle time", Integer.toString(mIdleTime));
- reportMetrics(listener, mTestLabel, idleTestMetrics);
- }
- }
- // Capture the bugreport.
- logBugReport(listener);
- logNetStats(listener);
- }
-
- /**
- * Capture the bugreport and log it.
- * @param listener {@link ITestInvocationListener}
- */
- void logBugReport(ITestInvocationListener listener) {
- try (InputStreamSource bugreport = mTestDevice.getBugreport()) {
- listener.testLog(BUG_REPORT_LABEL, LogDataType.BUGREPORT, bugreport);
- }
- }
-
- /**
- * Fetch the whole netstats details.
- * @param listener {@link ITestInvocationListener}
- * @throws DeviceNotAvailableException
- */
- void logNetStats(ITestInvocationListener listener) throws DeviceNotAvailableException {
- String output = mTestDevice.executeShellCommand("dumpsys netstats detail full");
- InputStreamSource is = new ByteArrayInputStreamSource(output.getBytes());
- listener.testLog(DUMPSYS_REPORT_LABEL, LogDataType.TEXT, is);
- }
-
- /**
- * Report run metrics by creating an empty test run to stick them in.
- *
- * @param listener the {@link ITestInvocationListener} of test results
- * @param runName the test name
- * @param metrics the {@link Map} that contains metrics for the given test
- */
- void reportMetrics(ITestInvocationListener listener, String runName,
- Map<String, String> metrics) {
- // Create an empty testRun to report the parsed runMetrics
- CLog.d("About to report metrics: %s", metrics);
- listener.testRunStarted(runName, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-
- @Override
- public void setDevice(ITestDevice device) {
- mTestDevice = device;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-
-}
diff --git a/prod-tests/src/com/android/framework/tests/DataIdleTestHelper.java b/prod-tests/src/com/android/framework/tests/DataIdleTestHelper.java
deleted file mode 100644
index 78447fa..0000000
--- a/prod-tests/src/com/android/framework/tests/DataIdleTestHelper.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2011 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.framework.tests;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.util.RunUtil;
-
-public class DataIdleTestHelper {
- private final static String[] PING_SERVER_LIST = {"www.google.com", "www.facebook.com",
- "www.bing.com", "www.ask.com", "www.yahoo.com"};
- private final static String PING_FAIL_STRING = "ping: unknown host";
- private ITestDevice mDevice;
- private final static int RETRY_ATTEMPTS = 5;
- private final static int PING_WAITING_TIME = 30 * 10000; // 30 seconds
-
- DataIdleTestHelper(ITestDevice device) {
- mDevice = device;
- }
-
- /**
- * Ping a series of popular servers to check for Internet connection.
- *
- * @return true if the device is able to ping the test servers.
- * @throws DeviceNotAvailableException
- */
- public boolean pingTest() throws DeviceNotAvailableException {
- for (int i = 0; i < RETRY_ATTEMPTS; ++i) {
- for (int j = 0; j < PING_SERVER_LIST.length; ++j) {
- String host = PING_SERVER_LIST[j];
- CLog.d("Start ping test, ping %s", host);
- String res = mDevice.executeShellCommand("ping -c 10 -w 100 " + host);
- CLog.d("res: %s", res);
- if (!res.contains(PING_FAIL_STRING)) {
- return true;
- }
- }
- RunUtil.getDefault().sleep(PING_WAITING_TIME);
- }
- return false;
- }
-
-
-}
diff --git a/prod-tests/src/com/android/framework/tests/DownloadManagerHostTests.java b/prod-tests/src/com/android/framework/tests/DownloadManagerHostTests.java
deleted file mode 100644
index d41b890..0000000
--- a/prod-tests/src/com/android/framework/tests/DownloadManagerHostTests.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2010 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.framework.tests;
-
-import com.android.ddmlib.Log;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ByteArrayInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.ResultForwarder;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.DeviceTestCase;
-
-import java.util.Hashtable;
-
-/**
- * Host-based tests of the DownloadManager API. (Uses a device-based app to actually invoke the
- * various tests.)
- */
-public class DownloadManagerHostTests extends DeviceTestCase {
- protected PackageManagerHostTestUtils mPMUtils = null;
-
- private static final String LOG_TAG = "android.net.DownloadManagerHostTests";
- private static final String FILE_DOWNLOAD_PKG = "com.android.frameworks.downloadmanagertests";
- private static final String FILE_DOWNLOAD_CLASS =
- "com.android.frameworks.downloadmanagertests.DownloadManagerTestApp";
- private static final String DOWNLOAD_TEST_RUNNER_NAME =
- "com.android.frameworks.downloadmanagertests.DownloadManagerTestRunner";
-
- // Extra parameters to pass to the TestRunner
- private static final String EXTERNAL_DOWNLOAD_URI_KEY = "external_download_uri";
-
- Hashtable<String, String> mExtraParams = null;
-
- @Option(name = "external-download-uri", description =
- "external URI under which the files downloaded by the tests can be found. Uri " +
- "must be accessible by the device during a test run.",
- importance = Importance.IF_UNSET)
- private String mExternalDownloadUriValue = null;
-
- @Option(name="wifi-network", description="the name of wifi network to connect to.")
- private String mWifiNetwork = null;
-
- @Option(name="wifi-psk", description="WPA-PSK passphrase of wifi network to connect to.")
- private String mWifiPsk = null;
-
- @Option(name = "wifi-attempts", description =
- "maximum number of attempts to connect to wifi network.")
- private int mWifiAttempts = 2;
-
- private ITestDevice mDevice = null;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mDevice = getDevice();
- assertNotNull(mDevice);
- mPMUtils = new PackageManagerHostTestUtils(mDevice);
- assertNotNull("Missing external-download-uri option", mExternalDownloadUriValue);
- mExtraParams = getExtraParams();
- assertTrue("Failed to connect to wifi!", connectToWifi());
- }
-
- /**
- * Helper function to connect to wifi
- * @throws DeviceNotAvailableException
- */
- protected boolean connectToWifi() throws DeviceNotAvailableException {
- return PackageManagerHostTestUtils.connectToWifi(mDevice,
- mWifiNetwork, mWifiPsk, mWifiAttempts);
- }
-
- /**
- * Helper function to get extra params that can be used to pass into the helper app.
- */
- protected Hashtable<String, String> getExtraParams() {
- Hashtable<String, String> extraParams = new Hashtable<String, String>();
- extraParams.put(EXTERNAL_DOWNLOAD_URI_KEY, mExternalDownloadUriValue);
- return extraParams;
- }
-
- /**
- * Tests that a large download over WiFi
- * @throws Exception if the test failed at any point
- */
- public void testLargeDownloadOverWiFi() throws Exception {
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "runLargeDownloadOverWiFi", DOWNLOAD_TEST_RUNNER_NAME,
- mExtraParams);
- assertTrue("Failed to install large file over WiFi in < 10 minutes!", testPassed);
- }
-
- /**
- * Spawns a device-based function to initiate a download on the device, reboots the device,
- * then waits and verifies the download succeeded.
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadManagerSingleReboot() throws Exception {
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "initiateDownload", DOWNLOAD_TEST_RUNNER_NAME,
- mExtraParams);
-
- assertTrue("Failed to initiate download properly!", testPassed);
- mDevice.reboot();
- assertTrue("Failed to connect to wifi after reboot!", connectToWifi());
- testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "verifyFileDownloadSucceeded", DOWNLOAD_TEST_RUNNER_NAME,
- mExtraParams);
- assertTrue("Failed to verify initiated download completed properly!", testPassed);
- }
-
- /**
- * Spawns a device-based function to initiate a download on the device, reboots the device three
- * times (using different intervals), then waits and verifies the download succeeded.
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadManagerMultipleReboots() throws Exception {
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "initiateDownload", DOWNLOAD_TEST_RUNNER_NAME,
- mExtraParams);
-
- assertTrue("Failed to initiate download properly!", testPassed);
- Thread.sleep(5000);
-
- // Do 3 random reboots - after 9, 5, and 6 seconds
- Log.i(LOG_TAG, "First reboot...");
- mDevice.reboot();
- assertTrue("Failed to connect to wifi after reboot!", connectToWifi());
- Thread.sleep(9000);
- Log.i(LOG_TAG, "Second reboot...");
- mDevice.reboot();
- assertTrue("Failed to connect to wifi after reboot!", connectToWifi());
- Thread.sleep(5000);
- Log.i(LOG_TAG, "Third reboot...");
- mDevice.reboot();
- assertTrue("Failed to connect to wifi after reboot!", connectToWifi());
- Thread.sleep(6000);
- testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "verifyFileDownloadSucceeded", DOWNLOAD_TEST_RUNNER_NAME,
- mExtraParams);
- assertTrue("Failed to verify initiated download completed properyly!", testPassed);
- }
-
- /**
- * Spawns a device-based function to test download while WiFi is enabled/disabled multiple times
- * during the download.
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadMultipleWiFiEnableDisable() throws Exception {
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "runDownloadMultipleWiFiEnableDisable",
- DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
- assertTrue(testPassed);
- }
-
- /**
- * Spawns a device-based function to test switching on/off both airplane mode and WiFi
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadMultipleSwitching() throws Exception {
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "runDownloadMultipleSwitching",
- DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
- assertTrue(testPassed);
- }
-
- /**
- * Spawns a device-based function to test switching on/off airplane mode multiple times
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadMultipleAirplaneModeEnableDisable() throws Exception {
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "runDownloadMultipleAirplaneModeEnableDisable",
- DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
- assertTrue(testPassed);
- }
-
- /**
- * Spawns a device-based function to test 15 concurrent downloads of 5,000,000-byte files
- *
- * @throws Exception if the test failed at any point
- */
- public void testDownloadMultipleSimultaneously() throws Exception {
- boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
- FILE_DOWNLOAD_CLASS, "runDownloadMultipleSimultaneously",
- DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
- assertTrue(testPassed);
- }
-
- /**
- * Saves dumpsys wifi log output if one of the tests fail.
- */
- private class WifiLogSaver extends ResultForwarder {
-
- public WifiLogSaver(ITestInvocationListener listener) {
- super(listener);
- }
-
- /** Take dumpsys wifi when test fails. */
- @Override
- public void testFailed(TestDescription test, String trace) {
- try {
- String output = mDevice.executeShellCommand("dumpsys wifi");
- if (output == null) {
- CLog.w("dumpsys wifi did not return output");
- } else {
- String name = test.getTestName() +"-dumpsys-wifi";
- try (ByteArrayInputStreamSource stream =
- new ByteArrayInputStreamSource(output.getBytes())) {
- super.testLog(name, LogDataType.TEXT, stream);
- }
- }
- } catch (DeviceNotAvailableException e) {
- CLog.e("Error getting dumpsys wifi");
- CLog.e(e);
- } finally {
- super.testFailed(test, trace);
- }
- }
- }
-
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- WifiLogSaver proxy = new WifiLogSaver(listener);
- super.run(proxy);
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/FrameworkPerfTest.java b/prod-tests/src/com/android/framework/tests/FrameworkPerfTest.java
deleted file mode 100644
index 366aca9..0000000
--- a/prod-tests/src/com/android/framework/tests/FrameworkPerfTest.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2012 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.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.IRunUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import com.google.common.collect.ImmutableMap;
-
-import org.junit.Assert;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test that measures the average latency of foreground and background
- * operations in various scenarios.
- */
-public class FrameworkPerfTest implements IRemoteTest, IDeviceTest {
-
- private static final String TEST_PACKAGE_NAME = "com.android.frameworkperffg";
- private static final String TEST_RUNNER_NAME = "android.test.InstrumentationTestRunner";
- private static final int PERF_TIMEOUT = 30 * 60 * 1000; //30 minutes timeout
- private static final int PRE_TEST_SLEEP_MS = 30 *1000; //30s sleep prior to test start
-
- private static final String LAYOUT = "frameworkfg_perf_layout";
- private static final String GC = "frameworkfg_perf_gc";
- private static final String XML = "frameworkfg_perf_xml";
- private static final String BITMAP = "frameworkfg_perf_bitmap";
- private static final String FILE = "frameworkfg_perf_file";
- private static final String OTHER = "frameworkfg_perf_other";
- private static final String MAP = "frameworkfg_perf_map";
- private static final ImmutableMap<String, String> TEST_TAG_MAP =
- new ImmutableMap.Builder<String, String>()
- .put("ReadFile",FILE)
- .put("CreateWriteFile",FILE)
- .put("CreateWriteSyncFile",FILE)
- .put("WriteFile",FILE)
- .put("CreateFile",FILE)
-
- .put("CreateRecycleBitmap",BITMAP)
- .put("LoadLargeScaledBitmap",BITMAP)
- .put("LoadSmallScaledBitmap",BITMAP)
- .put("LoadRecycleSmallBitmap",BITMAP)
- .put("LoadLargeBitmap",BITMAP)
- .put("CreateBitmap",BITMAP)
- .put("LoadSmallBitmap",BITMAP)
-
- .put("LayoutInflaterButton",LAYOUT)
- .put("LayoutInflaterImageButton",LAYOUT)
- .put("LayoutInflaterLarge",LAYOUT)
- .put("LayoutInflaterView",LAYOUT)
- .put("LayoutInflater",LAYOUT)
-
- .put("Gc",GC)
- .put("PaintGc",GC)
- .put("ObjectGc",GC)
- .put("FinalizingGc",GC)
-
- .put("OpenXmlRes",XML)
- .put("ParseXmlRes",XML)
- .put("ReadXmlAttrs",XML)
- .put("ParseLargeXmlRes",XML)
-
- .put("Sched",OTHER)
- .put("CPU",OTHER)
- .put("MethodCall",OTHER)
- .put("Ipc",OTHER)
-
- .put("GrowLargeArrayMap",MAP)
- .put("GrowLargeHashMap",MAP)
- .put("LookupSmallHashMap",MAP)
- .put("LookupSmallArrayMap",MAP)
- .put("LookupTinyHashMap",MAP)
- .put("GrowTinyHashMap",MAP)
- .put("LookupLargeHashMap",MAP)
- .put("LookupTinyArrayMap",MAP)
- .put("LookupLargeArrayMap",MAP)
- .put("GrowTinyArrayMap",MAP)
- .put("GrowSmallHashMap",MAP)
- .put("GrowSmallArrayMap",MAP)
- .build();
-
- private ITestDevice mTestDevice = null;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- Assert.assertNotNull(mTestDevice);
-
- getDevice().reboot();
- getRunUtil().sleep(PRE_TEST_SLEEP_MS);
- IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(TEST_PACKAGE_NAME,
- TEST_RUNNER_NAME, mTestDevice.getIDevice());
- runner.setMaxTimeToOutputResponse(PERF_TIMEOUT, TimeUnit.MILLISECONDS);
-
- CollectingTestListener collectingListener = new CollectingTestListener();
- Assert.assertTrue(mTestDevice.runInstrumentationTests(runner, collectingListener));
-
- Collection<TestResult> testResultsCollection =
- collectingListener.getCurrentRunResults().getTestResults().values();
-
- List<TestResult> testResults =
- new ArrayList<TestResult>(testResultsCollection);
-
- if (!testResults.isEmpty()) {
- Map<String, String> testMetrics = testResults.get(0).getMetrics();
- if (testMetrics != null) {
- reportMetrics(listener, testMetrics);
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mTestDevice = device;
- }
-
- /**
- * Report run metrics by creating an empty test run to stick them in.
- * @param listener The {@link ITestInvocationListener} of test results
- * @param metrics The {@link Map} that contains metrics for the given test
- */
- private void reportMetrics(ITestInvocationListener listener, Map<String, String> metrics) {
- // Parse out only averages
- Map<String, Map<String, String>> allMetrics = new HashMap<String, Map<String, String>>();
- for (String key : metrics.keySet()) {
- String testLabel = TEST_TAG_MAP.get(key);
- if (testLabel == null) {
- testLabel = OTHER;
- }
- if (!allMetrics.containsKey(testLabel)) {
- allMetrics.put(testLabel, new HashMap<String, String>());
- }
- allMetrics.get(testLabel).put(key, metrics.get(key));
- }
-
- for (String section : allMetrics.keySet()) {
- Map<String, String> sectionMetrics = allMetrics.get(section);
- if (sectionMetrics != null && !sectionMetrics.isEmpty()) {
- for (String section2 : sectionMetrics.keySet()) {
- CLog.i("%s ::'%s' : %s", section, section2, sectionMetrics.get(section2));
- }
- listener.testRunStarted(section, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(sectionMetrics));
- }
- }
- }
-
- IRunUtil getRunUtil() {
- return RunUtil.getDefault();
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/FrameworkStressTest.java b/prod-tests/src/com/android/framework/tests/FrameworkStressTest.java
deleted file mode 100644
index e987db3..0000000
--- a/prod-tests/src/com/android/framework/tests/FrameworkStressTest.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2011 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.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.loganalysis.item.BugreportItem;
-import com.android.loganalysis.item.LogcatItem;
-import com.android.loganalysis.parser.BugreportParser;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Test that instruments a stress test package, gathers iterations metrics, and posts the results.
- */
-public class FrameworkStressTest implements IDeviceTest, IRemoteTest {
- public static final String BUGREPORT_LOG_NAME = "bugreport_stress.txt";
-
- ITestDevice mTestDevice = null;
-
- @Option(name = "test-package-name", description = "Android test package name.")
- private String mTestPackageName;
-
- @Option(name = "test-class-name", description = "Test class name.")
- private String mTestClassName;
-
- @Option(name = "dashboard-test-label",
- description = "Test label to use when posting to dashboard.")
- private String mDashboardTestLabel;
-
- @Option(name = "setup-shell-command",
- description = "Setup shell command to run before the test, if any.")
- private String mSetupShellCommand;
-
- private static final String CURRENT_ITERATION_LABEL= "currentiterations";
- private static final String ANR_COUNT_LABEL = "anrs";
- private static final String JAVA_CRASH_COUNT_LABEL = "java_crashes";
- private static final String NATIVE_CRASH_COUNT_LABEL = "native_crashes";
- private static final String ITERATION_COUNT_LABEL = "iterations";
-
- private int mNumAnrsTotal = 0;
- private int mNumJavaCrashesTotal = 0;
- private int mNumNativeCrashesTotal = 0;
-
- @Override
- public void run(final ITestInvocationListener listener) throws DeviceNotAvailableException {
- Assert.assertNotNull(mTestDevice);
- if (mSetupShellCommand != null) {
- mTestDevice.executeShellCommand(mSetupShellCommand);
- }
- IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mTestPackageName,
- mTestDevice.getIDevice());
- runner.setClassName(mTestClassName);
- CollectingTestListener collectingListener = new CollectingMetricsTestListener(listener);
- mTestDevice.runInstrumentationTests(runner, collectingListener, listener);
-
- Map<TestDescription, TestResult> testResults =
- collectingListener.getCurrentRunResults().getTestResults();
- if (testResults != null) {
- for (Entry<TestDescription, TestResult> e : testResults.entrySet()) {
- TestResult res = e.getValue();
- Map<String, String> testMetrics = res.getMetrics();
- if (testMetrics != null) {
- CLog.d(testMetrics.toString());
- // Post everything to the dashboard.
- String label = String.format("%s#%s", mDashboardTestLabel,
- e.getKey().getTestName());
- reportMetrics(listener, label, testMetrics);
- }
- }
- }
- }
-
- /**
- * Report run metrics by creating an empty test run to stick them in.
- *
- * @param listener the {@link ITestInvocationListener} of test results
- * @param runName the test name
- * @param metrics the {@link Map} that contains metrics for the given test
- */
- void reportMetrics(ITestInvocationListener listener, String runName,
- Map<String, String> metrics) {
- // Create an empty testRun to report the parsed runMetrics
- CLog.d("About to report metrics: %s with label: %s", metrics, runName);
- listener.testRunStarted(runName, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-
- @Override
- public void setDevice(ITestDevice device) {
- mTestDevice = device;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-
- /**
- * Helper class to collect the Framework metrics at the end of each test.
- */
- private class CollectingMetricsTestListener extends CollectingTestListener {
-
- private ITestInvocationListener mListener;
-
- public CollectingMetricsTestListener(ITestInvocationListener listener) {
- mListener = listener;
- }
-
- @Override
- public void testEnded(TestDescription test, Map<String, String> testMetrics) {
- // Retrieve bugreport
- BugreportParser parser = new BugreportParser();
- BugreportItem bugreport = null;
- try (InputStreamSource bugSource = mTestDevice.getBugreport()) {
- mListener.testLog(BUGREPORT_LOG_NAME, LogDataType.BUGREPORT, bugSource);
- bugreport = parser.parse(new BufferedReader(new InputStreamReader(
- bugSource.createInputStream())));
- Assert.assertNotNull(bugreport);
- Assert.assertNotNull(bugreport.getSystemLog());
- } catch (IOException e) {
- Assert.fail(String.format("Failed to fetch and parse bugreport for device %s: "
- + "%s", mTestDevice.getSerialNumber(), e));
- }
- LogcatItem systemLog = bugreport.getSystemLog();
- // We only add errors found since last test run.
- Integer numArns = systemLog.getAnrs().size() - mNumAnrsTotal;
- mNumAnrsTotal = systemLog.getAnrs().size();
- testMetrics.put(ANR_COUNT_LABEL, numArns.toString());
-
- Integer numJavaCrashes = systemLog.getJavaCrashes().size() - mNumJavaCrashesTotal;
- mNumJavaCrashesTotal = systemLog.getJavaCrashes().size();
- testMetrics.put(JAVA_CRASH_COUNT_LABEL, numJavaCrashes.toString());
-
- Integer numNativeCrashes = systemLog.getNativeCrashes().size() - mNumNativeCrashesTotal;
- mNumNativeCrashesTotal = systemLog.getNativeCrashes().size();
- testMetrics.put(NATIVE_CRASH_COUNT_LABEL, numNativeCrashes.toString());
-
- Integer numSuccessfulIterations =
- Integer.parseInt(testMetrics.get(CURRENT_ITERATION_LABEL))
- - numArns - numJavaCrashes - numNativeCrashes;
- testMetrics.put(ITERATION_COUNT_LABEL, numSuccessfulIterations.toString());
-
- super.testEnded(test, testMetrics);
- }
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PackageManagerHostTestUtils.java b/prod-tests/src/com/android/framework/tests/PackageManagerHostTestUtils.java
deleted file mode 100644
index 0734140..0000000
--- a/prod-tests/src/com/android/framework/tests/PackageManagerHostTestUtils.java
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * Copyright (C) 2010 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.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.IFileEntry;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-
-import org.junit.Assert;
-
-import java.io.File;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Set of tests that verify host side install cases
- */
-public class PackageManagerHostTestUtils extends Assert {
- private ITestDevice mDevice = null;
- private boolean mEmulatedExternalStorage = false;
-
- // TODO: get this value from Android Environment instead of hard coding
- public static final String JB_APP_PRIVATE_PATH = "/mnt/asec/";
- public static final String DEVICE_APP_PATH = "/data/app/";
- public static final String SDCARD_APP_PATH = "/mnt/asec/";
-
- private static String mAppPrivatePath = JB_APP_PRIVATE_PATH;
-
- private static final int MAX_WAIT_FOR_DEVICE_TIME = 120 * 1000;
-
- // Install preference on the device-side
- public static enum InstallLocPreference {
- AUTO,
- INTERNAL,
- EXTERNAL
- }
-
- // Actual install location
- public static enum InstallLocation {
- DEVICE,
- SDCARD
- }
-
- /**
- * Constructor.
- *
- * @param device the {@link ITestDevice} to use when performing operations.
- * @throws DeviceNotAvailableException
- */
- public PackageManagerHostTestUtils(ITestDevice device)
- throws DeviceNotAvailableException {
- mDevice = device;
- determineExternalStorageEmulation();
- }
-
- /**
- * Returns the path on the device of forward-locked apps.
- *
- * @return path of forward-locked apps on the device
- */
- public static String getAppPrivatePath() {
- return mAppPrivatePath;
- }
-
- public static void setAppPrivatePath(String path) {
- mAppPrivatePath = path;
- }
-
- /**
- * Returns the path on the device of normal apps.
- *
- * @return path of forward-locked apps on the device
- */
- public static String getDeviceAppPath() {
- return DEVICE_APP_PATH;
- }
-
- /**
- * Returns the path of apps installed on the SD card.
- *
- * @return path of forward-locked apps on the device
- */
- public static String getSDCardAppPath() {
- return SDCARD_APP_PATH;
- }
-
- /**
- * Helper method to run tests and return the listener that collected the
- * results. For the optional params, pass null to use the default values.
- *
- * @param pkgName Android application package for tests
- * @param className (optional) The class containing the method to test
- * @param methodName (optional) The method in the class of which to test
- * @param runnerName (optional) The name of the TestRunner of the test on
- * the device to be run
- * @param params (optional) Any additional parameters to pass into the Test
- * Runner
- * @return the {@link CollectingTestListener}
- * @throws DeviceNotAvailableException
- */
- private CollectingTestListener doRunTests(String pkgName, String className,
- String methodName, String runnerName, Map<String, String> params)
- throws DeviceNotAvailableException {
- IRemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(pkgName, runnerName,
- mDevice.getIDevice());
-
- if (className != null && methodName != null) {
- testRunner.setMethodName(className, methodName);
- }
-
- // Add in any additional args to pass into the test
- if (params != null) {
- for (Entry<String, String> argPair : params.entrySet()) {
- testRunner.addInstrumentationArg(argPair.getKey(), argPair.getValue());
- }
- }
-
- CollectingTestListener listener = new CollectingTestListener();
- mDevice.runInstrumentationTests(testRunner, listener);
- return listener;
- }
-
- /**
- * Runs the specified packages tests, and returns whether all tests passed
- * or not.
- *
- * @param pkgName Android application package for tests
- * @param className The class containing the method to test
- * @param methodName The method in the class of which to test
- * @param runnerName The name of the TestRunner of the test on the device to
- * be run
- * @param params Any additional parameters to pass into the Test Runner
- * @return true if test passed, false otherwise.
- * @throws DeviceNotAvailableException
- */
- public boolean runDeviceTestsDidAllTestsPass(String pkgName, String className,
- String methodName, String runnerName, Map<String, String> params)
- throws DeviceNotAvailableException {
- CollectingTestListener listener = doRunTests(pkgName, className, methodName,
- runnerName, params);
- return !listener.hasFailedTests();
- }
-
- /**
- * Runs the specified packages tests, and returns whether all tests passed
- * or not.
- *
- * @param pkgName Android application package for tests
- * @return true if every test passed, false otherwise.
- * @throws DeviceNotAvailableException
- */
- public boolean runDeviceTestsDidAllTestsPass(String pkgName)
- throws DeviceNotAvailableException {
- CollectingTestListener listener = doRunTests(pkgName, null, null, null, null);
- return !listener.hasFailedTests();
- }
-
- /**
- * Helper method to install a file
- *
- * @param localFile the {@link File} to install
- * @param replace set to <code>true</code> if re-install of app should be
- * performed
- * @throws DeviceNotAvailableException
- */
- public void installFile(final File localFile, final boolean replace)
- throws DeviceNotAvailableException {
- String result = mDevice.installPackage(localFile, replace);
- assertEquals(null, result);
- }
-
- /**
- * Helper method to install a file to device as forward locked.
- *
- * @param apkFile the {@link File} to install
- * @param replace set to <code>true</code> if re-install of app should be
- * performed
- * @throws DeviceNotAvailableException if communication with device is lost
- */
- public String installFileForwardLocked(final File apkFile, final boolean replace)
- throws DeviceNotAvailableException {
- return mDevice.installPackage(apkFile, replace, "-l");
- }
-
- /**
- * Helper method to determine if file exists on the device containing a
- * given string.
- *
- * @param destPath the absolute path of the file
- * @return <code>true</code> if file exists containing given string,
- * <code>false</code> otherwise.
- * @throws DeviceNotAvailableException
- */
- public boolean doesRemoteFileExistContainingString(String destPath, String searchString)
- throws DeviceNotAvailableException {
- String lsResult = mDevice.executeShellCommand(String.format("ls %s", destPath));
- return lsResult.contains(searchString);
- }
-
- /**
- * Helper method to determine if package on device exists.
- *
- * @param packageName the Android manifest package to check.
- * @return <code>true</code> if package exists, <code>false</code> otherwise
- * @throws DeviceNotAvailableException
- */
- public boolean doesPackageExist(String packageName) throws DeviceNotAvailableException {
- String pkgGrep = mDevice.executeShellCommand(String.format("pm path %s", packageName));
- return pkgGrep.contains("package:");
- }
-
- /**
- * Determines if app was installed on device.
- *
- * @param packageName package name to check for
- * @return <code>true</code> if file exists, <code>false</code> otherwise.
- * @throws DeviceNotAvailableException
- */
- public boolean doesAppExistOnDevice(String packageName) throws DeviceNotAvailableException {
- return doesRemoteFileExistContainingString(DEVICE_APP_PATH, packageName);
- }
-
- /**
- * Determines if app was installed on SD card.
- *
- * @param packageName package name to check for
- * @return <code>true</code> if file exists, <code>false</code> otherwise.
- * @throws DeviceNotAvailableException
- */
- public boolean doesAppExistOnSDCard(String packageName) throws DeviceNotAvailableException {
-
- // if we're using emulated storage, the SDcard path is actually the
- // device's normal app path
- if (getIsExternalStorageEmulated()) {
- return doesRemoteFileExistContainingString(DEVICE_APP_PATH, packageName);
- }
- else {
- return doesRemoteFileExistContainingString(SDCARD_APP_PATH, packageName);
- }
- }
-
- /**
- * Helper method to determine if app was installed as forward locked.
- *
- * @param packageName package name to check for
- * @return <code>true</code> if file exists, <code>false</code> otherwise.
- * @throws DeviceNotAvailableException
- */
- public boolean doesAppExistAsForwardLocked(String packageName)
- throws DeviceNotAvailableException {
- return doesRemoteFileExistContainingString(mAppPrivatePath, packageName);
- }
-
- /**
- * Waits for device's package manager to respond.
- *
- * @throws DeviceNotAvailableException
- */
- public void waitForPackageManager() throws DeviceNotAvailableException {
- CLog.i("waiting for device");
- mDevice.waitForDeviceAvailable(MAX_WAIT_FOR_DEVICE_TIME);
- }
-
- /**
- * Helper method for installing an app to wherever is specified in its
- * manifest, and then verifying the app was installed onto SD Card.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param apkPath the path of the apk to install
- * @param pkgName the name of the package
- * @param overwrite <code>true</code> if the app should be overwritten,
- * <code>false</code> otherwise
- * @throws DeviceNotAvailableException
- */
- public void installAppAndVerifyExistsOnSDCard(File apkPath, String pkgName, boolean overwrite)
- throws DeviceNotAvailableException {
- // Start with a clean slate if we're not overwriting
- if (!overwrite) {
- // cleanup test app just in case it already exists
- mDevice.uninstallPackage(pkgName);
- // grep for package to make sure its not installed
- assertFalse(doesPackageExist(pkgName));
- }
-
- installFile(apkPath, overwrite);
- assertTrue(doesAppExistOnSDCard(pkgName));
- // TODO: is this necessary?
- waitForPackageManager();
-
- // grep for package to make sure it is installed
- assertTrue(doesPackageExist(pkgName));
- }
-
- /**
- * Helper method for installing an app to wherever is specified in its
- * manifest, and then verifying the app was installed onto device.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param apkFile the {@link File} of the apk to install
- * @param pkgName the name of the package
- * @param overwrite <code>true</code> if the app should be overwritten,
- * <code>false</code> otherwise
- * @throws DeviceNotAvailableException
- */
- public void installAppAndVerifyExistsOnDevice(File apkFile, String pkgName, boolean overwrite)
- throws DeviceNotAvailableException {
- // Start with a clean slate if we're not overwriting
- if (!overwrite) {
- // cleanup test app just in case it already exists
- mDevice.uninstallPackage(pkgName);
- // grep for package to make sure its not installed
- assertFalse(doesPackageExist(pkgName));
- }
-
- installFile(apkFile, overwrite);
- assertTrue(doesAppExistOnDevice(pkgName));
- // TODO: is this necessary?
- waitForPackageManager();
-
- // grep for package to make sure it is installed
- assertTrue(doesPackageExist(pkgName));
- }
-
- /**
- * Helper method for installing an app as forward-locked, and then verifying
- * the app was installed in the proper forward-locked location.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param apkFile the {@link File} of the apk to install
- * @param pkgName the name of the package
- * @param overwrite <code>true</code> if the app should be overwritten,
- * <code>false</code> otherwise
- * @throws Exception if failed to install app
- */
- public void installFwdLockedAppAndVerifyExists(File apkFile,
- String pkgName, boolean overwrite) throws Exception {
- // Start with a clean slate if we're not overwriting
- if (!overwrite) {
- // cleanup test app just in case it already exists
- mDevice.uninstallPackage(pkgName);
- // grep for package to make sure its not installed
- assertFalse(doesPackageExist(pkgName));
- }
-
- String result = installFileForwardLocked(apkFile, overwrite);
- assertEquals(null, result);
- assertTrue(doesAppExistAsForwardLocked(pkgName));
- waitForPackageManager();
-
- // grep for package to make sure it is installed
- assertTrue(doesPackageExist(pkgName));
- }
-
- /**
- * Helper method for uninstalling an app.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param pkgName package name to uninstall
- * @throws DeviceNotAvailableException
- */
- public void uninstallApp(String pkgName) throws DeviceNotAvailableException {
- mDevice.uninstallPackage(pkgName);
- waitForPackageManager();
- // make sure its not installed anymore
- assertFalse(doesPackageExist(pkgName));
- }
-
- /**
- * Sets the device's install location preference.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @throws DeviceNotAvailableException
- */
- public void setDevicePreferredInstallLocation(InstallLocPreference pref)
- throws DeviceNotAvailableException {
- String command = "pm set-install-location %d";
- int locValue = 0;
- switch (pref) {
- case INTERNAL:
- locValue = 1;
- break;
- case EXTERNAL:
- locValue = 2;
- break;
- default: // AUTO
- locValue = 0;
- break;
- }
- mDevice.executeShellCommand(String.format(command, locValue));
- }
-
- /**
- * Gets the device's install location preference.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @throws DeviceNotAvailableException
- */
- public InstallLocPreference getDevicePreferredInstallLocation()
- throws DeviceNotAvailableException {
- String result = mDevice.executeShellCommand("pm get-install-location");
- if (result.indexOf('0') != -1) {
- return InstallLocPreference.AUTO;
- }
- else if (result.indexOf('1') != -1) {
- return InstallLocPreference.INTERNAL;
- }
- else {
- return InstallLocPreference.EXTERNAL;
- }
- }
-
- /**
- * Determines whether the device is using emulated external storage.
- * <p/>
- * Sets mEmulatedExternalStorage based on the result Assumes adb is running
- * as root in device under test.
- *
- * @throws DeviceNotAvailableException
- */
- private void determineExternalStorageEmulation()
- throws DeviceNotAvailableException {
- String result = mDevice.executeShellCommand("sm get-primary-storage-uuid");
- if (result.trim().equalsIgnoreCase("null")) {
- CLog.i("Device is using emulated external storage.");
- mEmulatedExternalStorage = true;
- }
- else if (result.equals("primary_physical")) {
- CLog.i("Device is using actual external storage.");
- mEmulatedExternalStorage = false;
- }
- else {
- // older devices will not have mEmulated flag in the output
- CLog.i("Unable to precisely determine external storage emulation; assuming false.");
- mEmulatedExternalStorage = false;
- }
- }
-
- /**
- * Determine the location of the app private path.
- *
- * @param apkFile the {@link File} of test apk to determine packages'
- * install path.
- * @param pkgName the {@link String} pkgName of the test apk.
- * @throws DeviceNotAvailableException
- */
- public void determinePrivateAppPath(File apkFile, String pkgName)
- throws DeviceNotAvailableException {
- setAppPrivatePath(JB_APP_PRIVATE_PATH);
- }
-
- /**
- * Returns whether the external storage is emulated or not.
- *
- * @return <code>true</code> if external storage is emulated,
- * <code>false</code> otherwise.
- */
- public boolean getIsExternalStorageEmulated() {
- return mEmulatedExternalStorage;
- }
-
- /**
- * Connect device to wifi.
- *
- * @param device
- * @param wifiNetwork
- * @param wifiPsk
- * @param connectionAttempts
- * @return true if able to connect to wifi.
- * @throws DeviceNotAvailableException
- */
- public static boolean connectToWifi(ITestDevice device, String wifiNetwork, String wifiPsk,
- int connectionAttempts) throws DeviceNotAvailableException {
- if (wifiNetwork != null) {
- for (int i = 0; i < connectionAttempts; i++) {
- device.disconnectFromWifi();
- if (device.connectToWifiNetwork(wifiNetwork, wifiPsk)) {
- CLog.i("Connected to wifi network %s", wifiNetwork);
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Ensure that the file's permissions matches expectation.
- *
- * @param remoteFilePath {@link String} the remote path for the file to check.
- * @param expectedPerms {@link String} expected permissions.
- * @return true if the permissions for a given file matches, false otherwise.
- * @throws DeviceNotAvailableException
- */
- public boolean checkFilePermissions(String remoteFilePath, String expectedPerms)
- throws DeviceNotAvailableException {
- IFileEntry file = mDevice.getFileEntry(remoteFilePath);
- return file.getPermissions().equals(expectedPerms);
- }
-
- /**
- * Ensure that the file's owner matches expectation.
- *
- * @param remoteFilePath {@link String} the remote path for the file to check.
- * @param expectedOwner {@link String} the expected owner.
- * @return true if the owner for a given file matches, false otherwise.
- * @throws DeviceNotAvailableException
- */
- public boolean checkFileOwnerName(String remoteFilePath, String expectedOwner)
- throws DeviceNotAvailableException {
- //TODO: uncomment this, when we have support from ddmlib.
- //IFileEntry file = mDevice.getFileEntry(remoteFilePath);
- // return file.getOwner().equals(expectedOwner)
- return true;
- }
-
- /**
- * Ensure that the file's group matches expectation
- *
- * @param remoteFilePath {@link String} the remote path for the file to check.
- * @param expectedGroup {@link String} the expected group.
- * @return true if the group for a given file matches, false otherwise.
- * @throws DeviceNotAvailableException
- */
- public boolean checkFileGroupName(String remoteFilePath, String expectedGroup)
- throws DeviceNotAvailableException {
- //TODO: uncomment this, when we have support from ddmlib.
- //IFileEntry file = mDevice.getFileEntry(remoteFilePath);
- // return file.getGroup().equals(expectedOwner)
- return true;
- }
-
- /**
- * Returns the uid of the installed package.
- * @param pkgName package name of the test apk.
- * @return uid of the installed package
- * @throws DeviceNotAvailableException
- */
- public Integer getUid(String pkgName) throws DeviceNotAvailableException {
- String out = mDevice.executeShellCommand(String.format("dumpsys package %s", pkgName));
- Matcher m = Pattern.compile("userId=(\\d+)").matcher(out);
- assertTrue(m.find());
-
- Integer uid = Integer.parseInt(m.group(1));
- CLog.v("package %s has uid %d", pkgName, uid);
- return uid;
- }
-
- public String getAbi(String pkgName) throws DeviceNotAvailableException {
- String out = mDevice.executeShellCommand(String.format("dumpsys package %s", pkgName));
- Matcher m = Pattern.compile("primaryCpuAbi=(.+)").matcher(out);
- assertTrue(m.find());
-
- String abi = m.group(1);
- CLog.i("package %s has abi %s", pkgName, abi);
- return abi;
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PackageManagerHostTests.java b/prod-tests/src/com/android/framework/tests/PackageManagerHostTests.java
deleted file mode 100644
index 61c5987..0000000
--- a/prod-tests/src/com/android/framework/tests/PackageManagerHostTests.java
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * Copyright (C) 2010 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.framework.tests;
-
-import com.android.ddmlib.Log;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.util.FileUtil;
-
-import java.io.File;
-
-/**
- * Set of tests that verify host side install cases
- */
-public class PackageManagerHostTests extends DeviceTestCase {
-
- private static final String ABI_PROPERTY = "ro.product.cpu.abi";
- private static final String ARM64_V8A = "arm64-v8a";
- private static final String ARMEABI_V7A = "armeabi-v7a";
- private static final String LOG_TAG = "PackageManagerHostTests";
- private PackageManagerHostTestUtils mPMHostUtils = null;
-
- // Various test files and their corresponding package names...
-
- // testPushAppPrivate constants
- // these constants must match values defined in test-apps/SimpleTestApp
- private static final String SIMPLE_APK = "SimpleTestApp.apk";
- private static final String SIMPLE_PKG = "com.android.framework.simpletestapp";
-
- // Apk with install location set to auto
- private static final String AUTO_LOC_APK = "AutoLocTestApp.apk";
- private static final String AUTO_LOC_PKG = "com.android.framework.autoloctestapp";
- // Apk with install location set to internalOnly
- private static final String INTERNAL_LOC_APK = "InternalLocTestApp.apk";
- private static final String INTERNAL_LOC_PKG = "com.android.framework.internalloctestapp";
- // Apk with install location set to preferExternal
- private static final String EXTERNAL_LOC_APK = "ExternalLocTestApp.apk";
- private static final String EXTERNAL_LOC_PKG = "com.android.framework.externalloctestapp";
- // Apk with install location set to auto (2 versions, for update testing)
- @SuppressWarnings("unused")
- private static final String AUTO_LOC_VERSION_V1_APK = "AutoLocVersionedTestApp_v1.apk";
- @SuppressWarnings("unused")
- private static final String AUTO_LOC_VERSION_V2_APK = "AutoLocVersionedTestApp_v2.apk";
- @SuppressWarnings("unused")
- private static final String AUTO_LOC_VERSION_PKG =
- "com.android.framework.autolocversionedtestapp";
- // Apk with install location set to preferExternal (2 versions, for update
- // testing)
- private static final String EXTERNAL_LOC_VERSION_V1_APK = "ExternalLocVersionedTestApp_v1.apk";
- private static final String EXTERNAL_LOC_VERSION_V2_APK = "ExternalLocVersionedTestApp_v2.apk";
- private static final String EXTERNAL_LOC_VERSION_PKG =
- "com.android.framework.externallocversionedtestapp";
- // Apk with install location set to auto (2 versions, for update testing)
- private static final String NO_LOC_VERSION_V1_APK = "NoLocVersionedTestApp_v1.apk";
- private static final String NO_LOC_VERSION_V2_APK = "NoLocVersionedTestApp_v2.apk";
- private static final String NO_LOC_VERSION_PKG =
- "com.android.framework.nolocversionedtestapp";
- // Apk with no install location set
- private static final String NO_LOC_APK = "NoLocTestApp.apk";
- private static final String NO_LOC_PKG = "com.android.framework.noloctestapp";
- // Apk with 2 different versions - v1 is set to external, v2 has no location
- // setting
- private static final String UPDATE_EXTERNAL_LOC_V1_EXT_APK = "UpdateExternalLocTestApp_v1_ext.apk";
- private static final String UPDATE_EXTERNAL_LOC_V2_NONE_APK = "UpdateExternalLocTestApp_v2_none.apk";
- private static final String UPDATE_EXTERNAL_LOC_PKG = "com.android.framework.updateexternalloctestapp";
- // Apk with 2 different versions - v1 is set to external, v2 is set to
- // internalOnly
- private static final String UPDATE_EXT_TO_INT_LOC_V1_EXT_APK = "UpdateExtToIntLocTestApp_v1_ext.apk";
- private static final String UPDATE_EXT_TO_INT_LOC_V2_INT_APK = "UpdateExtToIntLocTestApp_v2_int.apk";
- private static final String UPDATE_EXT_TO_INT_LOC_PKG = "com.android.framework.updateexttointloctestapp";
- // Apk set to preferExternal, with Access Fine Location permissions set in
- // its manifest
- @SuppressWarnings("unused")
- private static final String FL_PERMS_APK = "ExternalLocPermsFLTestApp.apk";
- @SuppressWarnings("unused")
- private static final String FL_PERMS_PKG = "com.android.framework.externallocpermsfltestapp";
- // Apk set to preferExternal, with all permissions set in manifest
- private static final String ALL_PERMS_APK = "ExternalLocAllPermsTestApp.apk";
- private static final String ALL_PERMS_PKG = "com.android.framework.externallocallpermstestapp";
- // Apks with the same package name, but install location set to
- // one of: Internal, External, Auto, or None
- private static final String VERSATILE_LOC_PKG = "com.android.framework.versatiletestapp";
- private static final String VERSATILE_LOC_INTERNAL_APK = "VersatileTestApp_Internal.apk";
- private static final String VERSATILE_LOC_EXTERNAL_APK = "VersatileTestApp_External.apk";
- @SuppressWarnings("unused")
- private static final String VERSATILE_LOC_AUTO_APK = "VersatileTestApp_Auto.apk";
- @SuppressWarnings("unused")
- private static final String VERSATILE_LOC_NONE_APK = "VersatileTestApp_None.apk";
- // Apks with shared UserID
- private static final String SHARED_PERMS_APK = "ExternalSharedPermsTestApp.apk";
- private static final String SHARED_PERMS_PKG = "com.android.framework.externalsharedpermstestapp";
- private static final String SHARED_PERMS_FL_APK = "ExternalSharedPermsFLTestApp.apk";
- private static final String SHARED_PERMS_FL_PKG = "com.android.framework.externalsharedpermsfltestapp";
- private static final String SHARED_PERMS_BT_APK = "ExternalSharedPermsBTTestApp.apk";
- private static final String SHARED_PERMS_BT_PKG = "com.android.framework.externalsharedpermsbttestapp";
- // Apk with shared UserID, but signed with a different cert (the media cert)
- @SuppressWarnings("unused")
- private static final String SHARED_PERMS_DIFF_KEY_APK = "ExternalSharedPermsDiffKeyTestApp.apk";
- @SuppressWarnings("unused")
- private static final String SHARED_PERMS_DIFF_KEY_PKG = "com.android.framework.externalsharedpermsdiffkeytestapp";
-
- // Shared uid apks
- private static final String SHARED_UID_APK = "PMTest_Java.apk";
- private static final String SHARED_UID_PKG = "com.framework.shareduid.java";
- private static final String SHARED_UID_APK_32 = "PMTest_Java32.apk";
- private static final String SHARED_UID_PKG_32 = "com.framework.shareduid.bit32";
- private static final String SHARED_UID_APK_64 = "PMTest_Java64.apk";
- private static final String SHARED_UID_PKG_64 = "com.framework.shareduid.bit64";
- private static final String SHARED_UID_APK_DUAL = "PMTest_Java_dual.apk";
- private static final String SHARED_UID_PKG_DUAL = "com.framework.shareduid.dual";
-
- // TODO: consider fetching these files from build server instead.
- @Option(name = "app-repository-path", description =
- "path to the app repository containing large apks", importance = Importance.IF_UNSET)
- private File mAppRepositoryPath = null;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- // ensure apk path has been set before test is run
- assertNotNull("Missing --app-repository-path option", mAppRepositoryPath);
-
- // setup the PackageManager host tests utilities class, and get various
- // paths we'll need...
- mPMHostUtils = new PackageManagerHostTestUtils(getDevice());
- }
-
- /**
- * Get the absolute file system location of test app with given filename
- *
- * @param fileName the file name of the test app apk
- * @return {@link String} of absolute file path
- */
- public File getTestAppFilePath(String fileName) {
- return FileUtil.getFileForPath(mAppRepositoryPath, fileName);
- }
-
- /**
- * Regression test to verify that pushing an apk to the private app
- * directory doesn't install the app, and otherwise cause the system to blow
- * up.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @throws DeviceNotAvailableException
- */
- public void testPushAppPrivate() throws DeviceNotAvailableException {
- Log.i(LOG_TAG, "testing pushing an apk to /data/app-private");
- final String apkAppPrivatePath = PackageManagerHostTestUtils.getAppPrivatePath()
- + SIMPLE_APK;
-
- // cleanup test app just in case it was accidently installed
- getDevice().uninstallPackage(SIMPLE_PKG);
- getDevice().executeShellCommand("stop");
- getDevice().pushFile(getTestAppFilePath(SIMPLE_APK), apkAppPrivatePath);
-
- // sanity check to make sure file is there
- assertTrue(getDevice().doesFileExist(apkAppPrivatePath));
- getDevice().executeShellCommand("start");
-
- mPMHostUtils.waitForPackageManager();
-
- // grep for package to make sure its not installed
- assertFalse(mPMHostUtils.doesPackageExist(SIMPLE_PKG));
- // TODO: Is the apk supposed to uninstall itself?
- // ensure it has been deleted from app-private
- // assertFalse(getDevice().doesFileExist(apkAppPrivatePath));
- }
-
- /**
- * Helper to do a standard install of an apk and verify it installed to the
- * correct location.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param apkName the file name of the test app apk
- * @param pkgName the package name of the test app apk
- * @param expectedLocation the file name of the test app apk
- * @throws DeviceNotAvailableException
- */
- private void doStandardInstall(String apkName, String pkgName,
- PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws DeviceNotAvailableException {
-
- if (expectedLocation == PackageManagerHostTestUtils.InstallLocation.DEVICE) {
- mPMHostUtils.installAppAndVerifyExistsOnDevice(getTestAppFilePath(apkName), pkgName,
- false);
- } else {
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(apkName), pkgName,
- false);
- }
- }
-
- /**
- * Installs the Auto app and verifies it was installed at expected loc.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param expectedLocation the expected location of where the apk was
- * installed
- * @throws DeviceNotAvailableException
- */
- public void installAppAutoLoc(PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws DeviceNotAvailableException {
- try {
- // Auto app should go to storage with more free space when device has adopted storage
- doStandardInstall(AUTO_LOC_APK, AUTO_LOC_PKG, expectedLocation);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(AUTO_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its manifest set to
- * installLocation=auto will install the app to the device
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAppLocPrefIsAuto() throws Exception {
- Log.i(LOG_TAG, "Test app manifest installLocation=auto gets installed on device");
- installAppAutoLoc(PackageManagerHostTestUtils.InstallLocation.DEVICE);
- }
-
- /**
- * Installs the Internal app and verifies it was installed at expected loc.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param expectedLocation the expected location of where the apk was
- * installed
- */
- public void installAppInternalLoc(PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws Exception {
- try {
- doStandardInstall(INTERNAL_LOC_APK, INTERNAL_LOC_PKG, expectedLocation);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(INTERNAL_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its manifest set to
- * installLocation=internalOnly will install the app to the device when
- * device's preference is auto.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAppLocPrefIsInternal() throws Exception {
- Log.i(LOG_TAG, "Test app manifest installLocation=internal gets installed on device");
- installAppInternalLoc(PackageManagerHostTestUtils.InstallLocation.DEVICE);
- }
-
- /**
- * Regression test to verify that an app with its manifest set to
- * installLocation=preferExternal will install the app to expected loc.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @param expectedLocation the expected location of where the apk was
- * installed
- */
- public void installAppExternalLoc(
- PackageManagerHostTestUtils.InstallLocation expectedLocation)
- throws Exception {
- try {
- doStandardInstall(EXTERNAL_LOC_APK, EXTERNAL_LOC_PKG, expectedLocation);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its manifest set to
- * installLocation=preferExternal will install the app to the appropriate external storage.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAppLocPrefIsExternal() throws Exception {
- Log.i(LOG_TAG, "Test installLocation=external gets installed on SD Card");
- installAppExternalLoc(PackageManagerHostTestUtils.InstallLocation.SDCARD);
- }
-
- /**
- * Regression test to verify that an app without installLocation in its
- * manifest will install the app to the device by default
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAppNoLocPrefIsAuto() throws Exception {
- Log.i(LOG_TAG, "Test an app with no installLocation gets installed on device");
- try {
- mPMHostUtils.installAppAndVerifyExistsOnDevice(
- getTestAppFilePath(NO_LOC_APK), NO_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(NO_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its installLocation set to
- * internal that is forward-locked will get installed to the correct
- * location.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallFwdLockedAppInternal() throws Exception {
- Log.i(LOG_TAG, "Test an app with installLoc set to Internal gets installed to app-private");
-
- try {
- mPMHostUtils.installFwdLockedAppAndVerifyExists(
- getTestAppFilePath(INTERNAL_LOC_APK), INTERNAL_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(INTERNAL_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its installLocation set to
- * external that is forward-locked will get installed to the correct
- * location.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallFwdLockedAppExternal() throws Exception {
- Log.i(LOG_TAG, "Test an app with installLoc set to Internal gets installed to app-private");
-
- try {
- mPMHostUtils.installFwdLockedAppAndVerifyExists(
- getTestAppFilePath(EXTERNAL_LOC_APK), EXTERNAL_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with its installLocation set to
- * external that is forward-locked will get installed to the correct
- * location.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallFwdLockedAppAuto() throws Exception {
- Log.i(LOG_TAG, "Test an app with installLoc set to Auto gets installed to app-private");
-
- try {
- mPMHostUtils.installFwdLockedAppAndVerifyExists(
- getTestAppFilePath(AUTO_LOC_APK), AUTO_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(AUTO_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with no installLocation set and is
- * forward-locked installed will get installed to the correct location.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallFwdLockedAppNone() throws Exception {
- Log.i(LOG_TAG, "Test an app with no installLoc set gets installed to app-private");
-
- try {
- mPMHostUtils.installFwdLockedAppAndVerifyExists(
- getTestAppFilePath(NO_LOC_APK), NO_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(NO_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that we can install an app onto the device,
- * uninstall it, and reinstall it onto the SD card.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- // TODO: This currently relies on the app's manifest to switch from device
- // to
- // SD card install locations. We might want to make Device's
- // installPackage()
- // accept a installLocation flag so we can install a package to the
- // destination of our choosing.
- public void testReinstallInternalToExternal() throws Exception {
- Log.i(LOG_TAG, "Test installing an app first to the device, then to the SD Card");
-
- try {
- mPMHostUtils.installAppAndVerifyExistsOnDevice(
- getTestAppFilePath(VERSATILE_LOC_INTERNAL_APK), VERSATILE_LOC_PKG, false);
- mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(
- getTestAppFilePath(VERSATILE_LOC_EXTERNAL_APK), VERSATILE_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that we can install an app onto the SD Card,
- * uninstall it, and reinstall it onto the device.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- // TODO: This currently relies on the app's manifest to switch from device
- // to
- // SD card install locations. We might want to make Device's
- // installPackage()
- // accept a installLocation flag so we can install a package to the
- // destination of our choosing.
- public void testReinstallExternalToInternal() throws Exception {
- Log.i(LOG_TAG, "Test installing an app first to the SD Care, then to the device");
-
- try {
- // install the app externally
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(
- getTestAppFilePath(VERSATILE_LOC_EXTERNAL_APK), VERSATILE_LOC_PKG, false);
- mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
- // then replace the app with one marked for internalOnly
- mPMHostUtils.installAppAndVerifyExistsOnDevice(
- getTestAppFilePath(VERSATILE_LOC_INTERNAL_APK), VERSATILE_LOC_PKG, false);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(VERSATILE_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that updating an app on the SD card will
- * install the update onto the SD card as well when location is set to
- * external for both versions
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testUpdateBothExternal() throws Exception {
- Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
-
- try {
- // install the app externally
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- EXTERNAL_LOC_VERSION_V1_APK), EXTERNAL_LOC_VERSION_PKG, false);
- // now replace the app with one where the location is still set to
- // preferExternal
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- EXTERNAL_LOC_VERSION_V2_APK), EXTERNAL_LOC_VERSION_PKG, true);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(EXTERNAL_LOC_VERSION_PKG);
- }
- }
-
- /**
- * Regression test to verify that updating an app on the SD card will
- * install the update onto the SD card as well when location is not
- * explicitly set in the updated apps' manifest file.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testUpdateToSDCard() throws Exception {
- Log.i(LOG_TAG, "Test updating an app on the SD card stays on the SD card");
-
- try {
- // install the app externally
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- UPDATE_EXTERNAL_LOC_V1_EXT_APK), UPDATE_EXTERNAL_LOC_PKG, false);
- // now replace the app with one where the location is blank (app
- // should stay external)
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- UPDATE_EXTERNAL_LOC_V2_NONE_APK), UPDATE_EXTERNAL_LOC_PKG, true);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(UPDATE_EXTERNAL_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that updating an app on the SD card will
- * install the update onto the device if the manifest has changed to
- * installLocation=internalOnly
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testUpdateSDCardToDevice() throws Exception {
- Log.i(LOG_TAG, "Test updating an app on the SD card to the Device through manifest change");
-
- try {
- // install the app externally
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- UPDATE_EXT_TO_INT_LOC_V1_EXT_APK), UPDATE_EXT_TO_INT_LOC_PKG, false);
- // now replace the app with an update marked for
- // internalOnly...(should move internal)
- mPMHostUtils.installAppAndVerifyExistsOnDevice(getTestAppFilePath(
- UPDATE_EXT_TO_INT_LOC_V2_INT_APK), UPDATE_EXT_TO_INT_LOC_PKG, true);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(UPDATE_EXT_TO_INT_LOC_PKG);
- }
- }
-
- /**
- * Regression test to verify that installing and updating a forward-locked
- * app will install the update onto the device's forward-locked location
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAndUpdateExternalLocForwardLockedApp() throws Exception {
- Log.i(LOG_TAG, "Test updating a forward-locked app marked preferExternal");
-
- try {
- // first try to install the forward-locked app externally
- mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
- EXTERNAL_LOC_VERSION_V1_APK), EXTERNAL_LOC_VERSION_PKG, false);
- // now replace the app with an update marked for internalOnly and as
- // forward locked
- mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
- EXTERNAL_LOC_VERSION_V2_APK), EXTERNAL_LOC_VERSION_PKG, true);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(EXTERNAL_LOC_VERSION_PKG);
- }
- }
-
- /**
- * Regression test to verify that updating a forward-locked app will install
- * the update onto the device's forward-locked location
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAndUpdateNoLocForwardLockedApp() throws Exception {
- Log.i(LOG_TAG, "Test updating a forward-locked app with no installLocation pref set");
-
- try {
- // install the app
- mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
- NO_LOC_VERSION_V1_APK), NO_LOC_VERSION_PKG, false);
- // now replace the app with an update marked for internalOnly...
- mPMHostUtils.installFwdLockedAppAndVerifyExists(getTestAppFilePath(
- NO_LOC_VERSION_V2_APK), NO_LOC_VERSION_PKG, true);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(NO_LOC_VERSION_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with all permissions set can be
- * installed on SD card and then launched without crashing.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAndLaunchAllPermsAppOnSD() throws Exception {
- Log.i(LOG_TAG, "Test launching an app with all perms set, installed on SD card");
-
- try {
- // install the app
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- ALL_PERMS_APK), ALL_PERMS_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(ALL_PERMS_PKG);
- assert (testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(ALL_PERMS_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with ACCESS_FINE_LOCATION (GPS)
- * permissions can run without permissions errors.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAndLaunchFLPermsAppOnSD() throws Exception {
- Log.i(LOG_TAG, "Test launching an app with location perms set, installed on SD card");
-
- try {
- // install the app and verify we can launch it without permissions
- // errors
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_FL_PKG);
- assert (testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with BLUE_TOOTH permissions can run
- * without permissions errors.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAndLaunchBTPermsAppOnSD() throws Exception {
- Log.i(LOG_TAG, "Test launching an app with bluetooth perms set, installed on SD card");
-
- try {
- // install the app and verify we can launch it without permissions
- // errors
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_BT_APK), SHARED_PERMS_BT_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_BT_PKG);
- assert (testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
- }
- }
-
- /**
- * Regression test to verify that a shared app with no explicit permissions
- * throws a SecurityException when launched if its other shared apps are not
- * installed.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAndLaunchSharedPermsAppOnSD_NoPerms() throws Exception {
- Log.i(LOG_TAG, "Test launching an app with no explicit perms set, installed on SD card");
-
- try {
- // Make sure the 2 shared apps with needed permissions are not
- // installed...
- mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
- mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
-
- // now install the app and see if when we launch it we get a
- // permissions error
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_APK), SHARED_PERMS_PKG, false);
-
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
- assertEquals("Shared perms app should fail to run", false, testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_PKG);
- }
- }
-
- /**
- * Regression test to verify that a shared app with no explicit permissions
- * can run if its other shared apps are installed.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAndLaunchSharedPermsAppOnSD_GrantedPerms() throws Exception {
- Log.i(LOG_TAG, "Test launching an app with no explicit perms set, installed on SD card");
-
- try {
- // install the 2 shared apps with needed permissions first
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_BT_APK), SHARED_PERMS_BT_PKG, false);
-
- // now install the test app and see if we can launch it without
- // errors
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_APK), SHARED_PERMS_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
- assert (testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_PKG);
- mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
- mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
- }
- }
-
- /**
- * Regression test to verify that an app with ACCESS_FINE_LOCATION (GPS)
- * permissions can run without permissions errors even after a reboot
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAndLaunchFLPermsAppOnSD_Reboot() throws Exception {
- Log.i(LOG_TAG, "Test launching an app with location perms set, installed on SD card");
-
- try {
- // install the app and verify we can launch it without permissions
- // errors
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_FL_PKG);
- assert (testsPassed);
-
- getDevice().reboot();
-
- testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_FL_PKG);
- assert (testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
- }
- }
-
- /**
- * Regression test to verify that a shared app with no explicit permissions
- * can run if its other shared apps are installed, even after a reboot.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallAndLaunchSharedPermsAppOnSD_Reboot() throws Exception {
- Log.i(LOG_TAG, "Test launching an app on SD, with no explicit perms set after reboot");
-
- try {
- // install the 2 shared apps with needed permissions first
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_FL_APK), SHARED_PERMS_FL_PKG, false);
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_BT_APK), SHARED_PERMS_BT_PKG, false);
-
- // now install the test app and see if we can launch it without
- // errors
- mPMHostUtils.installAppAndVerifyExistsOnSDCard(getTestAppFilePath(
- SHARED_PERMS_APK), SHARED_PERMS_PKG, false);
- boolean testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
- assert (testsPassed);
-
- // reboot
- getDevice().reboot();
-
- // Verify we can still launch the app
- testsPassed = mPMHostUtils.runDeviceTestsDidAllTestsPass(SHARED_PERMS_PKG);
- assert (testsPassed);
- }
- // cleanup test app
- finally {
- mPMHostUtils.uninstallApp(SHARED_PERMS_PKG);
- mPMHostUtils.uninstallApp(SHARED_PERMS_BT_PKG);
- mPMHostUtils.uninstallApp(SHARED_PERMS_FL_PKG);
- }
- }
-
- public void testInstallApk32bit() throws DeviceNotAvailableException {
- try {
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_32), true);
- assertEquals(ARMEABI_V7A, mPMHostUtils.getAbi(SHARED_UID_PKG_32));
- } finally {
- mPMHostUtils.uninstallApp(SHARED_UID_PKG_32);
- }
-
- }
-
- public void testInstallApk64bit() throws DeviceNotAvailableException {
- try {
- if (!ARM64_V8A.equals(getDevice().getProperty(ABI_PROPERTY))) {
- return;
- }
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_64), true);
- assertEquals(ARM64_V8A, mPMHostUtils.getAbi(SHARED_UID_PKG_64));
- } finally {
- mPMHostUtils.uninstallApp(SHARED_UID_PKG_64);
- }
-
- }
-
- public void testInstallApkDualAbi() throws DeviceNotAvailableException {
- try {
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_DUAL), true);
- assertEquals(getDevice().getProperty(ABI_PROPERTY),
- mPMHostUtils.getAbi(SHARED_UID_PKG_DUAL));
- } finally {
- mPMHostUtils.uninstallApp(SHARED_UID_PKG_DUAL);
- }
- }
-
- public void testInstallSharedUid32() throws DeviceNotAvailableException {
- try{
- if (!ARMEABI_V7A.equals(getDevice().getProperty(ABI_PROPERTY))) {
- return;
- }
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK), true);
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_32), true);
- assertEquals(mPMHostUtils.getUid(SHARED_UID_PKG),
- mPMHostUtils.getUid(SHARED_UID_PKG_32));
- } finally {
- mPMHostUtils.uninstallApp(SHARED_UID_PKG);
- mPMHostUtils.uninstallApp(SHARED_UID_PKG_32);
- }
- }
-
- public void testInstallSharedUid64() throws DeviceNotAvailableException {
- try{
- if (!ARM64_V8A.equals(getDevice().getProperty(ABI_PROPERTY))) {
- return;
- }
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK), true);
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_64), true);
- assertEquals(mPMHostUtils.getUid(SHARED_UID_PKG),
- mPMHostUtils.getUid(SHARED_UID_PKG_64));
- } finally {
- mPMHostUtils.uninstallApp(SHARED_UID_PKG);
- mPMHostUtils.uninstallApp(SHARED_UID_PKG_64);
- }
- }
-
- public void testInstallSharedUidDual64() throws DeviceNotAvailableException {
- try{
- if (!ARM64_V8A.equals(getDevice().getProperty(ABI_PROPERTY))) {
- return;
- }
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_DUAL), true);
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_64), true);
- assertEquals(mPMHostUtils.getUid(SHARED_UID_PKG_DUAL),
- mPMHostUtils.getUid(SHARED_UID_PKG_64));
- } finally {
- mPMHostUtils.uninstallApp(SHARED_UID_PKG_DUAL);
- mPMHostUtils.uninstallApp(SHARED_UID_PKG_64);
- }
- }
-
- public void testInstallSharedUidDual32() throws DeviceNotAvailableException {
- try{
- if (!ARMEABI_V7A.equals(getDevice().getProperty(ABI_PROPERTY))) {
- return;
- }
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_DUAL), true);
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_32), true);
- assertEquals(mPMHostUtils.getUid(SHARED_UID_PKG_DUAL),
- mPMHostUtils.getUid(SHARED_UID_PKG_32));
- } finally {
- mPMHostUtils.uninstallApp(SHARED_UID_PKG_DUAL);
- mPMHostUtils.uninstallApp(SHARED_UID_PKG_32);
- }
- }
-
- public void testInstallSharedUidJavaDual() throws DeviceNotAvailableException {
- try{
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK_DUAL), true);
- mPMHostUtils.installFile(getTestAppFilePath(SHARED_UID_APK), true);
- assertEquals(mPMHostUtils.getUid(SHARED_UID_PKG_DUAL),
- mPMHostUtils.getUid(SHARED_UID_PKG));
- } finally {
- mPMHostUtils.uninstallApp(SHARED_UID_PKG_DUAL);
- mPMHostUtils.uninstallApp(SHARED_UID_PKG);
- }
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PackageManagerOTATestUtils.java b/prod-tests/src/com/android/framework/tests/PackageManagerOTATestUtils.java
deleted file mode 100644
index 9de3577..0000000
--- a/prod-tests/src/com/android/framework/tests/PackageManagerOTATestUtils.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * Copyright (C) 2012 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.framework.tests;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-
-import org.junit.Assert;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import java.io.File;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpression;
-import javax.xml.xpath.XPathFactory;
-/**
- * Utility method used for PackageMangerOTATests. Requires adb root.
- */
-public class PackageManagerOTATestUtils {
- public static final String USERDATA_PARTITION = "userdata";
- public static final String PACKAGE_XML_FILE = "/data/system/packages.xml";
-
- private ITestDevice mDevice = null;
-
- /**
- * Constructor.
- *
- * @param device the {@link ITestDevice} to use when performing operations.
- * @throws DeviceNotAvailableException
- */
- public PackageManagerOTATestUtils(ITestDevice device)
- throws DeviceNotAvailableException {
- mDevice = device;
- }
-
- /**
- * Wipe userdata partition on device.
- *
- * @throws DeviceNotAvailableException
- */
- public void wipeDevice() throws DeviceNotAvailableException {
- // Make sure to keep the local.prop file for testing purposes.
- File prop = mDevice.pullFile("/data/local.prop");
- mDevice.rebootIntoBootloader();
- mDevice.fastbootWipePartition(USERDATA_PARTITION);
- mDevice.rebootUntilOnline();
- if (prop != null) {
- mDevice.pushFile(prop, "/data/local.prop");
- mDevice.executeShellCommand("chmod 644 /data/local.prop");
- mDevice.reboot();
- }
- }
-
- /**
- * Remove a system app.
- * @param systemApp {@link String} name for the application in the /system/app folder
- * @param reboot set to <code>true</code> to optionally reboot device after app removal
- *
- * @throws DeviceNotAvailableException
- */
- public void removeSystemApp(String systemApp, boolean reboot)
- throws DeviceNotAvailableException {
- mDevice.remountSystemWritable();
- String cmd = String.format("rm %s", systemApp);
- mDevice.executeShellCommand(cmd);
- if (reboot) {
- mDevice.reboot();
- }
- mDevice.waitForDeviceAvailable();
- }
-
- /**
- * Remove a system app and wipe the device.
- * @param systemApp {@link String} name for the application in the /system/app folder
- *
- * @throws DeviceNotAvailableException
- */
- public void removeAndWipe(String systemApp)
- throws DeviceNotAvailableException {
- removeSystemApp(systemApp, false);
- wipeDevice();
- }
-
- /**
- * Expect that a given xpath exists in a given xml file.
- * @param xmlFile {@link File} xml file to process
- * @param xPathString {@link String} Xpath to look for
- *
- * @return true if the xpath is found
- */
- public boolean expectExists(File xmlFile, String xPathString) {
- Node n = getNodeForXPath(xmlFile, xPathString);
- if (n != null) {
- CLog.d("Found node %s for xpath %s", n.getNodeName(), xPathString);
- return true;
- }
- return false;
- }
-
- /**
- * Expect that the value of a given xpath starts with a given string.
- *
- * @param xmlFile {@link File} the xml file in question
- * @param xPathString {@link String} the xpath to look for
- * @param value {@link String} the expected start string of the xpath
- *
- * @return true if the value for the xpath starts with value, false otherwise
- */
- public boolean expectStartsWith(File xmlFile, String xPathString, String value) {
- Node n = getNodeForXPath(xmlFile, xPathString);
- if ( n==null ) {
- CLog.d("Failed to find node for xpath %s", xPathString);
- return false;
- }
- CLog.d("Value of node %s: %s", xPathString, n.getNodeValue());
- return n.getNodeValue().toLowerCase().startsWith(value.toLowerCase());
- }
-
- /**
- * Expect that the value of a given xpath matches.
- *
- * @param xmlFile {@link File} the xml file in question
- * @param xPathString {@link String} the xpath to look for
- * @param value {@link String} the expected string value
- *
- * @return true if the value for the xpath matches, false otherwise
- */
- public boolean expectEquals(File xmlFile, String xPathString, String value) {
- Node n = getNodeForXPath(xmlFile, xPathString);
- if ( n==null ) {
- CLog.d("Failed to find node for xpath %s", xPathString);
- return false;
- }
- boolean result = n.getNodeValue().equalsIgnoreCase(value);
- if (!result) {
- CLog.v("Value of node %s: \"%s\", expected: \"%s\"",
- xPathString, n.getNodeValue(), value);
- }
- return result;
- }
-
- public Node getNodeForXPath(File xmlFile, String xPathString) {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- try {
- DocumentBuilder documentBuilder = factory.newDocumentBuilder();
- Document doc = documentBuilder.parse(xmlFile);
- XPathFactory xpFactory = XPathFactory.newInstance();
- XPath xpath = xpFactory.newXPath();
- XPathExpression expr = xpath.compile(xPathString);
- Node node = (Node) expr.evaluate(doc, XPathConstants.NODE);
- return node;
- } catch (Exception e) {
- CLog.e(e);
- }
- return null;
- }
-
- /**
- * Check if a given package has the said permission.
- * @param packageName {@link String} the package in question
- * @param permission {@link String} the permission to look for
- *
- * @return true if the permission exists, false otherwise
- *
- * @throws DeviceNotAvailableException
- */
- public boolean packageHasPermission(String packageName, String permission)
- throws DeviceNotAvailableException {
- String cmd = "dumpsys package " + packageName;
- String res = mDevice.executeShellCommand(cmd);
- if (res != null) {
- if (res.contains("grantedPermissions:")) {
- return res.contains(permission);
- } else {
- Pattern perm = Pattern.compile(String.format("^.*%s.*granted=true.*$", permission),
- Pattern.MULTILINE);
- Matcher m = perm.matcher(res);
- return m.find();
- }
- }
- CLog.d("Failed to execute shell command: %s", cmd);
- return false;
- }
-
- /**
- * Check if a given package has the said permission.
- * @param packageName {@link String} the package in question
- * @param flag {@link String} the permission to look for
- *
- * @return true if the permission exists, false otherwise
- *
- * @throws DeviceNotAvailableException
- */
- public boolean packageHasFlag(String packageName, String flag)
- throws DeviceNotAvailableException {
- String cmd = "dumpsys package " + packageName;
- String res = mDevice.executeShellCommand(cmd);
- if (res != null) {
- Pattern flags = Pattern.compile("^.*flags=\\[(.*?)\\]$", Pattern.MULTILINE);
- Matcher m = flags.matcher(res);
- if (m.find()) {
- return m.group(1).contains(flag);
- } else {
- CLog.d("Failed to find package flags record in dumpsys package output");
- }
- }
- CLog.d("Failed to execute shell command: %s", cmd);
- return false;
- }
-
- /**
- * Helper method to install a file
- *
- * @param localFile the {@link File} to install
- * @param replace set to <code>true</code> if re-install of app should be performed
- * @param extraArgs optional extra arguments to pass. See 'adb shell pm install --help' for
- * available options.
- *
- * @throws DeviceNotAvailableException
- */
- public void installFile(final File localFile, final boolean replace, String... extraArgs)
- throws DeviceNotAvailableException {
- String result = mDevice.installPackage(localFile, replace, extraArgs);
- Assert.assertNull(String.format("Failed to install file %s with result %s",
- localFile.getAbsolutePath(), result), result);
- }
-
- /**
- * Helper method to stop system shell.
- *
- * @throws DeviceNotAvailableException
- */
- public void stopSystem() throws DeviceNotAvailableException {
- mDevice.executeShellCommand("stop");
- }
-
- /**
- * Helper method to start system shell. It also reset the flag dev.bootcomplete to 0 to ensure
- * that the package manager had a chance to finish.
- *
- * @throws DeviceNotAvailableException
- */
- public void startSystem() throws DeviceNotAvailableException {
- mDevice.executeShellCommand("setprop dev.bootcomplete 0");
- mDevice.executeShellCommand("start");
- mDevice.waitForDeviceAvailable();
- }
-
- /**
- * Convenience method to stop, then start the runtime.
- *
- * @throws DeviceNotAvailableException
- */
- public void restartSystem() throws DeviceNotAvailableException {
- stopSystem();
- startSystem();
- }
-
- /**
- * Push apk to system app directory on the device.
- *
- * @param localFile {@link File} the local file to install
- * @param deviceFilePath {@link String} the remote device path where to install the application
- *
- * @throws DeviceNotAvailableException
- */
- public void pushSystemApp(final File localFile, final String deviceFilePath)
- throws DeviceNotAvailableException {
- mDevice.remountSystemWritable();
- stopSystem();
- mDevice.pushFile(localFile, deviceFilePath);
- startSystem();
- }
-
- /**
- * Pulls packages xml file from the device.
- * @return {@link File} xml file for all packages on device.
- *
- * @throws DeviceNotAvailableException
- */
- public File pullPackagesXML() throws DeviceNotAvailableException {
- return mDevice.pullFile(PACKAGE_XML_FILE);
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PackageManagerOTATests.java b/prod-tests/src/com/android/framework/tests/PackageManagerOTATests.java
deleted file mode 100644
index 4911ba5..0000000
--- a/prod-tests/src/com/android/framework/tests/PackageManagerOTATests.java
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * Copyright (C) 2012 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.framework.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.util.FileUtil;
-
-import java.io.File;
-
-public class PackageManagerOTATests extends DeviceTestCase {
-
- @Option(name = "test-app-path", description =
- "path to the app repository containing test apks", importance = Importance.IF_UNSET)
- private File mTestAppRepositoryPath = null;
- @Option(name = "use-priv-path", description =
- "set to true if the special priviledged app directory should be used; default is false",
- importance = Importance.IF_UNSET)
- private boolean mUsePrivAppDirectory = false;
-
- private PackageManagerOTATestUtils mUtils = null;
- private String mSystemAppPath = "/system/app/version_test.apk";
- private String mDiffSystemAppPath = "/system/app/version_test_diff.apk";
-
- // String constants use for the tests.
- private static final String PACKAGE_XPATH = "/packages/package[@name=\"" +
- "com.android.frameworks.coretests.version_test\"]";
- private static final String UPDATE_PACKAGE_XPATH = "/packages/updated-package[@name=\"" +
- "com.android.frameworks.coretests.version_test\"]";
- private static final String VERSION_XPATH = "/packages/package[@name=\"" +
- "com.android.frameworks.coretests.version_test\"]/@version";
- private static final String CODE_PATH_XPATH = "/packages/package[@name=\"" +
- "com.android.frameworks.coretests.version_test\"]/@codePath";
- private static final String VERSION_1_APK = "FrameworkCoreTests_version_1.apk";
- private static final String VERSION_2_APK = "FrameworkCoreTests_version_2.apk";
- private static final String VERSION_3_APK = "FrameworkCoreTests_version_3.apk";
- private static final String VERSION_1_NO_SYS_PERMISSION_APK =
- "FrameworkCoreTests_version_1_nosys.apk";
- private static final String DATA_APP_DIRECTORY = "/data/app/";
- private static final String PACKAGE_NAME = "com.android.frameworks.coretests.version_test";
- private static final String VIBRATE_PERMISSION = "android.permission.VIBRATE";
- private static final String CACHE_PERMISSION = "android.permission.ACCESS_CACHE_FILESYSTEM";
-
-
- // Temporary file used when examine the packages xml file from the device.
- private File mPackageXml = null;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- mUtils = new PackageManagerOTATestUtils(getDevice());
-
- if (mUsePrivAppDirectory) {
- mSystemAppPath = "/system/priv-app/version_test.apk";
- mDiffSystemAppPath = "/system/priv-app/version_test_diff.apk";
- }
-
- // Clean up any potential old files from previous tests.
- // delete from /system if exists
- getDevice().enableAdbRoot();
- mUtils.removeSystemApp(mSystemAppPath, false);
- mUtils.removeSystemApp(mDiffSystemAppPath, false);
- mUtils.restartSystem();
- // delete from /data if there is one
- getDevice().uninstallPackage(PACKAGE_NAME);
-
- String res = getDevice().executeShellCommand("pm path " + PACKAGE_NAME).trim();
- assertTrue("Package should not be installed before test", res.isEmpty());
- }
-
- @Override
- protected void tearDown() throws Exception {
- // Clean up.
- if (mPackageXml != null) {
- FileUtil.deleteFile(mPackageXml);
- }
- }
-
- /**
- * Get the absolute file system location of test app with given filename
- *
- * @param fileName the file name of the test app apk
- * @return {@link String} of absolute file path
- */
- public File getTestAppFilePath(String fileName) {
- // need to check both data/app/apkFileName and
- // data/app/apkFileName/apkFileName
- File file = FileUtil.getFileForPath(mTestAppRepositoryPath, fileName);
- if (file.exists()) {
- return file;
- }
-
- int index = fileName.lastIndexOf('.');
- String dir = fileName.substring(0, index);
- file = FileUtil.getFileForPath(mTestAppRepositoryPath, dir, fileName);
- CLog.d("Test path : %s", file.getAbsolutePath());
- return file;
- }
-
- /**
- * Test case when system app added is newer than update.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @throws DeviceNotAvailableException
- */
- public void testSystemAppAddedNewerThanUpdate() throws DeviceNotAvailableException {
- mUtils.installFile(getTestAppFilePath(VERSION_1_APK), true);
- mPackageXml = mUtils.pullPackagesXML();
- assertNotNull("Failed to pull packages xml file from device", mPackageXml);
- assertTrue("Initial package should be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertTrue("Package version should be 1",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "1"));
- assertFalse("Updated-package should not be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertFalse("Package should not have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertFalse("ACCESS_CACHE_FILESYSTEM permission should NOT be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.pushSystemApp(getTestAppFilePath(VERSION_2_APK), mSystemAppPath);
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("After system app push, package should still be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertTrue("After system app push, system app should be visible",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
- assertFalse("Updated-package should not be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
- }
-
- /**
- * Test case when system app added is older than update.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @throws DeviceNotAvailableException
- */
- public void testSystemAppAddedOlderThanUpdate() throws DeviceNotAvailableException {
- mUtils.installFile(getTestAppFilePath(VERSION_2_APK), true);
- mPackageXml = mUtils.pullPackagesXML();
- assertNotNull("Failed to pull packages xml file from device", mPackageXml);
- assertTrue("Initial package should be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertTrue("Package version should be 2",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
- assertFalse("Updated-package should not be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertFalse("Package should not have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertFalse("ACCESS_CACHE_FILESYSTEM permission should NOT be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.pushSystemApp(getTestAppFilePath(VERSION_1_APK), mSystemAppPath);
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("After system app push, package should still be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertTrue("After system app push, system app should be visible",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
- assertTrue("Updated-package should be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
- }
-
- /**
- * Test when system app gets removed.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @throws DeviceNotAvailableException
- */
- public void testSystemAppRemoved() throws DeviceNotAvailableException {
- mUtils.pushSystemApp(getTestAppFilePath(VERSION_1_APK), mSystemAppPath);
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("Initial package should be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertFalse("Updated-package should not be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- mUtils.removeSystemApp(mSystemAppPath, true);
- mPackageXml = mUtils.pullPackagesXML();
- assertFalse("Package should not be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertFalse("Updated-package should not be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- }
-
- /**
- * Test when update has a newer version.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @throws DeviceNotAvailableException
- */
- public void testSystemAppUpdatedNewerVersion() throws DeviceNotAvailableException {
- mUtils.pushSystemApp(getTestAppFilePath(VERSION_2_APK), mSystemAppPath);
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("The package should be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertTrue("Package version should be 2",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
- assertFalse("Updated-package should not be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.installFile(getTestAppFilePath(VERSION_3_APK), true);
- mPackageXml = mUtils.pullPackagesXML();
- assertFalse("After system app upgrade, the path should be the upgraded app on /data",
- mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
- assertTrue("Package version should be 3",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
- assertTrue("Updated-package should be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.restartSystem();
- mPackageXml = mUtils.pullPackagesXML();
- assertFalse("After system app upgrade, the path should be the upgraded app on /data",
- mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
- assertTrue("Package version should be 3",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
- assertTrue("Updated-package should be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.restartSystem();
- mPackageXml = mUtils.pullPackagesXML();
- assertFalse("After system app upgrade, the path should be the upgraded app on /data",
- mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
- assertTrue("Package version should be 3",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
- assertTrue("Updated-package should be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
- }
-
- /**
- * Test when update has an older version.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @throws DeviceNotAvailableException
- */
- public void testSystemAppUpdatedOlderVersion() throws DeviceNotAvailableException {
- mUtils.pushSystemApp(getTestAppFilePath(VERSION_2_APK), mSystemAppPath);
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("After system app push, the package should be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertTrue("Package version should be 2",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
- assertFalse("Updated-package should not be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- // The "-d" command forces a downgrade.
- mUtils.installFile(getTestAppFilePath(VERSION_1_APK), true, "-d");
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("After system app upgrade, the path should be the upgraded app on /data",
- mUtils.expectStartsWith(mPackageXml, CODE_PATH_XPATH,
- DATA_APP_DIRECTORY + PACKAGE_NAME));
- assertTrue("Package version should be 1",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "1"));
- assertTrue("Updated-package should be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.restartSystem();
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("After reboot, the path should be the be installed",
- mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
- assertTrue("Package version should be 2",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
- assertFalse("Updated-package should NOT be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.restartSystem();
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("After reboot, the path should be the be installed",
- mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
- assertTrue("Package version should be 2",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
- assertFalse("Updated-package should NOT be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
- }
-
- /**
- * Test when updated system app has the same version. Package manager is expected to use
- * the newly installed upgrade.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @throws DeviceNotAvailableException
- */
- public void testSystemAppUpdatedSameVersion_PreferUpdatedApk()
- throws DeviceNotAvailableException {
- mUtils.pushSystemApp(getTestAppFilePath(VERSION_2_APK), mSystemAppPath);
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("The package should be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertTrue("Package version should be 2",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
- assertFalse("Updated-package should not be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.installFile(getTestAppFilePath(VERSION_2_APK), true);
- mPackageXml = mUtils.pullPackagesXML();
- assertFalse("After system app upgrade, the path should be the upgraded app in /data",
- mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
- assertTrue("Package version should be 2",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
- assertTrue("Updated-package should be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.restartSystem();
- mPackageXml = mUtils.pullPackagesXML();
- assertFalse("After reboot, the path should be the upgraded app in /data",
- mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
- assertTrue("Package version should be 2",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "2"));
- assertTrue("Updated-package should be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- }
-
- /**
- * Test when update has system app removed.
- * <p/>
- * Assumes adb is running as root in device under test.
- *
- * @throws DeviceNotAvailableException
- */
- public void testUpdatedSystemAppRemoved() throws DeviceNotAvailableException {
- mUtils.pushSystemApp(getTestAppFilePath(VERSION_1_APK), mSystemAppPath);
- mUtils.installFile(getTestAppFilePath(VERSION_2_APK), true);
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("Package should be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertTrue("Updated-package should be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.removeSystemApp(mSystemAppPath, true);
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("Package should still be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertFalse("Updated-package entry should not be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertFalse("Package should not have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertFalse("ACCESS_CACHE_FILESYSTEM permission should NOT be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
- }
-
- /**
- * Test when system app is updated with a new permission. Specifically:
- * <ol>
- * <li>system app FOO is present, does not declare system permission</li>
- * <li>FOO is overlain by an installed update that declares new permission</li>
- * <li>FOO is replaced during an OTA, but installed update still has higher version number</li>
- * <li>Verify permission is granted</li>
- * </ol>
- *
- * @throws DeviceNotAvailableException
- */
- public void testSystemAppUpdatedNewPermission() throws DeviceNotAvailableException {
- mUtils.pushSystemApp(getTestAppFilePath(VERSION_1_NO_SYS_PERMISSION_APK), mSystemAppPath);
- mPackageXml = mUtils.pullPackagesXML();
- assertTrue("The package should be installed",
- mUtils.expectExists(mPackageXml, PACKAGE_XPATH));
- assertTrue("Package version should be 1",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "1"));
- assertFalse("Updated-package should not be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertFalse("ACCESS_CACHE_FILESYSTEM permission should NOT be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.installFile(getTestAppFilePath(VERSION_3_APK), true);
- mPackageXml = mUtils.pullPackagesXML();
- assertFalse("After system app upgrade, the path should be the upgraded app on /data",
- mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
- assertTrue("Package version should be 3",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
- assertTrue("Updated-package should be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertFalse("ACCESS_CACHE_FILESYSTEM permission should NOT be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.pushSystemApp(getTestAppFilePath(VERSION_2_APK), mSystemAppPath);
- mUtils.restartSystem();
- mPackageXml = mUtils.pullPackagesXML();
- assertFalse("After reboot, the path should be the data app",
- mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
- assertTrue("Package version should be 3",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
- assertTrue("Updated-package should be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
-
- mUtils.restartSystem();
- mPackageXml = mUtils.pullPackagesXML();
- assertFalse("After reboot, the path should be the data app",
- mUtils.expectEquals(mPackageXml, CODE_PATH_XPATH, mSystemAppPath));
- assertTrue("Package version should be 3",
- mUtils.expectEquals(mPackageXml, VERSION_XPATH, "3"));
- assertTrue("Updated-package should be present",
- mUtils.expectExists(mPackageXml, UPDATE_PACKAGE_XPATH));
- assertTrue("Package should have FLAG_SYSTEM",
- mUtils.packageHasFlag(PACKAGE_NAME, " SYSTEM "));
- assertTrue("VIBRATE permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, VIBRATE_PERMISSION));
- assertTrue("ACCESS_CACHE_FILESYSTEM permission should be granted",
- mUtils.packageHasPermission(PACKAGE_NAME, CACHE_PERMISSION));
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PackageManagerStressHostTests.java b/prod-tests/src/com/android/framework/tests/PackageManagerStressHostTests.java
deleted file mode 100644
index b02663b..0000000
--- a/prod-tests/src/com/android/framework/tests/PackageManagerStressHostTests.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2010 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.framework.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.testtype.DeviceTestCase;
-import com.android.tradefed.util.FileUtil;
-
-import java.io.File;
-
-/**
- * Set of tests that verify host side stress scenarios (large apps, multiple upgrades, etc.)
- */
-public class PackageManagerStressHostTests extends DeviceTestCase {
-
- private PackageManagerHostTestUtils mPMHostUtils = null;
-
- // Path to the app repository and various subdirectories of it
- // Note: These stress tests require large apks that cannot be checked into the tree.
- // These variables define static locations that point to existing APKs (not built from
- // the tree) which can be used by the stress tests in this file.
- private static final String LARGE_APPS_DIRECTORY_NAME = "largeApps";
- private static final String MISC_APPS_DIRECTORY_NAME = "miscApps";
- private static final String VERSIONED_APPS_DIRECTORY_NAME = "versionedApps";
- private static final String MANY_APPS_DIRECTORY_NAME = "manyApps";
-
- // Large apps (>1mb) - filenames and their corresponding package names:
- private static enum APK {
- FILENAME,
- PACKAGENAME;
- }
- private static final String[][] LARGE_APPS = {
- {"External1mb.apk", "com.appsonsd.mytests.External1mb"},
- {"External2mb.apk", "com.appsonsd.mytests.External2mb"},
- {"External3mb.apk", "com.appsonsd.mytests.External3mb"},
- {"External4mb.apk", "com.appsonsd.mytests.External4mb"},
- {"External5mb.apk", "com.appsonsd.mytests.External5mb"},
- {"External6mb.apk", "com.appsonsd.mytests.External6mb"},
- {"External7mb.apk", "com.appsonsd.mytests.External7mb"},
- {"External8mb.apk", "com.appsonsd.mytests.External8mb"},
- {"External9mb.apk", "com.appsonsd.mytests.External9mb"},
- {"External10mb.apk", "com.appsonsd.mytests.External10mb"},
- {"External16mb.apk", "com.appsonsd.mytests.External16mb"},
- {"External28mb.apk", "com.appsonsd.mytests.External28mb"},
- {"External34mb.apk", "com.appsonsd.mytests.External34mb"},
- {"External46mb.apk", "com.appsonsd.mytests.External46mb"},
- {"External58mb.apk", "com.appsonsd.mytests.External58mb"},
- {"External65mb.apk", "com.appsonsd.mytests.External65mb"},
- {"External72mb.apk", "com.appsonsd.mytests.External72mb"},
- {"External79mb.apk", "com.appsonsd.mytests.External79mb"},
- {"External86mb.apk", "com.appsonsd.mytests.External86mb"},
- {"External93mb.apk", "com.appsonsd.mytests.External93mb"}};
-
- // Various test files and their corresponding package names
- private static final String EXTERNAL_LOC_APK = "External931kb.apk";
- private static final String EXTERNAL_LOC_PKG = "com.appsonsd.mytests.External931kb";
-
- // Versioned test apps
- private static final String VERSIONED_APPS_FILENAME_PREFIX = "External455kb_v";
- private static final String VERSIONED_APPS_PKG = "com.appsonsd.mytests.External455kb";
- private static final int VERSIONED_APPS_START_VERSION = 1; // inclusive
- private static final int VERSIONED_APPS_END_VERSION = 250; // inclusive
-
- // Large number of app installs
- // @TODO: increase the max when we can install more apps
- private static final int MANY_APPS_START = 1;
- private static final int MANY_APPS_END = 100;
- private static final String MANY_APPS_PKG_PREFIX = "com.appsonsd.mytests.External49kb_";
- private static final String MANY_APPS_APK_PREFIX = "External49kb_";
- private static final int DEFAULT_ITERATION_COUNT = 100;
-
- @Option(name = "app-repository-path", description =
- "path to the app repository containing large apks.", importance = Importance.IF_UNSET)
- private File mAppRepositoryPath = null;
-
- @Option(name = "stress-iteration-count", description =
- "Number of iterations to run the package manager stress test for.",
- importance = Importance.IF_UNSET)
- private int mIterationCount = DEFAULT_ITERATION_COUNT;
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- // setup the PackageManager host tests utilities class, and get various paths we'll need...
- mPMHostUtils = new PackageManagerHostTestUtils(getDevice());
- // ensure apk path has been set before test is run
- assertNotNull("Missing --app-repository-path option", mAppRepositoryPath);
- }
-
- /**
- * Get the {@link File} of repository test app with given filename
- * @param fileName the file name of the test app apk
- * @return {@link File}
- */
- private File getRepositoryTestAppFilePath(String fileDirectory, String fileName) {
- return FileUtil.getFileForPath(mAppRepositoryPath, fileDirectory, fileName);
- }
-
- /**
- * Stress test to verify that we can update an app multiple times on the SD card.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testUpdateAppManyTimesOnSD() throws Exception {
- CLog.i("Test updating an app on SD numerous times");
- // cleanup test app just in case it already exists
- mPMHostUtils.uninstallApp(VERSIONED_APPS_PKG);
- try {
- for (int i = VERSIONED_APPS_START_VERSION; i <= VERSIONED_APPS_END_VERSION; ++i) {
- String currentApkName = String.format("%s%d.apk",
- VERSIONED_APPS_FILENAME_PREFIX, i);
- CLog.i("Installing app " + currentApkName);
- mPMHostUtils.installFile(getRepositoryTestAppFilePath(VERSIONED_APPS_DIRECTORY_NAME,
- currentApkName), true);
- mPMHostUtils.waitForPackageManager();
- assertTrue(mPMHostUtils.doesAppExistOnSDCard(VERSIONED_APPS_PKG));
- assertTrue(mPMHostUtils.doesPackageExist(VERSIONED_APPS_PKG));
- }
- }
- finally {
- // cleanup test app
- mPMHostUtils.uninstallApp(VERSIONED_APPS_PKG);
- }
- }
-
- /**
- * Stress test to verify that an app can be installed, uninstalled, and
- * reinstalled on SD many times.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testUninstallReinstallAppOnSDManyTimes() throws Exception {
- CLog.i("Test updating an app on the SD card stays on the SD card");
- // cleanup test app just in case it was already exists
- mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG);
- for (int i = 0; i < mIterationCount; ++i) {
- CLog.i("Installing app %s (%d)", EXTERNAL_LOC_PKG, i);
- try {
- // install the app
- mPMHostUtils.installFile(getRepositoryTestAppFilePath(MISC_APPS_DIRECTORY_NAME,
- EXTERNAL_LOC_APK), false);
- mPMHostUtils.waitForPackageManager();
- assertTrue(mPMHostUtils.doesAppExistOnSDCard(EXTERNAL_LOC_PKG));
- assertTrue(mPMHostUtils.doesPackageExist(EXTERNAL_LOC_PKG));
- }
- finally {
- // now uninstall the app
- CLog.i("Uninstalling app %s (%d)", EXTERNAL_LOC_PKG, i);
- mPMHostUtils.uninstallApp(EXTERNAL_LOC_PKG);
- }
- }
- }
-
- /**
- * Stress test to verify that we can install, 20 large apps (>1mb each)
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallManyLargeAppsOnSD() throws Exception {
- CLog.i("Test installing %d large apps onto the sd card", LARGE_APPS.length);
- try {
- // Install all the large apps
- for (int i = 0; i < LARGE_APPS.length; ++i) {
- String apkName = LARGE_APPS[i][APK.FILENAME.ordinal()];
- String pkgName = LARGE_APPS[i][APK.PACKAGENAME.ordinal()];
- // cleanup test app just in case it already exists
- mPMHostUtils.uninstallApp(pkgName);
- CLog.i("Installing app " + apkName);
- // install the app
- mPMHostUtils.installFile(getRepositoryTestAppFilePath(LARGE_APPS_DIRECTORY_NAME,
- apkName), false);
- mPMHostUtils.waitForPackageManager();
- assertTrue(mPMHostUtils.doesAppExistOnSDCard(pkgName));
- assertTrue(mPMHostUtils.doesPackageExist(pkgName));
- }
- }
- finally {
- // Cleanup - ensure we uninstall all large apps if they were installed
- for (int i = 0; i < LARGE_APPS.length; ++i) {
- String apkName = LARGE_APPS[i][APK.FILENAME.ordinal()];
- String pkgName = LARGE_APPS[i][APK.PACKAGENAME.ordinal()];
- CLog.i("Uninstalling app " + apkName);
- // cleanup test app just in case it was accidently installed
- mPMHostUtils.uninstallApp(pkgName);
- assertFalse(mPMHostUtils.doesAppExistOnSDCard(pkgName));
- }
- }
- }
-
- /**
- * Stress test to verify that we can install many small apps onto SD.
- * <p/>
- * Assumes adb is running as root in device under test.
- */
- public void testInstallManyAppsOnSD() throws Exception {
- CLog.i("Test installing %d small apps onto SD", MANY_APPS_END);
- try {
- for (int i = MANY_APPS_START; i <= MANY_APPS_END; ++i) {
- String currentPkgName = String.format("%s%d", MANY_APPS_PKG_PREFIX, i);
- // cleanup test app just in case it already exists
- mPMHostUtils.uninstallApp(currentPkgName);
- String currentApkName = String.format("%s%d.apk", MANY_APPS_APK_PREFIX, i);
- CLog.i("Installing app " + currentApkName);
- mPMHostUtils.installFile(getRepositoryTestAppFilePath(MANY_APPS_DIRECTORY_NAME,
- currentApkName), true);
- mPMHostUtils.waitForPackageManager();
- assertTrue(mPMHostUtils.doesAppExistOnSDCard(currentPkgName));
- assertTrue(mPMHostUtils.doesPackageExist(currentPkgName));
- }
- }
- finally {
- for (int i = MANY_APPS_START; i <= MANY_APPS_END; ++i) {
- String currentPkgName = String.format("%s%d", MANY_APPS_PKG_PREFIX, i);
- // cleanup test app
- mPMHostUtils.uninstallApp(currentPkgName);
- }
- }
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/PreloadedClassesTest.java b/prod-tests/src/com/android/framework/tests/PreloadedClassesTest.java
deleted file mode 100644
index 04ab7b7..0000000
--- a/prod-tests/src/com/android/framework/tests/PreloadedClassesTest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/*
- * 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.framework.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RunUtil;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Runs a series of automated use cases and collects loaded class information in order to generate
- * a list of preloaded classes based on the input thresholds.
- */
-public class PreloadedClassesTest implements IRemoteTest, IDeviceTest, IBuildReceiver {
- private static final String JUNIT_RUNNER = "android.support.test.runner.AndroidJUnitRunner";
- // Preload tool commands
- private static final String TOOL_CMD = "java -cp %s com.android.preload.Main --seq %s %s";
- private static final String SCAN_ALL_CMD = "scan-all";
- private static final String COMPUTE_CMD = "comp %d %s";
- private static final String EXPORT_CMD = "export %s";
- private static final String IMPORT_CMD = "import %s";
- // Large, common timeouts
- private static final long SCAN_TIMEOUT_MS = 5 * 60 * 1000;
- private static final long COMPUTE_TIMEOUT_MS = 60 * 1000;
-
- @Option(name = "package",
- description = "Instrumentation package for use case automation.",
- mandatory = true)
- private String mPackage = null;
-
- @Option(name = "test-case",
- description = "List of use cases to exercise from the package.",
- mandatory = true)
- private List<String> mTestCases = new ArrayList<>();
-
- @Option(name = "preload-tool", description = "Overridden location of the preload JAR file.")
- private String mPreloadToolJarPath = null;
-
- @Option(name = "threshold",
- description = "List of thresholds for computing preloaded classes.",
- mandatory = true)
- private List<String> mThresholds = new ArrayList<>();
-
- @Option(name = "quit-on-error",
- description = "Quits if errors are encountered anywhere in the process.",
- mandatory = false)
- private boolean mQuitOnError = false;
-
- private ITestDevice mDevice;
- private IBuildInfo mBuildInfo;
- private List<File> mExportFiles = new ArrayList<>();
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- // Download preload tool, if not supplied
- if (mPreloadToolJarPath == null) {
- File preload = mBuildInfo.getFile("preload2.jar");
- if (preload != null && preload.exists()) {
- mPreloadToolJarPath = preload.getAbsolutePath();
- } else {
- CLog.e("Unable to find the preload tool.");
- }
- } else {
- CLog.v("Using alternative preload tool path, %s", mPreloadToolJarPath);
- }
-
- IRemoteAndroidTestRunner runner =
- new RemoteAndroidTestRunner(mPackage, JUNIT_RUNNER, getDevice().getIDevice());
-
- for (String testCaseIdentifier : mTestCases) {
- // Run an individual use case
- runner.addInstrumentationArg("class", testCaseIdentifier);
- getDevice().runInstrumentationTests(runner, listener);
- // Scan loaded classes and export
- File outfile = scanAndExportClasses();
- if (outfile != null) {
- mExportFiles.add(outfile);
- } else {
- String msg = String.format("Failed to find outfile after %s", testCaseIdentifier);
- if (mQuitOnError) {
- throw new RuntimeException(msg);
- } else {
- CLog.e(msg + ". Continuing anyway...");
- }
- }
- }
-
- try {
- // Consider each threshold input
- for (String thresholdStr : mThresholds) {
- int threshold = 0;
- try {
- threshold = Integer.parseInt(thresholdStr);
- } catch (NumberFormatException e) {
- if (mQuitOnError) {
- throw e;
- } else {
- CLog.e("Failed to parse threshold: %s", thresholdStr);
- CLog.e(e);
- continue;
- }
- }
- // Generate the corresponding preloaded classes
- File classes = writePreloadedClasses(threshold);
- if (classes != null) {
- try (FileInputStreamSource stream = new FileInputStreamSource(classes)) {
- String name = String.format("preloaded-classes-threshold-%s", thresholdStr);
- listener.testLog(name, LogDataType.TEXT, stream);
- }
- // Clean up after uploading
- FileUtil.deleteFile(classes);
- } else {
- String msg = String.format(
- "Failed to generate classes file for threshold, %s", thresholdStr);
- if (mQuitOnError) {
- throw new RuntimeException(msg);
- } else {
- CLog.e(msg + ". Continuing anyway...");
- }
- }
- }
- } finally {
- // Clean up temporary export files.
- for (File f : mExportFiles) {
- FileUtil.deleteFile(f);
- }
- }
- }
-
- /**
- * Calls the preload tool to pull and scan heap profiles and to generate and export the list of
- * loaded Java classes.
- * @return {@link File} containing the loaded Java classes
- */
- private File scanAndExportClasses() {
- File temp = null;
- try {
- temp = FileUtil.createTempFile("scanned", ".txt");
- } catch (IOException e) {
- CLog.e("Failed while creating temp file.");
- CLog.e(e);
- return null;
- }
- // Construct the command
- String exportCmd = String.format(EXPORT_CMD, temp.getAbsolutePath());
- String actionCmd = String.format("%s %s", SCAN_ALL_CMD, exportCmd);
- String[] fullCmd = constructPreloadCommand(actionCmd);
- CommandResult result = RunUtil.getDefault().runTimedCmd(SCAN_TIMEOUT_MS, fullCmd);
- if (CommandStatus.SUCCESS.equals(result.getStatus())) {
- return temp;
- } else {
- // Clean up the temp file
- FileUtil.deleteFile(temp);
- // Log and return the failure
- CLog.e("Error scanning: %s", result.getStderr());
- return null;
- }
- }
-
- /**
- * Calls the preload tool to import the previously exported files and to generate the list of
- * preloaded classes based on the threshold input.
- * @return {@link File} containing the generated list of preloaded classes
- */
- private File writePreloadedClasses(int threshold) {
- File temp = null;
- try {
- temp = FileUtil.createTempFile("preloaded-classes", ".txt");
- } catch (IOException e) {
- CLog.e("Failed while creating temp file.");
- CLog.e(e);
- return null;
- }
- // Construct the command
- String actionCmd = "";
- for (File f : mExportFiles) {
- String importCmd = String.format(IMPORT_CMD, f.getAbsolutePath());
- actionCmd += importCmd + " ";
- }
- actionCmd += String.format(COMPUTE_CMD, threshold, temp.getAbsolutePath());
- String[] fullCmd = constructPreloadCommand(actionCmd);
- CommandResult result = RunUtil.getDefault().runTimedCmd(COMPUTE_TIMEOUT_MS, fullCmd);
- if (CommandStatus.SUCCESS.equals(result.getStatus())) {
- return temp;
- } else {
- // Clean up the temp file
- FileUtil.deleteFile(temp);
- // Log and return the failure
- CLog.e("Error computing classes: %s", result.getStderr());
- return null;
- }
- }
-
- private String[] constructPreloadCommand(String command) {
- return String.format(TOOL_CMD, mPreloadToolJarPath, getDevice().getSerialNumber(), command)
- .split(" ");
- }
-
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- @Override
- public void setBuild(IBuildInfo buildInfo) {
- mBuildInfo = buildInfo;
- }
-}
diff --git a/prod-tests/src/com/android/framework/tests/TestDirForwarder.java b/prod-tests/src/com/android/framework/tests/TestDirForwarder.java
deleted file mode 100644
index 379969a..0000000
--- a/prod-tests/src/com/android/framework/tests/TestDirForwarder.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2011 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.framework.tests;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.IDeviceBuildInfo;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationReceiver;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.targetprep.BaseTargetPreparer;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.TargetSetupError;
-import com.android.tradefed.util.FileUtil;
-
-import java.io.File;
-
-/**
- * A ITargetPreparer that forwards the location of the tests/data/app dir from the {@link
- * IDeviceBuildInfo} as an {@link Option}.
- */
-public class TestDirForwarder extends BaseTargetPreparer implements IConfigurationReceiver {
-
- private IConfiguration mConfig = null;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
- BuildError, DeviceNotAvailableException {
- if (!(buildInfo instanceof IDeviceBuildInfo)) {
- throw new IllegalArgumentException("buildInfo is not a IDeviceBuildInfo");
- }
- if (mConfig == null) {
- // should never happen
- throw new IllegalArgumentException("missing config");
- }
- IDeviceBuildInfo deviceBuild = (IDeviceBuildInfo)buildInfo;
- File testAppDir = FileUtil.getFileForPath(deviceBuild.getTestsDir(), "DATA", "app");
- // option with name test-app-path must exist!
- try {
- mConfig.injectOptionValue("test-app-path", testAppDir.getAbsolutePath());
- } catch (ConfigurationException e) {
- throw new TargetSetupError("Mis-configuration: no object which consumes test-app-path "
- + "option", e, device.getDeviceDescriptor());
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setConfiguration(IConfiguration config) {
- mConfig = config;
- }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/FlatlandTest.java b/prod-tests/src/com/android/graphics/tests/FlatlandTest.java
deleted file mode 100644
index 5baa9e6..0000000
--- a/prod-tests/src/com/android/graphics/tests/FlatlandTest.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (C) 2014 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.graphics.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.CollectingOutputReceiver;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.AbiFormatter;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test Runner for graphics Flatland Benchmark test.
- * <p>
- * Flatland test is a benchmark for measuring GPU performance in various 2D UI rendering and
- * window composition scenarios.
- * <p>
- * Since it is measuring the hardware performance, the test should be executed in
- * as consistent and static an environment as possible.
- * <ul>
- * <li>The display should be turned off and background service should be stopped before
- * running the benchmark. Running 'adb shell stop' is probably sufficient for this,
- * but if there are device specific background services that consume
- * much CPU cycles, memory bandwidth, or might otherwise interfere with GPU rendering,
- * those should be stopped as well
- * <li>All relevant hardware clocks should be locked at particular frequency when running the test.
- * </ul>
- * <p>
- * If running the benchmark with clocks locked causes thermal throttling, set option "--sleep-time"
- * to 10 to 50 (ms) to insert sleep between each benchmark sample run.
- * <p>
- * Output interpretation:
- * For each test case, the expected time in milliseconds that a single frame of the scenario
- * takes to complete will be printed out. Four types of values could displayed:
- * <ul>
- * <li>fast - frames of the scenarios are completed too fast to be reliably benchmarked. This
- * corresponds to frame time less than 3 ms. The scenario was skipped. "0" will be posted into
- * the dashboard.
- * <li>slow - frame time is too long, normally orver 50 ms. The scenario was skipped. "1000" will
- * be posted into the dashboard.
- * <li>varies - frame time was not stable. rerun the test to get a stable results. If that results
- * show repeatedly, something is wrong with the environment, signal to file a bug.
- * <li>decimal number - frame time for the scenarios are measured.
- * </ul>
- */
-public class FlatlandTest implements IDeviceTest, IRemoteTest {
-
- private static final long SHELL_TIMEOUT = 30*60*1000;
- private static final String COMMAND = "flatland|#ABI32#|";
- private static final String FIRST_LINE = "cmdline:";
- private static final String TITLE = "Scenario";
- private static final long START_TIMER = 2 * 60 * 1000; // 2 minutes
- private static final String RESULT_FAST = "fast";
- private static final String RESULT_SLOW = "slow";
- private static final String RESULT_VARIES = "varies";
-
- private ITestDevice mTestDevice = null;
- // HashMap to store results for
- public Map<String, String> mResultMap = new HashMap<String, String>();
-
- @Option(name = "ru-key", description = "Reporting unit key to use when posting results")
- private String mRuKey = "flatland";
-
- @Option(name = "run-path",
- description = "path for the binary")
- private String mRunPath = "/data/local/tmp/";
-
- @Option(name = "sleep-time",
- description = "sleep for N ms between samples, set to 10 - 50 ms if the locked CPU"
- + " frequency causes thermal throttle.")
- private int mSleepTime = 50;
-
- @Option(name = "schema-map",
- description = "map a test case name to a schema key")
- private Map<String, String> mSchemaMap = new HashMap<String, String>();
-
- @Option(name = AbiFormatter.FORCE_ABI_STRING,
- description = AbiFormatter.FORCE_ABI_DESCRIPTION,
- importance = Importance.IF_UNSET)
- private String mForceAbi = null;
-
- @Override
- public void setDevice(ITestDevice testDevice) {
- mTestDevice = testDevice;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-
- @Override
- public void run(ITestInvocationListener standardListener) throws DeviceNotAvailableException {
- Assert.assertNotNull(mRunPath);
- RunUtil.getDefault().sleep(START_TIMER);
-
- // execute test
- StringBuilder cmd = new StringBuilder();
- cmd.append(mRunPath);
- cmd.append(COMMAND);
- if (mSleepTime > 0) {
- cmd.append(" -s ");
- cmd.append(mSleepTime);
- }
- standardListener.testRunStarted(mRuKey, 1);
- long start = System.currentTimeMillis();
- CollectingOutputReceiver receiver = new CollectingOutputReceiver();
- mTestDevice.executeShellCommand(AbiFormatter.formatCmdForAbi(cmd.toString(), mForceAbi),
- receiver, SHELL_TIMEOUT, TimeUnit.MILLISECONDS, 2);
- String result = receiver.getOutput();
- if (result == null) {
- CLog.v("no test results returned. Test failed?");
- return;
- }
- // parse results and report metrics
- parseResult(result);
- standardListener.testRunEnded(
- (System.currentTimeMillis() - start), TfMetricProtoUtil.upgradeConvert(mResultMap));
- }
-
- /**
- * Parse results returned from running the benchmark
- */
- public void parseResult(String result) {
- String[] lines = result.split(System.getProperty("line.separator"));
- if (lines.length <= 0) {
- return;
- }
- for (int i = 0; i < lines.length; i++) {
- if (!lines[i].contains(FIRST_LINE) && !(lines[i].contains(TITLE))) {
- // skip the first two lines
- String[] items = lines[i].trim().split("\\|");
- if (items.length == 3) {
- String schemaKey = String.format("%s %s", items[0].trim(), items[1].trim());
- if (mSchemaMap.get(schemaKey) != null) {
- // get the mapped schema key if there is any
- schemaKey = mSchemaMap.get(schemaKey);
- }
- String renderTime = items[2].trim();
- if (renderTime != null) {
- if (renderTime.equals(RESULT_FAST)) {
- mResultMap.put(schemaKey, "0");
- } else if (renderTime.equals(RESULT_SLOW)) {
- mResultMap.put(schemaKey, "1000");
- } else if (renderTime.equals(RESULT_VARIES)){
- mResultMap.put(schemaKey, "-1");
- } else {
- mResultMap.put(schemaKey, renderTime);
- }
- }
- }
- }
- }
- }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/FlatlandTestFuncTest.java b/prod-tests/src/com/android/graphics/tests/FlatlandTestFuncTest.java
deleted file mode 100644
index bd3c08d..0000000
--- a/prod-tests/src/com/android/graphics/tests/FlatlandTestFuncTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2014 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.graphics.tests;
-
-import com.android.tradefed.log.LogUtil.CLog;
-
-import junit.framework.TestCase;
-
-import org.junit.Assert;
-
-import java.util.Map;
-
-public class FlatlandTestFuncTest extends TestCase {
-
- private final String output = " cmdline: /data/local/tmp/flatland\n" +
- " Scenario | Resolution | Time (ms)\n" +
- " 16:10 Single Static Window | 1280 x 800 | fast\n" +
- " 16:10 Single Static Window | 1920 x 1200 | 3.136\n" +
- " 16:10 Single Static Window | 2560 x 1600 | 5.524\n" +
- " 16:10 Single Static Window | 3840 x 2400 | 11.841\n" +
- " 4:3 Single Static Window | 2048 x 1536 | 4.292\n" +
- " 16:10 App -> Home Transition | 1280 x 800 | varies\n" +
- " 16:10 App -> Home Transition | 1920 x 1200 | 5.724\n" +
- " 16:10 App -> Home Transition | 2560 x 1600 | 10.033\n" +
- " 16:10 App -> Home Transition | 3840 x 2400 | 22.034\n" +
- " 4:3 App -> Home Transition | 2048 x 1536 | 8.003\n" +
- " 16:10 SurfaceView -> Home Transition | 1280 x 800 | slow\n" +
- " 16:10 SurfaceView -> Home Transition | 1920 x 1200 | 7.023\n" +
- " 16:10 SurfaceView -> Home Transition | 2560 x 1600 | 12.337\n" +
- " 16:10 SurfaceView -> Home Transition | 3840 x 2400 | 27.283\n" +
- " 4:3 SurfaceView -> Home Transition | 2048 x 1536 | 9.918\n";
-
- public void testPraseResults() throws Exception {
- FlatlandTest ft = new FlatlandTest();
- ft.parseResult(output);
- // "0" represents a "fast" result
- String t = ft.mResultMap.get("16:10 Single Static Window 1280 x 800");
- Assert.assertTrue(t.equals("0"));
-
- t = ft.mResultMap.get("16:10 Single Static Window 1920 x 1200");
- Assert.assertTrue(t.equals("3.136"));
-
- t = ft.mResultMap.get("16:10 App -> Home Transition 1280 x 800");
- Assert.assertTrue(t.equals("-1"));
-
- t = ft.mResultMap.get("16:10 SurfaceView -> Home Transition 1280 x 800");
- Assert.assertTrue(t.equals("1000"));
-
- for(Map.Entry<String, String> entry: ft.mResultMap.entrySet()) {
- CLog.e("key:%s, value:%s", entry.getKey(), entry.getValue());
- }
- }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/ImageProcessingTest.java b/prod-tests/src/com/android/graphics/tests/ImageProcessingTest.java
deleted file mode 100644
index 58e2ad7..0000000
--- a/prod-tests/src/com/android/graphics/tests/ImageProcessingTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2011 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.graphics.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.BugreportCollector;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Run the ImageProcessing test. The test provides benchmark for image processing
- * in Android System.
- */
-public class ImageProcessingTest implements IDeviceTest, IRemoteTest {
-
- private ITestDevice mTestDevice = null;
-
- // Define instrumentation test package and runner.
- private static final String TEST_PACKAGE_NAME = "com.android.rs.image";
- private static final String TEST_RUNNER_NAME = ".ImageProcessingTestRunner";
- private static final String TEST_CLASS = "com.android.rs.image.ImageProcessingTest";
- private static final long START_TIMER = 2 * 60 * 1000; // 2 minutes
-
- // Define keys for data posting
- private static final String TEST_RUN_NAME = "graphics_image_processing";
- private static final String BENCHMARK_KEY = "Benchmark";
- private static final String TEST_NAME_KEY = "Testname";
-
- //Max test timeout - 30 mins
- private static final int MAX_TEST_TIMEOUT = 30 * 60 * 1000;
-
- /**
- * Run the ImageProcessing benchmark test, parse test results.
- */
- @Override
- public void run(ITestInvocationListener standardListener)
- throws DeviceNotAvailableException {
- Assert.assertNotNull(mTestDevice);
- // Start the test after device is fully booted and stable
- // FIXME: add option in TF to wait until device is booted and stable
- RunUtil.getDefault().sleep(START_TIMER);
-
- IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
- TEST_PACKAGE_NAME, TEST_RUNNER_NAME, mTestDevice.getIDevice());
- runner.setClassName(TEST_CLASS);
- runner.setMaxTimeToOutputResponse(MAX_TEST_TIMEOUT, TimeUnit.MILLISECONDS);
- // Add bugreport listener for failed test
- BugreportCollector bugListener = new
- BugreportCollector(standardListener, mTestDevice);
- bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
- bugListener.setDescriptiveName(TEST_CLASS);
-
- // Add collecting listener for test results collecting
- CollectingTestListener collectListener = new CollectingTestListener();
- mTestDevice.runInstrumentationTests(runner, collectListener, bugListener, standardListener);
-
- // Capture a bugreport after the test
- try (InputStreamSource bugreport = mTestDevice.getBugreport()) {
- standardListener.testLog("bugreport.txt", LogDataType.BUGREPORT, bugreport);
- }
-
- // Collect test metrics from the instrumentation test output.
- Map<String, String> resultMetrics = new HashMap<String, String>();
- Collection<TestResult> testRunResults =
- collectListener.getCurrentRunResults().getTestResults().values();
-
- if (testRunResults != null) {
- for (TestResult testCaseResult: testRunResults) {
- Map<String, String> testMetrics = testCaseResult.getMetrics();
- // Each test metrics includes the following:
- // Testname=LEVELS_VEC3_FULL
- // Benchmark=50.171757
- // Iterations=5
- if (testMetrics != null) {
- String schemaKey = null;
- String schemaValue = null;
- for (Map.Entry<String, String> entry : testMetrics.entrySet()) {
- String entryKey = entry.getKey();
- String entryValue = entry.getValue();
- if (TEST_NAME_KEY.equals(entryKey)) {
- schemaKey = entryValue;
- } else if (BENCHMARK_KEY.equals(entryKey)) {
- schemaValue = entryValue;
- }
- }
- if (schemaKey != null && schemaValue != null) {
- CLog.v(String.format("%s: %s", schemaKey, schemaValue));
- resultMetrics.put(schemaKey, schemaValue);
- }
- }
- }
- // Post results to the dashboard.
- reportMetrics(TEST_RUN_NAME, standardListener, resultMetrics);
- }
- }
-
- /**
- * Report metrics by creating an empty test run to stick them in
- */
- private void reportMetrics(String metricsName, ITestInvocationListener listener,
- Map<String, String> metrics) {
- // Create an empty testRun to report the parsed runMetrics
- CLog.d("About to report metrics to %s: %s", metricsName, metrics);
- listener.testRunStarted(metricsName, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-
- @Override
- public void setDevice(ITestDevice testDevice) {
- mTestDevice = testDevice;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/OpenGlPerformanceTest.java b/prod-tests/src/com/android/graphics/tests/OpenGlPerformanceTest.java
deleted file mode 100644
index f847736..0000000
--- a/prod-tests/src/com/android/graphics/tests/OpenGlPerformanceTest.java
+++ /dev/null
@@ -1,512 +0,0 @@
-/*
- * Copyright (C) 2011 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.graphics.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.BugreportCollector;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RegexTrie;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.SimpleStats;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import junit.framework.TestCase;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Run the OpenGl performance test. The OpenGl performance test benchmarks the performance
- * of RenderScript in Android System.
- */
-public class OpenGlPerformanceTest implements IDeviceTest, IRemoteTest {
-
- private ITestDevice mTestDevice = null;
-
- // Define instrumentation test package and runner.
- private static final String TEST_PACKAGE_NAME = "com.android.perftest";
- private static final String TEST_RUNNER_NAME = ".RsPerfTestRunner";
- private static final String TEST_CLASS = "com.android.perftest.RsBenchTest";
- private static final String OUTPUT_FILE = "rsbench_result";
- private static final int TEST_TIMER = 60 * 60 *1000; // test running timer 1 hour
- private static final long START_TIMER = 2 * 60 * 1000; // 2 minutes
-
- private final RegexTrie<String> mPatternMap = new RegexTrie<>();
- private Map<String, String[]> mKeyMap = new HashMap<>();
- private Map<String, Double[]> mTestResults = new HashMap<>();
-
- @Option(name="iterations",
- description="The number of iterations to run benchmark tests.")
- private int mIterations = 5;
-
- public OpenGlPerformanceTest() {
- // 3 tests, RenderScript Text Rendering
- mPatternMap.put("text1", "Fill screen with text 1 time, (\\d+.\\d+),");
- mPatternMap.put("text2", "Fill screen with text 3 times, (\\d+.\\d+),");
- mPatternMap.put("text3", "Fill screen with text 5 times, (\\d+.\\d+),");
- // 6 tests, RenderScript Texture Blending
- mPatternMap.put("10xSingleTexture", "Fill screen 10x singletexture, (\\d+.\\d+),");
- mPatternMap.put("Multitexture", "Fill screen 10x 3tex multitexture, (\\d+.\\d+),");
- mPatternMap.put("BlendedSingleTexture", "Fill screen 10x blended singletexture, " +
- "(\\d+.\\d+),");
- mPatternMap.put("BlendedMultiTexture", "Fill screen 10x blended 3tex multitexture, " +
- "(\\d+.\\d+),");
- mPatternMap.put("3xModulatedBlendedSingletexture",
- "Fill screen 3x modulate blended singletexture, (\\d+.\\d+),");
- mPatternMap.put("1xModulatedBlendedSingletexture",
- "Fill screen 1x modulate blended singletexture, (\\d+.\\d+),");
- // 3 tests, RenderScript Mesh
- mPatternMap.put("FullScreenMesh10", "Full screen mesh 10 by 10, (\\d+.\\d+),");
- mPatternMap.put("FullScrennMesh100", "Full screen mesh 100 by 100, (\\d+.\\d+),");
- mPatternMap.put("FullScreenMeshW4", "Full screen mesh W / 4 by H / 4, (\\d+.\\d+),");
- // 6 tests, RenderScript Geo Test (light)
- mPatternMap.put("GeoTestFlatColor1", "Geo test 25.6k flat color, (\\d+.\\d+),");
- mPatternMap.put("GeoTestFlatColor2", "Geo test 51.2k flat color, (\\d+.\\d+),");
- mPatternMap.put("GeoTestFlatColor3", "Geo test 204.8k small tries flat color, " +
- "(\\d+.\\d+),");
- mPatternMap.put("GeoTestSingleTexture1", "Geo test 25.6k single texture, (\\d+.\\d+),");
- mPatternMap.put("GeoTestSingleTexture2", "Geo test 51.2k single texture, (\\d+.\\d+),");
- mPatternMap.put("GeoTestSingleTexture3", "Geo test 204.8k small tries single texture, " +
- "(\\d+.\\d+),");
- // 9 tests, RenderScript Geo Test (heavy)
- mPatternMap.put("GeoTestHeavyVertex1","Geo test 25.6k geo heavy vertex, (\\d+.\\d+),");
- mPatternMap.put("GeoTestHeavyVertex2","Geo test 51.2k geo heavy vertex, (\\d+.\\d+),");
- mPatternMap.put("GeoTestHeavyVertex3", "Geo test 204.8k geo raster load heavy vertex, " +
- "(\\d+.\\d+),");
- mPatternMap.put("GeoTestHeavyFrag1", "Geo test 25.6k heavy fragment, (\\d+.\\d+),");
- mPatternMap.put("GeoTestHeavyFrag2", "Geo test 51.2k heavy fragment, (\\d+.\\d+),");
- mPatternMap.put("GeoTestHeavyFrag3", "Geo test 204.8k small tries heavy fragment, " +
- "(\\d+.\\d+),");
- mPatternMap.put("GeoTestHeavyFragHeavyVertex1",
- "Geo test 25.6k heavy fragment heavy vertex, (\\d+.\\d+),");
- mPatternMap.put("GeoTestHeavyFragHeavyVertex2",
- "Geo test 51.2k heavy fragment heavy vertex, (\\d+.\\d+),");
- mPatternMap.put("GeoTestHeavyFragHeavyVertex3",
- "Geo test 204.8k small tries heavy fragment heavy vertex, (\\d+.\\d+),");
- // 6 tests, RenerScript UI Test
- mPatternMap.put("UITestWithIcon10by10", "UI test with icon display 10 by 10, " +
- "(\\d+.\\d+),");
- mPatternMap.put("UITestWithIcon100by100", "UI test with icon display 100 by 100, " +
- "(\\d+.\\d+),");
- mPatternMap.put("UITestWithImageText3", "UI test with image and text display 3 pages, " +
- "(\\d+.\\d+),");
- mPatternMap.put("UITestWithImageText5", "UI test with image and text display 5 pages, " +
- "(\\d+.\\d+),");
- mPatternMap.put("UITestListView", "UI test with list view, (\\d+.\\d+),");
- mPatternMap.put("UITestLiveWallPaper", "UI test with live wallpaper, (\\d+.\\d+),");
-
- mKeyMap.put("graphics_text", (new String[]{"text1", "text2", "text3"}));
- mKeyMap.put("graphics_geo_light", (new String[]{"GeoTestFlatColor1", "GeoTestFlatColor2",
- "GeoTestFlatColor3", "GeoTestSingleTexture1", "GeoTestSingleTexture2",
- "GeoTestSingleTexture3"}));
- mKeyMap.put("graphics_mesh", (new String[]{"FullScreenMesh10","FullScrennMesh100",
- "FullScreenMeshW4"}));
- mKeyMap.put("graphics_geo_heavy", (new String[]{"GeoTestHeavyVertex1",
- "GeoTestHeavyVertex2", "GeoTestHeavyVertex3", "GeoTestHeavyFrag1",
- "GeoTestHeavyFrag2", "GeoTestHeavyFrag3", "GeoTestHeavyFragHeavyVertex1",
- "GeoTestHeavyFragHeavyVertex2", "GeoTestHeavyFragHeavyVertex3"}));
- mKeyMap.put("graphics_texture", (new String[]{"10xSingleTexture", "Multitexture",
- "BlendedSingleTexture", "BlendedMultiTexture", "3xModulatedBlendedSingletexture",
- "1xModulatedBlendedSingletexture"}));
- mKeyMap.put("graphics_ui", (new String[]{"UITestWithIcon10by10", "UITestWithIcon100by100",
- "UITestWithImageText3", "UITestWithImageText5",
- "UITestListView", "UITestLiveWallPaper"}));
- }
-
- /**
- * Run the OpenGl benchmark tests
- * Collect results and post results to test listener.
- */
- @Override
- public void run(ITestInvocationListener standardListener)
- throws DeviceNotAvailableException {
- Assert.assertNotNull(mTestDevice);
- CLog.d("option values: mIterations(%d)", mIterations);
-
- // Start the test after device is fully booted and stable
- // FIXME: add option in TF to wait until device is booted and stable
- RunUtil.getDefault().sleep(START_TIMER);
-
- IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
- TEST_PACKAGE_NAME, TEST_RUNNER_NAME, mTestDevice.getIDevice());
- runner.addInstrumentationArg("iterations", Integer.toString(mIterations));
- runner.setClassName(TEST_CLASS);
- runner.setMaxTimeToOutputResponse(TEST_TIMER, TimeUnit.MILLISECONDS);
- // Add bugreport listener for failed test
- BugreportCollector bugListener = new
- BugreportCollector(standardListener, mTestDevice);
- bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
- bugListener.setDescriptiveName(TEST_CLASS);
- mTestDevice.runInstrumentationTests(runner, bugListener);
- logOutputFile(bugListener);
- cleanOutputFiles();
- }
-
- /**
- * Collect test results, report test results to test listener.
- *
- * @param listener
- */
- private void logOutputFile(ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- // take a bug report, it is possible the system crashed
- try (InputStreamSource bugreport = mTestDevice.getBugreport()) {
- listener.testLog("bugreport.txt", LogDataType.BUGREPORT, bugreport);
- }
- File resFile = null;
- InputStreamSource outputSource = null;
-
- for (int i = 0; i < mIterations; i++) {
- // In each iteration, the test result is saved in a file rsbench_result*.csv
- // e.g. for 10 iterations, results are in rsbench_result0.csv - rsbench_result9.csv
- String outputFileName = String.format("%s%d.csv", OUTPUT_FILE, i);
- CLog.d("pull result %s", outputFileName);
-
- try {
- resFile = mTestDevice.pullFileFromExternal(outputFileName);
- if (resFile != null) {
- // Save a copy of the output file
- CLog.d("Sending %d byte file %s into the logosphere!",
- resFile.length(), resFile);
- outputSource = new FileInputStreamSource(resFile);
- listener.testLog(outputFileName, LogDataType.TEXT,
- outputSource);
-
- // Parse the results file and report results to dash board
- parseOutputFile(new FileInputStream(resFile), i);
- } else {
- CLog.v("File %s doesn't exist or pulling the file failed", outputFileName);
- }
- } catch (IOException e) {
- CLog.e("IOException while reading outputfile %s", outputFileName);
- } finally {
- FileUtil.deleteFile(resFile);
- StreamUtil.cancel(outputSource);
- }
- }
-
- printTestResults();
- printKeyMap();
-
- Map<String, String> runMetrics = new HashMap<>();
-
- // After processing the output file, calculate average data and report data
- // Find the RU-ITEM keys mapping for data posting
- for (Map.Entry<String, String[]> entry: mKeyMap.entrySet()) {
- String[] itemKeys = entry.getValue();
-
- CLog.v("ru key: %s", entry.getKey());
-
- for (String key: itemKeys) {
- CLog.v("item key: %s", key);
- if (mTestResults.get(key) == null) {
- continue;
- }
- SimpleStats simpleStats = new SimpleStats();
- simpleStats.addAll(Arrays.asList(mTestResults.get(key)));
- double averageFps = simpleStats.mean();
- runMetrics.put(key, String.valueOf(averageFps));
- }
- reportMetrics(entry.getKey(), runMetrics, listener);
- runMetrics.clear();
- }
- }
-
- // Parse one result file and save test name and fps value
- private void parseOutputFile(InputStream dataInputStream, int iterationId) {
- try {
- BufferedReader br= new BufferedReader(new InputStreamReader(dataInputStream));
- String line = null;
- while ((line = br.readLine()) != null) {
- List<List<String>> capture = new ArrayList<>(1);
- String key = mPatternMap.retrieve(capture, line);
-
- if (key != null) {
- for (int i = 0; i < capture.size(); i++) {
- CLog.v("caputre.get[%d]: %s", i, capture.get(i).toString());
- }
-
- CLog.v("Retrieve key: %s, catpure: %s",
- key, capture.toString());
-
- // for value into the corresponding
- Double[] fps = mTestResults.get(key);
- if (fps == null) {
- fps = new Double[mIterations];
- CLog.v("initialize fps array");
- }
- fps[iterationId] = Double.parseDouble(capture.get(0).get(0));
- mTestResults.put(key, fps);
- }
- }
- } catch (IOException e) {
- CLog.e("IOException while reading from data stream");
- CLog.e(e);
- return;
- }
- }
-
- private void printKeyMap() {
- for (Map.Entry<String, String[]> entry:mKeyMap.entrySet()) {
- CLog.v("ru key: %s", entry.getKey());
- for (String itemKey: entry.getValue()) {
- CLog.v("item key: %s", itemKey);
- }
- }
- }
-
- private void printTestResults() {
- for (Map.Entry<String, Double[]> entry: mTestResults.entrySet()) {
- CLog.v("key %s:", entry.getKey());
- for (Double d: entry.getValue()) {
- CLog.v("value: %f", d.doubleValue());
- }
- }
- }
-
- /**
- * Report run metrics by creating an empty test run to stick them in
- * <p />
- * Exposed for unit testing
- */
- protected void reportMetrics(String metricsName, Map<String, String> metrics,
- ITestInvocationListener listener) {
- // Create an empty testRun to report the parsed runMetrics
- CLog.d("About to report metrics to %s: %s", metricsName, metrics);
- listener.testRunStarted(metricsName, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-
- /**
- * Clean up output files from the last test run
- */
- private void cleanOutputFiles() throws DeviceNotAvailableException {
- for (int i = 0; i < mIterations; i++) {
- String outputFileName = String.format("%s%d.csv", OUTPUT_FILE, i);
- String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
- mTestDevice.executeShellCommand(String.format("rm %s/%s", extStore, outputFileName));
- }
- }
-
- @Override
- public void setDevice(ITestDevice testDevice) {
- mTestDevice = testDevice;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-
- /**
- * A meta-test to ensure the parsing working properly
- * To run the meta test, run command
- * tradefed.sh run singleCommand host -n --class
- * 'com.android.graphics.tests.OpenGlPerformanceTest$MetaTest'
- */
- public static class MetaTest extends TestCase {
- private OpenGlPerformanceTest mTestInstance = null;
-
- private static String join(String... subStrings) {
- StringBuilder sb = new StringBuilder();
- for (String subString : subStrings) {
- sb.append(subString);
- sb.append("\n");
- }
- return sb.toString();
- }
-
- @Override
- public void setUp() throws Exception {
- mTestInstance = new OpenGlPerformanceTest() {};
- }
-
- // Make sure that parsing works
- public void testParseOutputFile() throws Exception {
- String output = join(
- "Fill screen with text 1 time, 97.65624,",
- "Fill screen with text 3 times, 36.576443,",
- "Fill screen with text 5 times, 12.382367,",
- "Fill screen 10x singletexture, 40.617382,",
- "Fill screen 10x 3tex multitexture, 28.32861,",
- "Fill screen 10x blended singletexture, 18.389112,",
- "Fill screen 10x blended 3tex multitexture, 5.4448433,",
- "Fill screen 3x modulate blended singletexture, 27.754648,",
- "Fill screen 1x modulate blended singletexture, 58.207214,",
- "Full screen mesh 10 by 10, 12.727504,",
- "Full screen mesh 100 by 100, 4.489136,",
- "Full screen mesh W / 4 by H / 4, 2.688967,",
- "Geo test 25.6k flat color, 31.259768,",
- "Geo test 51.2k flat color, 17.985611,",
- "Geo test 204.8k small tries flat color, 3.6580455,",
- "Geo test 25.6k single texture, 30.03905,",
- "Geo test 51.2k single texture, 14.622021,",
- "Geo test 204.8k small tries single texture, 3.7195458,",
- "Geo test 25.6k geo heavy vertex, 20.104542,",
- "Geo test 51.2k geo heavy vertex, 8.982305,",
- "Geo test 204.8k geo raster load heavy vertex, 2.9978714,",
- "Geo test 25.6k heavy fragment, 30.788176,",
- "Geo test 51.2k heavy fragment, 6.938662,",
- "Geo test 204.8k small tries heavy fragment, 2.9441204,",
- "Geo test 25.6k heavy fragment heavy vertex, 16.331863,",
- "Geo test 51.2k heavy fragment heavy vertex, 4.531243,",
- "Geo test 204.8k small tries heavy fragment heavy vertex, 1.6915321,",
- "UI test with icon display 10 by 10, 93.370674,",
- "UI test with icon display 100 by 100, 1.2948335,",
- "UI test with image and text display 3 pages, 99.50249,",
- "UI test with image and text display 5 pages, 77.57951,",
- "UI test with list view, 117.78562,",
- "UI test with live wallpaper, 38.197098,");
-
- InputStream inputStream = new ByteArrayInputStream(output.getBytes());
- mTestInstance.parseOutputFile(inputStream, 0);
- assertNotNull(mTestInstance.mTestResults);
-
- // 3 tests, RenderScript Text Rendering
- assertEquals("97.65624", mTestInstance.mTestResults.get("text1")[0].toString());
- assertEquals("36.576443", mTestInstance.mTestResults.get("text2")[0].toString());
- assertEquals("12.382367", mTestInstance.mTestResults.get("text3")[0].toString());
-
- // 6 tests, RenderScript Texture Blending
- assertEquals("40.617382",
- mTestInstance.mTestResults.get("10xSingleTexture")[0].toString());
- assertEquals("28.32861",
- mTestInstance.mTestResults.get("Multitexture")[0].toString());
- assertEquals("18.389112",
- mTestInstance.mTestResults.get("BlendedSingleTexture")[0].toString());
- assertEquals("5.4448433",
- mTestInstance.mTestResults.get("BlendedMultiTexture")[0].toString());
- assertEquals("27.754648",
- mTestInstance.mTestResults.get(
- "3xModulatedBlendedSingletexture")[0].toString());
- assertEquals("58.207214",
- mTestInstance.mTestResults.get(
- "1xModulatedBlendedSingletexture")[0].toString());
-
- // 3 tests, RenderScript Mesh
- assertEquals("12.727504",
- mTestInstance.mTestResults.get("FullScreenMesh10")[0].toString());
- assertEquals("4.489136",
- mTestInstance.mTestResults.get("FullScrennMesh100")[0].toString());
- assertEquals("2.688967",
- mTestInstance.mTestResults.get("FullScreenMeshW4")[0].toString());
-
- // 6 tests, RenderScript Geo Test (light)
- assertEquals("31.259768",
- mTestInstance.mTestResults.get("GeoTestFlatColor1")[0].toString());
- assertEquals("17.985611",
- mTestInstance.mTestResults.get("GeoTestFlatColor2")[0].toString());
- assertEquals("3.6580455",
- mTestInstance.mTestResults.get("GeoTestFlatColor3")[0].toString());
- assertEquals("30.03905",
- mTestInstance.mTestResults.get("GeoTestSingleTexture1")[0].toString());
- assertEquals("14.622021",
- mTestInstance.mTestResults.get("GeoTestSingleTexture2")[0].toString());
- assertEquals("3.7195458",
- mTestInstance.mTestResults.get("GeoTestSingleTexture3")[0].toString());
-
- // 9 tests, RenderScript Geo Test (heavy)
- assertEquals("20.104542",
- mTestInstance.mTestResults.get("GeoTestHeavyVertex1")[0].toString());
- assertEquals("8.982305",
- mTestInstance.mTestResults.get("GeoTestHeavyVertex2")[0].toString());
- assertEquals("2.9978714",
- mTestInstance.mTestResults.get("GeoTestHeavyVertex3")[0].toString());
- assertEquals("30.788176",
- mTestInstance.mTestResults.get("GeoTestHeavyFrag1")[0].toString());
- assertEquals("6.938662",
- mTestInstance.mTestResults.get("GeoTestHeavyFrag2")[0].toString());
- assertEquals("2.9441204",
- mTestInstance.mTestResults.get("GeoTestHeavyFrag3")[0].toString());
- assertEquals("16.331863",
- mTestInstance.mTestResults.get("GeoTestHeavyFragHeavyVertex1")[0].toString());
- assertEquals("4.531243",
- mTestInstance.mTestResults.get("GeoTestHeavyFragHeavyVertex2")[0].toString());
- assertEquals("1.6915321",
- mTestInstance.mTestResults.get("GeoTestHeavyFragHeavyVertex3")[0].toString());
-
- // 6 tests, RenerScript UI Test
- assertEquals("93.370674",
- mTestInstance.mTestResults.get("UITestWithIcon10by10")[0].toString());
- assertEquals("1.2948335",
- mTestInstance.mTestResults.get("UITestWithIcon100by100")[0].toString());
- assertEquals("99.50249",
- mTestInstance.mTestResults.get("UITestWithImageText3")[0].toString());
- assertEquals("77.57951",
- mTestInstance.mTestResults.get("UITestWithImageText5")[0].toString());
- assertEquals("117.78562",
- mTestInstance.mTestResults.get("UITestListView")[0].toString());
- assertEquals("38.197098",
- mTestInstance.mTestResults.get("UITestLiveWallPaper")[0].toString());
- }
-
- // Verify parsing two iterations
- public void testParseTwoInputs() throws Exception {
- String output1 = join(
- "Fill screen with text 1 time, 97.65624,",
- "Fill screen with text 3 times, 36.576443,",
- "UI test with live wallpaper, 38.197098,");
- String output2 = join(
- "Fill screen with text 1 time, 97.56097,",
- "Fill screen with text 3 times, 36.75119,",
- "UI test with live wallpaper, 38.05175,");
-
- InputStream inputStream = new ByteArrayInputStream(output1.getBytes());
- mTestInstance.parseOutputFile(inputStream, 0);
- //mTestInstance.printTestResults();
- inputStream = new ByteArrayInputStream(output2.getBytes());
- mTestInstance.parseOutputFile(inputStream, 1);
- assertNotNull(mTestInstance.mTestResults);
-
- assertEquals("97.65624", mTestInstance.mTestResults.get("text1")[0].toString());
- assertEquals("36.576443", mTestInstance.mTestResults.get("text2")[0].toString());
- assertEquals("38.197098",
- mTestInstance.mTestResults.get("UITestLiveWallPaper")[0].toString());
-
- assertEquals("97.56097", mTestInstance.mTestResults.get("text1")[1].toString());
- assertEquals("36.75119", mTestInstance.mTestResults.get("text2")[1].toString());
- assertEquals("38.05175",
- mTestInstance.mTestResults.get("UITestLiveWallPaper")[1].toString());
- }
- }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/SkiaTest.java b/prod-tests/src/com/android/graphics/tests/SkiaTest.java
deleted file mode 100644
index 9b647dd..0000000
--- a/prod-tests/src/com/android/graphics/tests/SkiaTest.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2014 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.graphics.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.IFileEntry;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-
-import java.io.File;
-import java.util.HashMap;
-
-/**
- * Test for running Skia native tests.
- *
- * The test is not necessarily Skia specific, but it provides
- * functionality that allows native Skia tests to be run.
- *
- * Includes options to specify the Skia test app to run (inside
- * nativetest directory), flags to pass to the test app, and a file
- * to retrieve off the device after the test completes. (Skia test
- * apps record their results to a json file, so retrieving this file
- * allows us to view the results so long as the app completed.)
- */
-@OptionClass(alias = "skia_native_tests")
-public class SkiaTest implements IRemoteTest, IDeviceTest {
- private ITestDevice mDevice;
-
- static final String DEFAULT_NATIVETEST_PATH = "/data/nativetest";
-
- @Option(name = "native-test-device-path",
- description = "The path on the device where native tests are located.")
- private String mNativeTestDevicePath = DEFAULT_NATIVETEST_PATH;
-
- @Option(name = "skia-flags",
- description = "Flags to pass to the skia program.")
- private String mFlags = "";
-
- @Option(name = "skia-app",
- description = "Skia program to run.",
- mandatory = true)
- private String mSkiaApp = "";
-
- @Option(name = "skia-json",
- description = "Full path on device for json output file.")
- private File mOutputFile = null;
-
- @Option(name = "skia-pngs",
- description = "Directory on device for holding png results for retrieval.")
- private File mPngDir = null;
-
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- if (mDevice == null) {
- throw new IllegalArgumentException("Device has not been set");
- }
-
- listener.testRunStarted(mSkiaApp, 1);
- long start = System.currentTimeMillis();
-
- // Native Skia tests are in nativeTestDirectory/mSkiaApp/mSkiaApp.
- String fullPath = mNativeTestDevicePath + "/"
- + mSkiaApp + "/" + mSkiaApp;
- IFileEntry app = mDevice.getFileEntry(fullPath);
- TestDescription testId = new TestDescription(mSkiaApp, "testFileExists");
- listener.testStarted(testId);
- if (app == null) {
- CLog.w("Could not find test %s in %s!", fullPath, mDevice.getSerialNumber());
- listener.testFailed(testId, "Device does not have " + fullPath);
- listener.testEnded(testId, new HashMap<String, Metric>());
- } else {
- // The test for detecting the file has ended.
- listener.testEnded(testId, new HashMap<String, Metric>());
- prepareDevice();
- runTest(app);
- retrieveFiles(mSkiaApp, listener);
- }
-
- listener.testRunEnded(System.currentTimeMillis() - start, new HashMap<String, Metric>());
- }
-
- /**
- * Emulates running mkdirs on an ITestDevice.
- *
- * Creates the directory named by dir *on device*, recursively creating missing parent
- * directories if necessary.
- *
- * @param dir Directory to create.
- */
- private void mkdirs(File dir) throws DeviceNotAvailableException {
- if (dir == null || mDevice.doesFileExist(dir.getPath())) {
- return;
- }
-
- String dirName = dir.getPath();
- CLog.v("creating folder '%s'", dirName);
- mDevice.executeShellCommand("mkdir -p " + dirName);
- }
-
- /**
- * Do pre-test setup on the device.
- *
- * Setup involves ensuring necessary directories exist and removing old
- * test result files.
- */
- private void prepareDevice() throws DeviceNotAvailableException {
- if (mOutputFile != null) {
- String path = mOutputFile.getPath();
- if (mDevice.doesFileExist(path)) {
- // Delete the file. We don't want to think this file from an
- // earlier run represents this one.
- CLog.v("Removing old file " + path);
- mDevice.executeShellCommand("rm " + path);
- } else {
- // Ensure its containing folder exists.
- mkdirs(mOutputFile.getParentFile());
- }
- }
-
- if (mPngDir != null) {
- String pngPath = mPngDir.getPath();
- if (mDevice.doesFileExist(pngPath)) {
- // Empty the old directory
- mDevice.executeShellCommand("rm -rf " + pngPath + "/*");
- } else {
- mkdirs(mPngDir);
- }
- }
- }
-
- /**
- * Retrieve a file from the device and upload it to the listener.
- *
- * <p>Each file for uploading is considered its own test, so we can track whether or not
- * uploading succeeded.
- *
- * @param remoteFile File on the device.
- * @param testIdClass String to be passed to TestDescription's constructor as className.
- * @param testIdMethod String passed to TestDescription's constructor as testName.
- * @param listener Listener for reporting test failure/success and uploading files.
- * @param type LogDataType of the file being uploaded.
- */
- private void retrieveAndUploadFile(
- File remoteFile,
- String testIdClass,
- String testIdMethod,
- ITestInvocationListener listener,
- LogDataType type)
- throws DeviceNotAvailableException {
- String remotePath = remoteFile.getPath();
- CLog.v("adb pull %s (using pullFile)", remotePath);
- File localFile = mDevice.pullFile(remotePath);
-
- TestDescription testId = new TestDescription(testIdClass, testIdMethod);
- listener.testStarted(testId);
- if (localFile == null) {
- listener.testFailed(testId, "Failed to pull " + remotePath);
- } else {
- CLog.v("pulled result file to " + localFile.getPath());
- try (FileInputStreamSource source = new FileInputStreamSource(localFile)) {
- // Use the original name, for clarity.
- listener.testLog(remoteFile.getName(), type, source);
- }
- if (!localFile.delete()) {
- CLog.w("Failed to delete temporary file %s", localFile.getPath());
- }
- }
- listener.testEnded(testId, new HashMap<String, Metric>());
- }
-
- /**
- * Retrieve files from the device.
- *
- * Report to the listener whether retrieving the files succeeded.
- *
- * @param appName Name of the app.
- * @param listener Listener for reporting results of file retrieval.
- */
- private void retrieveFiles(String appName,
- ITestInvocationListener listener) throws DeviceNotAvailableException {
- // FIXME: This could be achieved with DeviceFileReporter. Blocked on b/18408206.
- if (mOutputFile != null) {
- retrieveAndUploadFile(mOutputFile, appName, "outputJson", listener, LogDataType.TEXT);
- }
-
- if (mPngDir != null) {
- String pngDir = mPngDir.getPath();
- IFileEntry remotePngDir = mDevice.getFileEntry(pngDir);
- for (IFileEntry pngFile : remotePngDir.getChildren(false)) {
- if (pngFile.getName().endsWith("png")) {
- retrieveAndUploadFile(new File(pngFile.getFullPath()),
- "PngRetrieval", pngFile.getName(), listener, LogDataType.PNG);
- }
- }
- }
- }
-
- /**
- * Run a test on a device.
- *
- * @param app Test app to run.
- */
- private void runTest(IFileEntry app) throws DeviceNotAvailableException {
- String fullPath = app.getFullEscapedPath();
- // force file to be executable
- mDevice.executeShellCommand(String.format("chmod 755 %s", fullPath));
-
- // The device will not immediately capture logs in response to
- // startLogcat. Instead, it delays 5 * 1000ms. See TestDevice.java
- // mLogStartDelay. To ensure we see all the logs, sleep by the same
- // amount.
- mDevice.startLogcat();
- RunUtil.getDefault().sleep(5 * 1000);
-
- String cmd = fullPath + " " + mFlags;
- CLog.v("Running '%s' on %s", cmd, mDevice.getSerialNumber());
-
- mDevice.executeShellCommand("stop");
- mDevice.executeShellCommand(cmd);
- mDevice.executeShellCommand("start");
- }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/UiPerformanceTest.java b/prod-tests/src/com/android/graphics/tests/UiPerformanceTest.java
deleted file mode 100644
index 5ac9c83..0000000
--- a/prod-tests/src/com/android/graphics/tests/UiPerformanceTest.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2012 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.graphics.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.BugreportCollector;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Run UiPerformanceTest suite which measures the performance of
- * system operations and majors applications.
- */
-public class UiPerformanceTest implements IDeviceTest, IRemoteTest {
- private ITestDevice mTestDevice = null;
- // Define instrumentation test package and runner.
- private static final String TEST_PACKAGE_NAME =
- "com.android.testing.uiautomation.platform.uiperformance";
- // TODO: Add TEST_CLASS_NAME later when different tests requiring
- // different configurations.
- private static final String TEST_RUNNER_NAME =
- "com.android.testing.uiautomation.UiAutomationTestRunner";
- private static final String OUTPUT_FILE_NAME = "UiPerfTestsOutput.txt"; // output file
- private static final String RAW_DATA_DIRECTORY = "UiPerformanceRawData"; // raw data directory
-
- private static final String TEST_CASE_PREFIX = "test";
- private static final long START_TIMER = 2 * 60 * 1000; // 2 minutes
-
- private static final Pattern JANKINESS_PATTERN =
- Pattern.compile("^number of jankiness: (\\d+)");
- private static final Pattern MEDIAN_FRAME_LATENCY_PATTERN =
- Pattern.compile("^median of frame latency: (\\d+)");
- private static final Pattern FRAME_RATE_PATTERN =
- Pattern.compile("^average frame rate: (\\d+\\.\\d+)");
- private static final Pattern[] mPatterns = {
- JANKINESS_PATTERN, FRAME_RATE_PATTERN, MEDIAN_FRAME_LATENCY_PATTERN
- };
- private static final String[] ITEM_KEYS = {"number_jankiness", "frame_rate", "frame_latency"};
-
- @Override
- public void setDevice(ITestDevice testDevice) {
- mTestDevice = testDevice;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-
- private void setupDevice() throws DeviceNotAvailableException {
- cleanOutputFiles();
- String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
- String rawFileDir = String.format("%s/%s", extStore, RAW_DATA_DIRECTORY);
-
- if (!mTestDevice.doesFileExist(rawFileDir)) {
- CLog.v(String.format("The raw directory %s doesn't exist.", RAW_DATA_DIRECTORY));
- mTestDevice.executeShellCommand(String.format("mkdir \"%s\"", rawFileDir));
- } else {
- // remove files
- mTestDevice.executeShellCommand(String.format("rm %s/*", rawFileDir));
- CLog.v("remove files under the raw data directory");
- }
- }
-
- /**
- * Run UiPerformanceTests and parsing results from test output.
- */
- @Override
- public void run(ITestInvocationListener standardListener)
- throws DeviceNotAvailableException {
- Assert.assertNotNull(mTestDevice);
- setupDevice();
- // start the test until device is fully booted and stable
- RunUtil.getDefault().sleep(START_TIMER);
- IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
- TEST_PACKAGE_NAME, TEST_RUNNER_NAME, mTestDevice.getIDevice());
-
- // Add bugreport listener for failed test
- BugreportCollector bugListener = new
- BugreportCollector(standardListener, mTestDevice);
- bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
- bugListener.setDescriptiveName(this.getClass().getName());
- mTestDevice.runInstrumentationTests(runner, bugListener);
- logOutputFile(bugListener);
- pullRawDataFile(bugListener);
- cleanOutputFiles();
- }
-
- private void pullRawDataFile(ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
- String rawFileDir = String.format("%s/%s", extStore, RAW_DATA_DIRECTORY);
-
- String rawFileList =
- mTestDevice.executeShellCommand(String.format("ls \"%s\"", rawFileDir));
- String[] rawFileString = rawFileList.split("\r?\n");
- File resFile = null;
- InputStreamSource outputSource = null;
- for (int i = 0; i < rawFileString.length; i++) {
- CLog.v("file %d is: \"%s\"", i, rawFileString[i]);
- try {
- resFile = mTestDevice.pullFileFromExternal(
- String.format("%s/%s", RAW_DATA_DIRECTORY, rawFileString[i]));
- outputSource = new FileInputStreamSource(resFile, true /* delete */);
- listener.testLog(rawFileString[i], LogDataType.TEXT, outputSource);
- } finally {
- StreamUtil.cancel(outputSource);
- }
- }
- }
-
-
- // Parse the output file
- private void logOutputFile(ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- // catch a bugreport after the test
- try (InputStreamSource bugreport = mTestDevice.getBugreport()) {
- listener.testLog("bugreport", LogDataType.BUGREPORT, bugreport);
- }
-
- File resFile = null;
- InputStreamSource outputSource = null;
- Map<String, String> runMetrics = new HashMap<>();
- BufferedReader br = null;
- try {
- resFile = mTestDevice.pullFileFromExternal(OUTPUT_FILE_NAME);
- if (resFile == null) {
- CLog.v("File %s doesn't exist or pulling the file failed");
- return;
- }
- CLog.d("output file: %s", resFile.getPath());
- // Save a copy of the output file
- CLog.d("Sending %d byte file %s into the logosphere!",
- resFile.length(), resFile);
- outputSource = new FileInputStreamSource(resFile);
- listener.testLog(OUTPUT_FILE_NAME, LogDataType.TEXT, outputSource);
-
- // Parse the results file
- br = new BufferedReader(new FileReader(resFile));
- String line = null;
- String unitKey = null;
- int size = mPatterns.length;
- while ((line = br.readLine()) != null) {
- if (line.startsWith(TEST_CASE_PREFIX)) {
- // report the previous test case results
- if (unitKey != null) {
- reportMetrics(unitKey, listener, runMetrics);
- }
- runMetrics.clear();
- // processing the next test case
- unitKey = line.trim();
- continue;
- } else {
- for (int i = 0; i < size; i++) {
- Matcher match = mPatterns[i].matcher(line);
- if (match.matches()) {
- String value = match.group(1);
- runMetrics.put(ITEM_KEYS[i], value);
- break;
- }
- }
- }
- }
- reportMetrics(unitKey, listener, runMetrics);
- } catch (IOException e) {
- CLog.e("IOException while reading outputfile %s", OUTPUT_FILE_NAME);
- } finally {
- FileUtil.deleteFile(resFile);
- StreamUtil.cancel(outputSource);
- StreamUtil.close(br);
- }
- }
-
- // Report run metrics by creating an empty test run to stick them in
- private void reportMetrics(String metricsName, ITestInvocationListener listener,
- Map<String, String> metrics) {
- // Create an empty testRun to report the parsed runMetrics
- CLog.d("About to report metrics to %s: %s", metricsName, metrics);
- listener.testRunStarted(metricsName, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-
- // clean up output file
- private void cleanOutputFiles() throws DeviceNotAvailableException {
- String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
- mTestDevice.executeShellCommand(String.format("rm %s/%s", extStore, OUTPUT_FILE_NAME));
- }
-}
diff --git a/prod-tests/src/com/android/graphics/tests/UserActionBenchmark.java b/prod-tests/src/com/android/graphics/tests/UserActionBenchmark.java
deleted file mode 100644
index 9448d99..0000000
--- a/prod-tests/src/com/android/graphics/tests/UserActionBenchmark.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2011 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.graphics.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.NullOutputReceiver;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Runs the user action framerate benchmark test. This test capture
- * use the scripted monkey to inject the keyevent to mimic the real
- * user action, capture the average framerate and save the result
- * file to the sdcard.
- * <p/>
- * Note that this test will not run properly unless /sdcard is mounted and
- * writable.
- */
-public class UserActionBenchmark implements IDeviceTest, IRemoteTest {
- private static final String LOG_TAG = "UserActionBenchmark";
-
- ITestDevice mTestDevice = null;
-
- private static final long START_TIMER = 2 * 60 * 1000; // 2 minutes
-
- @Option(name = "test-output-filename", description = "The test output filename.")
- private String mDeviceTestOutputFilename = "avgFrameRateOut.txt";
-
- // The time in ms to wait the scripted monkey finish.
- private static final int CMD_TIMEOUT = 60 * 60 * 1000;
-
- private static final Pattern AVERAGE_FPS = Pattern.compile("(.*):(\\d+.\\d+)");
-
- @Option(name = "test-case", description = "The name of test-cases to run. May be repeated.")
- private Collection<String> mTestCases = new ArrayList<>();
-
- @Option(name = "iteration", description = "Test run iteration")
- private int mIteration = 1;
-
- @Option(name = "throttle", description = "Scripted monkey throttle time")
- private int mThrottle = 500; // in milliseconds
-
- @Option(name = "script-path", description = "Test script path")
- private String mScriptPath = "userActionFPSScript";
-
- @Option(name = "test-label", description = "Test label")
- private String mTestLabel = "UserActionFramerateBenchmark";
-
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- Assert.assertNotNull(mTestDevice);
-
- // Start the test after device is fully booted and stable
- // FIXME: add option in TF to wait until device is booted and stable
- RunUtil.getDefault().sleep(START_TIMER);
-
- String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
- String scriptFullPath =
- String.format("%s/%s/%s", extStore, mScriptPath, mTestDevice.getProductType());
- for (String testCase : mTestCases) {
- // Start the scripted monkey command
- mTestDevice.executeShellCommand(String.format(
- "monkey -f /%s/%s.txt --throttle %d %d", scriptFullPath,
- testCase, mThrottle, mIteration), new NullOutputReceiver(),
- CMD_TIMEOUT, TimeUnit.MILLISECONDS, 2);
- logOutputFiles(listener);
- cleanResultFile();
- }
- }
-
- /**
- * Clean up the test result file from test run
- */
- private void cleanResultFile() throws DeviceNotAvailableException {
- String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
- mTestDevice.executeShellCommand(String.format("rm %s/%s", extStore,
- mDeviceTestOutputFilename));
- }
-
- /**
- * Pull the output files from the device, add it to the logs, and also parse
- * out the relevant test metrics and report them.
- */
- private void logOutputFiles(ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- File outputFile = null;
- InputStreamSource outputSource = null;
- try {
- outputFile = mTestDevice.pullFileFromExternal(mDeviceTestOutputFilename);
-
- if (outputFile == null) {
- return;
- }
-
- // Upload a verbatim copy of the output file
- Log.d(LOG_TAG, String.format("Sending %d byte file %s into the logosphere!",
- outputFile.length(), outputFile));
- outputSource = new FileInputStreamSource(outputFile);
- listener.testLog(mDeviceTestOutputFilename, LogDataType.TEXT, outputSource);
-
- // Parse the output file to upload aggregated metrics
- parseOutputFile(new FileInputStream(outputFile), listener);
- } catch (IOException e) {
- Log.e(LOG_TAG, String.format(
- "IOException while reading or parsing output file: %s", e));
- } finally {
- FileUtil.deleteFile(outputFile);
- StreamUtil.cancel(outputSource);
- }
- }
-
- /**
- * Parse the test result, calculate the average and parse the metrics
- * from the scripted monkey test output file
- */
- private void parseOutputFile(InputStream dataStream,
- ITestInvocationListener listener) {
-
- Map<String, String> runMetrics = new HashMap<>();
-
- // try to parse it
- String contents;
- try {
- contents = StreamUtil.getStringFromStream(dataStream);
- } catch (IOException e) {
- Log.e(LOG_TAG, String.format(
- "Got IOException during test processing: %s", e));
- return;
- }
-
- List<String> lines = Arrays.asList(contents.split("\n"));
- String key = null;
- float averageResult;
- float totalResult = 0;
- int counter = 0;
-
- // collect the result and calculate the average
- for (String line: lines) {
- Matcher m = AVERAGE_FPS.matcher(line);
- if (m.matches()) {
- key = m.group(1);
- totalResult += Float.parseFloat(m.group(2));
- counter++;
- }
- }
- averageResult = totalResult / counter;
- Log.i(LOG_TAG, String.format("averageResult = %s\n", averageResult));
- runMetrics.put(key, Float.toString(averageResult));
- reportMetrics(listener, runMetrics);
- }
-
- /**
- * Report run metrics by creating an empty test run to stick them in
- * <p />
- * Exposed for unit testing
- */
- void reportMetrics(ITestInvocationListener listener, Map<String, String> metrics) {
- Log.d(LOG_TAG, String.format("About to report metrics: %s", metrics));
- listener.testRunStarted(mTestLabel, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-
- @Override
- public void setDevice(ITestDevice device) {
- mTestDevice = device;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-}
diff --git a/prod-tests/src/com/android/monkey/AnrReportGenerator.java b/prod-tests/src/com/android/monkey/AnrReportGenerator.java
deleted file mode 100644
index 68525c0..0000000
--- a/prod-tests/src/com/android/monkey/AnrReportGenerator.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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.monkey;
-
-import com.android.tradefed.log.ITestLogger;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RunUtil;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * A utility class that encapsulates details of calling post-processing scripts to generate monkey
- * ANR reports.
- */
-public class AnrReportGenerator {
-
- private static final long REPORT_GENERATION_TIMEOUT = 30 * 1000; // 30s
-
- private File mCachedMonkeyLog = null;
- private File mCachedBugreport = null;
-
- private final String mReportScriptPath;
- private final String mReportBasePath;
- private final String mReportUrlPrefix;
- private final String mReportPath;
- private final String mDeviceSerial;
-
- private String mBuildId = null;
- private String mBuildFlavor = null;
-
- /**
- * Constructs the instance with details of report script and output location information. See
- * matching options on {@link MonkeyBase} for more info.
- */
- public AnrReportGenerator(String reportScriptPath, String reportBasePath,
- String reportUrlPrefix, String reportPath,
- String buildId, String buildFlavor, String deviceSerial) {
- mReportScriptPath = reportScriptPath;
- mReportBasePath = reportBasePath;
- mReportUrlPrefix = reportUrlPrefix;
- mReportPath = reportPath;
- mBuildId = buildId;
- mBuildFlavor = buildFlavor;
- mDeviceSerial = deviceSerial;
-
- if (mReportBasePath == null || mReportPath == null || mReportScriptPath == null
- || mReportUrlPrefix == null) {
- throw new IllegalArgumentException("ANR post-processing enabled but missing "
- + "required parameters!");
- }
- }
-
- /**
- * Return the storage sub path based on build info. The path will not include trailing path
- * separator.
- */
- private String getPerBuildStoragePath() {
- if (mBuildId == null) {
- mBuildId = "-1";
- }
- if (mBuildFlavor == null) {
- mBuildFlavor = "unknown_flavor";
- }
- return String.format("%s/%s", mBuildId, mBuildFlavor);
- }
-
- /**
- * Sets bugreport information for ANR post-processing script
- * @param bugreportStream
- */
- public void setBugReportInfo(InputStreamSource bugreportStream) throws IOException {
- if (mCachedBugreport != null) {
- CLog.w("A bugreport for this invocation already existed at %s, overriding anyways",
- mCachedBugreport.getAbsolutePath());
- }
- mCachedBugreport = FileUtil.createTempFile("monkey-anr-report-bugreport", ".txt");
- FileUtil.writeToFile(bugreportStream.createInputStream(), mCachedBugreport);
- }
-
- /**
- * Sets monkey log information for ANR post-processing script
- * @param monkeyLogStream
- */
- public void setMonkeyLogInfo(InputStreamSource monkeyLogStream) throws IOException {
- if (mCachedMonkeyLog != null) {
- CLog.w("A monkey log for this invocation already existed at %s, overriding anyways",
- mCachedMonkeyLog.getAbsolutePath());
- }
- mCachedMonkeyLog = FileUtil.createTempFile("monkey-anr-report-monkey-log", ".txt");
- FileUtil.writeToFile(monkeyLogStream.createInputStream(), mCachedMonkeyLog);
- }
-
- public boolean genereateAnrReport(ITestLogger logger) {
- if (mCachedMonkeyLog == null || mCachedBugreport == null) {
- CLog.w("Cannot generate report: bugreport or monkey log not populated yet.");
- return false;
- }
- // generate monkey report and log it
- File reportPath = new File(mReportBasePath,
- String.format("%s/%s", mReportPath, getPerBuildStoragePath()));
- if (reportPath.exists()) {
- if (!reportPath.isDirectory()) {
- CLog.w("The expected report storage path is not a directory: %s",
- reportPath.getAbsolutePath());
- return false;
- }
- } else {
- if (!reportPath.mkdirs()) {
- CLog.w("Failed to create report storage directory: %s",
- reportPath.getAbsolutePath());
- return false;
- }
- }
- // now we should have the storage path, calculate the HTML report path
- // HTML report file should be named as:
- // monkey-anr-report-<device serial>-<random string>.html
- // under the pre-constructed base report storage path
- File htmlReport = null;
- try {
- htmlReport = FileUtil.createTempFile(
- String.format("monkey-anr-report-%s-", mDeviceSerial), ".html",
- reportPath);
- } catch (IOException ioe) {
- CLog.e("Error getting place holder file for HTML report.");
- CLog.e(ioe);
- return false;
- }
- // now ready to call the script
- String htmlReportPath = htmlReport.getAbsolutePath();
- String command[] = {
- mReportScriptPath, "--monkey", mCachedMonkeyLog.getAbsolutePath(), "--html",
- htmlReportPath, mCachedBugreport.getAbsolutePath()
- };
- CommandResult cr = RunUtil.getDefault().runTimedCmdSilently(REPORT_GENERATION_TIMEOUT,
- command);
- if (cr.getStatus() == CommandStatus.SUCCESS) {
- // Test log the generated HTML report
- try (InputStreamSource source = new FileInputStreamSource(htmlReport)) {
- logger.testLog("monkey-anr-report", LogDataType.HTML, source);
- }
- // Clean up and declare success!
- FileUtil.deleteFile(htmlReport);
- return true;
- } else {
- CLog.w(cr.getStderr());
- return false;
- }
- }
-
- public void cleanTempFiles() {
- FileUtil.deleteFile(mCachedBugreport);
- FileUtil.deleteFile(mCachedMonkeyLog);
- }
-}
diff --git a/prod-tests/src/com/android/monkey/AppPkgInjector.java b/prod-tests/src/com/android/monkey/AppPkgInjector.java
deleted file mode 100644
index 8250bc2..0000000
--- a/prod-tests/src/com/android/monkey/AppPkgInjector.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2012 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.monkey;
-
-import com.android.tradefed.build.IAppBuildInfo;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.VersionedFile;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationReceiver;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.targetprep.BaseTargetPreparer;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.ITargetPreparer;
-import com.android.tradefed.targetprep.TargetSetupError;
-import com.android.tradefed.util.AaptParser;
-
-import org.junit.Assert;
-
-/**
- * A {@link ITargetPreparer} for {@link IAppBuildInfo}, that dynamically determines the app package
- * name given its apk file. This saves the user from having to manually specify the --package arg
- * when running monkey.
- *
- * <p>Requires that aapt is on current path.
- */
-public class AppPkgInjector extends BaseTargetPreparer implements IConfigurationReceiver {
-
- @Option(name = "skip-injector", description = "Set to true if we should skip automatically " +
- "adding all package names of installed packages. Default is false.")
- private boolean mSkipInjecting = false;
-
- private IConfiguration mConfig;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setConfiguration(IConfiguration configuration) {
- mConfig = configuration;
-
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
- BuildError, DeviceNotAvailableException {
- if (mSkipInjecting) {
- return;
- }
- Assert.assertNotNull(mConfig);
- Assert.assertTrue("provided build is not a IAppBuildInfo",
- buildInfo instanceof IAppBuildInfo);
- IAppBuildInfo appBuild = (IAppBuildInfo)buildInfo;
- for (VersionedFile apkFile : appBuild.getAppPackageFiles()) {
- AaptParser aapt = AaptParser.parse(apkFile.getFile());
- if (aapt == null) {
- // throw a build error because typically aapt parse errors are issues with the apk
- throw new BuildError(String.format("aapt parse of %s failed",
- apkFile.getFile().getAbsolutePath()), device.getDeviceDescriptor());
- }
- String pkgName = aapt.getPackageName();
- if (pkgName == null) {
- // this should never happen
- throw new TargetSetupError(String.format("Failed to parse package name from %s",
- apkFile.getFile().getAbsolutePath()), device.getDeviceDescriptor());
- }
- try {
- mConfig.injectOptionValue("package", pkgName);
- } catch (ConfigurationException e) {
- throw new TargetSetupError("Failed to inject --package option.", e,
- device.getDeviceDescriptor());
- }
- }
- }
-}
diff --git a/prod-tests/src/com/android/monkey/MonkeyBase.java b/prod-tests/src/com/android/monkey/MonkeyBase.java
deleted file mode 100644
index 6b27bda..0000000
--- a/prod-tests/src/com/android/monkey/MonkeyBase.java
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- * Copyright (C) 2012 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.monkey;
-
-import com.android.ddmlib.CollectingOutputReceiver;
-import com.android.ddmlib.IShellOutputReceiver;
-import com.android.loganalysis.item.AnrItem;
-import com.android.loganalysis.item.BugreportItem;
-import com.android.loganalysis.item.MiscKernelLogItem;
-import com.android.loganalysis.item.MonkeyLogItem;
-import com.android.loganalysis.parser.BugreportParser;
-import com.android.loganalysis.parser.KernelLogParser;
-import com.android.loganalysis.parser.MonkeyLogParser;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ByteArrayInputStreamSource;
-import com.android.tradefed.result.DeviceFileReporter;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.testtype.IRetriableTest;
-import com.android.tradefed.util.ArrayUtil;
-import com.android.tradefed.util.Bugreport;
-import com.android.tradefed.util.CircularAtraceUtil;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.IRunUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Runner for stress tests which use the monkey command.
- */
-public class MonkeyBase implements IDeviceTest, IRemoteTest, IRetriableTest {
-
- public static final String MONKEY_LOG_NAME = "monkey_log";
- public static final String BUGREPORT_NAME = "bugreport";
-
- /**
- * Allow a 15 second buffer between the monkey run time and the delta uptime.
- */
- public static final long UPTIME_BUFFER = 15 * 1000;
-
- private static final String DEVICE_WHITELIST_PATH = "/data/local/tmp/monkey_whitelist.txt";
-
- /**
- * am command template to launch app intent with same action, category and task flags as if user
- * started it from the app's launcher icon
- */
- private static final String LAUNCH_APP_CMD = "am start -W -n '%s' " +
- "-a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x10200000";
-
- private static final String NULL_UPTIME = "0.00";
-
- /**
- * Helper to run a monkey command with an absolute timeout.
- * <p>
- * This is used so that the command can be stopped after a set timeout, since the timeout that
- * {@link ITestDevice#executeShellCommand(String, IShellOutputReceiver, long, TimeUnit, int)}
- * takes applies to the time between output, not the overall time of the command.
- * </p>
- */
- private class CommandHelper {
- private DeviceNotAvailableException mException = null;
- private String mOutput = null;
-
- public void runCommand(final ITestDevice device, final String command, long timeout)
- throws DeviceNotAvailableException {
- final CollectingOutputReceiver receiver = new CollectingOutputReceiver();
- Thread t = new Thread() {
- @Override
- public void run() {
- try {
- device.executeShellCommand(command, receiver);
- } catch (DeviceNotAvailableException e) {
- mException = e;
- }
- }
- };
-
- t.start();
-
- try {
- t.join(timeout);
- } catch (InterruptedException e) {
- // Ignore and log. The thread should terminate once receiver.cancel() is called.
- CLog.e("Thread was interrupted while running %s", command);
- }
-
- mOutput = receiver.getOutput();
- receiver.cancel();
-
- if (mException != null) {
- throw mException;
- }
- }
-
- public String getOutput() {
- return mOutput;
- }
- }
-
- @Option(name = "package", description = "Package name to send events to. May be repeated.")
- private Collection<String> mPackages = new LinkedList<>();
-
- @Option(name = "exclude-package", description = "Substring of package names to exclude from " +
- "the package list. May be repeated.", importance = Importance.IF_UNSET)
- private Collection<String> mExcludePackages = new HashSet<>();
-
- @Option(name = "category", description = "App Category. May be repeated.")
- private Collection<String> mCategories = new LinkedList<>();
-
- @Option(name = "option", description = "Option to pass to monkey command. May be repeated.")
- private Collection<String> mOptions = new LinkedList<>();
-
- @Option(name = "launch-extras-int", description = "Launch int extras. May be repeated. " +
- "Format: --launch-extras-i key value. Note: this will be applied to all components.")
- private Map<String, Integer> mIntegerExtras = new HashMap<>();
-
- @Option(name = "launch-extras-str", description = "Launch string extras. May be repeated. " +
- "Format: --launch-extras-s key value. Note: this will be applied to all components.")
- private Map<String, String> mStringExtras = new HashMap<>();
-
- @Option(name = "target-count", description = "Target number of events to send.",
- importance = Importance.ALWAYS)
- private int mTargetCount = 125000;
-
- @Option(name = "random-seed", description = "Random seed to use for the monkey.")
- private Long mRandomSeed = null;
-
- @Option(name = "throttle", description = "How much time to wait between sending successive " +
- "events, in msecs. Default is 0ms.")
- private int mThrottle = 0;
-
- @Option(name = "ignore-crashes", description = "Monkey should keep going after encountering " +
- "an app crash")
- private boolean mIgnoreCrashes = false;
-
- @Option(name = "ignore-timeout", description = "Monkey should keep going after encountering " +
- "an app timeout (ANR)")
- private boolean mIgnoreTimeouts = false;
-
- @Option(name = "reboot-device", description = "Reboot device before running monkey. Defaults " +
- "to true.")
- private boolean mRebootDevice = true;
-
- @Option(name = "idle-time", description = "How long to sleep before running monkey, in secs")
- private int mIdleTimeSecs = 5 * 60;
-
- @Option(name = "monkey-arg", description = "Extra parameters to pass onto monkey. Key/value " +
- "pairs should be passed as key:value. May be repeated.")
- private Collection<String> mMonkeyArgs = new LinkedList<>();
-
- @Option(name = "use-pkg-whitelist-file", description = "Whether to use the monkey " +
- "--pkg-whitelist-file option to work around cmdline length limits")
- private boolean mUseWhitelistFile = false;
-
- @Option(name = "monkey-timeout", description = "How long to wait for the monkey to " +
- "complete, in minutes. Default is 4 hours.")
- private int mMonkeyTimeout = 4 * 60;
-
- @Option(name = "warmup-component", description = "Component name of app to launch for " +
- "\"warming up\" before monkey test, will be used in an intent together with standard " +
- "flags and parameters as launched from Launcher. May be repeated")
- private List<String> mLaunchComponents = new ArrayList<>();
-
- @Option(name = "retry-on-failure", description = "Retry the test on failure")
- private boolean mRetryOnFailure = false;
-
- // FIXME: Remove this once traces.txt is no longer needed.
- @Option(name = "upload-file-pattern", description = "File glob of on-device files to upload " +
- "if found. Takes two arguments: the glob, and the file type " +
- "(text/xml/zip/gzip/png/unknown). May be repeated.")
- private Map<String, LogDataType> mUploadFilePatterns = new LinkedHashMap<>();
-
- @Option(name = "screenshot", description = "Take a device screenshot on monkey completion")
- private boolean mScreenshot = false;
-
- @Option(name = "ignore-security-exceptions",
- description = "Ignore SecurityExceptions while injecting events")
- private boolean mIgnoreSecurityExceptions = true;
-
- @Option(name = "collect-atrace",
- description = "Enable a continuous circular buffer to collect atrace information")
- private boolean mAtraceEnabled = false;
-
- // options for generating ANR report via post processing script
- @Option(name = "generate-anr-report", description = "Generate ANR report via post-processing")
- private boolean mGenerateAnrReport = false;
-
- @Option(name = "anr-report-script", description = "Path to the script for monkey ANR "
- + "report generation.")
- private String mAnrReportScriptPath = null;
-
- @Option(name = "anr-report-storage-backend-base-path", description = "Base path to the storage "
- + "backend used for saving the reports")
- private String mAnrReportBasePath = null;
-
- @Option(name = "anr-report-storage-backend-url-prefix", description = "URL prefix for the "
- + "storage backend that would enable web acess to the stored reports.")
- private String mAnrReportUrlPrefix = null;
-
- @Option(name = "anr-report-storage-path", description = "Sub path under the base storage "
- + "location for generated monkey ANR reports.")
- private String mAnrReportPath = null;
-
- private ITestDevice mTestDevice = null;
- private MonkeyLogItem mMonkeyLog = null;
- private BugreportItem mBugreport = null;
- private AnrReportGenerator mAnrGen = null;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- Assert.assertNotNull(getDevice());
-
- TestDescription id = new TestDescription(getClass().getCanonicalName(), "monkey");
- long startTime = System.currentTimeMillis();
-
- listener.testRunStarted(getClass().getCanonicalName(), 1);
- listener.testStarted(id);
-
- try {
- runMonkey(listener);
- } finally {
- listener.testEnded(id, new HashMap<String, Metric>());
- listener.testRunEnded(
- System.currentTimeMillis() - startTime, new HashMap<String, Metric>());
- }
- }
-
- /**
- * Returns the command that should be used to launch the app,
- */
- private String getAppCmdWithExtras() {
- String extras = "";
- for (Map.Entry<String, String> sEntry : mStringExtras.entrySet()) {
- extras += String.format(" -e %s %s", sEntry.getKey(), sEntry.getValue());
- }
- for (Map.Entry<String, Integer> sEntry : mIntegerExtras.entrySet()) {
- extras += String.format(" --ei %s %d", sEntry.getKey(), sEntry.getValue());
- }
- return LAUNCH_APP_CMD + extras;
- }
-
- /**
- * Run the monkey one time and return a {@link MonkeyLogItem} for the run.
- */
- protected void runMonkey(ITestInvocationListener listener) throws DeviceNotAvailableException {
- ITestDevice device = getDevice();
- if (mRebootDevice) {
- CLog.v("Rebooting device prior to running Monkey");
- device.reboot();
- } else {
- CLog.v("Pre-run reboot disabled; skipping...");
- }
-
- if (mIdleTimeSecs > 0) {
- CLog.i("Sleeping for %d seconds to allow device to settle...", mIdleTimeSecs);
- getRunUtil().sleep(mIdleTimeSecs * 1000);
- CLog.i("Done sleeping.");
- }
-
- // launch the list of apps that needs warm-up
- for (String componentName : mLaunchComponents) {
- getDevice().executeShellCommand(String.format(getAppCmdWithExtras(), componentName));
- // give it some more time to settle down
- getRunUtil().sleep(5000);
- }
-
- if (mUseWhitelistFile) {
- // Use \r\n for new lines on the device.
- String whitelist = ArrayUtil.join("\r\n", setSubtract(mPackages, mExcludePackages));
- device.pushString(whitelist.toString(), DEVICE_WHITELIST_PATH);
- }
-
- // Generate the monkey command to run, given the options
- String command = buildMonkeyCommand();
- CLog.i("About to run monkey with at %d minute timeout: %s", mMonkeyTimeout, command);
-
- StringBuilder outputBuilder = new StringBuilder();
- CommandHelper commandHelper = new CommandHelper();
-
- long start = System.currentTimeMillis();
- long duration = 0;
- Date dateAfter = null;
- String uptimeAfter = NULL_UPTIME;
- FileInputStreamSource atraceStream = null;
-
- // Generate the monkey log prefix, which includes the device uptime
- outputBuilder.append(String.format("# %s - device uptime = %s: Monkey command used " +
- "for this test:\nadb shell %s\n\n", new Date().toString(), getUptime(), command));
-
- // Start atrace before running the monkey command, but after reboot
- if (mAtraceEnabled) {
- CircularAtraceUtil.startTrace(getDevice(), null, 10);
- }
-
- if (mGenerateAnrReport) {
- mAnrGen = new AnrReportGenerator(mAnrReportScriptPath, mAnrReportBasePath,
- mAnrReportUrlPrefix, mAnrReportPath, mTestDevice.getBuildId(),
- mTestDevice.getBuildFlavor(), mTestDevice.getSerialNumber());
- }
-
- try {
- onMonkeyStart();
- commandHelper.runCommand(mTestDevice, command, getMonkeyTimeoutMs());
- } finally {
- // Wait for device to recover if it's not online. If it hasn't recovered, ignore.
- try {
- mTestDevice.waitForDeviceOnline(2 * 60 * 1000);
- duration = System.currentTimeMillis() - start;
- dateAfter = new Date();
- uptimeAfter = getUptime();
- onMonkeyFinish();
- takeScreenshot(listener, "screenshot");
-
- if (mAtraceEnabled) {
- atraceStream = CircularAtraceUtil.endTrace(getDevice());
- }
-
- mBugreport = takeBugreport(listener, BUGREPORT_NAME);
- // FIXME: Remove this once traces.txt is no longer needed.
- takeTraces(listener);
- } finally {
- // @@@ DO NOT add anything that requires device interaction into this block @@@
- // @@@ logging that no longer requires device interaction MUST be in this block @@@
- outputBuilder.append(commandHelper.getOutput());
- if (dateAfter == null) {
- dateAfter = new Date();
- }
-
- // Generate the monkey log suffix, which includes the device uptime.
- outputBuilder.append(String.format("\n# %s - device uptime = %s: Monkey command "
- + "ran for: %d:%02d (mm:ss)\n", dateAfter.toString(), uptimeAfter,
- duration / 1000 / 60, duration / 1000 % 60));
- mMonkeyLog = createMonkeyLog(listener, MONKEY_LOG_NAME, outputBuilder.toString());
-
- boolean isAnr = mMonkeyLog.getCrash() instanceof AnrItem;
- if (mAtraceEnabled && isAnr) {
- // This was identified as an ANR; post atrace data
- listener.testLog("circular-atrace", LogDataType.TEXT, atraceStream);
- }
- if (mAnrGen != null) {
- if (isAnr) {
- if (!mAnrGen.genereateAnrReport(listener)) {
- CLog.w("Failed to post-process ANR.");
- } else {
- CLog.i("Successfully post-processed ANR.");
- }
- mAnrGen.cleanTempFiles();
- } else {
- CLog.d("ANR post-processing enabled but no ANR detected.");
- }
- }
- StreamUtil.cancel(atraceStream);
- }
- }
-
- // Extra logs for what was found
- if (mBugreport != null && mBugreport.getLastKmsg() != null) {
- List<MiscKernelLogItem> kernelErrors = mBugreport.getLastKmsg().getMiscEvents(
- KernelLogParser.KERNEL_ERROR);
- List<MiscKernelLogItem> kernelResets = mBugreport.getLastKmsg().getMiscEvents(
- KernelLogParser.KERNEL_ERROR);
- CLog.d("Found %d kernel errors and %d kernel resets in last kmsg",
- kernelErrors.size(), kernelResets.size());
- for (int i = 0; i < kernelErrors.size(); i++) {
- String stack = kernelErrors.get(i).getStack();
- if (stack != null) {
- CLog.d("Kernel Error #%d: %s", i + 1, stack.split("\n")[0].trim());
- }
- }
- for (int i = 0; i < kernelResets.size(); i++) {
- String stack = kernelResets.get(i).getStack();
- if (stack != null) {
- CLog.d("Kernel Reset #%d: %s", i + 1, stack.split("\n")[0].trim());
- }
- }
- }
-
- checkResults();
- }
-
- /**
- * A hook to allow subclasses to perform actions just before the monkey starts.
- */
- protected void onMonkeyStart() {
- // empty
- }
-
- /**
- * A hook to allow sublaccess to perform actions just after the monkey finished.
- */
- protected void onMonkeyFinish() {
- // empty
- }
-
- /**
- * If enabled, capture a screenshot and send it to a listener.
- * @throws DeviceNotAvailableException
- */
- protected void takeScreenshot(ITestInvocationListener listener, String screenshotName)
- throws DeviceNotAvailableException {
- if (mScreenshot) {
- try (InputStreamSource screenshot = mTestDevice.getScreenshot("JPEG")) {
- listener.testLog(screenshotName, LogDataType.JPEG, screenshot);
- }
- }
- }
-
- /**
- * Capture a bugreport and send it to a listener.
- */
- protected BugreportItem takeBugreport(ITestInvocationListener listener, String bugreportName) {
- Bugreport bugreport = mTestDevice.takeBugreport();
- if (bugreport == null) {
- CLog.e("Could not take bugreport");
- return null;
- }
- bugreport.log(bugreportName, listener);
- File main = null;
- InputStreamSource is = null;
- try {
- main = bugreport.getMainFile();
- if (main == null) {
- CLog.e("Bugreport has no main file");
- return null;
- }
- if (mAnrGen != null) {
- is = new FileInputStreamSource(main);
- mAnrGen.setBugReportInfo(is);
- }
- return new BugreportParser().parse(new BufferedReader(new FileReader(main)));
- } catch (IOException e) {
- CLog.e("Could not process bugreport");
- CLog.e(e);
- return null;
- } finally {
- StreamUtil.close(bugreport);
- StreamUtil.cancel(is);
- FileUtil.deleteFile(main);
- }
- }
-
- protected void takeTraces(ITestInvocationListener listener) {
- DeviceFileReporter dfr = new DeviceFileReporter(mTestDevice, listener);
- dfr.addPatterns(mUploadFilePatterns);
- try {
- dfr.run();
- } catch (DeviceNotAvailableException e) {
- // Log but don't throw
- CLog.e("Device %s became unresponsive while pulling files",
- mTestDevice.getSerialNumber());
- }
- }
-
- /**
- * Create the monkey log, parse it, and send it to a listener.
- */
- protected MonkeyLogItem createMonkeyLog(ITestInvocationListener listener, String monkeyLogName,
- String log) {
- try (InputStreamSource source = new ByteArrayInputStreamSource(log.getBytes())) {
- if (mAnrGen != null) {
- mAnrGen.setMonkeyLogInfo(source);
- }
- listener.testLog(monkeyLogName, LogDataType.MONKEY_LOG, source);
- return new MonkeyLogParser().parse(new BufferedReader(new InputStreamReader(
- source.createInputStream())));
- } catch (IOException e) {
- CLog.e("Could not process monkey log.");
- CLog.e(e);
- return null;
- }
- }
-
- /**
- * A helper method to build a monkey command given the specified arguments.
- * <p>
- * Actual output argument order is:
- * {@code monkey [-p PACKAGE]... [-c CATEGORY]... [--OPTION]... -s SEED -v -v -v COUNT}
- * </p>
- *
- * @return a {@link String} containing the command with the arguments assembled in the proper
- * order.
- */
- protected String buildMonkeyCommand() {
- List<String> cmdList = new LinkedList<>();
- cmdList.add("monkey");
-
- if (!mUseWhitelistFile) {
- for (String pkg : setSubtract(mPackages, mExcludePackages)) {
- cmdList.add("-p");
- cmdList.add(pkg);
- }
- }
-
- for (String cat : mCategories) {
- cmdList.add("-c");
- cmdList.add(cat);
- }
-
- if (mIgnoreSecurityExceptions) {
- cmdList.add("--ignore-security-exceptions");
- }
-
- if (mThrottle >= 1) {
- cmdList.add("--throttle");
- cmdList.add(Integer.toString(mThrottle));
- }
- if (mIgnoreCrashes) {
- cmdList.add("--ignore-crashes");
- }
- if (mIgnoreTimeouts) {
- cmdList.add("--ignore-timeouts");
- }
-
- if (mUseWhitelistFile) {
- cmdList.add("--pkg-whitelist-file");
- cmdList.add(DEVICE_WHITELIST_PATH);
- }
-
- for (String arg : mMonkeyArgs) {
- String[] args = arg.split(":");
- cmdList.add(String.format("--%s", args[0]));
- if (args.length > 1) {
- cmdList.add(args[1]);
- }
- }
-
- cmdList.addAll(mOptions);
-
- cmdList.add("-s");
- if (mRandomSeed == null) {
- // Pick a number that is random, but in a small enough range that some seeds are likely
- // to be repeated
- cmdList.add(Long.toString(new Random().nextInt(1000)));
- } else {
- cmdList.add(Long.toString(mRandomSeed));
- }
-
- // verbose
- cmdList.add("-v");
- cmdList.add("-v");
- cmdList.add("-v");
- cmdList.add(Integer.toString(mTargetCount));
-
- return ArrayUtil.join(" ", cmdList);
- }
-
- /**
- * Get a {@link String} containing the number seconds since the device was booted.
- * <p>
- * {@code NULL_UPTIME} is returned if the device becomes unresponsive. Used in the monkey log
- * prefix and suffix.
- * </p>
- */
- protected String getUptime() {
- try {
- // make two attempts to get valid uptime
- for (int i = 0; i < 2; i++) {
- // uptime will typically have a format like "5278.73 1866.80". Use the first one
- // (which is wall-time)
- String uptime = mTestDevice.executeShellCommand("cat /proc/uptime").split(" ")[0];
- try {
- Float.parseFloat(uptime);
- // if this parsed, its a valid uptime
- return uptime;
- } catch (NumberFormatException e) {
- CLog.w("failed to get valid uptime from %s. Received: '%s'",
- mTestDevice.getSerialNumber(), uptime);
- }
- }
- } catch (DeviceNotAvailableException e) {
- CLog.e("Device %s became unresponsive while getting the uptime.",
- mTestDevice.getSerialNumber());
- }
- return NULL_UPTIME;
- }
-
- /**
- * Perform set subtraction between two {@link Collection} objects.
- * <p>
- * The return value will consist of all of the elements of {@code keep}, excluding the elements
- * that are also in {@code exclude}. Exposed for unit testing.
- * </p>
- *
- * @param keep the minuend in the subtraction
- * @param exclude the subtrahend
- * @return the collection of elements in {@code keep} that are not also in {@code exclude}. If
- * {@code keep} is an ordered {@link Collection}, the remaining elements in the return value
- * will remain in their original order.
- */
- static Collection<String> setSubtract(Collection<String> keep, Collection<String> exclude) {
- if (exclude.isEmpty()) {
- return keep;
- }
-
- Collection<String> output = new ArrayList<>(keep);
- output.removeAll(exclude);
- return output;
- }
-
- /**
- * Get {@link IRunUtil} to use. Exposed for unit testing.
- */
- IRunUtil getRunUtil() {
- return RunUtil.getDefault();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mTestDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-
- /**
- * {@inheritDoc}
- *
- * @return {@code false} if retry-on-failure is not set, if the monkey ran to completion,
- * crashed in an understood way, or if there were no packages to run, {@code true} otherwise.
- */
- @Override
- public boolean isRetriable() {
- return mRetryOnFailure;
- }
-
- /**
- * Check the results and return if valid or throw an assertion error if not valid.
- */
- private void checkResults() {
- Assert.assertNotNull("Monkey log is null", mMonkeyLog);
- Assert.assertNotNull("Bugreport is null", mBugreport);
- Assert.assertNotNull("Bugreport is empty", mBugreport.getTime());
-
- // If there are no activities, retrying the test won't matter.
- if (mMonkeyLog.getNoActivities()) {
- return;
- }
-
- Assert.assertNotNull("Start uptime is missing", mMonkeyLog.getStartUptimeDuration());
- Assert.assertNotNull("Stop uptime is missing", mMonkeyLog.getStopUptimeDuration());
- Assert.assertNotNull("Total duration is missing", mMonkeyLog.getTotalDuration());
-
- long startUptime = mMonkeyLog.getStartUptimeDuration();
- long stopUptime = mMonkeyLog.getStopUptimeDuration();
- long totalDuration = mMonkeyLog.getTotalDuration();
-
- Assert.assertTrue("Uptime failure",
- stopUptime - startUptime > totalDuration - UPTIME_BUFFER);
-
- // False count
- Assert.assertFalse("False count", mMonkeyLog.getIsFinished() &&
- mMonkeyLog.getTargetCount() - mMonkeyLog.getIntermediateCount() > 100);
-
- // Monkey finished or crashed, so don't fail
- if (mMonkeyLog.getIsFinished() || mMonkeyLog.getFinalCount() != null) {
- return;
- }
-
- // Missing count
- Assert.fail("Missing count");
- }
-
- /**
- * Get the monkey timeout in milliseconds
- */
- protected long getMonkeyTimeoutMs() {
- return mMonkeyTimeout * 60 * 1000;
- }
-}
diff --git a/prod-tests/src/com/android/monkey/MonkeyBrillopadForwarder.java b/prod-tests/src/com/android/monkey/MonkeyBrillopadForwarder.java
deleted file mode 100644
index a3314ea..0000000
--- a/prod-tests/src/com/android/monkey/MonkeyBrillopadForwarder.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2012 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.monkey;
-
-import com.android.loganalysis.item.AnrItem;
-import com.android.loganalysis.item.BugreportItem;
-import com.android.loganalysis.item.IItem;
-import com.android.loganalysis.item.JavaCrashItem;
-import com.android.loganalysis.item.LogcatItem;
-import com.android.loganalysis.item.MonkeyLogItem;
-import com.android.loganalysis.item.NativeCrashItem;
-import com.android.loganalysis.parser.BugreportParser;
-import com.android.loganalysis.parser.MonkeyLogParser;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.ResultForwarder;
-import com.android.tradefed.result.TestDescription;
-
-import com.google.common.base.Throwables;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A {@link ResultForwarder} that intercepts monkey and bug report logs, extracts relevant metrics
- * from them using brillopad, and forwards the results to the specified
- * {@link ITestInvocationListener}.
- */
-public class MonkeyBrillopadForwarder extends ResultForwarder {
-
- private enum MonkeyStatus {
- FINISHED("Money completed without errors."),
- CRASHED("Monkey run stopped because of a crash."),
- MISSING_COUNT("Monkey run failed to complete due to an unknown reason. " +
- "Check logs for details."),
- FALSE_COUNT("Monkey run reported an invalid count. " +
- "Check logs for details."),
- UPTIME_FAILURE("Monkey output is indicating an invalid uptime. " +
- "Device may have reset during run."),
- TIMEOUT("Monkey did not complete within the specified time");
-
- private String mDescription;
-
- MonkeyStatus(String desc) {
- mDescription = desc;
- }
-
- /** Returns a User friendly description of the status. */
- String getDescription() {
- return mDescription;
- }
- }
-
- private BugreportItem mBugreport = null;
- private MonkeyLogItem mMonkeyLog = null;
- private final long mMonkeyTimeoutMs;
-
- public MonkeyBrillopadForwarder(ITestInvocationListener listener, long monkeyTimeoutMs) {
- super(listener);
- mMonkeyTimeoutMs = monkeyTimeoutMs;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void testLog(String dataName, LogDataType dataType, InputStreamSource dataStream) {
- try {
- // just parse the logs for now. Forwarding of results will happen on test completion
- if (LogDataType.BUGREPORT.equals(dataType)) {
- CLog.i("Parsing %s", dataName);
- mBugreport = new BugreportParser().parse(new BufferedReader(new InputStreamReader(
- dataStream.createInputStream())));
- }
- if (LogDataType.MONKEY_LOG.equals(dataType)) {
- CLog.i("Parsing %s", dataName);
- mMonkeyLog = new MonkeyLogParser().parse(new BufferedReader(new InputStreamReader(
- dataStream.createInputStream())));
- }
- } catch (IOException e) {
- CLog.e("Could not parse file %s", dataName);
- }
- super.testLog(dataName, dataType, dataStream);
- }
-
- /** {@inheritDoc} */
- @Override
- public void testEnded(TestDescription monkeyTest, Map<String, String> metrics) {
- Map<String, String> monkeyMetrics = new HashMap<String, String>();
- try {
- Assert.assertNotNull("Failed to parse or retrieve bug report", mBugreport);
- Assert.assertNotNull("Cannot report run to brillopad, monkey log does not exist",
- mMonkeyLog);
- Assert.assertNotNull("monkey log is missing start time info",
- mMonkeyLog.getStartUptimeDuration());
- Assert.assertNotNull("monkey log is missing stop time info",
- mMonkeyLog.getStopUptimeDuration());
- LogcatItem systemLog = mBugreport.getSystemLog();
-
- MonkeyStatus status = reportMonkeyStats(mMonkeyLog, monkeyMetrics);
- StringBuilder crashTrace = new StringBuilder();
- reportAnrs(mMonkeyLog, monkeyMetrics, crashTrace);
- reportJavaCrashes(mMonkeyLog, monkeyMetrics, crashTrace);
- if (systemLog != null) {
- reportNativeCrashes(systemLog, monkeyMetrics, crashTrace);
- } else {
- CLog.w("Failed to get system log from bugreport");
- }
-
- if (!status.equals(MonkeyStatus.FINISHED)) {
- String failure = String.format("%s.\n%s", status.getDescription(),
- crashTrace.toString());
- super.testFailed(monkeyTest, failure);
- }
- } catch (AssertionError e) {
- super.testFailed(monkeyTest, Throwables.getStackTraceAsString(e));
- } catch (RuntimeException e) {
- super.testFailed(monkeyTest, Throwables.getStackTraceAsString(e));
- } finally {
- super.testEnded(monkeyTest, monkeyMetrics);
- }
- }
-
- /**
- * Report stats about the monkey run from the monkey log.
- */
- private MonkeyStatus reportMonkeyStats(MonkeyLogItem monkeyLog,
- Map<String, String> monkeyMetrics) {
- MonkeyStatus status = getStatus(monkeyLog);
- monkeyMetrics.put("throttle", convertToString(monkeyLog.getThrottle()));
- monkeyMetrics.put("status", status.toString());
- monkeyMetrics.put("target_count", convertToString(monkeyLog.getTargetCount()));
- monkeyMetrics.put("injected_count", convertToString(monkeyLog.getFinalCount()));
- monkeyMetrics.put("run_duration", convertToString(monkeyLog.getTotalDuration()));
- monkeyMetrics.put("uptime", convertToString((monkeyLog.getStopUptimeDuration() -
- monkeyLog.getStartUptimeDuration())));
- return status;
- }
-
- /**
- * A utility method that converts an {@link Integer} to a {@link String}, and that can handle
- * null.
- */
- private static String convertToString(Integer integer) {
- return integer == null ? "" : integer.toString();
- }
-
- /**
- * A utility method that converts a {@link Long} to a {@link String}, and that can handle null.
- */
- private static String convertToString(Long longInt) {
- return longInt == null ? "" : longInt.toString();
- }
-
- /**
- * Report stats about Java crashes from the monkey log.
- */
- private void reportJavaCrashes(MonkeyLogItem monkeyLog, Map<String, String> metrics,
- StringBuilder crashTrace) {
-
- if (monkeyLog.getCrash() != null && monkeyLog.getCrash() instanceof JavaCrashItem) {
- JavaCrashItem jc = (JavaCrashItem) monkeyLog.getCrash();
- metrics.put("java_crash", "1");
- crashTrace.append("Detected java crash:\n");
- crashTrace.append(jc.getStack());
- crashTrace.append("\n");
- }
- }
-
- /**
- * Report stats about the native crashes from the bugreport.
- */
- private void reportNativeCrashes(LogcatItem systemLog, Map<String, String> metrics,
- StringBuilder crashTrace) {
- if (systemLog.getEvents().size() > 0) {
- int nativeCrashes = 0;
- for (IItem item : systemLog.getEvents()) {
- if (item instanceof NativeCrashItem) {
- nativeCrashes++;
- crashTrace.append("Detected native crash:\n");
- crashTrace.append(((NativeCrashItem)item).getStack());
- crashTrace.append("\n");
- }
- }
- metrics.put("native_crash", Integer.toString(nativeCrashes));
- }
- }
-
- /**
- * Report stats about the ANRs from the monkey log.
- */
- private void reportAnrs(MonkeyLogItem monkeyLog, Map<String, String> metrics,
- StringBuilder crashTrace) {
- if (monkeyLog.getCrash() != null && monkeyLog.getCrash() instanceof AnrItem) {
- AnrItem anr = (AnrItem) monkeyLog.getCrash();
- metrics.put("anr_crash", "1");
- crashTrace.append("Detected ANR:\n");
- crashTrace.append(anr.getStack());
- crashTrace.append("\n");
- }
- }
-
- /**
- * Return the {@link MonkeyStatus} based on how the monkey run ran.
- */
- private MonkeyStatus getStatus(MonkeyLogItem monkeyLog) {
- // Uptime
- try {
- long startUptime = monkeyLog.getStartUptimeDuration();
- long stopUptime = monkeyLog.getStopUptimeDuration();
- long totalDuration = monkeyLog.getTotalDuration();
- if (stopUptime - startUptime < totalDuration - MonkeyBase.UPTIME_BUFFER) {
- return MonkeyStatus.UPTIME_FAILURE;
- }
- if (totalDuration >= mMonkeyTimeoutMs) {
- return MonkeyStatus.TIMEOUT;
- }
- } catch (NullPointerException e) {
- return MonkeyStatus.UPTIME_FAILURE;
- }
-
- // False count
- if (monkeyLog.getIsFinished() &&
- monkeyLog.getIntermediateCount() + 100 < monkeyLog.getTargetCount()) {
- return MonkeyStatus.FALSE_COUNT;
- }
-
- // Finished
- if (monkeyLog.getIsFinished()) {
- return MonkeyStatus.FINISHED;
- }
-
- // Crashed
- if (monkeyLog.getFinalCount() != null) {
- return MonkeyStatus.CRASHED;
- }
-
- // Missing count
- return MonkeyStatus.MISSING_COUNT;
- }
-}
diff --git a/prod-tests/src/com/android/monkey/MonkeyMetricsTest.java b/prod-tests/src/com/android/monkey/MonkeyMetricsTest.java
deleted file mode 100644
index 849bcf9..0000000
--- a/prod-tests/src/com/android/monkey/MonkeyMetricsTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2012 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.monkey;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.result.ITestInvocationListener;
-
-/**
- * A {@link MonkeyBase} specialization that uses the brillopad parser to extract and report
- * monkey related metrics.
- */
-public class MonkeyMetricsTest extends MonkeyBase {
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- MonkeyBrillopadForwarder brilloAnalyzer = new MonkeyBrillopadForwarder(listener,
- getMonkeyTimeoutMs());
- super.run(brilloAnalyzer);
- }
-}
diff --git a/prod-tests/src/com/android/monkey/MonkeyPairedBase.java b/prod-tests/src/com/android/monkey/MonkeyPairedBase.java
deleted file mode 100644
index 1739916..0000000
--- a/prod-tests/src/com/android/monkey/MonkeyPairedBase.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * 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.monkey;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IMultiDeviceTest;
-import com.android.tradefed.util.clockwork.ClockworkUtils;
-
-import java.util.ArrayList;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.List;
-import java.util.Map;
-
-/** Runner for paired stress tests which use the monkey command. */
-public class MonkeyPairedBase extends MonkeyBase implements IMultiDeviceTest {
-
- @Option(name = "companion-recurring-command", description = "recurring shell command "
- + "on companion")
- private String mCompanionRecurringCommand = null;
-
- @Option(name = "companion-recurring-interval", description = "interval between recurring "
- + "command in seconds")
- private int mCompanionRecurringInterval = 25;
-
- private ITestDevice mCompanion;
- private List<ITestDevice> mDeviceList = new ArrayList<>();
- private ScheduledExecutorService mScheduler;
-
- /**
- * Fetches the companion device allocated for the primary device
- *
- * @return the allocated companion device
- * @throws RuntimeException if no companion device has been allocated
- */
- protected ITestDevice getCompanion() {
- return mCompanion;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- if (mCompanionRecurringCommand != null) {
- scheduleRecurringCommand();
- }
- try {
- super.run(listener);
- } finally {
- stopRecurringCommand();
- }
- }
-
- protected void scheduleRecurringCommand() {
- mScheduler = Executors.newScheduledThreadPool(1);
- mScheduler.scheduleAtFixedRate(new Runnable() {
- @Override
- public void run() {
- try {
- getCompanion().executeShellCommand(mCompanionRecurringCommand);
- } catch (DeviceNotAvailableException e) {
- CLog.e("Recurring command failed on %s (%s)", getCompanion().getSerialNumber(),
- mCompanionRecurringCommand);
- }
- }
- }, mCompanionRecurringInterval, mCompanionRecurringInterval, TimeUnit.SECONDS);
- }
-
- protected void stopRecurringCommand() {
- mScheduler.shutdownNow();
- try {
- mScheduler.awaitTermination(mCompanionRecurringInterval, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- CLog.e("Could not terminate recurring command on %s (%s)",
- getCompanion().getSerialNumber(), mCompanionRecurringCommand);
- }
- }
-
- /** {@inheritDoc} */
- @Override
- public void setDeviceInfos(Map<ITestDevice, IBuildInfo> deviceInfos) {
- ClockworkUtils cwUtils = new ClockworkUtils();
- mCompanion = cwUtils.setUpMultiDevice(deviceInfos, mDeviceList);
- }
-}
\ No newline at end of file
diff --git a/prod-tests/src/com/android/ota/tests/OtaStabilityTest.java b/prod-tests/src/com/android/ota/tests/OtaStabilityTest.java
deleted file mode 100644
index e74747a..0000000
--- a/prod-tests/src/com/android/ota/tests/OtaStabilityTest.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright (C) 2011 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.ota.tests;
-
-import com.android.ddmlib.Log;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationReceiver;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.ITargetPreparer;
-import com.android.tradefed.targetprep.TargetSetupError;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.testtype.IResumableTest;
-import com.android.tradefed.testtype.IShardableTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.IRunUtil;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-
-/**
- * A test that will flash a build on a device, wait for the device to be OTA-ed to another build,
- * and then repeat N times.
- * <p/>
- * Note: this test assumes that the {@link ITargetPreparer}s included in this test's
- * {@link IConfiguration} will flash the device back to a baseline build, and prepare the device
- * to receive the OTA to a new build.
- */
-@OptionClass(alias = "ota-stability")
-public class OtaStabilityTest implements IDeviceTest, IBuildReceiver, IConfigurationReceiver,
- IShardableTest, IResumableTest {
-
- private static final String LOG_TAG = "OtaStabilityTest";
- private IBuildInfo mDeviceBuild;
- private IConfiguration mConfiguration;
- private ITestDevice mDevice;
-
- @Option(name = "run-name", description =
- "The name of the ota stability test run. Used to report metrics.")
- private String mRunName = "ota-stability";
-
- @Option(name = "iterations", description =
- "Number of ota stability 'flash + wait for ota' iterations to run.")
- private int mIterations = 20;
-
- @Option(name = "wait-recovery-time", description =
- "Number of minutes to wait for device to begin installing ota.")
- private int mWaitRecoveryTime = 15;
-
- @Option(name = "wait-install-time", description =
- "Number of minutes to wait for device to be online after beginning ota installation.")
- private int mWaitInstallTime = 10;
-
- @Option(name = "shards", description = "Optional number of shards to split test into. " +
- "Iterations will be split evenly among shards.", importance = Importance.IF_UNSET)
- private Integer mShards = null;
-
- @Option(name = "resume", description = "Resume the ota test run if an device setup error " +
- "stopped the previous test run.")
- private boolean mResumeMode = false;
-
- /** controls if this test should be resumed. Only used if mResumeMode is enabled */
- private boolean mResumable = true;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setConfiguration(IConfiguration configuration) {
- mConfiguration = configuration;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setBuild(IBuildInfo buildInfo) {
- mDeviceBuild = buildInfo;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- /**
- * Set the wait recovery time
- */
- void setWaitRecoveryTime(int waitRecoveryTime) {
- mWaitRecoveryTime = waitRecoveryTime;
- }
-
- /**
- * Set the wait install time
- */
- void setWaitInstallTime(int waitInstallTime) {
- mWaitInstallTime = waitInstallTime;
- }
-
- /**
- * Set the run name
- */
- void setRunName(String runName) {
- mRunName = runName;
- }
-
- /**
- * Return the number of iterations.
- * <p/>
- * Exposed for unit testing
- */
- public int getIterations() {
- return mIterations;
- }
-
- /**
- * Set the iterations
- */
- void setIterations(int iterations) {
- mIterations = iterations;
- }
-
- /**
- * Set the number of shards
- */
- void setShards(int shards) {
- mShards = shards;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Collection<IRemoteTest> split() {
- if (mShards == null || mShards <= 1) {
- return null;
- }
- Collection<IRemoteTest> shards = new ArrayList<>(mShards);
- int remainingIterations = mIterations;
- for (int i = mShards; i > 0; i--) {
- OtaStabilityTest testShard = new OtaStabilityTest();
- // device and configuration will be set by test invoker
- testShard.setRunName(mRunName);
- testShard.setWaitInstallTime(mWaitInstallTime);
- testShard.setWaitRecoveryTime(mWaitRecoveryTime);
- // attempt to divide iterations evenly among shards with no remainder
- int iterationsForShard = Math.round(remainingIterations/i);
- if (iterationsForShard > 0) {
- testShard.setIterations(iterationsForShard);
- remainingIterations -= iterationsForShard;
- shards.add(testShard);
- }
- }
- return shards;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- // started run, turn to off
- mResumable = false;
- checkFields();
-
- long startTime = System.currentTimeMillis();
- listener.testRunStarted(mRunName, 0);
- int actualIterations = 0;
- try {
- waitForOta(listener);
- for (actualIterations = 1; actualIterations < mIterations; actualIterations++) {
- flashDevice();
- String buildId = waitForOta(listener);
- Log.i(LOG_TAG,
- String.format("Device %s successfully OTA-ed to build %s. Iteration: %d",
- mDevice.getSerialNumber(), buildId, actualIterations));
- }
- } catch (AssertionError error) {
- Log.e(LOG_TAG, error);
- } catch (TargetSetupError e) {
- CLog.i("Encountered TargetSetupError, marking this test as resumable");
- mResumable = true;
- CLog.e(e);
- // throw up an exception so this test can be resumed
- Assert.fail(e.toString());
- } catch (BuildError e) {
- Log.e(LOG_TAG, e);
- } catch (ConfigurationException e) {
- Log.e(LOG_TAG, e);
- } finally {
- HashMap<String, Metric> metrics = new HashMap<>();
- metrics.put(
- "iterations",
- TfMetricProtoUtil.stringToMetric(Integer.toString(actualIterations)));
- long endTime = System.currentTimeMillis() - startTime;
- listener.testRunEnded(endTime, metrics);
- }
- }
-
-
- /**
- * Flash the device back to baseline build.
- * <p/>
- * Currently does this by re-running {@link ITargetPreparer#setUp(ITestDevice, IBuildInfo)}
- *
- * @throws DeviceNotAvailableException
- * @throws BuildError
- * @throws TargetSetupError
- * @throws ConfigurationException
- */
- private void flashDevice() throws TargetSetupError, BuildError, DeviceNotAvailableException,
- ConfigurationException {
- // assume the target preparers will flash the device back to device build
- for (ITargetPreparer preparer : mConfiguration.getTargetPreparers()) {
- preparer.setUp(mDevice, mDeviceBuild);
- }
- }
-
- /**
- * Get the {@link IRunUtil} instance to use.
- * <p/>
- * Exposed so unit tests can mock.
- */
- IRunUtil getRunUtil() {
- return RunUtil.getDefault();
- }
-
- /**
- * Blocks and waits for OTA package to be installed.
- *
- * @param listener the {@link ITestInvocationListener}
- * @return the build id the device ota-ed to
- * @throws DeviceNotAvailableException
- * @throws AssertionError
- */
- private String waitForOta(ITestInvocationListener listener)
- throws DeviceNotAvailableException, AssertionError {
- String currentBuildId = mDevice.getBuildId();
- Assert.assertEquals(String.format("device %s does not have expected build id on boot.",
- mDevice.getSerialNumber()), currentBuildId, mDeviceBuild.getBuildId());
- // give some time for device to settle
- getRunUtil().sleep(5*1000);
- // force a checkin so device downloads OTA immediately
- mDevice.executeShellCommand(
- "am broadcast -a android.server.checkin.CHECKIN com.google.android.gms");
- Assert.assertTrue(String.format(
- "Device %s did not enter recovery after %d min.",
- mDevice.getSerialNumber(), mWaitRecoveryTime),
- mDevice.waitForDeviceInRecovery(mWaitRecoveryTime * 60 * 1000));
- try {
- mDevice.waitForDeviceOnline(mWaitInstallTime * 60 * 1000);
- } catch (DeviceNotAvailableException e) {
- Log.e(LOG_TAG, String.format(
- "Device %s did not come back online after leaving recovery",
- mDevice.getSerialNumber()));
- sendRecoveryLog(listener);
- throw e;
- }
- try {
- mDevice.waitForDeviceAvailable();
- } catch (DeviceNotAvailableException e) {
- Log.e(LOG_TAG, String.format(
- "Device %s did not boot up successfully after leaving recovery/installing OTA",
- mDevice.getSerialNumber()));
- throw e;
- }
- currentBuildId = mDevice.getBuildId();
- // TODO: should exact expected build id be checked?
- Assert.assertNotEquals(
- String.format(
- "Device %s build id did not change after leaving recovery",
- mDevice.getSerialNumber()),
- currentBuildId,
- mDeviceBuild.getBuildId());
- return currentBuildId;
- }
-
- private void sendRecoveryLog(ITestInvocationListener listener) throws
- DeviceNotAvailableException {
- File destFile = null;
- InputStreamSource destSource = null;
- try {
- // get recovery log
- destFile = FileUtil.createTempFile("recovery", "log");
- boolean gotFile = mDevice.pullFile("/tmp/recovery.log", destFile);
- if (gotFile) {
- destSource = new FileInputStreamSource(destFile);
- listener.testLog("recovery_log", LogDataType.TEXT, destSource);
- }
- } catch (IOException e) {
- Log.e(LOG_TAG, String.format("Failed to get recovery log from device %s",
- mDevice.getSerialNumber()));
- Log.e(LOG_TAG, e);
- } finally {
- FileUtil.deleteFile(destFile);
- StreamUtil.cancel(destSource);
- }
- }
-
- private void checkFields() {
- if (mDevice == null) {
- throw new IllegalArgumentException("missing device");
- }
- if (mConfiguration == null) {
- throw new IllegalArgumentException("missing configuration");
- }
- if (mDeviceBuild == null) {
- throw new IllegalArgumentException("missing build info");
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isResumable() {
- return mResumeMode && mResumable;
- }
-}
diff --git a/prod-tests/src/com/android/ota/tests/OtaStabilityTestTest.java b/prod-tests/src/com/android/ota/tests/OtaStabilityTestTest.java
deleted file mode 100644
index 1216c83..0000000
--- a/prod-tests/src/com/android/ota/tests/OtaStabilityTestTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2011 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.ota.tests;
-
-import com.android.tradefed.testtype.IRemoteTest;
-
-import junit.framework.TestCase;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-/**
- * Unit tests for {@link OtaStabilityTest}
- */
-public class OtaStabilityTestTest extends TestCase {
-
- /**
- * Test basic case {@link OtaStabilityTest#split()}, where iterations divide evenly into each
- * shards.
- */
- public void testSplit_even() {
- OtaStabilityTest test = new OtaStabilityTest();
- test.setIterations(10);
- test.setShards(5);
- Collection<IRemoteTest> shards = test.split();
- assertEquals(5, shards.size());
- for (IRemoteTest shardTest : shards) {
- OtaStabilityTest otaShard = (OtaStabilityTest)shardTest;
- assertEquals(2, otaShard.getIterations());
- }
- }
-
- /**
- * Test {@link OtaStabilityTest#split()}, where there are more iterations than shards.
- */
- public void testSplit_shards() {
- OtaStabilityTest test = new OtaStabilityTest();
- test.setIterations(5);
- test.setShards(10);
- Collection<IRemoteTest> shards = test.split();
- assertEquals(5, shards.size());
- for (IRemoteTest shardTest : shards) {
- OtaStabilityTest otaShard = (OtaStabilityTest)shardTest;
- assertEquals(1, otaShard.getIterations());
- }
- }
-
- /**
- * Test {@link OtaStabilityTest#split()}, where iterations does not divide evenly
- */
- public void testSplit_remainder() {
- OtaStabilityTest test = new OtaStabilityTest();
- test.setIterations(10);
- test.setShards(3);
- Collection<IRemoteTest> shards = test.split();
- assertEquals(3, shards.size());
- Iterator<IRemoteTest> iterator = shards.iterator();
- IRemoteTest first = iterator.next();
- assertEquals(3, ((OtaStabilityTest)first).getIterations());
-
- IRemoteTest second = iterator.next();
- assertEquals(3, ((OtaStabilityTest)second).getIterations());
-
- IRemoteTest three = iterator.next();
- assertEquals(4, ((OtaStabilityTest)three).getIterations());
- }
-}
diff --git a/prod-tests/src/com/android/ota/tests/SideloadOtaStabilityTest.java b/prod-tests/src/com/android/ota/tests/SideloadOtaStabilityTest.java
deleted file mode 100644
index b475dda..0000000
--- a/prod-tests/src/com/android/ota/tests/SideloadOtaStabilityTest.java
+++ /dev/null
@@ -1,634 +0,0 @@
-/*
- * Copyright (C) 2012 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.ota.tests;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertThat;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.IDeviceBuildInfo;
-import com.android.tradefed.build.OtaDeviceBuildInfo;
-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;
-import com.android.tradefed.device.IManagedTestDevice;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.TestDeviceState;
-import com.android.tradefed.log.LogReceiver;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.ITargetPreparer;
-import com.android.tradefed.targetprep.TargetSetupError;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IResumableTest;
-import com.android.tradefed.util.DeviceRecoveryModeUtil;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A test that will perform repeated flash + install OTA actions on a device.
- * <p/>
- * adb must have root.
- * <p/>
- * Expects a {@link OtaDeviceBuildInfo}.
- * <p/>
- * Note: this test assumes that the {@link ITargetPreparer}s included in this test's
- * {@link IConfiguration} will flash the device back to a baseline build, and prepare the device to
- * receive the OTA to a new build.
- */
-@OptionClass(alias = "ota-stability")
-public class SideloadOtaStabilityTest implements IDeviceTest, IBuildReceiver,
- IConfigurationReceiver, IResumableTest {
-
- private static final String UNCRYPT_FILE_PATH = "/cache/recovery/uncrypt_file";
- private static final String UNCRYPT_STATUS_FILE = "/cache/recovery/uncrypt_status";
- private static final String BLOCK_MAP_PATH = "@/cache/recovery/block.map";
- private static final String RECOVERY_COMMAND_PATH = "/cache/recovery/command";
- private static final String LOG_RECOV = "/cache/recovery/last_log";
- private static final String LOG_KMSG = "/cache/recovery/last_kmsg";
- private static final String KMSG_CMD = "cat /proc/kmsg";
- private static final long SOCKET_RETRY_CT = 30;
- private static final long UNCRYPT_TIMEOUT = 15 * 60 * 1000;
-
- private static final long SHORT_WAIT_UNCRYPT = 3 * 1000;
-
- private OtaDeviceBuildInfo mOtaDeviceBuild;
- private IConfiguration mConfiguration;
- private ITestDevice mDevice;
-
- @Option(name = "run-name", description =
- "The name of the ota stability test run. Used to report metrics.")
- private String mRunName = "ota-stability";
-
- @Option(name = "iterations", description =
- "Number of ota stability 'flash + wait for ota' iterations to run.")
- private int mIterations = 20;
-
- @Option(name = "resume", description = "Resume the ota test run if an device setup error "
- + "stopped the previous test run.")
- private boolean mResumeMode = false;
-
- @Option(name = "max-install-time", description =
- "The maximum time to wait for an ota to install in seconds.")
- private int mMaxInstallOnlineTimeSec = 5 * 60;
-
- @Option(name = "package-data-path", description =
- "path on /data for the package to be saved to")
- /* This is currently the only path readable by uncrypt on the userdata partition */
- private String mPackageDataPath = "/data/data/com.google.android.gsf/app_download/update.zip";
-
- @Option(name = "max-reboot-time", description =
- "The maximum time to wait for a device to reboot out of recovery if it fails")
- private long mMaxRebootTimeSec = 5 * 60;
-
- @Option(name = "uncrypt-only", description = "if true, only uncrypt then exit")
- private boolean mUncryptOnly = false;
-
- /** controls if this test should be resumed. Only used if mResumeMode is enabled */
- private boolean mResumable = true;
-
- private long mUncryptDuration;
- private LogReceiver mKmsgReceiver;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setConfiguration(IConfiguration configuration) {
- mConfiguration = configuration;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setBuild(IBuildInfo buildInfo) {
- mOtaDeviceBuild = (OtaDeviceBuildInfo) buildInfo;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- /**
- * Set the run name
- */
- void setRunName(String runName) {
- mRunName = runName;
- }
-
- /**
- * Return the number of iterations.
- * <p/>
- * Exposed for unit testing
- */
- public int getIterations() {
- return mIterations;
- }
-
- /**
- * Set the iterations
- */
- void setIterations(int iterations) {
- mIterations = iterations;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- // started run, turn to off
- mResumable = false;
- mKmsgReceiver = new LogReceiver(getDevice(), KMSG_CMD, "kmsg");
- checkFields();
-
- CLog.i("Starting OTA sideload test from %s to %s, for %d iterations",
- mOtaDeviceBuild.getDeviceImageVersion(),
- mOtaDeviceBuild.getOtaBuild().getOtaPackageVersion(), mIterations);
-
- long startTime = System.currentTimeMillis();
- listener.testRunStarted(mRunName, 0);
- int actualIterations = 0;
- BootTimeInfo lastBootTime = null;
- try {
- while (actualIterations < mIterations) {
- if (actualIterations != 0) {
- // don't need to flash device on first iteration
- flashDevice();
- }
- lastBootTime = installOta(listener, mOtaDeviceBuild.getOtaBuild());
- actualIterations++;
- CLog.i("Device %s successfully OTA-ed to build %s. Iteration: %d of %d",
- mDevice.getSerialNumber(),
- mOtaDeviceBuild.getOtaBuild().getOtaPackageVersion(),
- actualIterations, mIterations);
- }
- } catch (AssertionError | BuildError e) {
- CLog.e(e);
- } catch (TargetSetupError e) {
- CLog.i("Encountered TargetSetupError, marking this test as resumable");
- mResumable = true;
- CLog.e(e);
- // throw up an exception so this test can be resumed
- Assert.fail(e.toString());
- } finally {
- // if the device is down, we need to recover it so we can safely pull logs
- IManagedTestDevice managedDevice = (IManagedTestDevice) mDevice;
- if (!managedDevice.getDeviceState().equals(TestDeviceState.ONLINE)) {
- // not all IDeviceRecovery implementations can handle getting out of recovery mode,
- // so we should just reboot in that case since we no longer need to be in
- // recovery
- CLog.i("Device is not online, attempting to recover before capturing logs");
- DeviceRecoveryModeUtil.bootOutOfRecovery((IManagedTestDevice) mDevice,
- mMaxInstallOnlineTimeSec * 1000);
- }
- double updateTime = sendRecoveryLog(listener);
- Map<String, String> metrics = new HashMap<>(1);
- metrics.put("iterations", Integer.toString(actualIterations));
- metrics.put("failed_iterations", Integer.toString(mIterations - actualIterations));
- metrics.put("update_time", Double.toString(updateTime));
- metrics.put("uncrypt_time", Long.toString(mUncryptDuration));
- if (lastBootTime != null) {
- metrics.put("boot_time_online", Double.toString(lastBootTime.mOnlineTime));
- metrics.put("boot_time_available", Double.toString(lastBootTime.mAvailTime));
- }
- long endTime = System.currentTimeMillis() - startTime;
- listener.testRunEnded(endTime, TfMetricProtoUtil.upgradeConvert(metrics));
- }
- }
-
- /**
- * Flash the device back to baseline build.
- * <p/>
- * Currently does this by re-running {@link ITargetPreparer#setUp(ITestDevice, IBuildInfo)}
- */
- private void flashDevice() throws TargetSetupError, BuildError, DeviceNotAvailableException {
- // assume the target preparers will flash the device back to device build
- for (ITargetPreparer preparer : mConfiguration.getTargetPreparers()) {
- preparer.setUp(mDevice, mOtaDeviceBuild);
- }
- }
-
- private void checkFields() {
- if (mDevice == null) {
- throw new IllegalArgumentException("missing device");
- }
- if (mConfiguration == null) {
- throw new IllegalArgumentException("missing configuration");
- }
- if (mOtaDeviceBuild == null) {
- throw new IllegalArgumentException("missing build info");
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isResumable() {
- return mResumeMode && mResumable;
- }
-
- /**
- * Actually install the OTA.
- * @param listener
- * @param otaBuild
- * @return the amount of time in ms that the device took to boot after installing.
- * @throws DeviceNotAvailableException
- */
- private BootTimeInfo installOta(ITestInvocationListener listener, IDeviceBuildInfo otaBuild)
- throws DeviceNotAvailableException {
- TestDescription test =
- new TestDescription(getClass().getName(), String.format("apply_ota[%s]", mRunName));
- Map<String, String> metrics = new HashMap<String, String>();
- listener.testStarted(test);
- try {
- mKmsgReceiver.start();
- try {
- CLog.i("Pushing OTA package %s", otaBuild.getOtaPackageFile().getAbsolutePath());
- Assert.assertTrue(mDevice.pushFile(otaBuild.getOtaPackageFile(), mPackageDataPath));
- // this file needs to be uncrypted, since /data isn't mounted in recovery
- // block.map should be empty since cache should be cleared
- mDevice.pushString(mPackageDataPath + "\n", UNCRYPT_FILE_PATH);
- // Flushing the file to flash.
- mDevice.executeShellCommand("sync");
-
- mUncryptDuration = doUncrypt(SocketFactory.getInstance(), listener);
- metrics.put("uncrypt_duration", Long.toString(mUncryptDuration));
- String installOtaCmd = String.format("--update_package=%s\n", BLOCK_MAP_PATH);
- mDevice.pushString(installOtaCmd, RECOVERY_COMMAND_PATH);
- CLog.i("Rebooting to install OTA");
- } finally {
- // Kmsg contents during the OTA will be capture in last_kmsg, so we can turn off the
- // kmsg receiver now
- mKmsgReceiver.postLog(listener);
- mKmsgReceiver.stop();
- }
- // uncrypt is complete
- if (mUncryptOnly) {
- return new BootTimeInfo(-1, -1);
- }
- try {
- mDevice.rebootIntoRecovery();
- } catch (DeviceNotAvailableException e) {
- // The device will only enter the RECOVERY state if it hits the recovery menu.
- // Since we added a command to /cache/recovery/command, recovery mode executes the
- // command rather than booting into the menu. While applying the update as a result
- // of the installed command, the device reports its state as NOT_AVAILABLE. If the
- // device *actually* becomes unavailable, we will catch the resulting DNAE in the
- // next call to waitForDeviceOnline.
- CLog.i("Didn't go to recovery, went straight to update");
- }
-
- mDevice.waitForDeviceNotAvailable(mMaxInstallOnlineTimeSec * 1000);
- long start = System.currentTimeMillis();
-
- try {
- mDevice.waitForDeviceOnline(mMaxInstallOnlineTimeSec * 1000);
- } catch (DeviceNotAvailableException e) {
- CLog.e("Device %s did not come back online after recovery", mDevice.getSerialNumber());
- listener.testFailed(test, e.getLocalizedMessage());
- listener.testRunFailed("Device did not come back online after recovery");
- sendUpdatePackage(listener, otaBuild);
- throw new AssertionError("Device did not come back online after recovery");
- }
- double onlineTime = (System.currentTimeMillis() - start) / 1000.0;
- try {
- mDevice.waitForDeviceAvailable();
- } catch (DeviceNotAvailableException e) {
- CLog.e("Device %s did not boot up successfully after installing OTA",
- mDevice.getSerialNumber());
- listener.testFailed(test, e.getLocalizedMessage());
- listener.testRunFailed("Device failed to boot after OTA");
- sendUpdatePackage(listener, otaBuild);
- throw new AssertionError("Device failed to boot after OTA");
- }
- double availTime = (System.currentTimeMillis() - start) / 1000.0;
- return new BootTimeInfo(availTime, onlineTime);
- } finally {
- listener.testEnded(test, TfMetricProtoUtil.upgradeConvert(metrics));
- }
- }
-
- private InputStreamSource pullLogFile(String location)
- throws DeviceNotAvailableException {
- try {
- // get recovery log
- File destFile = FileUtil.createTempFile("recovery", "log");
- boolean gotFile = mDevice.pullFile(location, destFile);
- if (gotFile) {
- return new FileInputStreamSource(destFile, true /* delete */);
- }
- } catch (IOException e) {
- CLog.e("Failed to get recovery log from device %s", mDevice.getSerialNumber());
- CLog.e(e);
- }
- return null;
- }
-
- protected void sendUpdatePackage(ITestInvocationListener listener, IDeviceBuildInfo otaBuild) {
- InputStreamSource pkgSource = null;
- try {
- pkgSource = new FileInputStreamSource(otaBuild.getOtaPackageFile());
- listener.testLog(mRunName + "_package", LogDataType.ZIP, pkgSource);
- } catch (NullPointerException e) {
- CLog.w("Couldn't save update package due to exception");
- CLog.e(e);
- return;
- } finally {
- StreamUtil.cancel(pkgSource);
- }
- }
-
- protected double sendRecoveryLog(ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- InputStreamSource lastLog = pullLogFile(LOG_RECOV);
- InputStreamSource lastKmsg = pullLogFile(LOG_KMSG);
- InputStreamSource blockMap = pullLogFile(BLOCK_MAP_PATH.substring(1));
- double elapsedTime = 0;
- // last_log contains a timing metric in its last line, capture it here and return it
- // for the metrics map to report
- try {
- if (lastLog == null || lastKmsg == null) {
- CLog.w(
- "Could not find last_log at directory %s, or last_kmsg at directory %s",
- LOG_RECOV, LOG_KMSG);
- return elapsedTime;
- }
-
- try {
- String[] lastLogLines = StreamUtil.getStringFromSource(lastLog).split("\n");
- String endLine = lastLogLines[lastLogLines.length - 1];
- elapsedTime = Double.parseDouble(
- endLine.substring(endLine.indexOf('[') + 1, endLine.indexOf(']')).trim());
- } catch (IOException | NumberFormatException | NullPointerException e) {
- CLog.w("Couldn't get elapsed time from last_log due to exception");
- CLog.e(e);
- }
- listener.testLog(this.mRunName + "_recovery_log", LogDataType.TEXT,
- lastLog);
- listener.testLog(this.mRunName + "_recovery_kmsg", LogDataType.TEXT,
- lastKmsg);
- if (blockMap == null) {
- CLog.w("Could not find block.map");
- } else {
- listener.testLog(this.mRunName + "_block_map", LogDataType.TEXT,
- blockMap);
- }
- return elapsedTime;
- } finally {
- StreamUtil.cancel(lastLog);
- StreamUtil.cancel(lastKmsg);
- StreamUtil.cancel(blockMap);
- }
- }
-
- /**
- * Uncrypt needs to attach to a socket before it will actually begin work, so we need to attach
- * a socket to it.
- *
- * @return Elapse time of uncrypt
- */
- public long doUncrypt(
- ISocketFactory sockets, @SuppressWarnings("unused") ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- // init has to start uncrypt or the socket will not be allocated
- CLog.i("Starting uncrypt service");
- mDevice.executeShellCommand("setprop ctl.start uncrypt");
- try {
- // This is a workaround for known issue with f2fs system.
- CLog.i("Sleeping %d for uncrypt to be ready for socket connection.",
- SHORT_WAIT_UNCRYPT);
- Thread.sleep(SHORT_WAIT_UNCRYPT);
- } catch (InterruptedException e) {
- CLog.i("Got interrupted when waiting to uncrypt file.");
- Thread.currentThread().interrupt();
- }
- // MNC version of uncrypt does not require socket connection
- if (mDevice.getApiLevel() < 24) {
- CLog.i("Waiting for MNC uncrypt service finish");
- return waitForUncrypt();
- }
- int port;
- try {
- port = getFreePort();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- // The socket uncrypt wants to run on is a local unix socket, so we can forward a tcp
- // port to connect to it.
- CLog.i("Connecting to uncrypt on port %d", port);
- mDevice.executeAdbCommand("forward", "tcp:" + port, "localreserved:uncrypt");
- // connect to uncrypt!
- String hostname = "localhost";
- long start = System.currentTimeMillis();
- try (Socket uncrypt = sockets.createClientSocket(hostname, port)) {
- connectSocket(uncrypt, hostname, port);
- try (DataInputStream dis = new DataInputStream(uncrypt.getInputStream());
- DataOutputStream dos = new DataOutputStream(uncrypt.getOutputStream())) {
- int status = Integer.MIN_VALUE;
- while (true) {
- status = dis.readInt();
- if (isUncryptSuccess(status)) {
- dos.writeInt(0);
- break;
- }
- }
- CLog.i("Final uncrypt status: %d", status);
- return System.currentTimeMillis() - start;
- }
- } catch (IOException e) {
- CLog.e("Lost connection with uncrypt due to IOException:");
- CLog.e(e);
- return waitForUncrypt();
- }
- }
-
- private long waitForUncrypt() throws DeviceNotAvailableException {
- CLog.i("Continuing to watch uncrypt progress for %d ms", UNCRYPT_TIMEOUT);
- long time = 0;
- int lastStatus = -1;
- long start = System.currentTimeMillis();
- while ((time = System.currentTimeMillis() - start) < UNCRYPT_TIMEOUT) {
- int status = readUncryptStatusFromFile();
- if (isUncryptSuccess(status)) {
- return time;
- }
- if (status != lastStatus) {
- lastStatus = status;
- CLog.d("uncrypt status: %d", status);
- }
- try {
- Thread.sleep(1000);
- } catch (InterruptedException unused) {
- Thread.currentThread().interrupt();
- }
- }
- CLog.e("Uncrypt didn't finish, last status was %d", lastStatus);
- throw new RuntimeException("Uncrypt didn't succeed after timeout");
- }
-
- private boolean isUncryptSuccess(int status) {
- if (status == 100) {
- CLog.i("Uncrypt finished successfully");
- return true;
- } else if (status > 100 || status < 0) {
- CLog.e("Uncrypt returned error status %d", status);
- assertThat(status, not(equalTo(100)));
- }
- return false;
- }
-
- protected int getFreePort() throws IOException {
- try (ServerSocket sock = new ServerSocket(0)) {
- return sock.getLocalPort();
- }
- }
-
- /**
- * Read the error status from uncrypt_status on device.
- *
- * @return 0 if uncrypt succeed, -1 if file not exists, specific error code otherwise.
- */
- protected int readUncryptStatusFromFile()
- throws DeviceNotAvailableException {
- try {
- InputStreamSource status = pullLogFile(UNCRYPT_STATUS_FILE);
- if (status == null) {
- return -1;
- }
- String[] lastLogLines = StreamUtil.getStringFromSource(status).split("\n");
- String endLine = lastLogLines[lastLogLines.length - 1];
- if (endLine.toLowerCase().startsWith("uncrypt_error:")) {
- String[] elements = endLine.split(":");
- return Integer.parseInt(elements[1].trim());
- } else {
- // MNC device case
- return Integer.parseInt(endLine.trim());
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- protected void connectSocket(Socket s, String host, int port) {
- SocketAddress address = new InetSocketAddress(host, port);
- boolean connected = false;
- for (int i = 0; i < SOCKET_RETRY_CT; i++) {
- try {
- if (!s.isConnected()) {
- s.connect(address);
- }
- connected = true;
- break;
- } catch (IOException unused) {
- try {
- Thread.sleep(1000);
- CLog.d("Uncrypt socket was not ready on iteration %d of %d, retrying", i,
- SOCKET_RETRY_CT);
- } catch (InterruptedException e) {
- CLog.w("Interrupted while connecting uncrypt socket on iteration %d", i);
- Thread.currentThread().interrupt();
- }
- }
- }
- if (!connected) {
- throw new RuntimeException("failed to connect uncrypt socket");
- }
- }
-
- /**
- * Provides a client socket. Allows for providing mock sockets to doUncrypt in unit testing.
- */
- public interface ISocketFactory {
- public Socket createClientSocket(String host, int port) throws IOException;
- }
-
- /**
- * Default implementation of {@link ISocketFactory}, which provides a {@link Socket}.
- */
- protected static class SocketFactory implements ISocketFactory {
- private static SocketFactory sInstance;
-
- private SocketFactory() {
- }
-
- public static SocketFactory getInstance() {
- if (sInstance == null) {
- sInstance = new SocketFactory();
- }
- return sInstance;
- }
-
- @Override
- public Socket createClientSocket(String host, int port) throws IOException {
- return new Socket(host, port);
- }
- }
-
- private static class BootTimeInfo {
- /**
- * Time (s) until device is completely available
- */
- public double mAvailTime;
- /**
- * Time (s) until device is in "ONLINE" state
- */
- public double mOnlineTime;
-
- public BootTimeInfo(double avail, double online) {
- mAvailTime = avail;
- mOnlineTime = online;
- }
- }
-}
diff --git a/prod-tests/src/com/android/performance/tests/AppInstallTest.java b/prod-tests/src/com/android/performance/tests/AppInstallTest.java
deleted file mode 100644
index 427ae56..0000000
--- a/prod-tests/src/com/android/performance/tests/AppInstallTest.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * 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.performance.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.OptionClass;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.AaptParser;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.junit.Assert;
-
-@OptionClass(alias = "app-install-perf")
-// Test framework that measures the install time for all apk files located under a given directory.
-// The test needs aapt to be in its path in order to determine the package name of the apk. The
-// package name is needed to clean up after the test is done.
-public class AppInstallTest implements IDeviceTest, IRemoteTest {
-
- @Option(name = "test-apk-dir", description = "Directory that contains the test apks.",
- importance= Option.Importance.ALWAYS)
- private String mTestApkPath;
-
- @Option(name = "test-label", description = "Unique test identifier label.")
- private String mTestLabel = "AppInstallPerformance";
-
- @Option(name = "test-start-delay",
- description = "Delay in ms to wait for before starting the install test.")
- private long mTestStartDelay = 60000;
-
- // TODO: remove this once prod is updated.
- @Option(name = "test-use-dex-metedata")
- private boolean mUseDexMetadataMisspelled = false;
- @Option(name = "test-dex-metedata-variant")
- private String mDexMetadataVariantMisspelled = "";
-
- @Option(
- name = "test-use-dex-metadata",
- description = "If the test should install the dex metadata files."
- )
- private boolean mUseDexMetadata = false;
-
- @Option(name = "test-delay-between-installs",
- description = "Delay in ms to wait for before starting the install test.")
- private long mTestDelayBetweenInstalls = 5000;
-
- @Option(
- name = "test-dex-metadata-variant",
- description =
- "The dex metadata variant that should be used."
- + "When specified, the DM file name for foo.apk will be "
- + "constructed as fooVARIANT.dm"
- )
- private String mDexMetadataVariant = "";
-
- @Option(name = "test-uninstall-after",
- description = "If the apk should be uninstalled after.")
- private boolean mUninstallAfter = true;
-
- @Option(name = "package-list",
- description = "If given, filters the apk files in the test dir based on the list of "
- + "packages. It checks that the apk name is packageName-version.apk")
- private List<String> mPackages = new ArrayList<String>();
-
- private ITestDevice mDevice;
-
- /*
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- /*
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- /*
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- // Check if we need to use the obsolete, misspelled flags.
- if (!mUseDexMetadata) {
- mUseDexMetadata = mUseDexMetadataMisspelled;
- }
- if (mDexMetadataVariant.isEmpty()) {
- mDexMetadataVariant = mDexMetadataVariantMisspelled;
- }
-
- // Delay test start time to give the background processes to finish.
- if (mTestStartDelay > 0) {
- RunUtil.getDefault().sleep(mTestStartDelay);
- }
-
- Assert.assertFalse(mTestApkPath.isEmpty());
- File apkDir = new File(mTestApkPath);
- Assert.assertTrue(apkDir.isDirectory());
- // Find all apks in directory.
- String[] files = apkDir.list();
- Map<String, String> metrics = new HashMap<String, String> ();
- try {
- for (String fileName : files) {
- if (!fileName.endsWith(".apk")) {
- CLog.d("Skipping non-apk %s", fileName);
- continue;
- } else if (!matchesPackagesForInstall(fileName)) {
- CLog.d("Skipping apk %s", fileName);
- continue;
- }
- File file = new File(apkDir, fileName);
- // Install app and measure time.
- long installTime = installAndTime(file);
- if (installTime > 0) {
- metrics.put(fileName, Long.toString(installTime));
- }
- RunUtil.getDefault().sleep(mTestDelayBetweenInstalls);
- }
- } finally {
- reportMetrics(listener, mTestLabel, metrics);
- }
- }
-
- /**
- * Install file and time its install time. Cleans up after itself.
- * @param packageFile apk file to install
- * @return install time in msecs.
- * @throws DeviceNotAvailableException
- */
- long installAndTime(File packageFile) throws DeviceNotAvailableException {
- AaptParser parser = AaptParser.parse(packageFile);
- if (parser == null) {
- CLog.e("Failed to parse %s", packageFile);
- return -1;
- }
- String packageName = parser.getPackageName();
-
- String remotePath = "/data/local/tmp/" + packageFile.getName();
- if (!mDevice.pushFile(packageFile, remotePath)) {
- CLog.e("Failed to push %s", packageFile);
- return -1;
- }
-
- String dmRemotePath = null;
- if (mUseDexMetadata) {
- File dexMetadataFile = getDexMetadataFile(packageFile);
- dmRemotePath = "/data/local/tmp/" + dexMetadataFile.getName();
- if (!mDevice.pushFile(dexMetadataFile, dmRemotePath)) {
- CLog.e("Failed to push %s", dexMetadataFile);
- return -1;
- }
- }
-
- long start = System.currentTimeMillis();
-
- // Create install session.
- String output = mDevice.executeShellCommand("pm install-create -r -d -g");
- if (!checkSuccess(output, packageFile, "install-create")) {
- return -1;
- }
- String session = sessionFromInstallCreateOutput(output);
-
- // Write the files to the session
- output = mDevice.executeShellCommand(String.format(
- "pm install-write %s %s %s", session, "base.apk", remotePath));
- if (!checkSuccess(output, packageFile, "install-write base.apk")) {
- return -1;
- }
-
- if (mUseDexMetadata) {
- output = mDevice.executeShellCommand(String.format(
- "pm install-write %s %s %s", session, "base.dm", dmRemotePath));
- if (!checkSuccess(output, packageFile, "install-write base.dm")) {
- return -1;
- }
- }
-
- // Commit the session.
- output = mDevice.executeShellCommand(String.format("pm install-commit %s", session));
-
- long end = System.currentTimeMillis();
- if (!checkSuccess(output, packageFile, "install-commit")) {
- return -1;
- }
-
- // Remove the temp files.
- mDevice.executeShellCommand(String.format("rm \"%s\"", remotePath));
- if (mUseDexMetadata) {
- mDevice.executeShellCommand(String.format("rm \"%s\"", dmRemotePath));
- }
-
- // Uninstall the package if needed.
- if (mUninstallAfter && packageName != null) {
- CLog.d("Uninstalling: %s", packageName);
- mDevice.uninstallPackage(packageName);
- }
- return end - start;
- }
-
- /**
- * Report run metrics by creating an empty test run to stick them in
- *
- * @param listener the {@link ITestInvocationListener} of test results
- * @param runName the test name
- * @param metrics the {@link Map} that contains metrics for the given test
- */
- void reportMetrics(ITestInvocationListener listener, String runName,
- Map<String, String> metrics) {
- // Create an empty testRun to report the parsed runMetrics
- CLog.d("About to report metrics: %s", metrics);
- listener.testRunStarted(runName, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-
- /**
- * Extracts the session id from 'pm install-create' output.
- * Usual output is: "Success: created install session [710542260]"
- */
- private String sessionFromInstallCreateOutput(String output) {
- int start = output.indexOf("[");
- int end = output.indexOf("]");
- return output.substring(start + 1, end);
- }
-
- /**
- * Verifies that the output contains the "Success" mark.
- */
- private boolean checkSuccess(String output, File packageFile, String stepForErrorLog) {
- if (output == null || output.indexOf("Success") == -1) {
- CLog.e("Failed to execute [%s] for package %s with error %s",
- stepForErrorLog, packageFile, output);
- return false;
- }
- return true;
- }
-
- private File getDexMetadataFile(File packageFile) {
- return new File(packageFile.getAbsolutePath().replace(".apk", mDexMetadataVariant + ".dm"));
- }
-
- private boolean matchesPackagesForInstall(String fileName) {
- if (mPackages.isEmpty()) {
- return true;
- }
-
- for (String pkg : mPackages) {
- // "-" is the version delimiter and ensures we don't match for example
- // com.google.android.apps.docs for com.google.android.apps.docs.slides.
- if (fileName.contains(pkg + "-")) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/prod-tests/src/com/android/performance/tests/AppTransitionTests.java b/prod-tests/src/com/android/performance/tests/AppTransitionTests.java
deleted file mode 100644
index e3aff45..0000000
--- a/prod-tests/src/com/android/performance/tests/AppTransitionTests.java
+++ /dev/null
@@ -1,725 +0,0 @@
-/*
- * 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.performance.tests;
-
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.loganalysis.item.LatencyItem;
-import com.android.loganalysis.item.TransitionDelayItem;
-import com.android.loganalysis.parser.EventsLogParser;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.IFileEntry;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.LogcatReceiver;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.result.TestRunResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.SimpleStats;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.ZipUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test that drives the transition delays during different user behavior like
- * cold launch from launcher, hot launch from recent etc.This class invokes
- * the instrumentation test apk that does the transition and captures the events logs
- * during the transition and parse them and report in the dashboard.
- */
-public class AppTransitionTests implements IRemoteTest, IDeviceTest {
-
- private static final String PACKAGE_NAME = "com.android.apptransition.tests";
- private static final String CLASS_NAME = "com.android.apptransition.tests.AppTransitionTests";
- private static final String TEST_COLD_LAUNCH = "testColdLaunchFromLauncher";
- private static final String TEST_HOT_LAUNCH = "testHotLaunchFromLauncher";
- private static final String TEST_APP_TO_HOME = "testAppToHome";
- private static final String TEST_APP_TO_RECENT = "testAppToRecents";
- private static final String TEST_LATENCY = "testLatency";
- private static final String TEST_HOT_LAUNCH_FROM_RECENTS = "testHotLaunchFromRecents";
- private static final String DROP_CACHE_SCRIPT_FILE = "dropCache";
- private static final String SCRIPT_EXTENSION = ".sh";
- private static final String DROP_CACHE_CMD = "echo 3 > /proc/sys/vm/drop_caches";
- private static final String DEVICE_TEMPORARY_DIR_PATH = "/data/local/tmp/";
- private static final String REMOVE_CMD = "rm -rf %s/%s";
- private static final String EVENTS_CMD = "logcat -v threadtime -b events";
- private static final String EVENTS_CLEAR_CMD = "logcat -v threadtime -b events -c";
- private static final String EVENTS_LOG = "events_log";
- private static final long EVENTS_LOGCAT_SIZE = 80 * 1024 * 1024;
-
- @Option(name = "cold-apps", description = "Apps used for cold app launch"
- + " transition delay testing from launcher screen.")
- private String mColdLaunchApps = null;
-
- @Option(name = "hot-apps", description = "Apps used for hot app launch"
- + " transition delay testing from launcher screen.")
- private String mHotLaunchApps = null;
-
- @Option(name = "pre-launch-apps", description = "Apps used for populating the"
- + " recents apps list before starting app_to_recents or hot_app_from_recents"
- + " testing.")
- private String mPreLaunchApps = null;
-
- @Option(name = "apps-to-recents", description = "Apps used for app to recents"
- + " transition delay testing.")
- private String mAppToRecents = null;
-
- @Option(name = "hot-apps-from-recents", description = "Apps used for hot"
- + " launch app from recents list transition delay testing.")
- private String mRecentsToApp = null;
-
- @Option(name = "launch-iteration", description = "Iterations for launching each app to"
- + "test the transition delay.")
- private int mLaunchIteration = 10;
-
- @Option(name = "trace-directory", description = "Directory to store the trace files"
- + "while testing ther app transition delay.")
- private String mTraceDirectory = null;
-
- @Option(name = "runner", description = "The instrumentation test runner class name to use.")
- private String mRunnerName = "android.support.test.runner.AndroidJUnitRunner";
-
- @Option(name = "run-arg",
- description = "Additional test specific arguments to provide.")
- private Map<String, String> mArgMap = new LinkedHashMap<String, String>();
-
- @Option(name = "launcher-activity", description = "Home activity name")
- private String mLauncherActivity = ".NexusLauncherActivity";
-
- @Option(name = "class",
- description = "test class to run, may be repeated; multiple classess will be run"
- + " in the same order as provided in command line")
- private List<String> mClasses = new ArrayList<String>();
-
- @Option(name = "package",
- description = "The manifest package name of the UI test package")
- private String mPackage = "com.android.apptransition.tests";
-
- @Option(name = "latency-iteration", description = "Iterations to be used in the latency tests.")
- private int mLatencyIteration = 10;
-
- @Option(name = "timeout",
- description = "Aborts the test run if any test takes longer than the specified number "
- + "of milliseconds. For no timeout, set to 0.", isTimeVal = true)
- private long mTestTimeout = 45 * 60 * 1000; // default to 45 minutes
-
- private ITestDevice mDevice = null;
- private IRemoteAndroidTestRunner mRunner = null;
- private CollectingTestListener mLaunchListener = null;
- private LogcatReceiver mLaunchEventsLogs = null;
- private EventsLogParser mEventsLogParser = new EventsLogParser();
- private ITestInvocationListener mListener = null;
-
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-
- addDropCacheScriptFile();
- mListener = listener;
-
- if (null != mColdLaunchApps && !mColdLaunchApps.isEmpty()) {
- try {
- mRunner = createRemoteAndroidTestRunner(TEST_COLD_LAUNCH, mColdLaunchApps, null);
- mLaunchListener = new CollectingTestListener();
- mLaunchEventsLogs = new LogcatReceiver(getDevice(), EVENTS_CMD, EVENTS_LOGCAT_SIZE,
- 0);
- startEventsLogs(mLaunchEventsLogs, TEST_COLD_LAUNCH);
- runTests();
- analyzeColdLaunchDelay(parseTransitionDelayInfo());
- } finally {
- stopEventsLogs(mLaunchEventsLogs, TEST_COLD_LAUNCH);
- if (isTraceDirEnabled()) {
- uploadTraceFiles(listener, TEST_COLD_LAUNCH);
- }
- }
- }
-
- if (null != mHotLaunchApps && !mHotLaunchApps.isEmpty()) {
- try {
- mRunner = createRemoteAndroidTestRunner(TEST_HOT_LAUNCH, mHotLaunchApps, null);
- mLaunchListener = new CollectingTestListener();
- mLaunchEventsLogs = new LogcatReceiver(getDevice(), EVENTS_CMD, EVENTS_LOGCAT_SIZE,
- 0);
- startEventsLogs(mLaunchEventsLogs, TEST_HOT_LAUNCH);
- runTests();
- analyzeHotLaunchDelay(parseTransitionDelayInfo());
- } finally {
- stopEventsLogs(mLaunchEventsLogs, TEST_HOT_LAUNCH);
- if (isTraceDirEnabled()) {
- uploadTraceFiles(listener, TEST_HOT_LAUNCH);
- }
- }
- }
-
- if ((null != mAppToRecents && !mAppToRecents.isEmpty()) &&
- (null != mPreLaunchApps && !mPreLaunchApps.isEmpty())) {
- try {
- mRunner = createRemoteAndroidTestRunner(TEST_APP_TO_RECENT, mAppToRecents,
- mPreLaunchApps);
- mLaunchListener = new CollectingTestListener();
- mLaunchEventsLogs = new LogcatReceiver(getDevice(), EVENTS_CMD, EVENTS_LOGCAT_SIZE,
- 0);
- startEventsLogs(mLaunchEventsLogs, TEST_APP_TO_RECENT);
- runTests();
- analyzeAppToRecentsDelay(parseTransitionDelayInfo());
- } finally {
- stopEventsLogs(mLaunchEventsLogs, TEST_APP_TO_RECENT);
- if (isTraceDirEnabled()) {
- uploadTraceFiles(listener, TEST_APP_TO_RECENT);
- }
- }
- }
-
- if ((null != mRecentsToApp && !mRecentsToApp.isEmpty()) &&
- (null != mPreLaunchApps && !mPreLaunchApps.isEmpty())) {
- try {
- mRunner = createRemoteAndroidTestRunner(TEST_HOT_LAUNCH_FROM_RECENTS,
- mRecentsToApp,
- mPreLaunchApps);
- mLaunchListener = new CollectingTestListener();
- mLaunchEventsLogs = new LogcatReceiver(getDevice(), EVENTS_CMD, EVENTS_LOGCAT_SIZE,
- 0);
- startEventsLogs(mLaunchEventsLogs, TEST_HOT_LAUNCH_FROM_RECENTS);
- runTests();
- analyzeRecentsToAppDelay(parseTransitionDelayInfo());
- } finally {
- stopEventsLogs(mLaunchEventsLogs, TEST_HOT_LAUNCH_FROM_RECENTS);
- if (isTraceDirEnabled()) {
- uploadTraceFiles(listener, TEST_HOT_LAUNCH_FROM_RECENTS);
- }
- }
- }
-
- if (!mClasses.isEmpty()) {
- try {
- mRunner = createTestRunner();
- mLaunchListener = new CollectingTestListener();
- mLaunchEventsLogs = new LogcatReceiver(getDevice(), EVENTS_CMD, EVENTS_LOGCAT_SIZE,
- 0);
- startEventsLogs(mLaunchEventsLogs, TEST_LATENCY);
- runTests();
- analyzeLatencyInfo(parseLatencyInfo());
- } finally {
- stopEventsLogs(mLaunchEventsLogs, TEST_LATENCY);
- if (isTraceDirEnabled()) {
- uploadTraceFiles(listener, TEST_LATENCY);
- }
- }
- }
-
- }
-
- private void runTests() throws DeviceNotAvailableException {
- mDevice.runInstrumentationTests(mRunner, mLaunchListener);
- final TestRunResult runResults = mLaunchListener.getCurrentRunResults();
- if (runResults.isRunFailure()) {
- throw new RuntimeException("Error: test run failed!");
- }
- if (runResults.hasFailedTests()) {
- throw new RuntimeException("Error: some tests failed!");
- }
- }
-
- /**
- * Push drop cache script file to test device used for clearing the cache between the app
- * launches.
- *
- * @throws DeviceNotAvailableException
- */
- private void addDropCacheScriptFile() throws DeviceNotAvailableException {
- File scriptFile = null;
- try {
- scriptFile = FileUtil.createTempFile(DROP_CACHE_SCRIPT_FILE, SCRIPT_EXTENSION);
- FileUtil.writeToFile(DROP_CACHE_CMD, scriptFile);
- getDevice().pushFile(scriptFile, String.format("%s%s.sh",
- DEVICE_TEMPORARY_DIR_PATH, DROP_CACHE_SCRIPT_FILE));
- } catch (IOException ioe) {
- CLog.e("Unable to create the Script file");
- CLog.e(ioe);
- }
- getDevice().executeShellCommand(String.format("chmod 755 %s%s.sh",
- DEVICE_TEMPORARY_DIR_PATH, DROP_CACHE_SCRIPT_FILE));
- scriptFile.delete();
- }
-
- /**
- * Method to create the runner with given list of arguments
- *
- * @return the {@link IRemoteAndroidTestRunner} to use.
- * @throws DeviceNotAvailableException
- */
- IRemoteAndroidTestRunner createRemoteAndroidTestRunner(String testName, String launchApps,
- String preLaunchApps) throws DeviceNotAvailableException {
- RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
- PACKAGE_NAME, mRunnerName, mDevice.getIDevice());
- runner.setMethodName(CLASS_NAME, testName);
- runner.addInstrumentationArg("launch_apps", launchApps);
- runner.setMaxTimeout(mTestTimeout, TimeUnit.MILLISECONDS);
- if (null != preLaunchApps && !preLaunchApps.isEmpty()) {
- runner.addInstrumentationArg("pre_launch_apps", preLaunchApps);
- }
- runner.addInstrumentationArg("launch_iteration", Integer.toString(mLaunchIteration));
- for (Map.Entry<String, String> entry : getTestRunArgMap().entrySet()) {
- runner.addInstrumentationArg(entry.getKey(), entry.getValue());
- }
- if (isTraceDirEnabled()) {
- mDevice.executeShellCommand(String.format("rm -rf %s/%s", mTraceDirectory, testName));
- runner.addInstrumentationArg("trace_directory", mTraceDirectory);
- }
- return runner;
- }
-
- /**
- * Method to create the runner with given runner name, package and list of classes.
- * @return the {@link IRemoteAndroidTestRunner} to use.
- * @throws DeviceNotAvailableException
- */
- IRemoteAndroidTestRunner createTestRunner() throws DeviceNotAvailableException {
- IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(mPackage, mRunnerName,
- getDevice().getIDevice());
- if (!mClasses.isEmpty()) {
- runner.setClassNames(mClasses.toArray(new String[] {}));
- }
- runner.addInstrumentationArg("iteration_count", Integer.toString(mLatencyIteration));
- for (Map.Entry<String, String> entry : getTestRunArgMap().entrySet()) {
- runner.addInstrumentationArg(entry.getKey(), entry.getValue());
- }
- if (isTraceDirEnabled()) {
- mDevice.executeShellCommand(String.format("rm -rf %s/%s", mTraceDirectory,
- TEST_LATENCY));
- runner.addInstrumentationArg("trace_directory",
- String.format("%s/%s", mTraceDirectory, TEST_LATENCY));
- }
- return runner;
- }
-
-
- /**
- * Start the events logcat
- *
- * @param logReceiver
- * @param testName
- * @throws DeviceNotAvailableException
- */
- private void startEventsLogs(LogcatReceiver logReceiver, String testName)
- throws DeviceNotAvailableException {
- getDevice().clearLogcat();
- getDevice().executeShellCommand(EVENTS_CLEAR_CMD);
- logReceiver.start();
- }
-
- /**
- * Stop the events logcat and upload the data to sponge
- *
- * @param logReceiver
- */
- private void stopEventsLogs(LogcatReceiver logReceiver,String launchDesc) {
- try (InputStreamSource logcatData = logReceiver.getLogcatData()) {
- mListener.testLog(
- String.format("%s-%s", EVENTS_LOG, launchDesc), LogDataType.TEXT, logcatData);
- } finally {
- logReceiver.stop();
- }
- }
-
- /**
- * Pull the trace files if exist under destDirectory and log it.
- *
- * @param listener test result listener
- * @param srcDirectory source directory in the device where the files are copied to the local
- * tmp directory
- * @param subFolderName to store the files corresponding to the test
- * @throws DeviceNotAvailableException
- * @throws IOException
- */
- private void logTraceFiles(
- ITestInvocationListener listener, String srcDirectory, String subFolderName)
- throws DeviceNotAvailableException, IOException {
- File tmpDestDir = null;
- FileInputStreamSource streamSource = null;
- File zipFile = null;
- try {
- tmpDestDir = FileUtil.createTempDir(subFolderName);
- IFileEntry srcDir = mDevice.getFileEntry(String.format("%s/%s",
- srcDirectory, subFolderName));
- // Files are retrieved from source directory in device
- if (srcDir != null) {
- for (IFileEntry file : srcDir.getChildren(false)) {
- File pulledFile = new File(tmpDestDir, file.getName());
- if (!mDevice.pullFile(file.getFullPath(), pulledFile)) {
- throw new IOException(
- "Not able to pull the file from test device");
- }
- }
- zipFile = ZipUtil.createZip(tmpDestDir);
- streamSource = new FileInputStreamSource(zipFile);
- listener.testLog(tmpDestDir.getName(), LogDataType.ZIP, streamSource);
- }
- } finally {
- FileUtil.recursiveDelete(tmpDestDir);
- StreamUtil.cancel(streamSource);
- FileUtil.deleteFile(zipFile);
- }
- }
-
- /**
- * To upload the trace files stored in the traceDirectory in device to sponge.
- *
- * @param listener
- * @param subFolderName
- * @throws DeviceNotAvailableException
- */
- private void uploadTraceFiles(ITestInvocationListener listener, String subFolderName)
- throws DeviceNotAvailableException {
- try {
- logTraceFiles(listener, mTraceDirectory, subFolderName);
- } catch (IOException ioe) {
- CLog.e("Problem in uploading the log files.");
- CLog.e(ioe);
- }
- mDevice.executeShellCommand(String.format(REMOVE_CMD, mTraceDirectory,
- subFolderName));
- }
-
- /**
- * Returns false if the traceDirectory is not set.
- */
- private boolean isTraceDirEnabled() {
- return (null != mTraceDirectory && !mTraceDirectory.isEmpty());
- }
-
- /**
- * To parse the transition delay info from the events log.
- */
- private List<TransitionDelayItem> parseTransitionDelayInfo() {
- List<TransitionDelayItem> transitionDelayItems = null;
- try (InputStreamSource logcatData = mLaunchEventsLogs.getLogcatData();
- InputStream logcatStream = logcatData.createInputStream();
- InputStreamReader streamReader = new InputStreamReader(logcatStream);
- BufferedReader reader = new BufferedReader(streamReader)) {
- transitionDelayItems = mEventsLogParser.parseTransitionDelayInfo(reader);
- } catch (IOException e) {
- CLog.e("Problem in parsing the transition delay items from events log");
- CLog.e(e);
- }
- return transitionDelayItems;
- }
-
- /**
- * To parse the latency info from the events log.
- */
- private List<LatencyItem> parseLatencyInfo() {
- List<LatencyItem> latencyItems = null;
- try (InputStreamSource logcatData = mLaunchEventsLogs.getLogcatData();
- InputStream logcatStream = logcatData.createInputStream();
- InputStreamReader streamReader = new InputStreamReader(logcatStream);
- BufferedReader reader = new BufferedReader(streamReader)) {
- latencyItems = mEventsLogParser.parseLatencyInfo(reader);
- } catch (IOException e) {
- CLog.e("Problem in parsing the latency items from events log");
- CLog.e(e);
- }
- return latencyItems;
- }
-
- /**
- * Analyze and report the cold launch transition delay from launcher screen.
- *
- * @param transitionDelayItems
- */
- private void analyzeColdLaunchDelay(List<TransitionDelayItem> transitionDelayItems) {
- Map<String, String> cmpNameAppMap = reverseAppCmpInfoMap(getAppComponentInfoMap());
- Map<String, List<Long>> appKeyTransitionDelayMap = new HashMap<>();
- // Handle launcher to cold app launch transition
- for (TransitionDelayItem delayItem : transitionDelayItems) {
- if (cmpNameAppMap.containsKey(delayItem.getComponentName())) {
- String appName = cmpNameAppMap.get(delayItem.getComponentName());
- if (delayItem.getStartingWindowDelay() != null) {
- if (appKeyTransitionDelayMap.containsKey(appName)) {
- appKeyTransitionDelayMap.get(appName).add(
- delayItem.getStartingWindowDelay());
- } else {
- List<Long> delayTimeList = new ArrayList<Long>();
- delayTimeList.add(delayItem.getStartingWindowDelay());
- appKeyTransitionDelayMap.put(appName, delayTimeList);
- }
- }
- }
- }
- removeAdditionalLaunchInfo(appKeyTransitionDelayMap);
- computeAndUploadResults(TEST_COLD_LAUNCH, appKeyTransitionDelayMap);
- }
-
- /**
- * Analyze and report the hot launch transition delay from launcher and app
- * to home transition delay. Keep track of launcher to app transition delay
- * which immediately followed by app to home transition. Skip the
- * intitial cold launch on the apps.
- *
- * @param transitionDelayItems
- */
- private void analyzeHotLaunchDelay(List<TransitionDelayItem> transitionDelayItems) {
- Map<String, String> cmpNameAppMap = reverseAppCmpInfoMap(getAppComponentInfoMap());
- Map<String, List<Long>> appKeyTransitionDelayMap = new HashMap<>();
- Map<String, List<Long>> appToHomeKeyTransitionDelayMap = new HashMap<>();
- String prevAppName = null;
- for (TransitionDelayItem delayItem : transitionDelayItems) {
- // Handle app to home transition
- if (null != prevAppName) {
- if (delayItem.getComponentName().contains(mLauncherActivity)) {
- if (appToHomeKeyTransitionDelayMap.containsKey(prevAppName)) {
- appToHomeKeyTransitionDelayMap
- .get(prevAppName)
- .add(delayItem.getWindowDrawnDelay());
- } else {
- List<Long> delayTimeList = new ArrayList<Long>();
- delayTimeList.add(delayItem.getWindowDrawnDelay());
- appToHomeKeyTransitionDelayMap.put(prevAppName, delayTimeList);
- }
- prevAppName = null;
- }
- continue;
- }
- // Handle launcher to hot app launch transition
- if (cmpNameAppMap.containsKey(delayItem.getComponentName())) {
- // Not to consider the first cold launch for the app.
- if (delayItem.getStartingWindowDelay() != null) {
- continue;
- }
- String appName = cmpNameAppMap.get(delayItem.getComponentName());
- if (appKeyTransitionDelayMap.containsKey(appName)) {
- appKeyTransitionDelayMap.get(appName).add(delayItem.getTransitionDelay());
- } else {
- List<Long> delayTimeList = new ArrayList<Long>();
- delayTimeList.add(delayItem.getTransitionDelay());
- appKeyTransitionDelayMap.put(appName, delayTimeList);
- }
- prevAppName = appName;
- }
- }
- // Remove the first hot launch info through intents
- removeAdditionalLaunchInfo(appKeyTransitionDelayMap);
- computeAndUploadResults(TEST_HOT_LAUNCH, appKeyTransitionDelayMap);
- removeAdditionalLaunchInfo(appToHomeKeyTransitionDelayMap);
- computeAndUploadResults(TEST_APP_TO_HOME, appToHomeKeyTransitionDelayMap);
- }
-
- /**
- * Analyze and report app to recents transition delay info.
- *
- * @param transitionDelayItems
- */
- private void analyzeAppToRecentsDelay(List<TransitionDelayItem> transitionDelayItems) {
- Map<String, String> cmpNameAppMap = reverseAppCmpInfoMap(getAppComponentInfoMap());
- Map<String, List<Long>> appKeyTransitionDelayMap = new HashMap<>();
- String prevAppName = null;
- for (TransitionDelayItem delayItem : transitionDelayItems) {
- if (delayItem.getComponentName().contains(mLauncherActivity)) {
- if (appKeyTransitionDelayMap.containsKey(prevAppName)) {
- appKeyTransitionDelayMap.get(prevAppName).add(delayItem.getWindowDrawnDelay());
- } else {
- if (null != prevAppName) {
- List<Long> delayTimeList = new ArrayList<Long>();
- delayTimeList.add(delayItem.getWindowDrawnDelay());
- appKeyTransitionDelayMap.put(prevAppName, delayTimeList);
- }
- }
- prevAppName = null;
- continue;
- }
-
- if (cmpNameAppMap.containsKey(delayItem.getComponentName())) {
- prevAppName = cmpNameAppMap.get(delayItem.getComponentName());
- }
- }
- //Removing the first cold launch to recents transition delay.
- removeAdditionalLaunchInfo(appKeyTransitionDelayMap);
- computeAndUploadResults(TEST_APP_TO_RECENT, appKeyTransitionDelayMap);
- }
-
- /**
- * Analyze and report recents to hot app launch delay info. Skip the intitial cold
- * launch transition delay on the apps. Also the first launch cannot always be the
- * cold launch because the apps could be part of preapps list. The transition delay is
- * tracked based on recents to apps transition delay items.
- *
- * @param transitionDelayItems
- */
- private void analyzeRecentsToAppDelay(List<TransitionDelayItem> transitionDelayItems) {
- Map<String, String> cmpNameAppMap = reverseAppCmpInfoMap(getAppComponentInfoMap());
- Map<String, List<Long>> appKeyTransitionDelayMap = new HashMap<>();
- boolean isRecentsBefore = false;
- for (TransitionDelayItem delayItem : transitionDelayItems) {
- if (delayItem.getComponentName().contains(mLauncherActivity)) {
- isRecentsBefore = true;
- continue;
- }
- if (isRecentsBefore && cmpNameAppMap.containsKey(delayItem.getComponentName())) {
- if (delayItem.getStartingWindowDelay() != null) {
- continue;
- }
- String appName = cmpNameAppMap.get(delayItem.getComponentName());
- if (appKeyTransitionDelayMap.containsKey(appName)) {
- appKeyTransitionDelayMap.get(appName).add(delayItem.getTransitionDelay());
- } else {
- List<Long> delayTimeList = new ArrayList<Long>();
- delayTimeList.add(delayItem.getTransitionDelay());
- appKeyTransitionDelayMap.put(appName, delayTimeList);
- }
- }
- isRecentsBefore = false;
- }
- removeAdditionalLaunchInfo(appKeyTransitionDelayMap);
- computeAndUploadResults(TEST_HOT_LAUNCH_FROM_RECENTS, appKeyTransitionDelayMap);
- }
-
-
- /**
- * Analyze and report different latency delay items captured from the events log
- * file while running the LatencyTests
- * @param latencyItemsList
- */
- private void analyzeLatencyInfo(List<LatencyItem> latencyItemsList) {
- Map<String, List<Long>> actionDelayListMap = new HashMap<>();
- for (LatencyItem delayItem : latencyItemsList) {
- if (actionDelayListMap.containsKey(Integer.toString(delayItem.getActionId()))) {
- actionDelayListMap.get(Integer.toString(delayItem.getActionId())).add(
- delayItem.getDelay());
- } else {
- List<Long> delayList = new ArrayList<Long>();
- delayList.add(delayItem.getDelay());
- actionDelayListMap.put(Integer.toString(delayItem.getActionId()), delayList);
- }
- }
- computeAndUploadResults(TEST_LATENCY, actionDelayListMap);
- }
-
-
- /**
- * To remove the additional launch info at the beginning of the test.
- *
- * @param appKeyTransitionDelayMap
- */
- private void removeAdditionalLaunchInfo(Map<String, List<Long>> appKeyTransitionDelayMap) {
- for (List<Long> delayList : appKeyTransitionDelayMap.values()) {
- while (delayList.size() > mLaunchIteration) {
- delayList.remove(0);
- }
- }
- }
-
- /**
- * To compute the min,max,avg,median and std_dev on the transition delay for each app
- * and upload the metrics
- *
- * @param reportingKey
- * @param appKeyTransitionDelayMap
- */
- private void computeAndUploadResults(String reportingKey,
- Map<String, List<Long>> appKeyTransitionDelayMap) {
- CLog.i(String.format("Testing : %s", reportingKey));
- Map<String, String> activityMetrics = new HashMap<String, String>();
- for (String appNameKey : appKeyTransitionDelayMap.keySet()) {
- List<Long> delayList = appKeyTransitionDelayMap.get(appNameKey);
- StringBuffer delayListStr = new StringBuffer();
- for (Long delayItem : delayList) {
- delayListStr.append(delayItem);
- delayListStr.append(",");
- }
- CLog.i("%s : %s", appNameKey, delayListStr);
- SimpleStats stats = new SimpleStats();
- for (Long delay : delayList) {
- stats.add(Double.parseDouble(delay.toString()));
- }
- activityMetrics.put(appNameKey + "_min", stats.min().toString());
- activityMetrics.put(appNameKey + "_max", stats.max().toString());
- activityMetrics.put(appNameKey + "_avg", stats.mean().toString());
- activityMetrics.put(appNameKey + "_median", stats.median().toString());
- activityMetrics.put(appNameKey + "_std_dev", stats.stdev().toString());
- }
- mListener.testRunStarted(reportingKey, 0);
- mListener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(activityMetrics));
- }
-
- /**
- * Retrieve the map of appname,componenetname from the results.
- */
- private Map<String,String> getAppComponentInfoMap() {
- Collection<TestResult> testResultsCollection = mLaunchListener
- .getCurrentRunResults().getTestResults().values();
- List<TestResult> testResults = new ArrayList<>(
- testResultsCollection);
- return testResults.get(0).getMetrics();
- }
-
- /**
- * Reverse and returnthe given appName,componentName info map to componenetName,appName info
- * map.
- */
- private Map<String, String> reverseAppCmpInfoMap(Map<String, String> appNameCmpNameMap) {
- Map<String, String> cmpNameAppNameMap = new HashMap<String, String>();
- for (Map.Entry<String, String> entry : appNameCmpNameMap.entrySet()) {
- cmpNameAppNameMap.put(entry.getValue(), entry.getKey());
- }
- return cmpNameAppNameMap;
- }
-
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- /**
- * @return the arguments map to pass to the test runner.
- */
- public Map<String, String> getTestRunArgMap() {
- return mArgMap;
- }
-
- /**
- * @param runArgMap the arguments to pass to the test runner.
- */
- public void setTestRunArgMap(Map<String, String> runArgMap) {
- mArgMap = runArgMap;
- }
-
-}
-
diff --git a/prod-tests/src/com/android/performance/tests/EmmcPerformanceTest.java b/prod-tests/src/com/android/performance/tests/EmmcPerformanceTest.java
deleted file mode 100644
index 6e8f61a..0000000
--- a/prod-tests/src/com/android/performance/tests/EmmcPerformanceTest.java
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * 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.performance.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.AbiFormatter;
-import com.android.tradefed.util.SimplePerfResult;
-import com.android.tradefed.util.SimplePerfUtil;
-import com.android.tradefed.util.SimplePerfUtil.SimplePerfType;
-import com.android.tradefed.util.SimpleStats;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * This test is targeting eMMC performance on read/ write.
- */
-public class EmmcPerformanceTest implements IDeviceTest, IRemoteTest {
- private enum TestType {
- DD,
- RANDOM;
- }
-
- private static final String RUN_KEY = "emmc_performance_tests";
-
- private static final String SEQUENTIAL_READ_KEY = "sequential_read";
- private static final String SEQUENTIAL_WRITE_KEY = "sequential_write";
- private static final String RANDOM_READ_KEY = "random_read";
- private static final String RANDOM_WRITE_KEY = "random_write";
- private static final String PERF_RANDOM = "/data/local/tmp/rand_emmc_perf|#ABI32#|";
-
- private static final Pattern DD_PATTERN = Pattern.compile(
- "\\d+ bytes transferred in \\d+\\.\\d+ secs \\((\\d+) bytes/sec\\)");
-
- private static final Pattern EMMC_RANDOM_PATTERN = Pattern.compile(
- "(\\d+) (\\d+)byte iops/sec");
- private static final int BLOCK_SIZE = 1048576;
- private static final int SEQ_COUNT = 200;
-
- @Option(name = "cpufreq", description = "The path to the cpufreq directory on the DUT.")
- private String mCpufreq = "/sys/devices/system/cpu/cpu0/cpufreq";
-
- @Option(name = "auto-discover-cache-info",
- description =
- "Indicate if test should attempt auto discover cache path and partition size "
- + "from the test device. Default to be false, ie. manually set "
- + "cache-device and cache-partition-size, or use default."
- + " If fail to discover, it will fallback to what is set in "
- + "cache-device")
- private boolean mAutoDiscoverCacheInfo = false;
-
- @Option(name = "cache-device", description = "The path to the cache block device on the DUT." +
- " Nakasi: /dev/block/platform/sdhci-tegra.3/by-name/CAC\n" +
- " Prime: /dev/block/platform/omap/omap_hsmmc.0/by-name/cache\n" +
- " Stingray: /dev/block/platform/sdhci-tegra.3/by-name/cache\n" +
- " Crespo: /dev/block/platform/s3c-sdhci.0/by-name/userdata\n",
- importance = Importance.IF_UNSET)
- private String mCache = null;
-
- @Option(name = "iterations", description = "The number of iterations to run")
- private int mIterations = 100;
-
- @Option(name = AbiFormatter.FORCE_ABI_STRING,
- description = AbiFormatter.FORCE_ABI_DESCRIPTION,
- importance = Importance.IF_UNSET)
- private String mForceAbi = null;
-
- @Option(name = "cache-partition-size", description = "Cache partiton size in MB")
- private static int mCachePartitionSize = 100;
-
- @Option(name = "simpleperf-mode",
- description = "Whether use simpleperf to get low level metrics")
- private boolean mSimpleperfMode = false;
-
- @Option(name = "simpleperf-argu", description = "simpleperf arguments")
- private List<String> mSimpleperfArgu = new ArrayList<String>();
-
- ITestDevice mTestDevice = null;
- SimplePerfUtil mSpUtil = null;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- try {
- setUp();
-
- listener.testRunStarted(RUN_KEY, 5);
- long beginTime = System.currentTimeMillis();
- Map<String, String> metrics = new HashMap<String, String>();
-
- runSequentialRead(mIterations, listener, metrics);
- runSequentialWrite(mIterations, listener, metrics);
- // FIXME: Figure out cache issues with random read and reenable test.
- // runRandomRead(mIterations, listener, metrics);
- // runRandomWrite(mIterations, listener, metrics);
-
- CLog.d("Metrics: %s", metrics.toString());
- listener.testRunEnded(
- (System.currentTimeMillis() - beginTime),
- TfMetricProtoUtil.upgradeConvert(metrics));
- } finally {
- cleanUp();
- }
- }
-
- /**
- * Run the sequential read test.
- */
- private void runSequentialRead(int iterations, ITestInvocationListener listener,
- Map<String, String> metrics) throws DeviceNotAvailableException {
- String command = String.format("dd if=%s of=/dev/null bs=%d count=%d", mCache, BLOCK_SIZE,
- SEQ_COUNT);
- runTest(SEQUENTIAL_READ_KEY, command, TestType.DD, true, iterations, listener, metrics);
- }
-
- /**
- * Run the sequential write test.
- */
- private void runSequentialWrite(int iterations, ITestInvocationListener listener,
- Map<String, String> metrics) throws DeviceNotAvailableException {
- String command = String.format("dd if=/dev/zero of=%s bs=%d count=%d", mCache, BLOCK_SIZE,
- SEQ_COUNT);
- runTest(SEQUENTIAL_WRITE_KEY, command, TestType.DD, false, iterations, listener, metrics);
- }
-
- /**
- * Run the random read test.
- */
- @SuppressWarnings("unused")
- private void runRandomRead(int iterations, ITestInvocationListener listener,
- Map<String, String> metrics) throws DeviceNotAvailableException {
- String command = String.format("%s -r %d %s",
- AbiFormatter.formatCmdForAbi(PERF_RANDOM, mForceAbi), mCachePartitionSize, mCache);
- runTest(RANDOM_READ_KEY, command, TestType.RANDOM, true, iterations, listener, metrics);
- }
-
- /**
- * Run the random write test with OSYNC disabled.
- */
- private void runRandomWrite(int iterations, ITestInvocationListener listener,
- Map<String, String> metrics) throws DeviceNotAvailableException {
- String command = String.format("%s -w %d %s",
- AbiFormatter.formatCmdForAbi(PERF_RANDOM, mForceAbi), mCachePartitionSize, mCache);
- runTest(RANDOM_WRITE_KEY, command, TestType.RANDOM, false, iterations, listener, metrics);
- }
-
- /**
- * Run a test for a number of iterations.
- *
- * @param testKey the key used to report metrics.
- * @param command the command to be run on the device.
- * @param type the {@link TestType}, which determines how each iteration should be run.
- * @param dropCache whether to drop the cache before starting each iteration.
- * @param iterations the number of iterations to run.
- * @param listener the {@link ITestInvocationListener}.
- * @param metrics the map to store metrics of.
- * @throws DeviceNotAvailableException If the device was not available.
- */
- private void runTest(String testKey, String command, TestType type, boolean dropCache,
- int iterations, ITestInvocationListener listener, Map<String, String> metrics)
- throws DeviceNotAvailableException {
- CLog.i("Starting test %s", testKey);
-
- TestDescription id = new TestDescription(RUN_KEY, testKey);
- listener.testStarted(id);
-
- Map<String, SimpleStats> simpleperfMetricsMap = new HashMap<String, SimpleStats>();
- SimpleStats stats = new SimpleStats();
- for (int i = 0; i < iterations; i++) {
- if (dropCache) {
- dropCache();
- }
-
- Double kbps = null;
- switch (type) {
- case DD:
- kbps = runDdIteration(command, simpleperfMetricsMap);
- break;
- case RANDOM:
- kbps = runRandomIteration(command, simpleperfMetricsMap);
- break;
- }
-
- if (kbps != null) {
- CLog.i("Result for %s, iteration %d: %f KBps", testKey, i + 1, kbps);
- stats.add(kbps);
- } else {
- CLog.w("Skipping %s, iteration %d", testKey, i + 1);
- }
- }
-
- if (stats.mean() != null) {
- metrics.put(testKey, Double.toString(stats.median()));
- for (Map.Entry<String, SimpleStats> entry : simpleperfMetricsMap.entrySet()) {
- metrics.put(String.format("%s_%s", testKey, entry.getKey()),
- Double.toString(entry.getValue().median()));
- }
- } else {
- listener.testFailed(id, "No metrics to report (see log)");
- }
- CLog.i("Test %s finished: mean=%f, stdev=%f, samples=%d", testKey, stats.mean(),
- stats.stdev(), stats.size());
- listener.testEnded(id, new HashMap<String, Metric>());
- }
-
- /**
- * Run a single iteration of the dd (sequential) test.
- *
- * @param command the command to run on the device.
- * @param simpleperfMetricsMap the map contain simpleperf metrics aggregated results
- * @return The speed of the test in KBps or null if there was an error running or parsing the
- * test.
- * @throws DeviceNotAvailableException If the device was not available.
- */
- private Double runDdIteration(String command, Map<String, SimpleStats> simpleperfMetricsMap)
- throws DeviceNotAvailableException {
- String[] output;
- SimplePerfResult spResult = null;
- if (mSimpleperfMode) {
- spResult = mSpUtil.executeCommand(command);
- output = spResult.getCommandRawOutput().split("\n");
- } else {
- output = mTestDevice.executeShellCommand(command).split("\n");
- }
- String line = output[output.length - 1].trim();
-
- Matcher m = DD_PATTERN.matcher(line);
- if (m.matches()) {
- simpleperfResultAggregation(spResult, simpleperfMetricsMap);
- return convertBpsToKBps(Double.parseDouble(m.group(1)));
- } else {
- CLog.w("Line \"%s\" did not match expected output, ignoring", line);
- return null;
- }
- }
-
- /**
- * Run a single iteration of the random test.
- *
- * @param command the command to run on the device.
- * @param simpleperfMetricsMap the map contain simpleperf metrics aggregated results
- * @return The speed of the test in KBps or null if there was an error running or parsing the
- * test.
- * @throws DeviceNotAvailableException If the device was not available.
- */
- private Double runRandomIteration(String command, Map<String, SimpleStats> simpleperfMetricsMap)
- throws DeviceNotAvailableException {
- String output;
- SimplePerfResult spResult = null;
- if (mSimpleperfMode) {
- spResult = mSpUtil.executeCommand(command);
- output = spResult.getCommandRawOutput();
- } else {
- output = mTestDevice.executeShellCommand(command);
- }
- Matcher m = EMMC_RANDOM_PATTERN.matcher(output.trim());
- if (m.matches()) {
- simpleperfResultAggregation(spResult, simpleperfMetricsMap);
- return convertIopsToKBps(Double.parseDouble(m.group(1)));
- } else {
- CLog.w("Line \"%s\" did not match expected output, ignoring", output);
- return null;
- }
- }
-
- /**
- * Helper function to aggregate simpleperf results
- *
- * @param spResult object that holds simpleperf results
- * @param simpleperfMetricsMap map holds aggregated simpleperf results
- */
- private void simpleperfResultAggregation(SimplePerfResult spResult,
- Map<String, SimpleStats> simpleperfMetricsMap) {
- if (mSimpleperfMode) {
- Assert.assertNotNull("simpleperf result is null object", spResult);
- for (Map.Entry<String, String> entry : spResult.getBenchmarkMetrics().entrySet()) {
- try {
- Double metricValue = NumberFormat.getNumberInstance(Locale.US)
- .parse(entry.getValue()).doubleValue();
- if (!simpleperfMetricsMap.containsKey(entry.getKey())) {
- SimpleStats newStat = new SimpleStats();
- simpleperfMetricsMap.put(entry.getKey(), newStat);
- }
- simpleperfMetricsMap.get(entry.getKey()).add(metricValue);
- } catch (ParseException e) {
- CLog.e("Simpleperf metrics parse failure: " + e.toString());
- }
- }
- }
- }
-
- /**
- * Drop the disk cache on the device.
- */
- private void dropCache() throws DeviceNotAvailableException {
- mTestDevice.executeShellCommand("echo 3 > /proc/sys/vm/drop_caches");
- }
-
- /**
- * Convert bytes / sec reported by the dd tests into KBps.
- */
- private double convertBpsToKBps(double bps) {
- return bps / 1024;
- }
-
- /**
- * Convert the iops reported by the random tests into KBps.
- * <p>
- * The iops is number of 4kB block reads/writes per sec. This makes the conversion factor 4.
- * </p>
- */
- private double convertIopsToKBps(double iops) {
- return 4 * iops;
- }
-
- /**
- * Setup the device for tests by unmounting partitions and maxing the cpu speed.
- */
- private void setUp() throws DeviceNotAvailableException {
- if (mAutoDiscoverCacheInfo) {
- discoverCacheInfo();
- }
- mTestDevice.executeShellCommand("umount /sdcard");
- mTestDevice.executeShellCommand("umount /data");
- mTestDevice.executeShellCommand("umount /cache");
-
- mTestDevice.executeShellCommand(
- String.format("cat %s/cpuinfo_max_freq > %s/scaling_max_freq", mCpufreq, mCpufreq));
- mTestDevice.executeShellCommand(
- String.format("cat %s/cpuinfo_max_freq > %s/scaling_min_freq", mCpufreq, mCpufreq));
-
- if (mSimpleperfMode) {
- mSpUtil = SimplePerfUtil.newInstance(mTestDevice, SimplePerfType.STAT);
- if (mSimpleperfArgu.size() == 0) {
- mSimpleperfArgu.add("-e cpu-cycles:k,cpu-cycles:u");
- }
- mSpUtil.setArgumentList(mSimpleperfArgu);
- }
- }
-
- /**
- * Attempt to detect cache path and cache partition size automatically
- */
- private void discoverCacheInfo() throws DeviceNotAvailableException {
- // Expected output look similar to the following:
- //
- // > ... vdc dump | grep cache
- // 0 4123 /dev/block/platform/soc/7824900.sdhci/by-name/cache /cache ext4 rw, \
- // seclabel,nosuid,nodev,noatime,discard,data=ordered 0 0
- if (mTestDevice.enableAdbRoot()) {
- String output = mTestDevice.executeShellCommand("vdc dump | grep cache");
- CLog.d("Output from shell command 'vdc dump | grep cache':\n%s", output);
- String[] segments = output.split("\\s+");
- if (segments.length >= 3) {
- mCache = segments[2];
- } else {
- CLog.w("Fail to detect cache path. Fall back to use '%s'", mCache);
- }
- } else {
- CLog.d("Cannot get cache path because device %s is not rooted.",
- mTestDevice.getSerialNumber());
- }
-
- // Expected output looks similar to the following:
- //
- // > ... df cache
- // Filesystem 1K-blocks Used Available Use% Mounted on
- // /dev/block/mmcblk0p34 60400 56 60344 1% /cache
- String output = mTestDevice.executeShellCommand("df cache");
- CLog.d(String.format("Output from shell command 'df cache':\n%s", output));
- String[] lines = output.split("\r?\n");
- if (lines.length >= 2) {
- String[] segments = lines[1].split("\\s+");
- if (segments.length >= 2) {
- if (lines[0].toLowerCase().contains("1k-blocks")) {
- mCachePartitionSize = Integer.parseInt(segments[1]) / 1024;
- } else {
- throw new IllegalArgumentException("Unknown unit for the cache size.");
- }
- }
- }
-
- CLog.d("cache-device is set to %s ...", mCache);
- CLog.d("cache-partition-size is set to %d ...", mCachePartitionSize);
- }
-
- /**
- * Clean up the device by formatting a new cache partition.
- */
- private void cleanUp() throws DeviceNotAvailableException {
- mTestDevice.executeShellCommand(String.format("mke2fs %s", mCache));
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mTestDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-}
-
diff --git a/prod-tests/src/com/android/performance/tests/FioBenchmarkTest.java b/prod-tests/src/com/android/performance/tests/FioBenchmarkTest.java
deleted file mode 100644
index 69ff904..0000000
--- a/prod-tests/src/com/android/performance/tests/FioBenchmarkTest.java
+++ /dev/null
@@ -1,1062 +0,0 @@
-/*
- * Copyright (C) 2011 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.performance.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.MultiLineReceiver;
-import com.android.ddmlib.NullOutputReceiver;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import junit.framework.TestCase;
-
-import org.junit.Assert;
-
-import java.io.File;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Runs the FIO benchmarks.
- * <p>
- * This test pushes the FIO executable to the device and runs several benchmarks. Running each
- * benchmark consists of creating a config file, creating one or more data files, clearing the disk
- * cache and then running FIO. The test runs a variety of different configurations including a
- * simple benchmark with a single thread, a storage benchmark with 4 threads, a media server
- * emulator, and a media scanner emulator.
- * </p>
- */
-public class FioBenchmarkTest implements IDeviceTest, IRemoteTest {
- // TODO: Refactor this to only pick out fields we care about.
- private static final String[] FIO_V0_RESULT_FIELDS = {
- "jobname", "groupid", "error",
- // Read stats
- "read-kb-io", "read-bandwidth", "read-runtime",
- "read-slat-min", "read-slat-max", "read-slat-mean", "read-slat-stddev",
- "read-clat-min", "read-clat-max", "read-clat-mean", "read-clat-stddev",
- "read-bandwidth-min", "read-bandwidth-max", "read-bandwidth-percent", "read-bandwidth-mean",
- "read-bandwidth-stddev",
- // Write stats
- "write-kb-io", "write-bandwidth", "write-runtime",
- "write-slat-min", "write-slat-max", "write-slat-mean", "write-slat-stddev",
- "write-clat-min", "write-clat-max", "write-clat-mean", "write-clat-stddev",
- "write-bandwidth-min", "write-bandwidth-max", "write-bandwidth-percent",
- "write-bandwidth-mean", "write-bandwidth-stddev",
- // CPU stats
- "cpu-user", "cpu-system", "cpu-context-switches", "cpu-major-page-faults",
- "cpu-minor-page-faults",
- // IO depth stats
- "io-depth-1", "io-depth-2", "io-depth-4", "io-depth-8", "io-depth-16", "io-depth-32",
- "io-depth-64",
- // IO lat stats
- "io-lat-2-ms", "io-lat-4-ms", "io-lat-10-ms", "io-lat-20-ms", "io-lat-50-ms",
- "io-lat-100-ms", "io-lat-250-ms", "io-lat-500-ms", "io-lat-750-ms", "io-lat-1000-ms",
- "io-lat-2000-ms"
- };
- private static final String[] FIO_V3_RESULT_FIELDS = {
- "terse-version", "fio-version", "jobname", "groupid", "error",
- // Read stats
- "read-kb-io", "read-bandwidth", "read-iops", "read-runtime",
- "read-slat-min", "read-slat-max", "read-slat-mean", "read-slat-stddev",
- "read-clat-min", "read-clat-max", "read-clat-mean", "read-clat-stddev",
- null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null,
- "read-lat-min", "read-lat-max", "read-lat-mean", "read-lat-stddev",
- "read-bandwidth-min", "read-bandwidth-max", "read-bandwidth-percent", "read-bandwidth-mean",
- "read-bandwidth-stddev",
- // Write stats
- "write-kb-io", "write-bandwidth", "write-iops", "write-runtime",
- "write-slat-min", "write-slat-max", "write-slat-mean", "write-slat-stddev",
- "write-clat-min", "write-clat-max", "write-clat-mean", "write-clat-stddev",
- null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
- null, null, null, null, null,
- "write-lat-min", "write-lat-max", "write-lat-mean", "write-lat-stddev",
- "write-bandwidth-min", "write-bandwidth-max", "write-bandwidth-percent",
- "write-bandwidth-mean", "write-bandwidth-stddev",
- // CPU stats
- "cpu-user", "cpu-system", "cpu-context-switches", "cpu-major-page-faults",
- "cpu-minor-page-faults",
- // IO depth stats
- "io-depth-1", "io-depth-2", "io-depth-4", "io-depth-8", "io-depth-16", "io-depth-32",
- "io-depth-64",
- // IO lat stats
- "io-lat-2-us", "io-lat-4-us", "io-lat-10-us", "io-lat-20-us", "io-lat-50-us",
- "io-lat-100-us", "io-lat-250-us", "io-lat-500-us", "io-lat-750-us", "io-lat-1000-us",
- "io-lat-2-ms", "io-lat-4-ms", "io-lat-10-ms", "io-lat-20-ms", "io-lat-50-ms",
- "io-lat-100-ms", "io-lat-250-ms", "io-lat-500-ms", "io-lat-750-ms", "io-lat-1000-ms",
- "io-lat-2000-ms", "io-lat-greater"
- };
-
- private List<TestInfo> mTestCases = null;
-
- /**
- * Holds info about a job. The job translates into a job in the FIO config file. Contains the
- * job name and a map from keys to values.
- */
- private static class JobInfo {
- public String mJobName = null;
- public Map<String, String> mParameters = new HashMap<>();
-
- /**
- * Gets the job as a string.
- *
- * @return a string of the job formatted for the config file.
- */
- public String createJob() {
- if (mJobName == null) {
- return "";
- }
- StringBuilder sb = new StringBuilder();
- sb.append(String.format("[%s]\n", mJobName));
- for (Entry<String, String> parameter : mParameters.entrySet()) {
- if (parameter.getValue() == null) {
- sb.append(String.format("%s\n", parameter.getKey()));
- } else {
- sb.append(String.format("%s=%s\n", parameter.getKey(), parameter.getValue()));
- }
- }
- return sb.toString();
- }
- }
-
- /**
- * Holds info about a file used in the benchmark. Because of limitations in FIO on Android,
- * the file needs to be created before the tests are run. Contains the file name and size in kB.
- */
- private static class TestFileInfo {
- public String mFileName = null;
- public int mSize = -1;
- }
-
- /**
- * Holds info about the perf metric that are cared about for a given job.
- */
- private static class PerfMetricInfo {
- public enum ResultType {
- STRING, INT, FLOAT, PERCENT;
-
- String value(String input) {
- switch(this) {
- case STRING:
- case INT:
- case FLOAT:
- return input;
- case PERCENT:
- if (input.length() < 2 || !input.endsWith("%")) {
- return null;
- }
- try {
- return String.format("%f", Double.parseDouble(
- input.substring(0, input.length() - 1)) / 100);
- } catch (NumberFormatException e) {
- return null;
- }
- default: return null;
- }
- }
- }
-
- public String mJobName = null;
- public String mFieldName = null;
- public String mPostKey = null;
- public ResultType mType = ResultType.STRING;
- }
-
- /**
- * Holds the info associated with a test.
- * <p>
- * Contains the test name, key, a list of {@link JobInfo}, a set of {@link TestFileInfo},
- * and a set of {@link PerfMetricInfo}.
- * </p>
- */
- private static class TestInfo {
- public String mTestName = null;
- public String mKey = null;
- public List<JobInfo> mJobs = new LinkedList<>();
- public Set<TestFileInfo> mTestFiles = new HashSet<>();
- public Set<PerfMetricInfo> mPerfMetrics = new HashSet<>();
-
- /**
- * Gets the config file.
- *
- * @return a string containing the contents of the config file needed to run the benchmark.
- */
- private String createConfig() {
- StringBuilder sb = new StringBuilder();
- for (JobInfo job : mJobs) {
- sb.append(String.format("%s\n", job.createJob()));
- }
- return sb.toString();
- }
- }
-
- /**
- * Parses the output of the FIO and allows the values to be looked up by job name and property.
- */
- private static class FioParser extends MultiLineReceiver {
- public Map<String, Map<String, String>> mResults = new HashMap<>();
-
- /**
- * Gets the result for a job and property, or null if the job or the property do not exist.
- *
- * @param job the name of the job.
- * @param property the name of the property. See {@code FIO_RESULT_FIELDS}.
- * @return the fio results for the job and property or null if it does not exist.
- */
- public String getResult(String job, String property) {
- if (!mResults.containsKey(job)) {
- return null;
- }
- return mResults.get(job).get(property);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void processNewLines(String[] lines) {
- for (String line : lines) {
- CLog.d(line);
- String[] fields = line.split(";");
- if (fields.length < FIO_V0_RESULT_FIELDS.length) {
- continue;
- }
- if (fields.length < FIO_V3_RESULT_FIELDS.length) {
- Map<String, String> r = new HashMap<>();
- for (int i = 0; i < FIO_V0_RESULT_FIELDS.length; i++) {
- r.put(FIO_V0_RESULT_FIELDS[i], fields[i]);
- }
- mResults.put(fields[0], r); // Job name is index 0
- } else if ("3".equals(fields[0])) {
- Map<String, String> r = new HashMap<>();
- for (int i = 0; i < FIO_V3_RESULT_FIELDS.length; i++) {
- r.put(FIO_V3_RESULT_FIELDS[i], fields[i]);
- }
- mResults.put(fields[2], r); // Job name is index 2
- } else {
- Assert.fail("Unknown fio terse output version");
- }
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean isCancelled() {
- return false;
- }
- }
-
- ITestDevice mTestDevice = null;
-
- private String mFioDir = null;
- private String mFioBin = null;
- private String mFioConfig = null;
-
- @Option(name="fio-location", description="The path to the precompiled FIO executable. If "
- + "unset, try to use fio from the system image.")
- private String mFioLocation = null;
-
- @Option(name="tmp-dir", description="The directory used for interal benchmarks.")
- private String mTmpDir = "/data/tmp/fio";
-
- @Option(name="internal-test-dir", description="The directory used for interal benchmarks.")
- private String mInternalTestDir = "/data/fio/data";
-
- @Option(name="media-test-dir", description="The directory used for media benchmarks.")
- private String mMediaTestDir = "${EXTERNAL_STORAGE}/fio";
-
- @Option(name="external-test-dir", description="The directory used for external benchmarks.")
- private String mExternalTestDir = "${EXTERNAL_STORAGE}/fio";
-
- @Option(name="collect-yaffs-logs", description="Collect yaffs logs before and after tests")
- private Boolean mCollectYaffsLogs = false;
-
- @Option(name="run-simple-internal-test", description="Run the simple internal benchmark.")
- private Boolean mRunSimpleInternalTest = true;
-
- @Option(name="simple-internal-file-size",
- description="The file size of the simple internal benchmark in MB.")
- private int mSimpleInternalFileSize = 256;
-
- @Option(name="run-simple-external-test", description="Run the simple external benchmark.")
- private Boolean mRunSimpleExternalTest = false;
-
- @Option(name="simple-external-file-size",
- description="The file size of the simple external benchmark in MB.")
- private int mSimpleExternalFileSize = 256;
-
- @Option(name="run-storage-internal-test", description="Run the storage internal benchmark.")
- private Boolean mRunStorageInternalTest = true;
-
- @Option(name="storage-internal-file-size",
- description="The file size of the storage internal benchmark in MB.")
- private int mStorageInternalFileSize = 256;
-
- @Option(name="storage-internal-job-count",
- description="The number of jobs for the storage internal benchmark.")
- private int mStorageInternalJobCount = 4;
-
- @Option(name="run-storage-external-test", description="Run the storage external benchmark.")
- private Boolean mRunStorageExternalTest = false;
-
- @Option(name="storage-external-file-size",
- description="The file size of the storage external benchmark in MB.")
- private int mStorageExternalFileSize = 256;
-
- @Option(name="storage-external-job-count",
- description="The number of jobs for the storage external benchmark.")
- private int mStorageExternalJobCount = 4;
-
- @Option(name="run-media-server-test", description="Run the media server benchmark.")
- private Boolean mRunMediaServerTest = false;
-
- @Option(name="media-server-duration",
- description="The duration of the media server benchmark in secs.")
- private long mMediaServerDuration = 30;
-
- @Option(name="media-server-media-file-size",
- description="The media file size of the media server benchmark in MB.")
- private int mMediaServerMediaFileSize = 256;
-
- @Option(name="media-server-worker-file-size",
- description="The worker file size of the media server benchmark in MB.")
- private int mMediaServerWorkerFileSize = 256;
-
- @Option(name="media-server-worker-job-count",
- description="The number of worker jobs for the media server benchmark.")
- private int mMediaServerWorkerJobCount = 4;
-
- @Option(name="run-media-scanner-test", description="Run the media scanner benchmark.")
- private Boolean mRunMediaScannerTest = false;
-
- @Option(name="media-scanner-media-file-size",
- description="The media file size of the media scanner benchmark in kB.")
- private int mMediaScannerMediaFileSize = 8;
-
- @Option(name="media-scanner-media-file-count",
- description="The number of media files to scan.")
- private int mMediaScannerMediaFileCount = 256;
-
- @Option(name="media-scanner-worker-file-size",
- description="The worker file size of the media scanner benchmark in MB.")
- private int mMediaScannerWorkerFileSize = 256;
-
- @Option(name="media-scanner-worker-job-count",
- description="The number of worker jobs for the media server benchmark.")
- private int mMediaScannerWorkerJobCount = 4;
-
- @Option(name="key-suffix",
- description="The suffix to add to the reporting key in order to override the default")
- private String mKeySuffix = null;
-
- /**
- * Sets up all the benchmarks.
- */
- private void setupTests() {
- if (mTestCases != null) {
- // assume already set up
- return;
- }
-
- mTestCases = new LinkedList<>();
-
- if (mRunSimpleInternalTest) {
- addSimpleTest("read", "sync", true);
- addSimpleTest("write", "sync", true);
- addSimpleTest("randread", "sync", true);
- addSimpleTest("randwrite", "sync", true);
- addSimpleTest("randread", "mmap", true);
- addSimpleTest("randwrite", "mmap", true);
- }
-
- if (mRunSimpleExternalTest) {
- addSimpleTest("read", "sync", false);
- addSimpleTest("write", "sync", false);
- addSimpleTest("randread", "sync", false);
- addSimpleTest("randwrite", "sync", false);
- addSimpleTest("randread", "mmap", false);
- addSimpleTest("randwrite", "mmap", false);
- }
-
- if (mRunStorageInternalTest) {
- addStorageTest("read", "sync", true);
- addStorageTest("write", "sync", true);
- addStorageTest("randread", "sync", true);
- addStorageTest("randwrite", "sync", true);
- addStorageTest("randread", "mmap", true);
- addStorageTest("randwrite", "mmap", true);
- }
-
- if (mRunStorageExternalTest) {
- addStorageTest("read", "sync", false);
- addStorageTest("write", "sync", false);
- addStorageTest("randread", "sync", false);
- addStorageTest("randwrite", "sync", false);
- addStorageTest("randread", "mmap", false);
- addStorageTest("randwrite", "mmap", false);
- }
-
- if (mRunMediaServerTest) {
- addMediaServerTest("read");
- addMediaServerTest("write");
- }
-
- if (mRunMediaScannerTest) {
- addMediaScannerTest();
- }
- }
-
- /**
- * Sets up the simple FIO benchmark.
- * <p>
- * The test consists of a single process reading or writing to a file.
- * </p>
- *
- * @param rw the type of IO pattern. One of {@code read}, {@code write}, {@code randread}, or
- * {@code randwrite}.
- * @param ioengine defines how the job issues I/O. Such as {@code sync}, {@code vsync},
- * {@code mmap}, or {@code cpuio} and others.
- * @param internal whether the test should be run on the internal (/data) partition or the
- * external partition.
- */
- private void addSimpleTest(String rw, String ioengine, boolean internal) {
- String fileName = "testfile";
- String jobName = "job";
-
- String directory;
- int fileSize;
-
- TestInfo t = new TestInfo();
- if (internal) {
- t.mTestName = String.format("SimpleBenchmark-int-%s-%s", ioengine, rw);
- t.mKey = "fio_simple_int_benchmark";
- directory = mInternalTestDir;
- fileSize = mSimpleInternalFileSize;
- } else {
- t.mTestName = String.format("SimpleBenchmark-ext-%s-%s", ioengine, rw);
- t.mKey = "fio_simple_ext_benchmark";
- directory = mExternalTestDir;
- fileSize = mSimpleExternalFileSize;
- }
-
- TestFileInfo f = new TestFileInfo();
- f.mFileName = new File(directory, fileName).getAbsolutePath();
- f.mSize = fileSize * 1024; // fileSize is in MB but we want it in kB.
- t.mTestFiles.add(f);
-
- JobInfo j = new JobInfo();
- j.mJobName = jobName;
- j.mParameters.put("directory", directory);
- j.mParameters.put("filename", fileName);
- j.mParameters.put("fsync", "1024");
- j.mParameters.put("ioengine", ioengine);
- j.mParameters.put("rw", rw);
- j.mParameters.put("size", String.format("%dM",fileSize));
- t.mJobs.add(j);
-
- PerfMetricInfo m = new PerfMetricInfo();
- m.mJobName = jobName;
- if ("sync".equals(ioengine)) {
- m.mPostKey = String.format("%s_bandwidth", rw);
- } else {
- m.mPostKey = String.format("%s_%s_bandwidth", rw, ioengine);
- }
- m.mType = PerfMetricInfo.ResultType.FLOAT;
- if (rw.endsWith("read")) {
- m.mFieldName = "read-bandwidth-mean";
- } else if (rw.endsWith("write")) {
- m.mFieldName = "write-bandwidth-mean";
- }
- t.mPerfMetrics.add(m);
-
- mTestCases.add(t);
- }
-
- /**
- * Sets up the storage FIO benchmark.
- * <p>
- * The test consists of several processes reading or writing to a file.
- * </p>
- *
- * @param rw the type of IO pattern. One of {@code read}, {@code write}, {@code randread}, or
- * {@code randwrite}.
- * @param ioengine defines how the job issues I/O. Such as {@code sync}, {@code vsync},
- * {@code mmap}, or {@code cpuio} and others.
- * @param internal whether the test should be run on the internal (/data) partition or the
- * external partition.
- */
- private void addStorageTest(String rw, String ioengine, boolean internal) {
- String fileName = "testfile";
- String jobName = "workers";
-
- String directory;
- int fileSize;
- int jobCount;
-
- TestInfo t = new TestInfo();
- if (internal) {
- t.mTestName = String.format("StorageBenchmark-int-%s-%s", ioengine, rw);
- t.mKey = "fio_storage_int_benchmark";
- directory = mInternalTestDir;
- fileSize = mStorageInternalFileSize;
- jobCount = mStorageInternalJobCount;
- } else {
- t.mTestName = String.format("StorageBenchmark-ext-%s-%s", ioengine, rw);
- t.mKey = "fio_storage_ext_benchmark";
- directory = mExternalTestDir;
- fileSize = mStorageExternalFileSize;
- jobCount = mStorageExternalJobCount;
- }
-
- TestFileInfo f = new TestFileInfo();
- f.mFileName = new File(directory, fileName).getAbsolutePath();
- f.mSize = fileSize * 1024; // fileSize is in MB but we want it in kB.
- t.mTestFiles.add(f);
-
- JobInfo j = new JobInfo();
- j.mJobName = jobName;
- j.mParameters.put("directory", directory);
- j.mParameters.put("filename", fileName);
- j.mParameters.put("fsync", "1024");
- j.mParameters.put("group_reporting", null);
- j.mParameters.put("ioengine", ioengine);
- j.mParameters.put("new_group", null);
- j.mParameters.put("numjobs", String.format("%d", jobCount));
- j.mParameters.put("rw", rw);
- j.mParameters.put("size", String.format("%dM",fileSize));
- t.mJobs.add(j);
-
- PerfMetricInfo m = new PerfMetricInfo();
- m.mJobName = jobName;
- if ("sync".equals(ioengine)) {
- m.mPostKey = String.format("%s_bandwidth", rw);
- } else {
- m.mPostKey = String.format("%s_%s_bandwidth", rw, ioengine);
- }
- m.mType = PerfMetricInfo.ResultType.FLOAT;
- if (rw.endsWith("read")) {
- m.mFieldName = "read-bandwidth-mean";
- } else if (rw.endsWith("write")) {
- m.mFieldName = "write-bandwidth-mean";
- }
- t.mPerfMetrics.add(m);
-
- m = new PerfMetricInfo();
- m.mJobName = jobName;
- if ("sync".equals(ioengine)) {
- m.mPostKey = String.format("%s_latency", rw);
- } else {
- m.mPostKey = String.format("%s_%s_latency", rw, ioengine);
- }
- m.mType = PerfMetricInfo.ResultType.FLOAT;
- if (rw.endsWith("read")) {
- m.mFieldName = "read-clat-mean";
- } else if (rw.endsWith("write")) {
- m.mFieldName = "write-clat-mean";
- }
- t.mPerfMetrics.add(m);
-
- mTestCases.add(t);
- }
-
- /**
- * Sets up the media server benchmark.
- * <p>
- * The test consists of a single process at a higher priority reading or writing to a file
- * while several other worker processes read and write to a different file.
- * </p>
- *
- * @param rw the type of IO pattern. One of {@code read}, {@code write}
- */
- private void addMediaServerTest(String rw) {
- String mediaJob = "media-server";
- String mediaFile = "mediafile";
- String workerJob = "workers";
- String workerFile = "workerfile";
-
- TestInfo t = new TestInfo();
- t.mTestName = String.format("MediaServerBenchmark-%s", rw);
- t.mKey = "fio_media_server_benchmark";
-
- TestFileInfo f = new TestFileInfo();
- f.mFileName = new File(mMediaTestDir, mediaFile).getAbsolutePath();
- f.mSize = mMediaServerMediaFileSize * 1024; // File size is in MB but we want it in kB.
- t.mTestFiles.add(f);
-
- f = new TestFileInfo();
- f.mFileName = new File(mMediaTestDir, workerFile).getAbsolutePath();
- f.mSize = mMediaServerWorkerFileSize * 1024; // File size is in MB but we want it in kB.
- t.mTestFiles.add(f);
-
- JobInfo j = new JobInfo();
- j.mJobName = "global";
- j.mParameters.put("directory", mMediaTestDir);
- j.mParameters.put("fsync", "1024");
- j.mParameters.put("ioengine", "sync");
- j.mParameters.put("runtime", String.format("%d", mMediaServerDuration));
- j.mParameters.put("time_based", null);
- t.mJobs.add(j);
-
- j = new JobInfo();
- j.mJobName = mediaJob;
- j.mParameters.put("filename", mediaFile);
- j.mParameters.put("iodepth", "32");
- j.mParameters.put("nice", "-16");
- j.mParameters.put("rate", "6m");
- j.mParameters.put("rw", rw);
- j.mParameters.put("size", String.format("%dM", mMediaServerMediaFileSize));
- t.mJobs.add(j);
-
- j = new JobInfo();
- j.mJobName = workerJob;
- j.mParameters.put("filename", workerFile);
- j.mParameters.put("group_reporting", null);
- j.mParameters.put("new_group", null);
- j.mParameters.put("nice", "0");
- j.mParameters.put("numjobs", String.format("%d", mMediaServerWorkerJobCount));
- j.mParameters.put("rw", "randrw");
- j.mParameters.put("size", String.format("%dM", mMediaServerWorkerFileSize));
- t.mJobs.add(j);
-
- PerfMetricInfo m = new PerfMetricInfo();
- m.mJobName = mediaJob;
- m.mPostKey = String.format("%s_media_bandwidth", rw);
- m.mType = PerfMetricInfo.ResultType.FLOAT;
- if (rw.endsWith("read")) {
- m.mFieldName = "read-bandwidth-mean";
- } else if (rw.endsWith("write")) {
- m.mFieldName = "write-bandwidth-mean";
- }
- t.mPerfMetrics.add(m);
-
- m = new PerfMetricInfo();
- m.mJobName = mediaJob;
- m.mPostKey = String.format("%s_media_latency", rw);
- m.mType = PerfMetricInfo.ResultType.FLOAT;
- if (rw.endsWith("read")) {
- m.mFieldName = "read-clat-mean";
- } else if (rw.endsWith("write")) {
- m.mFieldName = "write-clat-mean";
- }
- t.mPerfMetrics.add(m);
-
- m = new PerfMetricInfo();
- m.mJobName = workerJob;
- m.mPostKey = String.format("%s_workers_read_bandwidth", rw);
- m.mFieldName = "read-bandwidth-mean";
- m.mType = PerfMetricInfo.ResultType.FLOAT;
- t.mPerfMetrics.add(m);
-
- m = new PerfMetricInfo();
- m.mJobName = workerJob;
- m.mPostKey = String.format("%s_workers_write_bandwidth", rw);
- m.mFieldName = "write-bandwidth-mean";
- m.mType = PerfMetricInfo.ResultType.FLOAT;
- t.mPerfMetrics.add(m);
-
- mTestCases.add(t);
- }
-
- /**
- * Sets up the media scanner benchmark.
- * <p>
- * The test consists of a single process reading several small files while several other worker
- * processes read and write to a different file.
- * </p>
- */
- private void addMediaScannerTest() {
- String mediaJob = "media-server";
- String mediaFile = "mediafile.%d";
- String workerJob = "workers";
- String workerFile = "workerfile";
-
- TestInfo t = new TestInfo();
- t.mTestName = "MediaScannerBenchmark";
- t.mKey = "fio_media_scanner_benchmark";
-
- TestFileInfo f;
- for (int i = 0; i < mMediaScannerMediaFileCount; i++) {
- f = new TestFileInfo();
- f.mFileName = new File(mMediaTestDir, String.format(mediaFile, i)).getAbsolutePath();
- f.mSize = mMediaScannerMediaFileSize; // File size is already in kB so do nothing.
- t.mTestFiles.add(f);
- }
-
- f = new TestFileInfo();
- f.mFileName = new File(mMediaTestDir, workerFile).getAbsolutePath();
- f.mSize = mMediaScannerWorkerFileSize * 1024; // File size is in MB but we want it in kB.
- t.mTestFiles.add(f);
-
- JobInfo j = new JobInfo();
- j.mJobName = "global";
- j.mParameters.put("directory", mMediaTestDir);
- j.mParameters.put("fsync", "1024");
- j.mParameters.put("ioengine", "sync");
- t.mJobs.add(j);
-
- j = new JobInfo();
- j.mJobName = mediaJob;
- StringBuilder fileNames = new StringBuilder();
- fileNames.append(String.format(mediaFile, 0));
- for (int i = 1; i < mMediaScannerMediaFileCount; i++) {
- fileNames.append(String.format(":%s", String.format(mediaFile, i)));
- }
- j.mParameters.put("filename", fileNames.toString());
- j.mParameters.put("exitall", null);
- j.mParameters.put("openfiles", "4");
- j.mParameters.put("rw", "read");
- t.mJobs.add(j);
-
- j = new JobInfo();
- j.mJobName = workerJob;
- j.mParameters.put("filename", workerFile);
- j.mParameters.put("group_reporting", null);
- j.mParameters.put("new_group", null);
- j.mParameters.put("numjobs", String.format("%d", mMediaScannerWorkerJobCount));
- j.mParameters.put("rw", "randrw");
- j.mParameters.put("size", String.format("%dM", mMediaScannerWorkerFileSize));
- t.mJobs.add(j);
-
- PerfMetricInfo m = new PerfMetricInfo();
- m.mJobName = mediaJob;
- m.mPostKey = "media_bandwidth";
- m.mFieldName = "read-bandwidth-mean";
- m.mType = PerfMetricInfo.ResultType.FLOAT;
- t.mPerfMetrics.add(m);
-
- m = new PerfMetricInfo();
- m.mJobName = mediaJob;
- m.mPostKey = "media_latency";
- m.mFieldName = "read-clat-mean";
- m.mType = PerfMetricInfo.ResultType.FLOAT;
- t.mPerfMetrics.add(m);
-
- m = new PerfMetricInfo();
- m.mJobName = workerJob;
- m.mPostKey = "workers_read_bandwidth";
- m.mFieldName = "read-bandwidth-mean";
- m.mType = PerfMetricInfo.ResultType.FLOAT;
- t.mPerfMetrics.add(m);
-
- m = new PerfMetricInfo();
- m.mJobName = workerJob;
- m.mPostKey = "workers_write_bandwidth";
- m.mFieldName = "write-bandwidth-mean";
- m.mType = PerfMetricInfo.ResultType.FLOAT;
- t.mPerfMetrics.add(m);
-
- mTestCases.add(t);
- }
-
- /**
- * Creates the directories needed to run FIO, pushes the FIO executable to the device, and
- * stops the runtime.
- *
- * @throws DeviceNotAvailableException if the device is not available.
- */
- private void setupDevice() throws DeviceNotAvailableException {
- mTestDevice.executeShellCommand("stop");
- mTestDevice.executeShellCommand(String.format("mkdir -p %s", mFioDir));
- mTestDevice.executeShellCommand(String.format("mkdir -p %s", mTmpDir));
- mTestDevice.executeShellCommand(String.format("mkdir -p %s", mInternalTestDir));
- mTestDevice.executeShellCommand(String.format("mkdir -p %s", mMediaTestDir));
- if (mExternalTestDir != null) {
- mTestDevice.executeShellCommand(String.format("mkdir -p %s", mExternalTestDir));
- }
- if (mFioLocation != null) {
- mTestDevice.pushFile(new File(mFioLocation), mFioBin);
- mTestDevice.executeShellCommand(String.format("chmod 755 %s", mFioBin));
- }
- }
-
- /**
- * Reverses the actions of {@link #setDevice(ITestDevice)}.
- *
- * @throws DeviceNotAvailableException If the device is not available.
- */
- private void cleanupDevice() throws DeviceNotAvailableException {
- if (mExternalTestDir != null) {
- mTestDevice.executeShellCommand(String.format("rm -r %s", mExternalTestDir));
- }
- mTestDevice.executeShellCommand(String.format("rm -r %s", mMediaTestDir));
- mTestDevice.executeShellCommand(String.format("rm -r %s", mInternalTestDir));
- mTestDevice.executeShellCommand(String.format("rm -r %s", mTmpDir));
- mTestDevice.executeShellCommand(String.format("rm -r %s", mFioDir));
- mTestDevice.executeShellCommand("start");
- mTestDevice.waitForDeviceAvailable();
- }
-
- /**
- * Runs a single test, including creating the test files, clearing the cache, collecting before
- * and after files, running the benchmark, and reporting the results.
- *
- * @param test the benchmark.
- * @param listener the ITestInvocationListener
- * @throws DeviceNotAvailableException if the device is not available.
- */
- private void runTest(TestInfo test, ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- CLog.i("Running %s benchmark", test.mTestName);
- mTestDevice.executeShellCommand(String.format("rm -r %s/*", mTmpDir));
- mTestDevice.executeShellCommand(String.format("rm -r %s/*", mInternalTestDir));
- mTestDevice.executeShellCommand(String.format("rm -r %s/*", mMediaTestDir));
- if (mExternalTestDir != null) {
- mTestDevice.executeShellCommand(String.format("rm -r %s/*", mExternalTestDir));
- }
-
- for (TestFileInfo file : test.mTestFiles) {
- CLog.v("Creating file: %s, size: %dkB", file.mFileName, file.mSize);
- String cmd = String.format("dd if=/dev/urandom of=%s bs=1024 count=%d", file.mFileName,
- file.mSize);
- int timeout = file.mSize * 2 * 1000; // Timeout is 2 seconds per kB.
- mTestDevice.executeShellCommand(cmd, new NullOutputReceiver(),
- timeout, TimeUnit.MILLISECONDS, 2);
- }
-
- CLog.i("Creating config");
- CLog.d("Config file:\n%s", test.createConfig());
- mTestDevice.pushString(test.createConfig(), mFioConfig);
-
- CLog.i("Dropping cache");
- mTestDevice.executeShellCommand("echo 3 > /proc/sys/vm/drop_caches");
-
- collectLogs(test, listener, "before");
-
- CLog.i("Running test");
- FioParser output = new FioParser();
- // Run FIO with a timeout of 1 hour.
- mTestDevice.executeShellCommand(String.format("%s --minimal %s", mFioBin, mFioConfig),
- output, 60 * 60 * 1000, TimeUnit.MILLISECONDS, 2);
-
- collectLogs(test, listener, "after");
-
- // Report metrics
- Map<String, String> metrics = new HashMap<>();
- String key = mKeySuffix == null ? test.mKey : test.mKey + mKeySuffix;
-
- listener.testRunStarted(key, 0);
- for (PerfMetricInfo m : test.mPerfMetrics) {
- if (!output.mResults.containsKey(m.mJobName)) {
- CLog.w("Job name %s was not found in the results", m.mJobName);
- continue;
- }
-
- String value = output.getResult(m.mJobName, m.mFieldName);
- if (value != null) {
- metrics.put(m.mPostKey, m.mType.value(value));
- } else {
- CLog.w("%s was not in results for the job %s", m.mFieldName, m.mJobName);
- }
- }
-
- CLog.d("About to report metrics to %s: %s", key, metrics);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-
- private void collectLogs(TestInfo testInfo, ITestInvocationListener listener,
- String descriptor) throws DeviceNotAvailableException {
- if (mCollectYaffsLogs && mTestDevice.doesFileExist("/proc/yaffs")) {
- logFile("/proc/yaffs", String.format("%s-yaffs-%s", testInfo.mTestName, descriptor),
- mTestDevice, listener);
- }
- }
-
- private void logFile(String remoteFileName, String localFileName, ITestDevice testDevice,
- ITestInvocationListener listener) throws DeviceNotAvailableException {
- File outputFile = null;
- InputStreamSource outputSource = null;
- try {
- outputFile = testDevice.pullFile(remoteFileName);
- if (outputFile != null) {
- CLog.d("Sending %d byte file %s to logosphere!", outputFile.length(), outputFile);
- outputSource = new FileInputStreamSource(outputFile);
- listener.testLog(localFileName, LogDataType.TEXT, outputSource);
- }
- } finally {
- FileUtil.deleteFile(outputFile);
- StreamUtil.cancel(outputSource);
- }
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- Assert.assertNotNull(mTestDevice);
-
- mFioDir = new File(mTestDevice.getMountPoint(IDevice.MNT_DATA), "fio").getAbsolutePath();
- if (mFioLocation != null) {
- mFioBin = new File(mFioDir, "fio").getAbsolutePath();
- } else {
- mFioBin = "fio";
- }
- mFioConfig = new File(mFioDir, "config.fio").getAbsolutePath();
-
- setupTests();
- setupDevice();
-
- for (TestInfo test : mTestCases) {
- runTest(test, listener);
- }
-
- cleanupDevice();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mTestDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-
- /**
- * A meta-test to ensure that the bits of FioBenchmarkTest are working properly.
- */
- public static class MetaTest extends TestCase {
-
- /**
- * Test that {@link JobInfo#createJob()} properly formats a job.
- */
- public void testCreateJob() {
- JobInfo j = new JobInfo();
- assertEquals("", j.createJob());
- j.mJobName = "job";
- assertEquals("[job]\n", j.createJob());
- j.mParameters.put("param1", null);
- j.mParameters.put("param2", "value");
- String[] lines = j.createJob().split("\n");
- assertEquals(3, lines.length);
- assertEquals("[job]", lines[0]);
- Set<String> params = new HashSet<>(2);
- params.add(lines[1]);
- params.add(lines[2]);
- assertTrue(params.contains("param1"));
- assertTrue(params.contains("param2=value"));
- }
-
- /**
- * Test that {@link TestInfo#createConfig()} properly formats a config.
- */
- public void testCreateConfig() {
- TestInfo t = new TestInfo();
- JobInfo j = new JobInfo();
- j.mJobName = "job1";
- j.mParameters.put("param1", "value1");
- t.mJobs.add(j);
-
- j = new JobInfo();
- j.mJobName = "job2";
- j.mParameters.put("param2", "value2");
- t.mJobs.add(j);
-
- j = new JobInfo();
- j.mJobName = "job3";
- j.mParameters.put("param3", "value3");
- t.mJobs.add(j);
-
- assertEquals("[job1]\nparam1=value1\n\n" +
- "[job2]\nparam2=value2\n\n" +
- "[job3]\nparam3=value3\n\n", t.createConfig());
- }
-
- /**
- * Test that output lines are parsed correctly by the FioParser, invalid lines are ignored,
- * and that the various fields are accessible with
- * {@link FioParser#getResult(String, String)}.
- */
- public void testFioParser() {
- String[] lines = new String[4];
- // We build the lines up as follows (assuming FIO_RESULTS_FIELDS.length == 58):
- // 0;3;6;...;171
- // 1;4;7;...;172
- // 2;5;8;...;173
- for (int i = 0; i < 3; i++) {
- StringBuilder sb = new StringBuilder();
- sb.append(i);
- for (int j = 1; j < FIO_V0_RESULT_FIELDS.length; j++) {
- sb.append(";");
- sb.append(j * 3 + i);
- }
- lines[i] = sb.toString();
- }
- // A line may have an optional description on the end which we don't care about, make
- // sure it still parses.
- lines[2] = lines[2] += ";description";
- // Make sure an invalid output line does not parse.
- lines[3] = "invalid";
-
- FioParser p = new FioParser();
- p.processNewLines(lines);
-
-
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < FIO_V0_RESULT_FIELDS.length; j++) {
- assertEquals(String.format("job=%d, field=%s", i, FIO_V0_RESULT_FIELDS[j]),
- String.format("%d", j * 3 + i),
- p.getResult(String.format("%d", i), FIO_V0_RESULT_FIELDS[j]));
- }
- }
- assertNull(p.getResult("missing", "jobname"));
- assertNull(p.getResult("invalid", "jobname"));
- assertNull(p.getResult("0", "missing"));
- }
-
- /**
- * Test that {@link PerfMetricInfo.ResultType#value(String)} correctly transforms strings
- * based on the result type.
- */
- public void testResultTypeValue() {
- assertEquals("test", PerfMetricInfo.ResultType.STRING.value("test"));
- assertEquals("1", PerfMetricInfo.ResultType.INT.value("1"));
- assertEquals("3.14159", PerfMetricInfo.ResultType.FLOAT.value("3.14159"));
- assertEquals(String.format("%f", 0.34567),
- PerfMetricInfo.ResultType.PERCENT.value("34.567%"));
- assertNull(PerfMetricInfo.ResultType.PERCENT.value(""));
- assertNull(PerfMetricInfo.ResultType.PERCENT.value("34.567"));
- assertNull(PerfMetricInfo.ResultType.PERCENT.value("test%"));
- }
- }
-}
diff --git a/prod-tests/src/com/android/performance/tests/GLBenchmarkTest.java b/prod-tests/src/com/android/performance/tests/GLBenchmarkTest.java
deleted file mode 100644
index 4a8fd29..0000000
--- a/prod-tests/src/com/android/performance/tests/GLBenchmarkTest.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2013 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.performance.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-/**
- * A harness that launches GLBenchmark and reports result. Requires GLBenchmark
- * custom XML. Assumes GLBenchmark app is already installed on device.
- */
-public class GLBenchmarkTest implements IDeviceTest, IRemoteTest {
-
- private static final String RUN_KEY = "glbenchmark";
- private static final long TIMEOUT_MS = 30 * 60 * 1000;
- private static final long POLLING_INTERVAL_MS = 5 * 1000;
- private static final Map<String, String> METRICS_KEY_MAP = createMetricsKeyMap();
-
- private ITestDevice mDevice;
-
- @Option(name = "custom-xml-path", description = "local path for GLBenchmark custom.xml",
- importance = Importance.ALWAYS)
- private File mGlbenchmarkCustomXmlLocal = new File("/tmp/glbenchmark_custom.xml");
-
- @Option(name = "gl-package-name", description = "GLBenchmark package name")
- private String mGlbenchmarkPackageName = "com.glbenchmark.glbenchmark25";
-
- @Option(name = "gl-version", description = "GLBenchmark version (e.g. 2.5.1_b306a5)")
- private String mGlbenchmarkVersion = "2.5.1_b306a5";
-
- private String mGlbenchmarkCacheDir =
- "${EXTERNAL_STORAGE}/Android/data/" + mGlbenchmarkPackageName + "/cache/";
- private String mGlbenchmarkCustomXmlPath =
- mGlbenchmarkCacheDir + "custom.xml";
- private String mGlbenchmarkResultXmlPath =
- mGlbenchmarkCacheDir + "last_results_" + mGlbenchmarkVersion + ".xml";
- private String mGlbenchmarkExcelResultXmlPath =
- mGlbenchmarkCacheDir + "results_%s_0.xml";
- private String mGlbenchmarkAllResultXmlPath =
- mGlbenchmarkCacheDir + "results*.xml";
-
- private static Map<String, String> createMetricsKeyMap() {
- Map<String, String> result = new HashMap<String, String>();
- result.put("Fill rate - C24Z16", "fill-rate");
- result.put("Fill rate - C24Z16 Offscreen", "fill-rate-offscreen");
- result.put("Triangle throughput: Textured - C24Z16", "triangle-c24z16");
- result.put("Triangle throughput: Textured - C24Z16 Offscreen",
- "triangle-c24z16-offscreen");
- result.put("Triangle throughput: Textured - C24Z16 Vertex lit",
- "triangle-c24z16-vertex-lit");
- result.put("Triangle throughput: Textured - C24Z16 Offscreen Vertex lit",
- "triangle-c24z16-offscreen-vertex-lit");
- result.put("Triangle throughput: Textured - C24Z16 Fragment lit",
- "triangle-c24z16-fragment-lit");
- result.put("Triangle throughput: Textured - C24Z16 Offscreen Fragment lit",
- "triangle-c24z16-offscreen-fragment-lit");
- result.put("GLBenchmark 2.5 Egypt HD - C24Z16", "egypt-hd-c24z16");
- result.put("GLBenchmark 2.5 Egypt HD - C24Z16 Offscreen", "egypt-hd-c24z16-offscreen");
- result.put("GLBenchmark 2.5 Egypt HD PVRTC4 - C24Z16", "egypt-hd-pvrtc4-c24z16");
- result.put("GLBenchmark 2.5 Egypt HD PVRTC4 - C24Z16 Offscreen",
- "egypt-hd-pvrtc4-c24z16-offscreen");
- result.put("GLBenchmark 2.5 Egypt HD - C24Z24MS4", "egypt-hd-c24z24ms4");
- result.put("GLBenchmark 2.5 Egypt HD - C24Z16 Fixed timestep",
- "egypt-hd-c24z16-fixed-timestep");
- result.put("GLBenchmark 2.5 Egypt HD - C24Z16 Fixed timestep Offscreen",
- "egypt-hd-c24z16-fixed-timestep-offscreen");
- result.put("GLBenchmark 2.1 Egypt Classic - C16Z16", "egypt-classic-c16z16");
- result.put("GLBenchmark 2.1 Egypt Classic - C16Z16 Offscreen",
- "egypt-classic-c16z16-offscreen");
- return Collections.unmodifiableMap(result);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- TestDescription testId = new TestDescription(getClass().getCanonicalName(), RUN_KEY);
- ITestDevice device = getDevice();
-
- // delete old result
- device.executeShellCommand(String.format("rm %s", mGlbenchmarkResultXmlPath));
- device.executeShellCommand(String.format("rm %s", mGlbenchmarkAllResultXmlPath));
-
- // push glbenchmark custom xml to device
- device.pushFile(mGlbenchmarkCustomXmlLocal, mGlbenchmarkCustomXmlPath);
-
- listener.testRunStarted(RUN_KEY, 0);
- listener.testStarted(testId);
-
- long testStartTime = System.currentTimeMillis();
- boolean isRunningBenchmark;
-
- boolean isTimedOut = false;
- boolean isResultGenerated = false;
- Map<String, String> metrics = new HashMap<String, String>();
- String errMsg = null;
-
- String deviceModel = device.executeShellCommand("getprop ro.product.model");
- String resultExcelXmlPath = String.format(mGlbenchmarkExcelResultXmlPath,
- deviceModel.trim().replaceAll("[ -]", "_").toLowerCase());
- CLog.i("Result excel xml path:" + resultExcelXmlPath);
-
- // start glbenchmark and wait for test to complete
- isTimedOut = false;
- long benchmarkStartTime = System.currentTimeMillis();
-
- device.executeShellCommand("am start -a android.intent.action.MAIN "
- + "-n com.glbenchmark.glbenchmark25/com.glbenchmark.activities.MainActivity "
- + "--ez custom true");
- isRunningBenchmark = true;
- while (isRunningBenchmark && !isResultGenerated && !isTimedOut) {
- RunUtil.getDefault().sleep(POLLING_INTERVAL_MS);
- isTimedOut = (System.currentTimeMillis() - benchmarkStartTime >= TIMEOUT_MS);
- isResultGenerated = device.doesFileExist(resultExcelXmlPath);
- isRunningBenchmark = device.executeShellCommand("ps").contains("glbenchmark");
- }
-
- if (isTimedOut) {
- errMsg = "GLBenchmark timed out.";
- } else {
- // pull result from device
- File benchmarkReport = device.pullFile(mGlbenchmarkResultXmlPath);
- if (benchmarkReport != null) {
- // parse result
- CLog.i("== GLBenchmark result ==");
- Map<String, String> benchmarkResult = parseResultXml(benchmarkReport);
- if (benchmarkResult == null) {
- errMsg = "Failed to parse GLBenchmark result XML.";
- } else {
- metrics = benchmarkResult;
- }
- // delete results from device and host
- device.executeShellCommand(String.format("rm %s", mGlbenchmarkResultXmlPath));
- device.executeShellCommand(String.format("rm %s", resultExcelXmlPath));
- benchmarkReport.delete();
- } else {
- errMsg = "GLBenchmark report not found.";
- }
- }
- if (errMsg != null) {
- CLog.e(errMsg);
- listener.testFailed(testId, errMsg);
- listener.testEnded(testId, TfMetricProtoUtil.upgradeConvert(metrics));
- listener.testRunFailed(errMsg);
- } else {
- long durationMs = System.currentTimeMillis() - testStartTime;
- listener.testEnded(testId, TfMetricProtoUtil.upgradeConvert(metrics));
- listener.testRunEnded(durationMs, TfMetricProtoUtil.upgradeConvert(metrics));
- }
- }
-
- /**
- * Parse GLBenchmark result XML.
- *
- * @param resultXml GLBenchmark result XML {@link File}
- * @return a {@link HashMap} that contains metrics key and result
- */
- private Map<String, String> parseResultXml(File resultXml) {
- Map<String, String> benchmarkResult = new HashMap<String, String>();
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- Document doc = null;
- try {
- DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
- doc = dBuilder.parse(resultXml);
- } catch (ParserConfigurationException e) {
- return null;
- } catch (IOException e) {
- return null;
- } catch (SAXException e) {
- return null;
- } catch (IllegalArgumentException e) {
- return null;
- }
- doc.getDocumentElement().normalize();
-
- NodeList nodes = doc.getElementsByTagName("test_result");
- for (int i = 0; i < nodes.getLength(); i++) {
- Node node = nodes.item(i);
- if (node.getNodeType() == Node.ELEMENT_NODE) {
- Element testResult = (Element) node;
- String testTitle = getData(testResult, "title");
- String testType = getData(testResult, "type");
- String fps = getData(testResult, "fps");
- String score = getData(testResult, "score");
- String testName = String.format("%s - %s", testTitle, testType);
- if (METRICS_KEY_MAP.containsKey(testName)) {
- if (testName.contains("Fill") || testName.contains("Triangle")) {
- // Use Mtexels/sec or MTriangles/sec as unit
- score = String.valueOf((long)(Double.parseDouble(score) / 1.0E6));
- }
- CLog.i(String.format("%s: %s (fps=%s)", testName, score, fps));
- String testKey = METRICS_KEY_MAP.get(testName);
- if (score != null && !score.trim().equals("0")) {
- benchmarkResult.put(testKey, score);
- if (fps != null && !fps.trim().equals("0.0")) {
- try {
- float fpsValue = Float.parseFloat(fps.replace("fps", ""));
- benchmarkResult.put(testKey + "-fps", String.valueOf(fpsValue));
- } catch (NumberFormatException e) {
- CLog.i(String.format("Got %s for fps value. Ignored.", fps));
- }
- }
- }
- }
- }
- }
- return benchmarkResult;
- }
-
- /**
- * Get value in the first matching tag under the element
- *
- * @param element the parent {@link Element} of the tag
- * @param tag {@link String} of the tag name
- * @return a {@link String} that contains the value in the tag; returns null if not found.
- */
- private String getData(Element element, String tag) {
- NodeList tagNodes = element.getElementsByTagName(tag);
- if (tagNodes.getLength() > 0) {
- Node tagNode = tagNodes.item(0);
- if (tagNode.getNodeType() == Node.ELEMENT_NODE) {
- Node node = tagNode.getChildNodes().item(0);
- if (node != null) {
- return node.getNodeValue();
- } else {
- return null;
- }
- }
- }
- return null;
- }
-}
diff --git a/prod-tests/src/com/android/performance/tests/GeekbenchTest.java b/prod-tests/src/com/android/performance/tests/GeekbenchTest.java
deleted file mode 100644
index 38263ea..0000000
--- a/prod-tests/src/com/android/performance/tests/GeekbenchTest.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright (C) 2013 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.performance.tests;
-
-import com.android.ddmlib.CollectingOutputReceiver;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONTokener;
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * A harness that launches Geekbench and reports result.
- * Requires Geekbench binary and plar file in device temporary directory.
- */
-public class GeekbenchTest implements IDeviceTest, IRemoteTest {
-
- private static final String RUN_KEY = "geekbench3";
- private static final int MAX_ATTEMPTS = 3;
- private static final int TIMEOUT_MS = 10 * 60 * 1000;
-
- private static final String DEVICE_TEMPORARY_DIR_PATH = "/data/local/tmp/";
- private static final String GEEKBENCH_BINARY_FILENAME = "geekbench_armeabi-v7a_32";
- private static final String GEEKBENCH_BINARY_DEVICE_PATH =
- DEVICE_TEMPORARY_DIR_PATH + GEEKBENCH_BINARY_FILENAME;
- private static final String GEEKBENCH_PLAR_DEVICE_PATH =
- DEVICE_TEMPORARY_DIR_PATH + "geekbench.plar";
- private static final String GEEKBENCH_RESULT_DEVICE_PATH =
- DEVICE_TEMPORARY_DIR_PATH + "result.txt";
-
- private static final String OVERALL_SCORE_NAME = "Overall Score";
- private static final Map<String, String> METRICS_KEY_MAP = createMetricsKeyMap();
-
- private ITestDevice mDevice;
-
- private static Map<String, String> createMetricsKeyMap() {
- Map<String, String> result = new HashMap<String, String>();
- result.put(OVERALL_SCORE_NAME, "overall");
- result.put("Integer", "integer");
- result.put("Floating Point", "floating-point");
- result.put("Memory", "memory");
- return Collections.unmodifiableMap(result);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- TestDescription testId = new TestDescription(getClass().getCanonicalName(), RUN_KEY);
- ITestDevice device = getDevice();
-
- // delete old results
- device.executeShellCommand(String.format("rm %s", GEEKBENCH_RESULT_DEVICE_PATH));
-
- Assert.assertTrue(String.format("Geekbench binary not found on device: %s",
- GEEKBENCH_BINARY_DEVICE_PATH), device.doesFileExist(GEEKBENCH_BINARY_DEVICE_PATH));
- Assert.assertTrue(String.format("Geekbench binary not found on device: %s",
- GEEKBENCH_PLAR_DEVICE_PATH), device.doesFileExist(GEEKBENCH_PLAR_DEVICE_PATH));
-
- listener.testRunStarted(RUN_KEY, 0);
- listener.testStarted(testId);
-
- long testStartTime = System.currentTimeMillis();
- Map<String, String> metrics = new HashMap<String, String>();
- String errMsg = null;
-
- // start geekbench and wait for test to complete
- CollectingOutputReceiver receiver = new CollectingOutputReceiver();
- device.executeShellCommand(String.format("%s --no-upload --export-json %s",
- GEEKBENCH_BINARY_DEVICE_PATH, GEEKBENCH_RESULT_DEVICE_PATH), receiver,
- TIMEOUT_MS, TimeUnit.MILLISECONDS, MAX_ATTEMPTS);
- CLog.v(receiver.getOutput());
-
- // pull result from device
- File benchmarkReport = device.pullFile(GEEKBENCH_RESULT_DEVICE_PATH);
- if (benchmarkReport != null) {
- // parse result
- CLog.i("== Geekbench 3 result ==");
- Map<String, String> benchmarkResult = parseResultJSON(benchmarkReport);
- if (benchmarkResult == null) {
- errMsg = "Failed to parse Geekbench result JSON.";
- } else {
- metrics = benchmarkResult;
- }
-
- // delete results from device and host
- benchmarkReport.delete();
- device.executeShellCommand("rm " + GEEKBENCH_RESULT_DEVICE_PATH);
- } else {
- errMsg = "Geekbench report not found.";
- }
-
- if (errMsg != null) {
- CLog.e(errMsg);
- listener.testFailed(testId, errMsg);
- listener.testEnded(testId, TfMetricProtoUtil.upgradeConvert(metrics));
- listener.testRunFailed(errMsg);
- } else {
- long durationMs = System.currentTimeMillis() - testStartTime;
- listener.testEnded(testId, TfMetricProtoUtil.upgradeConvert(metrics));
- listener.testRunEnded(durationMs, TfMetricProtoUtil.upgradeConvert(metrics));
- }
- }
-
- private Map<String, String> parseResultJSON(File resultJson) {
- Map<String, String> benchmarkResult = new HashMap<String, String>();
- try {
- BufferedReader bufferedReader = new BufferedReader(new FileReader(resultJson));
- String line = bufferedReader.readLine();
- bufferedReader.close();
- if (line != null) {
- JSONTokener tokener = new JSONTokener(line);
- JSONObject root = new JSONObject(tokener);
- String overallScore = root.getString("score");
- benchmarkResult.put(METRICS_KEY_MAP.get(OVERALL_SCORE_NAME), overallScore);
- CLog.i(String.format("Overall: %s", overallScore));
- String overallScoreMulticore = root.getString("multicore_score");
- benchmarkResult.put(METRICS_KEY_MAP.get(OVERALL_SCORE_NAME) + "-multi",
- overallScoreMulticore);
- CLog.i(String.format("Overall-multicore: %s", overallScore));
- JSONArray arr = root.getJSONArray("sections");
- for (int i = 0; i < arr.length(); i++) {
- JSONObject section = arr.getJSONObject(i);
- String sectionName = section.getString("name");
- String sectionScore = section.getString("score");
- String sectionScoreMulticore = section.getString("multicore_score");
- if (METRICS_KEY_MAP.containsKey(sectionName)) {
- CLog.i(String.format("%s: %s", sectionName, sectionScore));
- CLog.i(String.format("%s-multicore: %s", sectionName,
- sectionScoreMulticore));
- benchmarkResult.put(METRICS_KEY_MAP.get(sectionName), sectionScore);
- CLog.i(String.format("%s-multicore: %s", sectionName,
- sectionScoreMulticore));
- benchmarkResult.put(METRICS_KEY_MAP.get(sectionName) + "-multi",
- sectionScoreMulticore);
- }
- }
- }
- } catch (IOException e) {
- CLog.e("Geekbench3 result file not found.");
- return null;
- } catch (JSONException e) {
- CLog.e("Error parsing Geekbench3 JSON result.");
- return null;
- }
- return benchmarkResult;
- }
-}
diff --git a/prod-tests/src/com/android/performance/tests/HermeticLaunchTest.java b/prod-tests/src/com/android/performance/tests/HermeticLaunchTest.java
deleted file mode 100644
index bba0dc3..0000000
--- a/prod-tests/src/com/android/performance/tests/HermeticLaunchTest.java
+++ /dev/null
@@ -1,708 +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.performance.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.LogcatReceiver;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.CollectingTestListener;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestResult;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * To test the app launch performance for the list of activities present in the given target package
- * or the custom list of activities present in the target package.Activities are launched number of
- * times present in the launch count. Launch time is analyzed from the logcat data and more detailed
- * timing(section names) is analyzed from the atrace files captured when launching each activity.
- */
-public class HermeticLaunchTest implements IRemoteTest, IDeviceTest {
-
- private static enum AtraceSectionOptions {
- LAYOUT("layout"),
- DRAW("draw"),
- BINDAPPLICATION("bindApplication"),
- ACTIVITYSTART("activityStart"),
- ONCREATE("onCreate"),
- INFLATE("inflate");
-
- private final String name;
-
- private AtraceSectionOptions(String s) {
- this.name = s;
- }
-
- @Override
- public String toString() {
- return name;
- }
- }
-
- private static final String TOTALLAUNCHTIME = "totalLaunchTime";
- private static final String LOGCAT_CMD = "logcat -v threadtime ActivityManager:* *:s";
- private static final String LAUNCH_PREFIX="^\\d*-\\d*\\s*\\d*:\\d*:\\d*.\\d*\\s*\\d*\\s*"
- + "\\d*\\s*I ActivityManager: Displayed\\s*";
- private static final String LAUNCH_SUFFIX=":\\s*\\+(?<launchtime>.[a-zA-Z\\d]*)\\s*"
- + "(?<totallaunch>.*)\\s*$";
- private static final Pattern LAUNCH_ENTRY=Pattern.compile("^\\d*-\\d*\\s*\\d*:\\d*:\\d*."
- + "\\d*\\s*\\d*\\s*\\d*\\s*I ActivityManager: Displayed\\s*(?<launchinfo>.*)\\s*$");
- private static final Pattern TRACE_ENTRY1 = Pattern.compile(
- "^[^-]*-(?<tid>\\d+)\\s+\\[\\d+\\]\\s+\\S{4}\\s+" +
- "(?<secs>\\d+)\\.(?<usecs>\\d+):\\s+(?<function>.*)\\s*$");
- private static final Pattern TRACE_ENTRY2 = Pattern.compile(
- "^[^-]*-(?<tid>\\d+)\\s*\\(\\s*\\d*-*\\)\\s*\\[\\d+\\]\\s+\\S{4}\\s+" +
- "(?<secs>\\d+)\\.(?<usecs>\\d+):\\s+(?<function>.*)\\s*$");
- private static final Pattern ATRACE_BEGIN = Pattern
- .compile("tracing_mark_write: B\\|(?<pid>\\d+)\\|(?<name>.+)");
- // Matches new and old format of END time stamp.
- // rformanceLaunc-6315 ( 6315) [007] ...1 182.622217: tracing_mark_write: E|6315
- // rformanceLaunc-6315 ( 6315) [007] ...1 182.622217: tracing_mark_write: E
- private static final Pattern ATRACE_END = Pattern.compile(
- "tracing_mark_write: E\\|*(?<procid>\\d*)");
- private static final Pattern ATRACE_COUNTER = Pattern
- .compile("tracing_mark_write: C\\|(?<pid>\\d+)\\|(?<name>[^|]+)\\|(?<value>\\d+)");
- private static final Pattern ATRACE_HEADER_ENTRIES = Pattern
- .compile("# entries-in-buffer/entries-written:\\s+(?<buffered>\\d+)/"
- + "(?<written>\\d+)\\s+#P:\\d+\\s*");
- private static final int LOGCAT_SIZE = 20971520; //20 mb
- private static final long SEC_TO_MILLI = 1000;
- private static final long MILLI_TO_MICRO = 1000;
-
- @Option(name = "runner", description = "The instrumentation test runner class name to use.")
- private String mRunnerName = "android.support.test.runner.AndroidJUnitRunner";
-
- @Option(name = "package", shortName = 'p',
- description = "The manifest package name of the Android test application to run.",
- importance = Importance.IF_UNSET)
- private String mPackageName = "com.android.performanceapp.tests";
-
- @Option(name = "target-package", description = "package which contains all the "
- + "activities to launch")
- private String mtargetPackage = null;
-
- @Option(name = "activity-names", description = "Fully qualified activity "
- + "names separated by comma"
- + "If not set then all the activities will be included for launching")
- private String mactivityNames = "";
-
- @Option(name = "launch-count", description = "number of time to launch the each activity")
- private int mlaunchCount = 10;
-
- @Option(name = "save-atrace", description = "Upload the atrace file in permanent storage")
- private boolean mSaveAtrace = false;
-
- @Option(name = "atrace-section", description = "Section to be parsed from atrace file. "
- + "This option can be repeated")
- private Set<AtraceSectionOptions> mSectionOptionSet = new HashSet<>();
-
- @Option(name = "instantapp-url", description = "URL used to launch instant app")
- private String mInstantAppUrl = "";
-
- private ITestDevice mDevice = null;
- private IRemoteAndroidTestRunner mRunner;
- private LogcatReceiver mLogcat;
- private Set<String> mSectionSet = new HashSet<>();
- private Map<String, String> mActivityTraceFileMap;
- private Map<String, Map<String, String>> mActivityTimeResultMap = new HashMap<>();
- private Map<String,String> activityErrMsg=new HashMap<>();
-
- @Override
- public void run(ITestInvocationListener listener)
- throws DeviceNotAvailableException {
-
- mLogcat = new LogcatReceiver(getDevice(), LOGCAT_CMD, LOGCAT_SIZE, 0);
- mLogcat.start();
- try {
- if (mSectionOptionSet.isEmpty()) {
- // Default sections
- mSectionOptionSet.add(AtraceSectionOptions.LAYOUT);
- mSectionOptionSet.add(AtraceSectionOptions.DRAW);
- mSectionOptionSet.add(AtraceSectionOptions.BINDAPPLICATION);
- mSectionOptionSet.add(AtraceSectionOptions.ACTIVITYSTART);
- mSectionOptionSet.add(AtraceSectionOptions.ONCREATE);
- mSectionOptionSet.add(AtraceSectionOptions.INFLATE);
- } else if (mSectionOptionSet.contains(AtraceSectionOptions.LAYOUT)) {
- // If layout is added, draw should also be included
- mSectionOptionSet.add(AtraceSectionOptions.DRAW);
- }
-
- for (AtraceSectionOptions sectionOption : mSectionOptionSet) {
- mSectionSet.add(sectionOption.toString());
- }
-
- //Remove if there is already existing atrace_logs folder
- mDevice.executeShellCommand("rm -rf ${EXTERNAL_STORAGE}/atrace_logs");
-
- mRunner = createRemoteAndroidTestRunner(mPackageName, mRunnerName,
- mDevice.getIDevice());
- CollectingTestListener collectingListener = new CollectingTestListener();
- mDevice.runInstrumentationTests(mRunner, collectingListener);
-
- Collection<TestResult> testResultsCollection = collectingListener
- .getCurrentRunResults().getTestResults().values();
- List<TestResult> testResults = new ArrayList<>(
- testResultsCollection);
- /*
- * Expected Metrics : Map of <activity name>=<comma separated list of atrace file names in
- * external storage of the device>
- */
- mActivityTraceFileMap = testResults.get(0).getMetrics();
- Assert.assertTrue("Unable to get the path to the trace files stored in the device",
- (mActivityTraceFileMap != null && !mActivityTraceFileMap.isEmpty()));
-
- // Analyze the logcat data to get total launch time
- analyzeLogCatData(mActivityTraceFileMap.keySet());
- } finally {
- // Stop the logcat
- mLogcat.stop();
- }
-
- // Analyze the atrace data to get bindApplication,activityStart etc..
- analyzeAtraceData(listener);
-
- // Report the metrics to dashboard
- reportMetrics(listener);
- }
-
- /**
- * Report run metrics by creating an empty test run to stick them in.
- * @param listener The {@link ITestInvocationListener} of test results
- */
- private void reportMetrics(ITestInvocationListener listener) {
- for (String activityName : mActivityTimeResultMap.keySet()) {
- // Get the activity name alone from pkgname.activityname
- String[] activityNameSplit = activityName.split("\\.");
- if (!activityErrMsg.containsKey(activityName)) {
- Map<String, String> activityMetrics = mActivityTimeResultMap.get(activityName);
- if (activityMetrics != null && !activityMetrics.isEmpty()) {
- CLog.v("Metrics for the activity : %s", activityName);
- for (String sectionName : activityMetrics.keySet()) {
- CLog.v(String.format("Section name : %s - Time taken : %s",
- sectionName, activityMetrics.get(sectionName)));
- }
- listener.testRunStarted(
- activityNameSplit[activityNameSplit.length - 1].trim(), 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(activityMetrics));
- }
- } else {
- listener.testRunStarted(
- activityNameSplit[activityNameSplit.length - 1].trim(), 0);
- listener.testRunFailed(activityErrMsg.get(activityName));
- }
- }
- }
-
- /**
- * Method to create the runner with given list of arguments
- * @return the {@link IRemoteAndroidTestRunner} to use.
- * @throws DeviceNotAvailableException
- */
- IRemoteAndroidTestRunner createRemoteAndroidTestRunner(String packageName,
- String runnerName, IDevice device)
- throws DeviceNotAvailableException {
- RemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
- packageName, runnerName, device);
- runner.addInstrumentationArg("targetpackage", mtargetPackage);
- runner.addInstrumentationArg("launchcount", mlaunchCount + "");
- if(!mInstantAppUrl.isEmpty()){
- runner.addInstrumentationArg("instanturl", mInstantAppUrl);
- }
- if (mactivityNames != null && !mactivityNames.isEmpty()) {
- runner.addInstrumentationArg("activitylist", mactivityNames);
- }
- if (!mSaveAtrace) {
- runner.addInstrumentationArg("recordtrace", "false");
- }
- return runner;
- }
-
- /**
- * To analyze the log cat data to get the display time reported by activity manager during the
- * launches
- * activitySet is set of activityNames returned as a part of testMetrics from the device
- */
- public void analyzeLogCatData(Set<String> activitySet) {
- Map<String, List<Integer>> amLaunchTimes = new HashMap<>();
-
- Map<Pattern, String> activityPatternMap = new HashMap<>();
- Matcher match = null;
- String line;
-
- /*
- * Sample line format in logcat
- * 06-17 16:55:49.6 60 642 I ActivityManager: Displayed pkg/.activity: +Tms (total +9s9ms)
- */
- for (String activityName : activitySet) {
- int lastIndex = activityName.lastIndexOf(".");
- /*
- * actvitySet has set of activity names in the format packageName.activityName
- * logcat has the format packageName/.activityName --> activityAlias
- */
- String activityAlias = new String();
- if (mInstantAppUrl.isEmpty()) {
- activityAlias = activityName.subSequence(0, lastIndex)
- + "/" + activityName.subSequence(lastIndex, activityName.length());
- } else {
- activityAlias = mtargetPackage + ".*";
- }
- String finalPattern = LAUNCH_PREFIX + activityAlias + LAUNCH_SUFFIX;
- activityPatternMap.put(Pattern.compile(finalPattern),
- activityName);
- }
-
- try (InputStreamSource input = mLogcat.getLogcatData();
- BufferedReader br =
- new BufferedReader(new InputStreamReader(input.createInputStream()))) {
- while ((line = br.readLine()) != null) {
- /*
- * Launch entry needed otherwise we will end up in comparing all the lines for all
- * the patterns
- */
- if ((match = matches(LAUNCH_ENTRY, line)) != null) {
- for (Pattern pattern : activityPatternMap.keySet()) {
- if ((match = matches(pattern, line)) != null) {
- CLog.v("Launch Info : %s", line);
- int displayTimeInMs = extractLaunchTime(match.group("launchtime"));
- String activityName = activityPatternMap.get(pattern);
- if (amLaunchTimes.containsKey(activityName)) {
- amLaunchTimes.get(activityName).add(displayTimeInMs);
- } else {
- List<Integer> launchTimes = new ArrayList<>();
- launchTimes.add(displayTimeInMs);
- amLaunchTimes.put(activityName, launchTimes);
- }
- }
- }
- }
- }
- } catch (IOException io) {
- CLog.e(io);
- }
-
- // Verify logcat data
- for (String activityName : amLaunchTimes.keySet()) {
- Assert.assertEquals("Data lost for launch time for the activity :"
- + activityName, amLaunchTimes.get(activityName).size(), mlaunchCount);
- }
-
- /*
- * Extract and store the average launch time data reported by activity manager for each
- * activity
- */
- for (String activityName : amLaunchTimes.keySet()) {
- Double totalTime = 0d;
- for (Integer launchTime : amLaunchTimes.get(activityName)) {
- totalTime += launchTime;
- }
- Double averageTime = Double.valueOf(totalTime / amLaunchTimes.get(activityName).size());
- if (mActivityTimeResultMap.containsKey(activityName)) {
- mActivityTimeResultMap.get(activityName).put(TOTALLAUNCHTIME,
- String.format("%.2f", averageTime));
- } else {
- Map<String, String> launchTime = new HashMap<>();
- launchTime.put(TOTALLAUNCHTIME,
- String.format("%.2f", averageTime));
- mActivityTimeResultMap.put(activityName, launchTime);
- }
- }
- }
-
- /**
- * To extract the launch time displayed in given line
- *
- * @param duration
- * @return
- */
- public int extractLaunchTime(String duration) {
- String formattedString = duration.replace("ms", "");
- if (formattedString.contains("s")) {
- String[] splitString = formattedString.split("s");
- int finalTimeInMs = Integer.parseInt(splitString[0]) * 1000;
- finalTimeInMs = finalTimeInMs + Integer.parseInt(splitString[1]);
- return finalTimeInMs;
- } else {
- return Integer.parseInt(formattedString);
- }
- }
-
- /**
- * To analyze the trace data collected in the device during each activity launch.
- */
- public void analyzeAtraceData(ITestInvocationListener listener) throws DeviceNotAvailableException {
- for (String activityName : mActivityTraceFileMap.keySet()) {
- try {
- // Get the list of associated filenames for given activity
- String filePathAll = mActivityTraceFileMap.get(activityName);
- Assert.assertNotNull(
- String.format("Unable to find trace file paths for activity : %s",
- activityName), filePathAll);
- String[] filePaths = filePathAll.split(",");
- Assert.assertEquals(String.format("Unable to find file path for all the launches "
- + "for the activity :%s", activityName), filePaths.length, mlaunchCount);
- // Pull and parse the info
- List<Map<String, List<SectionPeriod>>> mutipleLaunchTraceInfo =
- new LinkedList<>();
- for (int count = 0; count < filePaths.length; count++) {
- File currentAtraceFile = pullAtraceInfoFile(filePaths[count]);
- String[] splitName = filePaths[count].split("-");
- // Process id is appended to original file name
- Map<String, List<SectionPeriod>> singleLaunchTraceInfo = parseAtraceInfoFile(
- currentAtraceFile,
- splitName[splitName.length - 1]);
- // Upload the file if needed
- if (mSaveAtrace) {
- try (FileInputStreamSource stream =
- new FileInputStreamSource(currentAtraceFile)) {
- listener.testLog(currentAtraceFile.getName(), LogDataType.TEXT, stream);
- }
- }
- // Remove the atrace files
- FileUtil.deleteFile(currentAtraceFile);
- mutipleLaunchTraceInfo.add(singleLaunchTraceInfo);
- }
-
- // Verify and Average out the aTrace Info and store it in result map
- averageAtraceData(activityName, mutipleLaunchTraceInfo);
- } catch (FileNotFoundException foe) {
- CLog.e(foe);
- activityErrMsg.put(activityName,
- "Unable to find the trace file for the activity launch :" + activityName);
- } catch (IOException ioe) {
- CLog.e(ioe);
- activityErrMsg.put(activityName,
- "Unable to read the contents of the atrace file for the activity :"
- + activityName);
- }
- }
-
- }
-
- /**
- * To pull the trace file from the device
- * @param aTraceFile
- * @return
- * @throws DeviceNotAvailableException
- */
- public File pullAtraceInfoFile(String aTraceFile)
- throws DeviceNotAvailableException {
- String dir = "${EXTERNAL_STORAGE}/atrace_logs";
- File atraceFileHandler = null;
- atraceFileHandler = getDevice().pullFile(dir + "/" + aTraceFile);
- Assert.assertTrue("Unable to retrieve the atrace files", atraceFileHandler != null);
- return atraceFileHandler;
- }
-
- /**
- * To parse and find the time taken for the given section names in each launch
- * @param currentAtraceFile
- * @param sectionSet
- * @param processId
- * @return
- * @throws FileNotFoundException,IOException
- */
- public Map<String, List<SectionPeriod>> parseAtraceInfoFile(
- File currentAtraceFile, String processId)
- throws FileNotFoundException, IOException {
- CLog.v("Currently parsing :" + currentAtraceFile.getName());
- String line;
- BufferedReader br = null;
- br = new BufferedReader(new FileReader(currentAtraceFile));
- LinkedList<TraceRecord> processStack = new LinkedList<>();
- Map<String, List<SectionPeriod>> sectionInfo = new HashMap<>();
-
- while ((line = br.readLine()) != null) {
- // Skip extra lines that aren't part of the trace
- if (line.isEmpty() || line.startsWith("capturing trace...")
- || line.equals("TRACE:") || line.equals("done")) {
- continue;
- }
- // Header information
- Matcher match = null;
- // Check if any trace entries were lost
- if ((match = matches(ATRACE_HEADER_ENTRIES, line)) != null) {
- int buffered = Integer.parseInt(match.group("buffered"));
- int written = Integer.parseInt(match.group("written"));
- if (written != buffered) {
- CLog.w(String.format("%d trace entries lost for the file %s",
- written - buffered, currentAtraceFile.getName()));
- }
- } else if ((match = matches(TRACE_ENTRY1, line)) != null
- || (match = matches(TRACE_ENTRY2, line)) != null) {
- /*
- * Two trace entries because trace format differs across devices <...>-tid [yyy]
- * ...1 zzz.ttt: tracing_mark_write: B|xxxx|tag_name pkg.name ( tid) [yyy] ...1
- * zzz.tttt: tracing_mark_write: B|xxxx|tag_name
- */
- long timestamp = SEC_TO_MILLI
- * Long.parseLong(match.group("secs"))
- + Long.parseLong(match.group("usecs")) / MILLI_TO_MICRO;
- // Get the function name from the trace entry
- String taskId = match.group("tid");
- String function = match.group("function");
- // Analyze the lines that matches the processid
- if (!taskId.equals(processId)) {
- continue;
- }
- if ((match = matches(ATRACE_BEGIN, function)) != null) {
- // Matching pattern looks like tracing_mark_write: B|xxxx|tag_name
- String sectionName = match.group("name");
- // Push to the stack
- processStack.add(new TraceRecord(sectionName, taskId,
- timestamp));
- } else if ((match = matches(ATRACE_END, function)) != null) {
- /*
- * Matching pattern looks like tracing_mark_write: E Pop from the stack when end
- * reaches
- */
- String endProcId = match.group("procid");
- if (endProcId.isEmpty() || endProcId.equals(processId)) {
- TraceRecord matchingBegin = processStack.removeLast();
- if (mSectionSet.contains(matchingBegin.name)) {
- if (sectionInfo.containsKey(matchingBegin.name)) {
- SectionPeriod newSecPeriod = new SectionPeriod(
- matchingBegin.timestamp, timestamp);
- CLog.v("Section :%s took :%f msecs ",
- matchingBegin.name, newSecPeriod.duration);
- sectionInfo.get(matchingBegin.name).add(newSecPeriod);
- } else {
- List<SectionPeriod> infoList = new LinkedList<>();
- SectionPeriod newSecPeriod = new SectionPeriod(
- matchingBegin.timestamp, timestamp);
- CLog.v(String.format("Section :%s took :%f msecs ",
- matchingBegin.name, newSecPeriod.duration));
- infoList.add(newSecPeriod);
- sectionInfo.put(matchingBegin.name, infoList);
- }
- }
- }
- } else if ((match = matches(ATRACE_COUNTER, function)) != null) {
- // Skip this for now. May want to track these later if needed.
- }
- }
-
- }
- StreamUtil.close(br);
- return sectionInfo;
- }
-
- /**
- * To take the average of the multiple launches for each activity
- * @param activityName
- * @param mutipleLaunchTraceInfo
- */
- public void averageAtraceData(String activityName,
- List<Map<String, List<SectionPeriod>>> mutipleLaunchTraceInfo) {
- String verificationResult = verifyAtraceMapInfo(mutipleLaunchTraceInfo);
- if (verificationResult != null) {
- CLog.w(
- "Not all the section info captured for the activity :%s. Missing: %s. "
- + "Please go to atrace file to look for detail.",
- activityName, verificationResult);
- }
- Map<String, Double> launchSum = new HashMap<>();
- for (String sectionName : mSectionSet) {
- launchSum.put(sectionName, 0d);
- }
- for (Map<String, List<SectionPeriod>> singleLaunchInfo : mutipleLaunchTraceInfo) {
- for (String sectionName : singleLaunchInfo.keySet()) {
- for (SectionPeriod secPeriod : singleLaunchInfo
- .get(sectionName)) {
- if (sectionName.equals(AtraceSectionOptions.DRAW.toString())) {
- // Get the first draw time for the launch
- Double currentSum = launchSum.get(sectionName)
- + secPeriod.duration;
- launchSum.put(sectionName, currentSum);
- break;
- }
- //Sum the multiple layout times before the first draw in this launch
- if (sectionName.equals(AtraceSectionOptions.LAYOUT.toString())) {
- Double drawStartTime = singleLaunchInfo
- .get(AtraceSectionOptions.DRAW.toString()).get(0).startTime;
- if (drawStartTime < secPeriod.startTime) {
- break;
- }
- }
- Double currentSum = launchSum.get(sectionName) + secPeriod.duration;
- launchSum.put(sectionName, currentSum);
- }
- }
- }
- // Update the final result map
- for (String sectionName : mSectionSet) {
- Double averageTime = launchSum.get(sectionName)
- / mutipleLaunchTraceInfo.size();
- mActivityTimeResultMap.get(activityName).put(sectionName,
- String.format("%.2f", averageTime));
- }
- }
-
- /**
- * To check if all the section info caught for all the app launches
- *
- * @param multipleLaunchTraceInfo
- * @return String: the missing section name, null if no section info missing.
- */
- public String verifyAtraceMapInfo(
- List<Map<String, List<SectionPeriod>>> multipleLaunchTraceInfo) {
- for (Map<String, List<SectionPeriod>> singleLaunchInfo : multipleLaunchTraceInfo) {
- Set<String> testSet = new HashSet<>(mSectionSet);
- testSet.removeAll(singleLaunchInfo.keySet());
- if (testSet.size() != 0) {
- return testSet.toString();
- }
- }
- return null;
- }
-
-
- /**
- * Checks whether {@code line} matches the given {@link Pattern}.
- * @return The resulting {@link Matcher} obtained by matching the {@code line} against
- * {@code pattern}, or null if the {@code line} does not match.
- */
- private static Matcher matches(Pattern pattern, String line) {
- Matcher ret = pattern.matcher(line);
- return ret.matches() ? ret : null;
- }
-
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- /**
- * A record to keep track of the section start time,end time and the duration in milliseconds.
- */
- public static class SectionPeriod {
-
- private double startTime;
- private double endTime;
- private double duration;
-
- public SectionPeriod(double startTime, double endTime) {
- this.startTime = startTime;
- this.endTime = endTime;
- this.duration = endTime - startTime;
- }
-
- public double getStartTime() {
- return startTime;
- }
-
- public void setStartTime(long startTime) {
- this.startTime = startTime;
- }
-
- public double getEndTime() {
- return endTime;
- }
-
- public void setEndTime(long endTime) {
- this.endTime = endTime;
- }
-
- public double getDuration() {
- return duration;
- }
-
- public void setDuration(long duration) {
- this.duration = duration;
- }
- }
-
- /**
- * A record of a trace event. Includes the name of the section, and the time that the event
- * occurred (in milliseconds).
- */
- public static class TraceRecord {
-
- private String name;
- private String processId;
- private double timestamp;
-
- /**
- * Construct a new {@link TraceRecord} with the given {@code name} and {@code timestamp} .
- */
- public TraceRecord(String name, String processId, long timestamp) {
- this.name = name;
- this.processId = processId;
- this.timestamp = timestamp;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getProcessId() {
- return processId;
- }
-
- public void setProcessId(String processId) {
- this.processId = processId;
- }
-
- public double getTimestamp() {
- return timestamp;
- }
-
- public void setTimestamp(long timestamp) {
- this.timestamp = timestamp;
- }
- }
-
-}
diff --git a/prod-tests/src/com/android/performance/tests/HermeticMemoryTest.java b/prod-tests/src/com/android/performance/tests/HermeticMemoryTest.java
deleted file mode 100644
index fcde5a2..0000000
--- a/prod-tests/src/com/android/performance/tests/HermeticMemoryTest.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * 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.performance.tests;
-
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ByteArrayInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.ProcessInfo;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Test to gather post launch memory details after launching app
- * that include app memory usage and system memory usage
- */
-public class HermeticMemoryTest implements IDeviceTest, IRemoteTest {
-
- private static final String AM_START = "am start -n %s";
- private static final String AM_BROADCAST = "am broadcast -a %s -n %s %s";
- private static final String PROC_MEMINFO = "cat /proc/meminfo";
- private static final String CACHED_PROCESSES = "dumpsys meminfo|awk '/Total PSS by category:"
- + "/{found=0} {if(found) print} /: Cached/{found=1}'|tr -d ' '";
- private static final Pattern PID_PATTERN = Pattern.compile("^.*pid(?<processid>[0-9]*).*$");
- private static final String DUMPSYS_PROCESS = "dumpsys meminfo %s";
- private static final String DUMPSYS_MEMINFO = "dumpsys meminfo -a ";
- private static final String MAPS_INFO = "cat /proc/%d/maps";
- private static final String SMAPS_INFO = "cat /proc/%d/smaps";
- private static final String STATUS_INFO = "cat /proc/%d/status";
- private static final String NATIVE_HEAP = "Native";
- private static final String DALVIK_HEAP = "Dalvik";
- private static final String HEAP = "Heap";
- private static final String MEMTOTAL = "MemTotal";
- private static final String MEMFREE = "MemFree";
- private static final String CACHED = "Cached";
- private static final int NO_PROCESS_ID = -1;
- private static final String DROP_CACHE = "echo 3 > /proc/sys/vm/drop_caches";
- private static final String SEPARATOR ="\\s+";
- private static final String LINE_SEPARATOR = "\\n";
- private static final String MEM_AVAIL_PATTERN = "^MemAvailable.*";
- private static final String MEM_TOTAL = "^\\s+TOTAL\\s+.*";
-
-
- @Option(name = "post-app-launch-delay",
- description = "The delay, between the app launch and the meminfo dump",
- isTimeVal = true)
- private long mPostAppLaunchDelay = 60;
-
- @Option(name = "component-name",
- description = "package/activity name to launch the activity")
- private String mComponentName = new String();
-
- @Option(name = "intent-action", description = "intent action to broadcast")
- private String mIntentAction = new String();
-
- @Option(name = "intent-params", description = "intent parameters")
- private String mIntentParams = new String();
-
- @Option(name = "total-memory-kb",
- description = "Built in total memory of the device")
- private long mTotalMemory = 0;
-
- @Option(name = "reporting-key", description = "Reporting key is the unique identifier"
- + "used to report data in the dashboard.")
- private String mRuKey = "";
-
- private ITestDevice mTestDevice = null;
- private ITestInvocationListener mlistener = null;
- private Map<String, String> mMetrics = new HashMap<String, String> ();
-
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- mlistener = listener;
-
- calculateFreeMem();
-
- String preMemInfo = mTestDevice.executeShellCommand(PROC_MEMINFO);
-
- if (!preMemInfo.isEmpty()) {
-
- uploadLogFile(preMemInfo, "BeforeLaunchProcMemInfo");
- } else {
- CLog.e("Not able to collect the /proc/meminfo before launching app");
- }
-
- Assert.assertTrue("Device built in memory in kb is mandatory.Use --total-memory-kb value"
- + "command line parameter",
- mTotalMemory != 0);
- RunUtil.getDefault().sleep(5000);
- mTestDevice.executeShellCommand(DROP_CACHE);
- RunUtil.getDefault().sleep(5000);
- Assert.assertTrue("Not a valid component name to start the activity",
- (mComponentName.split("/").length == 2));
- if (mIntentAction.isEmpty()) {
- mTestDevice.executeShellCommand(String.format(AM_START, mComponentName));
- } else {
- mTestDevice.executeShellCommand(
- String.format(AM_BROADCAST, mIntentAction, mComponentName, mIntentParams));
- }
-
- RunUtil.getDefault().sleep(mPostAppLaunchDelay);
- String postMemInfo = mTestDevice.executeShellCommand(PROC_MEMINFO);
- int processId = getProcessId();
- String dumpsysMemInfo = mTestDevice.executeShellCommand(
- String.format("%s %d", DUMPSYS_MEMINFO, processId));
- String mapsInfo = mTestDevice.executeShellCommand(
- String.format(MAPS_INFO, processId));
- String sMapsInfo = mTestDevice.executeShellCommand(
- String.format(SMAPS_INFO, processId));
- String statusInfo = mTestDevice.executeShellCommand(
- String.format(STATUS_INFO, processId));
-
- if (!postMemInfo.isEmpty()) {
- uploadLogFile(postMemInfo, "AfterLaunchProcMemInfo");
- parseProcInfo(postMemInfo);
- } else {
- CLog.e("Not able to collect the proc/meminfo after launching app");
- }
-
- if (NO_PROCESS_ID == processId) {
- CLog.e("Process Id not found for the activity launched");
- } else {
- if (!dumpsysMemInfo.isEmpty()) {
- uploadLogFile(dumpsysMemInfo, String.format("DumpsysMemInfo_%s", mComponentName));
- parseDumpsysInfo(dumpsysMemInfo);
- } else {
- CLog.e("Not able to collect the Dumpsys meminfo after launching app");
- }
- if (!mapsInfo.isEmpty()) {
- uploadLogFile(mapsInfo, "mapsInfo");
- } else {
- CLog.e("Not able to collect maps info after launching app");
- }
- if (!sMapsInfo.isEmpty()) {
- uploadLogFile(sMapsInfo, "smapsInfo");
- } else {
- CLog.e("Not able to collect smaps info after launching app");
- }
- if (!statusInfo.isEmpty()) {
- uploadLogFile(statusInfo, "statusInfo");
- } else {
- CLog.e("Not able to collect status info after launching app");
- }
- }
-
- reportMetrics(listener, mRuKey, mMetrics);
-
- }
-
- /**
- * Method to get the process id of the target package/activity name
- *
- * @return processId of the activity launched
- * @throws DeviceNotAvailableException
- */
- private int getProcessId() throws DeviceNotAvailableException {
- String pkgActivitySplit[] = mComponentName.split("/");
- if (pkgActivitySplit[0] != null) {
- ProcessInfo processData = mTestDevice.getProcessByName(pkgActivitySplit[0]);
- if (null != processData) {
- return processData.getPid();
- }
- }
- return NO_PROCESS_ID;
- }
-
- /**
- * Method to write the data to test logs.
- * @param data
- * @param fileName
- */
- private void uploadLogFile(String data, String fileName) {
- ByteArrayInputStreamSource inputStreamSrc = null;
- try {
- inputStreamSrc = new ByteArrayInputStreamSource(data.getBytes());
- mlistener.testLog(fileName, LogDataType.TEXT, inputStreamSrc);
- } finally {
- StreamUtil.cancel(inputStreamSrc);
- }
- }
-
- /**
- * Method to parse dalvik and heap info for launched app
- */
- private void parseDumpsysInfo(String dumpInfo) {
- String line[] = dumpInfo.split(LINE_SEPARATOR);
- for (int lineCount = 0; lineCount < line.length; lineCount++) {
- String dataSplit[] = line[lineCount].trim().split(SEPARATOR);
- if ((dataSplit[0].equalsIgnoreCase(NATIVE_HEAP) && dataSplit[1]
- .equalsIgnoreCase(HEAP)) ||
- (dataSplit[0].equalsIgnoreCase(DALVIK_HEAP) && dataSplit[1]
- .equalsIgnoreCase(HEAP)) ||
- dataSplit[0].equalsIgnoreCase("Total")) {
- if (dataSplit.length > 10) {
- if (dataSplit[0].contains(NATIVE_HEAP)
- || dataSplit[0].contains(DALVIK_HEAP)) {
- mMetrics.put(dataSplit[0] + ":PSS_TOTAL", dataSplit[2]);
- mMetrics.put(dataSplit[0] + ":SHARED_DIRTY", dataSplit[4]);
- mMetrics.put(dataSplit[0] + ":PRIVATE_DIRTY", dataSplit[5]);
- mMetrics.put(dataSplit[0] + ":HEAP_TOTAL", dataSplit[9]);
- mMetrics.put(dataSplit[0] + ":HEAP_ALLOC", dataSplit[10]);
- } else {
- mMetrics.put(dataSplit[0] + ":PSS", dataSplit[1]);
- }
- }
- }
- }
- }
-
- /**
- * Method to parse the system memory details
- */
- private void parseProcInfo(String memInfo) {
- String lineSplit[] = memInfo.split(LINE_SEPARATOR);
- long memTotal = 0;
- long memFree = 0;
- long cached = 0;
- for (int lineCount = 0; lineCount < lineSplit.length; lineCount++) {
- String line = lineSplit[lineCount].replace(":", "").trim();
- String dataSplit[] = line.split(SEPARATOR);
- if (dataSplit[0].equalsIgnoreCase(MEMTOTAL) ||
- dataSplit[0].equalsIgnoreCase(MEMFREE) ||
- dataSplit[0].equalsIgnoreCase(CACHED)) {
- if (dataSplit[0].equalsIgnoreCase(MEMTOTAL)) {
- memTotal = Long.parseLong(dataSplit[1]);
- }
- if (dataSplit[0].equalsIgnoreCase(MEMFREE)) {
- memFree = Long.parseLong(dataSplit[1]);
- }
- if (dataSplit[0].equalsIgnoreCase(CACHED)) {
- cached = Long.parseLong(dataSplit[1]);
- }
- mMetrics.put("System_" + dataSplit[0], dataSplit[1]);
- }
- }
- mMetrics.put("System_Kernal_Firmware", String.valueOf((mTotalMemory - memTotal)));
- mMetrics.put("System_Framework_Apps", String.valueOf((memTotal - (memFree + cached))));
- }
-
- /**
- * Method to parse the free memory based on total memory available from proc/meminfo and
- * private dirty and private clean information of the cached processess
- * from dumpsys meminfo.
- */
- private void calculateFreeMem() throws DeviceNotAvailableException {
- String memInfo = mTestDevice.executeShellCommand(PROC_MEMINFO);
- uploadLogFile(memInfo, "proc_meminfo_In_CacheProcDirty");
- Pattern p = Pattern.compile(MEM_AVAIL_PATTERN, Pattern.MULTILINE);
- Matcher m = p.matcher(memInfo);
- String memAvailable[] = null;
- if (m.find()) {
- memAvailable = m.group(0).split(SEPARATOR);
- }
- int cacheProcDirty = Integer.parseInt(memAvailable[1]);
-
- String cachedProcesses = mTestDevice.executeShellCommand(CACHED_PROCESSES);
- String processes[] = cachedProcesses.split(LINE_SEPARATOR);
- StringBuilder processesDumpsysInfo = new StringBuilder();
- for (String process : processes) {
- Matcher match = null;
- if (((match = matches(PID_PATTERN, process))) != null) {
- String processId = match.group("processid");
- processesDumpsysInfo.append(String.format("Process Name : %s - PID : %s", process,
- processId));
- processesDumpsysInfo.append("\n");
- String processInfoStr = mTestDevice.executeShellCommand(String.format(
- DUMPSYS_PROCESS, processId));
- processesDumpsysInfo.append(processInfoStr);
- processesDumpsysInfo.append("\n");
- Pattern p1 = Pattern.compile(MEM_TOTAL, Pattern.MULTILINE);
- Matcher m1 = p1.matcher(processInfoStr);
- String processInfo[] = null;
- if (m1.find()) {
- processInfo = m1.group(0).split(LINE_SEPARATOR);
- }
- if (null != processInfo && processInfo.length > 0) {
- String procDetails[] = processInfo[0].trim().split(SEPARATOR);
- cacheProcDirty = cacheProcDirty + Integer.parseInt(procDetails[2].trim())
- + Integer.parseInt(procDetails[3]);
- }
- }
- }
- uploadLogFile(processesDumpsysInfo.toString(), "ProcessesDumpsysInfo_In_CacheProcDirty");
- mMetrics.put("MemAvailable_CacheProcDirty", String.valueOf(cacheProcDirty));
- }
-
- /**
- * Report run metrics by creating an empty test run to stick them in
- *
- * @param listener the {@link ITestInvocationListener} of test results
- * @param runName the test name
- * @param metrics the {@link Map} that contains metrics for the given test
- */
- void reportMetrics(ITestInvocationListener listener, String runName,
- Map<String, String> metrics) {
- // Create an empty testRun to report the parsed runMetrics
- CLog.d("About to report metrics: %s", metrics);
- listener.testRunStarted(runName, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-
- /**
- * Checks whether {@code line} matches the given {@link Pattern}.
- *
- * @return The resulting {@link Matcher} obtained by matching the {@code line} against
- * {@code pattern}, or null if the {@code line} does not match.
- */
- private static Matcher matches(Pattern pattern, String line) {
- Matcher ret = pattern.matcher(line);
- return ret.matches() ? ret : null;
- }
-
- @Override
- public void setDevice(ITestDevice device) {
- mTestDevice = device;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-}
-
-
-
diff --git a/prod-tests/src/com/android/performance/tests/StartupMetricsTest.java b/prod-tests/src/com/android/performance/tests/StartupMetricsTest.java
deleted file mode 100644
index 6fabdf4..0000000
--- a/prod-tests/src/com/android/performance/tests/StartupMetricsTest.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2011 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.performance.tests;
-
-import com.android.loganalysis.item.BugreportItem;
-import com.android.loganalysis.item.MemInfoItem;
-import com.android.loganalysis.item.ProcrankItem;
-import com.android.loganalysis.parser.BugreportParser;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.device.ITestDevice.RecoveryMode;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Tests to gather device metrics from during and immediately after boot
- */
-public class StartupMetricsTest implements IDeviceTest, IRemoteTest {
- public static final String BUGREPORT_LOG_NAME = "bugreport_startup.txt";
-
- @Option(name="boot-time-ms", description="Timeout in ms to wait for device to boot.")
- private long mBootTimeMs = 20 * 60 * 1000;
-
- @Option(name="boot-poll-time-ms", description="Delay in ms between polls for device to boot.")
- private long mBootPoolTimeMs = 500;
-
- @Option(name="post-boot-delay-ms",
- description="Delay in ms after boot complete before taking the bugreport.")
- private long mPostBootDelayMs = 60000;
-
- @Option(name="skip-memory-stats", description="Report boot time only, without memory stats.")
- private boolean mSkipMemoryStats = false;
-
- ITestDevice mTestDevice = null;
-
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- Assert.assertNotNull(mTestDevice);
- executeRebootTest(listener);
- if (!mSkipMemoryStats) {
- fetchBugReportMetrics(listener);
- }
- }
-
- /**
- * Check how long the device takes to come online and become available after
- * a reboot.
- *
- * @param listener the {@link ITestInvocationListener} of test results
- */
- void executeRebootTest(ITestInvocationListener listener) throws DeviceNotAvailableException {
-
- /*Not using /proc/uptime to get the initial boot time
- because it includes delays running 'permission utils',
- and the CPU throttling waiter*/
- Map<String, String> runMetrics = new HashMap<String, String>();
- //Initial reboot
- mTestDevice.rebootIntoBootloader();
- mTestDevice.setUseFastbootErase(false);
- mTestDevice.fastbootWipePartition("userdata");
- mTestDevice.executeFastbootCommand("reboot");
- mTestDevice.waitForDeviceOnline(10 * 60 * 1000);
- long initOnlineTime = System.currentTimeMillis();
- Assert.assertTrue(waitForBootComplete(mTestDevice, mBootTimeMs, mBootPoolTimeMs));
- long initAvailableTime = System.currentTimeMillis();
- double initUnavailDuration = initAvailableTime - initOnlineTime;
- runMetrics.put("init-boot", Double.toString(initUnavailDuration / 1000.0));
-
- mTestDevice.setRecoveryMode(RecoveryMode.NONE);
- CLog.d("Reboot test start.");
- mTestDevice.nonBlockingReboot();
- long startTime = System.currentTimeMillis();
- mTestDevice.waitForDeviceOnline();
- long onlineTime = System.currentTimeMillis();
- Assert.assertTrue(waitForBootComplete(mTestDevice, mBootTimeMs, mBootPoolTimeMs));
- long availableTime = System.currentTimeMillis();
-
- double offlineDuration = onlineTime - startTime;
- double unavailDuration = availableTime - startTime;
- CLog.d("Reboot: %f millis until online, %f until available",
- offlineDuration, unavailDuration);
- runMetrics.put("online", Double.toString(offlineDuration/1000.0));
- runMetrics.put("bootcomplete", Double.toString(unavailDuration/1000.0));
-
- reportMetrics(listener, "boottime", runMetrics);
- }
-
- /**
- * Fetch proc rank metrics from the bugreport after reboot.
- *
- * @param listener the {@link ITestInvocationListener} of test results
- * @throws DeviceNotAvailableException
- */
- void fetchBugReportMetrics(ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- // Make sure the device is available and settled, before getting bugreport.
- mTestDevice.waitForDeviceAvailable();
- RunUtil.getDefault().sleep(mPostBootDelayMs);
- BugreportParser parser = new BugreportParser();
- BugreportItem bugreport = null;
- // Retrieve bugreport
- try (InputStreamSource bugSource = mTestDevice.getBugreport()) {
- listener.testLog(BUGREPORT_LOG_NAME, LogDataType.BUGREPORT, bugSource);
- bugreport = parser.parse(new BufferedReader(new InputStreamReader(
- bugSource.createInputStream())));
- } catch (IOException e) {
- Assert.fail(String.format("Failed to fetch and parse bugreport for device %s: %s",
- mTestDevice.getSerialNumber(), e));
- }
-
- if (bugreport != null) {
- // Process meminfo information and post it to the dashboard
- MemInfoItem item = bugreport.getMemInfo();
- if (item != null) {
- Map<String, String> memInfoMap = convertMap(item);
- reportMetrics(listener, "startup-meminfo", memInfoMap);
- }
-
- // Process procrank information and post it to the dashboard
- if (bugreport.getProcrank() != null) {
- parseProcRankMap(listener, bugreport.getProcrank());
- }
- }
- }
-
- /**
- * Helper method to convert a {@link MemInfoItem} to Map<String, String>.
- *
- * @param input the {@link Map} to convert from
- * @return output the converted {@link Map}
- */
- Map<String, String> convertMap(MemInfoItem item) {
- Map<String, String> output = new HashMap<String, String>();
- for (String key : item.keySet()) {
- output.put(key, item.get(key).toString());
- }
- return output;
- }
-
- /**
- * Report run metrics by creating an empty test run to stick them in
- *
- * @param listener the {@link ITestInvocationListener} of test results
- * @param runName the test name
- * @param metrics the {@link Map} that contains metrics for the given test
- */
- void reportMetrics(ITestInvocationListener listener, String runName,
- Map<String, String> metrics) {
- // Create an empty testRun to report the parsed runMetrics
- CLog.d("About to report metrics: %s", metrics);
- listener.testRunStarted(runName, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-
- /**
- * Aggregates the procrank data by the pss, rss, and uss values.
- *
- * @param listener the {@link ITestInvocationListener} of test results
- * @param procrank the {@link Map} parsed from brillopad for the procrank section
- */
- void parseProcRankMap(ITestInvocationListener listener, ProcrankItem procrank) {
- // final maps for pss, rss, and uss.
- Map<String, String> pssOutput = new HashMap<String, String>();
- Map<String, String> rssOutput = new HashMap<String, String>();
- Map<String, String> ussOutput = new HashMap<String, String>();
- // total number of processes.
- Integer numProcess = 0;
- // aggregate pss, rss, uss across all processes.
- Integer pssTotal = 0;
- Integer rssTotal = 0;
- Integer ussTotal = 0;
-
- for (Integer pid : procrank.getPids()) {
- numProcess++;
- Integer pss = procrank.getPss(pid);
- Integer rss = procrank.getRss(pid);
- Integer uss = procrank.getUss(pid);
- if (pss != null) {
- pssTotal += pss;
- pssOutput.put(procrank.getProcessName(pid), pss.toString());
- }
- if (rss != null) {
- rssTotal += rss;
- rssOutput.put(procrank.getProcessName(pid), rss.toString());
- }
- if (uss != null) {
- ussTotal += pss;
- ussOutput.put(procrank.getProcessName(pid), uss.toString());
- }
- }
- // Add aggregation data.
- pssOutput.put("count", numProcess.toString());
- pssOutput.put("total", pssTotal.toString());
- rssOutput.put("count", numProcess.toString());
- rssOutput.put("total", rssTotal.toString());
- ussOutput.put("count", numProcess.toString());
- ussOutput.put("total", ussTotal.toString());
-
- // Report metrics to dashboard
- reportMetrics(listener, "startup-procrank-pss", pssOutput);
- reportMetrics(listener, "startup-procrank-rss", rssOutput);
- reportMetrics(listener, "startup-procrank-uss", ussOutput);
- }
-
- /**
- * Blocks until the device's boot complete flag is set.
- *
- * @param device the {@link ITestDevice}
- * @param timeOut time in msecs to wait for the flag to be set
- * @param pollDelay time in msecs between checks
- * @return true if device's boot complete flag is set within the timeout
- * @throws DeviceNotAvailableException
- */
- private boolean waitForBootComplete(ITestDevice device,long timeOut, long pollDelay)
- throws DeviceNotAvailableException {
- long startTime = System.currentTimeMillis();
- while ((System.currentTimeMillis() - startTime) < timeOut) {
- String output = device.executeShellCommand("getprop dev.bootcomplete");
- output = output.replace('#', ' ').trim();
- if (output.equals("1")) {
- return true;
- }
- RunUtil.getDefault().sleep(pollDelay);
- }
- CLog.w("Device %s did not boot after %d ms", device.getSerialNumber(), timeOut);
- return false;
- }
-
- @Override
- public void setDevice(ITestDevice device) {
- mTestDevice = device;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-}
diff --git a/prod-tests/src/com/android/performance/tests/VellamoBenchmark.java b/prod-tests/src/com/android/performance/tests/VellamoBenchmark.java
deleted file mode 100644
index 3ab15b9..0000000
--- a/prod-tests/src/com/android/performance/tests/VellamoBenchmark.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2013 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.performance.tests;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A harness that launches VellamoBenchmark and reports result. Requires
- * VellamoBenchmark apk.
- */
-public class VellamoBenchmark implements IDeviceTest, IRemoteTest {
-
- private static final String LOGTAG = "VAUTOMATIC";
- private static final String RUN_KEY = "vellamobenchmark-3202";
- private static final String PACKAGE_NAME = "com.quicinc.vellamo";
- private static final long TIMEOUT_MS = 30 * 60 * 1000;
- private static final long POLLING_INTERVAL_MS = 10 * 1000;
- private static final int INDEX_NAME = 0;
- private static final int INDEX_CODE = 4;
- private static final int INDEX_SCORE = 5;
-
- private ITestDevice mDevice;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- TestDescription testId = new TestDescription(getClass().getCanonicalName(), RUN_KEY);
- ITestDevice device = getDevice();
- listener.testRunStarted(RUN_KEY, 0);
- listener.testStarted(testId);
-
- long testStartTime = System.currentTimeMillis();
- Map<String, String> metrics = new HashMap<String, String>();
- String errMsg = null;
-
- boolean isTimedOut = false;
- boolean isResultGenerated = false;
- boolean hasScore = false;
- double sumScore = 0;
- int errorCode = 0;
- device.clearErrorDialogs();
- isTimedOut = false;
-
- long benchmarkStartTime = System.currentTimeMillis();
- // start the vellamo benchmark app and run all the tests
- // the documentation and binary for the Vellamo 3.2.2 for Automation APK
- // can be found here:
- // https://b.corp.google.com/issue?id=23107318
- CLog.i("Starting Vellamo Benchmark");
- device.executeShellCommand("am start -a com.quicinc.vellamo.AUTOMATIC"
- + " -e w com.quicinc.skunkworks.wvb" // use System WebView
- + " -n com.quicinc.vellamo/.main.MainActivity");
- String line;
- while (!isResultGenerated && !isTimedOut) {
- RunUtil.getDefault().sleep(POLLING_INTERVAL_MS);
- isTimedOut = (System.currentTimeMillis() - benchmarkStartTime >= TIMEOUT_MS);
-
- // get the logcat and parse
- try (InputStreamSource logcatSource = device.getLogcat();
- BufferedReader logcat =
- new BufferedReader(
- new InputStreamReader(logcatSource.createInputStream()))) {
- while ((line = logcat.readLine()) != null) {
- // filter only output from the Vellamo process
- if (!line.contains(LOGTAG)) {
- continue;
- }
- line = line.substring(line.indexOf(LOGTAG) + LOGTAG.length());
- // we need to see if the score is generated since there are some
- // cases the result with </automatic> tag is generated but no score is included
- if (line.contains("</automatic>")) {
- if (hasScore) {
- isResultGenerated = true;
- break;
- }
- }
- // get the score out
- if (line.contains(" b: ")) {
- hasScore = true;
- String[] results = line.split(" b: ")[1].split(",");
- errorCode = Integer.parseInt(results[INDEX_CODE]);
- if (errorCode != 0) {
- CLog.w("Non-zero error code: %d from becnhmark '%s'",
- errorCode, results[INDEX_NAME]);
- } else {
- sumScore += Double.parseDouble(results[INDEX_SCORE]);
- }
- metrics.put(results[INDEX_NAME], results[INDEX_SCORE]);
- CLog.i("%s :: %s", results[INDEX_NAME], results[INDEX_SCORE]);
- }
- }
- } catch (IOException e) {
- CLog.e(e);
- }
-
- if (null == device.getProcessByName(PACKAGE_NAME)) {
- break;
- }
- }
-
- if (isTimedOut) {
- errMsg = "Vellamo Benchmark timed out.";
- } else {
- CLog.i("Done running Vellamo Benchmark");
- }
- if (!hasScore) {
- errMsg = "Test ended but no scores can be found.";
- }
- if (errMsg != null) {
- CLog.e(errMsg);
- listener.testFailed(testId, errMsg);
- }
- long durationMs = System.currentTimeMillis() - testStartTime;
- metrics.put("total", Double.toString(sumScore));
- CLog.i("total :: %f", sumScore);
- listener.testEnded(testId, new HashMap<String, Metric>());
- listener.testRunEnded(durationMs, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-}
diff --git a/prod-tests/src/com/android/sdk/tests/EmulatorGpsPreparer.java b/prod-tests/src/com/android/sdk/tests/EmulatorGpsPreparer.java
deleted file mode 100644
index 44a3e12..0000000
--- a/prod-tests/src/com/android/sdk/tests/EmulatorGpsPreparer.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 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.sdk.tests;
-
-import com.android.ddmlib.EmulatorConsole;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.targetprep.BaseTargetPreparer;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.TargetSetupError;
-
-import org.junit.Assert;
-
-/** Injects specific gps location into emulator. */
-public class EmulatorGpsPreparer extends BaseTargetPreparer {
-
- // default gps location for the gps test
- // TODO: make these options rather than hardcoding
- private static final double LONGITUDE = -122.08345770835876;
- private static final double LATITUDE = 37.41991859119417;
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
- BuildError, DeviceNotAvailableException {
- Assert.assertTrue("device is not a emulator", device.getIDevice().isEmulator());
- EmulatorConsole console = EmulatorConsole.getConsole(device.getIDevice());
- console.sendLocation(LONGITUDE, LATITUDE, 0);
- }
-}
diff --git a/prod-tests/src/com/android/sdk/tests/EmulatorSmsPreparer.java b/prod-tests/src/com/android/sdk/tests/EmulatorSmsPreparer.java
deleted file mode 100644
index 35063e0..0000000
--- a/prod-tests/src/com/android/sdk/tests/EmulatorSmsPreparer.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2014 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.sdk.tests;
-
-import com.android.ddmlib.EmulatorConsole;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.targetprep.BaseTargetPreparer;
-import com.android.tradefed.targetprep.BuildError;
-import com.android.tradefed.targetprep.TargetSetupError;
-
-import org.junit.Assert;
-
-/** Sends and SMS message to the emulator */
-public class EmulatorSmsPreparer extends BaseTargetPreparer {
-
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
- BuildError, DeviceNotAvailableException {
- Assert.assertTrue("device is not a emulator", device.getIDevice().isEmulator());
- EmulatorConsole console = EmulatorConsole.getConsole(device.getIDevice());
- // these values mus match exactly with platform/development/tools/emulator/...
- // test-apps/SmsTest/src/com/android/emulator/test/SmsTest.java
- console.sendSms("5551212","test sms");
- }
-}
diff --git a/prod-tests/src/com/android/stability/tests/RebootStressTest.java b/prod-tests/src/com/android/stability/tests/RebootStressTest.java
deleted file mode 100644
index 2532a0a..0000000
--- a/prod-tests/src/com/android/stability/tests/RebootStressTest.java
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2012 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.stability.tests;
-
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ByteArrayInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.testtype.IShardableTest;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A test that reboots device many times, and reports successful iteration count.
- */
-public class RebootStressTest implements IRemoteTest, IDeviceTest, IShardableTest {
-
- private static final String[] LAST_KMSG_PATHS = {
- "/sys/fs/pstore/console-ramoops-0",
- "/sys/fs/pstore/console-ramoops",
- "/proc/last_kmsg",
- };
- // max number of ms to allowed for the post-boot waitForDeviceAvailable check
- private static final long DEVICE_AVAIL_TIME = 3 * 1000;
-
- @Option(name = "iterations", description = "number of reboot iterations to perform")
- private int mIterations = 1;
-
- @Option(name = "shards", description = "Optional number of shards to split test into. " +
- "Iterations will be split evenly among shards.", importance = Importance.IF_UNSET)
- private Integer mShards = null;
-
- @Option(name = "run-name", description =
- "The test run name used to report metrics.")
- private String mRunName = "reboot-stress";
-
- @Option(name = "post-boot-wait-time", description =
- "Total number of seconds to wait between reboot attempts")
- private int mWaitTime = 10;
-
- @Option(name = "post-boot-poll-time", description =
- "Number of seconds to wait between device health checks")
- private int mPollSleepTime = 1;
-
- @Option(name = "wipe-data", description =
- "Flag to set if userdata should be wiped between reboots")
- private boolean mWipeUserData = false;
-
- @Option(name = "wipe-data-cmd", description =
- "the fastboot command(s) to use to wipe data and reboot device.")
- private Collection<String> mFastbootWipeCmds = new ArrayList<String>();
-
- @Option(name = "boot-into-bootloader", description =
- "Flag to set if reboot should enter bootloader")
- private boolean mBootIntoBootloader = true;
-
- private ITestDevice mDevice;
- private String mLastKmsg;
- private String mDmesg;
-
- /**
- * Set the run name
- */
- void setRunName(String runName) {
- mRunName = runName;
- }
-
- /**
- * Return the number of iterations.
- * <p/>
- * Exposed for unit testing
- */
- public int getIterations() {
- return mIterations;
- }
-
- /**
- * Set the iterations
- */
- void setIterations(int iterations) {
- mIterations = iterations;
- }
-
- /**
- * Set the number of shards
- */
- void setShards(int shards) {
- mShards = shards;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setDevice(ITestDevice device) {
- mDevice = device;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public ITestDevice getDevice() {
- return mDevice;
- }
-
- void setWaitTime(int waitTimeSec) {
- mWaitTime = waitTimeSec;
- }
-
- void setPollTime(int pollTime) {
- mPollSleepTime = pollTime;
-
- }
-
- void setWipeData(boolean wipeData) {
- mWipeUserData = wipeData;
- }
-
- void setFastbootWipeDataCmds(Collection<String> cmds) {
- mFastbootWipeCmds.addAll(cmds);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public Collection<IRemoteTest> split() {
- if (mShards == null || mShards <= 1) {
- return null;
- }
- Collection<IRemoteTest> shards = new ArrayList<IRemoteTest>(mShards);
- int remainingIterations = mIterations;
- for (int i = mShards; i > 0; i--) {
- RebootStressTest testShard = new RebootStressTest();
- // device will be set by test invoker
- testShard.setRunName(mRunName);
- testShard.setWaitTime(mWaitTime);
- testShard.setWipeData(mWipeUserData);
- testShard.setFastbootWipeDataCmds(mFastbootWipeCmds);
- testShard.setPollTime(mPollSleepTime);
- // attempt to divide iterations evenly among shards with no remainder
- int iterationsForShard = Math.round(remainingIterations/i);
- if (iterationsForShard > 0) {
- testShard.setIterations(iterationsForShard);
- remainingIterations -= iterationsForShard;
- shards.add(testShard);
- }
- }
- return shards;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- Assert.assertNotNull(getDevice());
-
- listener.testRunStarted(mRunName, 0);
- long startTime = System.currentTimeMillis();
- int actualIterations = 0;
- try {
- for (actualIterations = 0; actualIterations < mIterations; actualIterations++) {
- CLog.i("Reboot attempt %d of %d", actualIterations+1, mIterations);
- if (mBootIntoBootloader){
- getDevice().rebootIntoBootloader();
- if (mWipeUserData) {
- executeFastbootWipeCommand();
- } else {
- getDevice().executeFastbootCommand("reboot");
- }
- } else {
- getDevice().reboot();
- }
- getDevice().waitForDeviceAvailable();
- doWaitAndCheck();
- CLog.logAndDisplay(LogLevel.INFO, "Device %s completed %d of %d iterations",
- getDevice().getSerialNumber(), actualIterations+1, mIterations);
- }
- } finally {
- Map<String, String> metrics = new HashMap<String, String>(1);
- long durationMs = System.currentTimeMillis() - startTime;
- metrics.put("iterations", Integer.toString(actualIterations));
- metrics.put("shards", "1");
- listener.testRunEnded(durationMs, TfMetricProtoUtil.upgradeConvert(metrics));
- if (mLastKmsg != null) {
- listener.testLog(String.format("last_kmsg_%s", getDevice().getSerialNumber()),
- LogDataType.KERNEL_LOG,
- new ByteArrayInputStreamSource(mLastKmsg.getBytes()));
- }
- if (mDmesg != null) {
- listener.testLog(String.format("dmesg_%s", getDevice().getSerialNumber()),
- LogDataType.KERNEL_LOG, new ByteArrayInputStreamSource(mDmesg.getBytes()));
- }
- CLog.logAndDisplay(LogLevel.INFO, "Device %s completed %d of %d iterations",
- getDevice().getSerialNumber(), actualIterations, mIterations);
- }
- }
-
- private void executeFastbootWipeCommand() throws DeviceNotAvailableException {
- if (mFastbootWipeCmds.isEmpty()) {
- // default to use fastboot -w reboot
- mFastbootWipeCmds.add("-w reboot");
- }
- for (String fastbootCmd : mFastbootWipeCmds) {
- CLog.i("Running '%s'", fastbootCmd);
- CommandResult result = getDevice().executeFastbootCommand(fastbootCmd.split(" "));
- Assert.assertEquals(result.getStderr(), CommandStatus.SUCCESS, result.getStatus());
- }
- }
-
- /**
- * Perform wait between reboots. Perform periodic checks on device to ensure is still available.
- *
- * @throws DeviceNotAvailableException
- */
- private void doWaitAndCheck() throws DeviceNotAvailableException {
- long waitTimeMs = mWaitTime * 1000;
- long elapsedTime = 0;
-
- while (elapsedTime < waitTimeMs) {
- long startTime = System.currentTimeMillis();
- // ensure device is still up
- getDevice().waitForDeviceAvailable(DEVICE_AVAIL_TIME);
- checkForUserDataFailure();
- RunUtil.getDefault().sleep(mPollSleepTime * 1000);
- elapsedTime += System.currentTimeMillis() - startTime;
- }
- }
-
- /**
- * Check logs for userdata formatting/mounting issues.
- *
- * @throws DeviceNotAvailableException
- */
- private void checkForUserDataFailure() throws DeviceNotAvailableException {
- for (String path : LAST_KMSG_PATHS) {
- if (getDevice().doesFileExist(path)) {
- mLastKmsg = getDevice().executeShellCommand("cat " + path);
- Assert.assertFalse(String.format("Last kmsg log showed a kernel panic on %s",
- getDevice().getSerialNumber()), mLastKmsg.contains("Kernel panic"));
- break;
- }
- }
- mDmesg = getDevice().executeShellCommand("dmesg");
- Assert.assertFalse(String.format("Read only mount of userdata detected on %s",
- getDevice().getSerialNumber()),
- mDmesg.contains("Remounting filesystem read-only"));
- }
-}
diff --git a/prod-tests/src/com/android/tradefed/HelloWorldMultiDevices.java b/prod-tests/src/com/android/tradefed/HelloWorldMultiDevices.java
deleted file mode 100644
index 49d1030..0000000
--- a/prod-tests/src/com/android/tradefed/HelloWorldMultiDevices.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.tradefed;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.invoker.IInvocationContext;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.testtype.IInvocationContextReceiver;
-import com.android.tradefed.testtype.IMultiDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-
-import org.junit.Assert;
-
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Hello world example of Multiple Devices support in Trade Federation.
- * </p>
- * We implements the existing {@link IRemoteTest} interface to be a TradeFed Tests, and we can now
- * also implement the new {@link IMultiDeviceTest} to get all the device informations for our test.
- * OR you can implement {@link IInvocationContextReceiver} to get the full invocation metadata.
- * </p>
- * In this example we implement both but you should only implement one or the other.
- */
-public class HelloWorldMultiDevices implements IRemoteTest, IMultiDeviceTest,
- IInvocationContextReceiver {
-
- private Map<ITestDevice, IBuildInfo> mDevicesInfos;
- private IInvocationContext mContext;
-
- @Override
- public void setDeviceInfos(Map<ITestDevice, IBuildInfo> deviceInfos) {
- mDevicesInfos = deviceInfos;
- }
-
- @Override
- public void setInvocationContext(IInvocationContext invocationContext) {
- mContext = invocationContext;
- }
-
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- // This is going to iterate over all the devices in the configuration using the
- // {@link IMultiDeviceTest} interface
- for (Entry<ITestDevice, IBuildInfo> entry : mDevicesInfos.entrySet()) {
- CLog.i("Hello World! device '%s' with build id '%s'", entry.getKey().getSerialNumber(),
- entry.getValue().getBuildId());
- }
-
- // We can also use the IInvocationContext information, which have various functions to
- // access the ITestDevice or IBuildInfo.
- for (ITestDevice device : mContext.getDevices()) {
- CLog.i("Hello World! device '%s' from context with build '%s'",
- device.getSerialNumber(), mContext.getBuildInfo(device));
- }
-
- // We can do a look up by the device name in the configuration using the IInvocationContext
- for (String deviceName : mContext.getDeviceConfigNames()) {
- CLog.i(
- "device '%s' has the name '%s' in the config.",
- mContext.getDevice(deviceName).getSerialNumber(), deviceName);
- }
-
- // if the device name is known, doing a direct look up is possible.
- Assert.assertNotNull(mContext.getDevice("device1"));
- CLog.i(
- "device named device1 direct look up is '%s'",
- mContext.getDevice("device1").getSerialNumber());
- }
-}
diff --git a/prod-tests/src/com/android/tradefed/Sl4aBluetoothDiscovery.java b/prod-tests/src/com/android/tradefed/Sl4aBluetoothDiscovery.java
deleted file mode 100644
index 5dc1fc3..0000000
--- a/prod-tests/src/com/android/tradefed/Sl4aBluetoothDiscovery.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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.tradefed;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.testtype.IMultiDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.sl4a.Sl4aClient;
-import com.android.tradefed.util.sl4a.Sl4aEventDispatcher.EventSl4aObject;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.junit.Assert;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Bluetooth discovery test using Sl4A scripting layer to query some device APIs.
- */
-public class Sl4aBluetoothDiscovery implements IRemoteTest, IMultiDeviceTest {
-
- private ITestDevice mDut;
- private ITestDevice mDiscoverer;
- private Map<ITestDevice, IBuildInfo> mDevicesInfos;
-
- private static final String BLUETOOTH_NAME = "TEST_NAME";
-
- @Override
- public void setDeviceInfos(Map<ITestDevice, IBuildInfo> deviceInfos) {
- mDevicesInfos = deviceInfos;
- List<ITestDevice> listDevices = new ArrayList<>(mDevicesInfos.keySet());
- mDut = listDevices.get(0);
- mDiscoverer = listDevices.get(1);
- }
-
- /**
- * Setup the devices state before doing the actual test.
- *
- * @param clientDut sl4a client of the device under test (DUT)
- * @param clientDiscoverer sl4a client of the device doing the discovery of the DUT
- * @throws IOException
- */
- public void setup(Sl4aClient clientDut, Sl4aClient clientDiscoverer) throws IOException {
- clientDut.rpcCall("bluetoothToggleState", false);
- clientDut.getEventDispatcher().clearAllEvents();
- clientDut.rpcCall("bluetoothToggleState", true);
-
- clientDiscoverer.rpcCall("bluetoothToggleState", false);
- clientDiscoverer.getEventDispatcher().clearAllEvents();
- clientDiscoverer.rpcCall("bluetoothToggleState", true);
-
- EventSl4aObject response = clientDut.getEventDispatcher()
- .popEvent("BluetoothStateChangedOn", 20000);
- Assert.assertNotNull(response);
- response = clientDiscoverer.getEventDispatcher()
- .popEvent("BluetoothStateChangedOn", 20000);
- Assert.assertNotNull(response);
-
- Object rep = clientDut.rpcCall("bluetoothCheckState");
- Assert.assertEquals(true, rep);
-
- clientDut.rpcCall("bluetoothSetLocalName", BLUETOOTH_NAME);
- rep = clientDut.rpcCall("bluetoothGetLocalName");
- Assert.assertEquals(BLUETOOTH_NAME, rep);
- }
-
- @Override
- public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
- // We provide null path for the apk to assume it's already installed.
- Sl4aClient dutClient = Sl4aClient.startSL4A(mDut, null);
- Sl4aClient discovererClient = Sl4aClient.startSL4A(mDiscoverer, null);
-
- TestDescription testId =
- new TestDescription(this.getClass().getCanonicalName(), "bluetooth_discovery");
-
- long startTime = System.currentTimeMillis();
- listener.testRunStarted("sl4a_bluetooth", 1);
- listener.testStarted(testId);
-
- try {
- setup(dutClient, discovererClient);
- dutClient.rpcCall("bluetoothMakeDiscoverable");
- Object rep = dutClient.rpcCall("bluetoothGetScanMode");
- // 3 signifies CONNECTABLE and DISCOVERABLE
- Assert.assertEquals(3, rep);
-
- discovererClient.getEventDispatcher().clearAllEvents();
- discovererClient.rpcCall("bluetoothStartDiscovery");
- discovererClient.getEventDispatcher()
- .popEvent("BluetoothDiscoveryFinished", 60000);
- Object listDiscovered = discovererClient.rpcCall("bluetoothGetDiscoveredDevices");
- JSONArray response = (JSONArray) listDiscovered;
- boolean found = false;
- for (int i = 0; i < response.length(); i++) {
- JSONObject j = response.getJSONObject(i);
- if (j.has("name") && BLUETOOTH_NAME.equals(j.getString("name"))) {
- found = true;
- break;
- }
- }
- if (!found) {
- listener.testFailed(testId, "Did not find the bluetooth from DUT.");
- }
- } catch (IOException | JSONException e) {
- CLog.e(e);
- listener.testFailed(testId, "Exception " + e);
- } finally {
- listener.testEnded(testId, new HashMap<String, Metric>());
- listener.testRunEnded(
- System.currentTimeMillis() - startTime, new HashMap<String, Metric>());
- dutClient.close();
- discovererClient.close();
- }
- }
-}
diff --git a/prod-tests/src/com/android/tradefed/presubmit/DeviceTestsConfigValidation.java b/prod-tests/src/com/android/tradefed/presubmit/DeviceTestsConfigValidation.java
deleted file mode 100644
index aa94674..0000000
--- a/prod-tests/src/com/android/tradefed/presubmit/DeviceTestsConfigValidation.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tradefed.presubmit;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.IDeviceBuildInfo;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.ConfigurationFactory;
-import com.android.tradefed.config.ConfigurationUtil;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationFactory;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.suite.ValidateSuiteConfigHelper;
-
-import com.google.common.base.Joiner;
-
-import org.junit.Assume;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Validation tests to run against the configuration in device-tests.zip to ensure they can all
- * parse.
- *
- * <p>Do not add to UnitTests.java. This is meant to run standalone.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class DeviceTestsConfigValidation implements IBuildReceiver {
-
- private IBuildInfo mBuild;
-
- @Override
- public void setBuild(IBuildInfo buildInfo) {
- mBuild = buildInfo;
- }
-
- /** Get all the configuration copied to the build tests dir and check if they load. */
- @Test
- public void testConfigsLoad() throws Exception {
- List<String> errors = new ArrayList<>();
- Assume.assumeTrue(mBuild instanceof IDeviceBuildInfo);
-
- IConfigurationFactory configFactory = ConfigurationFactory.getInstance();
- List<File> configs = new ArrayList<>();
- IDeviceBuildInfo deviceBuildInfo = (IDeviceBuildInfo) mBuild;
- File testsDir = deviceBuildInfo.getTestsDir();
- List<File> extraTestCasesDirs = Arrays.asList(testsDir);
- // Only load the .config as .xml might be data in device-tests.zip case.
- configs.addAll(
- ConfigurationUtil.getConfigNamesFileFromDirs(
- null, extraTestCasesDirs, Arrays.asList(".*\\.config$")));
- for (File config : configs) {
- try {
- IConfiguration c =
- configFactory.createConfigurationFromArgs(
- new String[] {config.getAbsolutePath()});
- // All configurations in device-tests.zip should be module since they are generated
- // from AndroidTest.xml
- ValidateSuiteConfigHelper.validateConfig(c);
- // Add more checks if necessary
- } catch (ConfigurationException e) {
- errors.add(String.format("\t%s: %s", config.getName(), e.getMessage()));
- }
- }
-
- // If any errors report them in a final exception.
- if (!errors.isEmpty()) {
- throw new ConfigurationException(
- String.format("Fail configuration check:\n%s", Joiner.on("\n").join(errors)));
- }
- }
-}
diff --git a/prod-tests/src/com/android/tradefed/presubmit/GeneralTestsConfigValidation.java b/prod-tests/src/com/android/tradefed/presubmit/GeneralTestsConfigValidation.java
deleted file mode 100644
index 3c56ea0..0000000
--- a/prod-tests/src/com/android/tradefed/presubmit/GeneralTestsConfigValidation.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.tradefed.presubmit;
-
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.build.IDeviceBuildInfo;
-import com.android.tradefed.config.ConfigurationException;
-import com.android.tradefed.config.ConfigurationFactory;
-import com.android.tradefed.config.ConfigurationUtil;
-import com.android.tradefed.config.IConfiguration;
-import com.android.tradefed.config.IConfigurationFactory;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.suite.ValidateSuiteConfigHelper;
-
-import com.google.common.base.Joiner;
-
-import org.junit.Assume;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Validation tests to run against the configuration in general-tests.zip to ensure they can all
- * parse.
- *
- * <p>Do not add to UnitTests.java. This is meant to run standalone.
- */
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class GeneralTestsConfigValidation implements IBuildReceiver {
-
- private IBuildInfo mBuild;
-
- @Override
- public void setBuild(IBuildInfo buildInfo) {
- mBuild = buildInfo;
- }
-
- /** Get all the configuration copied to the build tests dir and check if they load. */
- @Test
- public void testConfigsLoad() throws Exception {
- List<String> errors = new ArrayList<>();
- Assume.assumeTrue(mBuild instanceof IDeviceBuildInfo);
-
- IConfigurationFactory configFactory = ConfigurationFactory.getInstance();
- List<String> configs = new ArrayList<>();
- IDeviceBuildInfo deviceBuildInfo = (IDeviceBuildInfo) mBuild;
- File testsDir = deviceBuildInfo.getTestsDir();
- List<File> extraTestCasesDirs = Arrays.asList(testsDir);
- configs.addAll(ConfigurationUtil.getConfigNamesFromDirs(null, extraTestCasesDirs));
- for (String configName : configs) {
- try {
- IConfiguration c =
- configFactory.createConfigurationFromArgs(new String[] {configName});
- // All configurations in general-tests.zip should be module since they are generated
- // from AndroidTest.xml
- ValidateSuiteConfigHelper.validateConfig(c);
- // Add more checks if necessary
- } catch (ConfigurationException e) {
- errors.add(String.format("\t%s: %s", configName, e.getMessage()));
- }
- }
-
- // If any errors report them in a final exception.
- if (!errors.isEmpty()) {
- throw new ConfigurationException(
- String.format("Fail configuration check:\n%s", Joiner.on("\n").join(errors)));
- }
- }
-}
diff --git a/prod-tests/src/com/android/wireless/tests/RadioHelper.java b/prod-tests/src/com/android/wireless/tests/RadioHelper.java
deleted file mode 100644
index 2b57de6..0000000
--- a/prod-tests/src/com/android/wireless/tests/RadioHelper.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2011 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.wireless.tests;
-
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.util.IRunUtil;
-import com.android.tradefed.util.RunUtil;
-
-/**
- * Helper class to get device radio settings
- */
-public class RadioHelper {
- private static final String[] PING_SERVER_LIST = {
- "www.google.com", "www.facebook.com", "www.bing.com", "www.ask.com", "www.yahoo.com"
- };
- private static final int RETRY_ATTEMPTS = 3;
- private static final int ACTIVATION_WAITING_TIME = 5 * 60 * 1000; // 5 minutes;
- private static final String WIFI_ONLY = "wifi-only";
- /* Maximum time to wait for device to connect to data network */
- public static final int MAX_DATA_SETUP_TIME = 3 * 60 * 1000; // 3 minutes
- private ITestDevice mDevice;
-
- RadioHelper(ITestDevice device) {
- mDevice = device;
- }
-
- /**
- * Gets the {@link IRunUtil} instance to use.
- */
- IRunUtil getRunUtil() {
- return RunUtil.getDefault();
- }
-
- /**
- * Get phone type 0 - None, 1 - GSM, 2 - CDMA
- */
- private String getPhoneType() throws DeviceNotAvailableException {
- return mDevice.getProperty("gsm.current.phone-type");
- }
-
- /**
- * Get sim state
- */
- private String getSimState() throws DeviceNotAvailableException {
- return mDevice.getProperty("gsm.sim.state");
- }
-
- /**
- * Verify whether a device is a CDMA only device
- * @return true for CDMA only device, false for GSM or LTE device
- * @throws DeviceNotAvailableException
- */
- public boolean isCdmaDevice() throws DeviceNotAvailableException {
- // Wait 30 seconds for SIM to load
- getRunUtil().sleep(30*1000);
- String phoneType = null;
- String simState = null;
- for (int i = 0; i < RETRY_ATTEMPTS && (phoneType == null || simState == null); i++) {
- phoneType = getPhoneType();
- simState = getSimState();
- CLog.d("phonetype: %s", phoneType);
- CLog.d("gsm.sim.state: %s", simState);
- RunUtil.getDefault().sleep(5 * 1000);
- }
-
- if (phoneType == null || simState == null) {
- CLog.d("Error: phoneType or simState is null.");
- return false;
- }
-
- if ((phoneType.compareToIgnoreCase("2") == 0) &&
- (simState.compareToIgnoreCase("UNKNOWN") == 0)) {
- // GSM device as phoneType "1"
- // LTE device should have SIM state set to "READY"
- CLog.d("it is a CDMA device, return true");
- return true;
- }
- return false;
- }
-
- /**
- * Verify whether a device is a Wi-Fi only device (e.g. Wingray)
- */
- public boolean isWifiOnlyDevice() throws DeviceNotAvailableException {
- return mDevice.getProperty("ro.carrier").contains(WIFI_ONLY);
- }
-
- public void resetBootComplete() throws DeviceNotAvailableException {
- mDevice.executeShellCommand("setprop dev.bootcomplete 0");
- }
-
- public boolean pingTest() throws DeviceNotAvailableException {
- String failString = "ping: unknown host";
- // assume the chance that all servers are down is very small
- for (int i = 0; i < PING_SERVER_LIST.length; i++ ) {
- String host = PING_SERVER_LIST[i];
- CLog.d("Start ping test, ping %s", host);
- String res = mDevice.executeShellCommand("ping -c 10 -w 100 " + host);
- if (!res.contains(failString)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Activate a device if it is needed.
- * @return true if the activation is successful.
- * @throws DeviceNotAvailableException
- */
- public boolean radioActivation() throws DeviceNotAvailableException {
- if (isWifiOnlyDevice()) {
- return true;
- }
- if (!isCdmaDevice()) {
- // for GSM device and LTE device
- CLog.d("not a CDMA device, no need to activiate the device");
- return true;
- } else if (pingTest()) {
- // for CDMA device which has been activiated (e.g. no radio updates)
- CLog.d("CDMA device has been activated.");
- return true;
- }
-
- // Activate a CDMA device which doesn't have data connection yet
- for (int i = 0; i < RETRY_ATTEMPTS; i++ ) {
- mDevice.executeShellCommand("radiooptions 8 *22899");
- long startTime = System.currentTimeMillis();
- while ((System.currentTimeMillis() - startTime) < ACTIVATION_WAITING_TIME) {
- getRunUtil().sleep(30 * 1000);
- if (pingTest()) {
- return true;
- }
- }
- }
- return false;
- }
-
- /**
- * Wait for device data setup
- *
- * @return true if data setup succeeded, false otherwise
- */
- public boolean waitForDataSetup() throws DeviceNotAvailableException {
- long startTime = System.currentTimeMillis();
- while ((System.currentTimeMillis() - startTime) < MAX_DATA_SETUP_TIME) {
- getRunUtil().sleep(30 * 1000);
- if (pingTest()) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/prod-tests/src/com/android/wireless/tests/WifiStressTest.java b/prod-tests/src/com/android/wireless/tests/WifiStressTest.java
deleted file mode 100644
index ddce045..0000000
--- a/prod-tests/src/com/android/wireless/tests/WifiStressTest.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * Copyright (C) 2011 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.wireless.tests;
-
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
-import com.android.tradefed.config.Option;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.result.BugreportCollector;
-import com.android.tradefed.result.FileInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.InputStreamSource;
-import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.FileUtil;
-import com.android.tradefed.util.RegexTrie;
-import com.android.tradefed.util.RunUtil;
-import com.android.tradefed.util.StreamUtil;
-import com.android.tradefed.util.proto.TfMetricProtoUtil;
-
-import org.junit.Assert;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Run the WiFi stress tests. This test stresses WiFi soft ap, WiFi scanning
- * and WiFi reconnection in which device switches between cellular and WiFi connection.
- */
-public class WifiStressTest implements IRemoteTest, IDeviceTest {
- private ITestDevice mTestDevice = null;
- private static final long START_TIMER = 5 * 60 * 1000; //5 minutes
- // Define instrumentation test package and runner.
- private static final String TEST_PACKAGE_NAME = "com.android.connectivitymanagertest";
- private static final String TEST_RUNNER_NAME = ".ConnectivityManagerStressTestRunner";
-
- private static final Pattern ITERATION_PATTERN =
- Pattern.compile("^iteration (\\d+) out of (\\d+)");
- private static final int AP_TEST_TIMER = 3 * 60 * 60 * 1000; // 3 hours
- private static final int SCAN_TEST_TIMER = 30 * 60 * 1000; // 30 minutes
- private static final int RECONNECT_TEST_TIMER = 12 * 60 * 60 * 1000; // 12 hours
-
- private String mOutputFile = "WifiStressTestOutput.txt";
-
- /**
- * Stores the test cases that we should consider running.
- * <p/>
- * This currently consists of "ap", "scanning", and "reconnection" tests.
- */
- private List<TestInfo> mTestList = null;
-
- private static class TestInfo {
- public String mTestName = null;
- public String mTestClass = null;
- public String mTestMethod = null;
- public String mTestMetricsName = null;
- public int mTestTimer;
- public RegexTrie<String> mPatternMap = null;
-
- @Override
- public String toString() {
- return String.format("TestInfo: mTestName(%s), mTestClass(%s), mTestMethod(%s)," +
- " mTestMetricsName(%s), mPatternMap(%s), mTestTimer(%d)", mTestName,
- mTestClass, mTestMethod, mTestMetricsName, mPatternMap.toString(), mTestTimer);
- }
- }
-
- @Option(
- name = "ap-iteration",
- description = "The number of iterations to run soft ap stress test"
- )
- private String mApIteration = "0";
-
- @Option(name="idle-time",
- description="The device idle time after screen off")
- private String mIdleTime = "30"; // 30 seconds
-
- @Option(name="reconnect-iteration",
- description="The number of iterations to run WiFi reconnection stress test")
- private String mReconnectionIteration = "100";
-
- @Option(name="reconnect-password",
- description="The password for the above ssid in WiFi reconnection stress test")
- private String mReconnectionPassword = "androidwifi";
-
- @Option(name="reconnect-ssid",
- description="The ssid for WiFi recoonection stress test")
- private String mReconnectionSsid = "securenetdhcp";
-
- @Option(name="reconnection-test",
- description="Option to run the wifi reconnection stress test")
- private boolean mReconnectionTestFlag = true;
-
- @Option(name="scan-iteration",
- description="The number of iterations to run WiFi scanning test")
- private String mScanIteration = "100";
-
- @Option(name="scan-test",
- description="Option to run the scan stress test")
- private boolean mScanTestFlag = true;
-
- @Option(name="skip-set-device-screen-timeout",
- description="Option to skip screen timeout configuration")
- private boolean mSkipSetDeviceScreenTimeout = false;
-
- @Option(name="tether-test",
- description="Option to run the tethering stress test")
- private boolean mTetherTestFlag = true;
-
- @Option(name="wifi-only")
- private boolean mWifiOnly = false;
-
- private void setupTests() {
- if (mTestList != null) {
- return;
- }
- mTestList = new ArrayList<>(3);
-
- // Add WiFi scanning test
- TestInfo t = new TestInfo();
- t.mTestName = "WifiScanning";
- t.mTestClass = "com.android.connectivitymanagertest.stress.WifiStressTest";
- t.mTestMethod = "testWifiScanning";
- t.mTestMetricsName = "wifi_scan_performance";
- t.mTestTimer = SCAN_TEST_TIMER;
- t.mPatternMap = new RegexTrie<>();
- t.mPatternMap.put("avg_scan_time", "^average scanning time is (\\d+)");
- t.mPatternMap.put("scan_quality","ssid appear (\\d+) out of (\\d+) scan iterations");
- if (mScanTestFlag) {
- mTestList.add(t);
- }
-
- // Add WiFi reconnection test
- t = new TestInfo();
- t.mTestName = "WifiReconnectionStress";
- t.mTestClass = "com.android.connectivitymanagertest.stress.WifiStressTest";
- t.mTestMethod = "testWifiReconnectionAfterSleep";
- t.mTestMetricsName = "wifi_stress";
- t.mTestTimer = RECONNECT_TEST_TIMER;
- t.mPatternMap = new RegexTrie<>();
- t.mPatternMap.put("wifi_reconnection_stress", ITERATION_PATTERN);
- if (mReconnectionTestFlag) {
- mTestList.add(t);
- }
- }
-
- /**
- * Configure screen timeout property
- * @throws DeviceNotAvailableException
- */
- private void setDeviceScreenTimeout() throws DeviceNotAvailableException {
- // Set device screen_off_timeout as svc power can be set to false in the Wi-Fi test
- String command = ("sqlite3 /data/data/com.android.providers.settings/databases/settings.db "
- + "\"UPDATE system SET value=\'600000\' WHERE name=\'screen_off_timeout\';\"");
- CLog.d("Command to set screen timeout value to 10 minutes: %s", command);
- mTestDevice.executeShellCommand(command);
-
- // reboot to allow the setting to take effect, post setup will be taken care by the reboot
- mTestDevice.reboot();
- }
-
- /**
- * Enable/disable screen never timeout property
- * @param on
- * @throws DeviceNotAvailableException
- */
- private void setScreenProperty(boolean on) throws DeviceNotAvailableException {
- CLog.d("set svc power stay on " + on);
- mTestDevice.executeShellCommand("svc power stayon " + on);
- }
-
- @Override
- public void setDevice(ITestDevice testDevice) {
- mTestDevice = testDevice;
- }
-
- @Override
- public ITestDevice getDevice() {
- return mTestDevice;
- }
-
- /**
- * Run the Wi-Fi stress test
- * Collect results and post results to dashboard
- */
- @Override
- public void run(ITestInvocationListener standardListener)
- throws DeviceNotAvailableException {
- Assert.assertNotNull(mTestDevice);
- setupTests();
- if (!mSkipSetDeviceScreenTimeout) {
- setDeviceScreenTimeout();
- }
- RunUtil.getDefault().sleep(START_TIMER);
-
- if (!mWifiOnly) {
- final RadioHelper radioHelper = new RadioHelper(mTestDevice);
- Assert.assertTrue("Radio activation failed", radioHelper.radioActivation());
- Assert.assertTrue("Data setup failed", radioHelper.waitForDataSetup());
- }
-
- IRemoteAndroidTestRunner runner = new RemoteAndroidTestRunner(
- TEST_PACKAGE_NAME, TEST_RUNNER_NAME, mTestDevice.getIDevice());
- runner.addInstrumentationArg("softap_iterations", mApIteration);
- runner.addInstrumentationArg("scan_iterations", mScanIteration);
- runner.addInstrumentationArg("reconnect_iterations", mReconnectionIteration);
- runner.addInstrumentationArg("reconnect_ssid", mReconnectionSsid);
- runner.addInstrumentationArg("reconnect_password", mReconnectionPassword);
- runner.addInstrumentationArg("sleep_time", mIdleTime);
- if (mWifiOnly) {
- runner.addInstrumentationArg("wifi-only", String.valueOf(mWifiOnly));
- }
-
- // Add bugreport listener for failed test
- BugreportCollector bugListener = new
- BugreportCollector(standardListener, mTestDevice);
- bugListener.addPredicate(BugreportCollector.AFTER_FAILED_TESTCASES);
- // Device may reboot during the test, to capture a bugreport after that,
- // wait for 30 seconds for device to be online, otherwise, bugreport will be empty
- bugListener.setDeviceWaitTime(30);
-
- for (TestInfo testCase : mTestList) {
- // for Wi-Fi reconnection test,
- if ("WifiReconnectionStress".equals(testCase.mTestName)) {
- setScreenProperty(false);
- } else {
- setScreenProperty(true);
- }
- CLog.d("TestInfo: " + testCase.toString());
- runner.setClassName(testCase.mTestClass);
- runner.setMethodName(testCase.mTestClass, testCase.mTestMethod);
- runner.setMaxTimeToOutputResponse(testCase.mTestTimer, TimeUnit.MILLISECONDS);
- bugListener.setDescriptiveName(testCase.mTestName);
- mTestDevice.runInstrumentationTests(runner, bugListener);
- logOutputFile(testCase, bugListener);
- cleanOutputFiles();
- }
- }
-
- /**
- * Collect test results, report test results to dash board.
- *
- * @param test
- * @param listener
- */
- private void logOutputFile(TestInfo test, ITestInvocationListener listener)
- throws DeviceNotAvailableException {
- File resFile = null;
- InputStreamSource outputSource = null;
-
- try {
- resFile = mTestDevice.pullFileFromExternal(mOutputFile);
- if (resFile != null) {
- // Save a copy of the output file
- CLog.d("Sending %d byte file %s into the logosphere!",
- resFile.length(), resFile);
- outputSource = new FileInputStreamSource(resFile);
- listener.testLog(String.format("result-%s.txt", test.mTestName), LogDataType.TEXT,
- outputSource);
-
- // Parse the results file and post results to test listener
- parseOutputFile(test, resFile, listener);
- }
- } finally {
- FileUtil.deleteFile(resFile);
- StreamUtil.cancel(outputSource);
- }
- }
-
- private void parseOutputFile(TestInfo test, File dataFile,
- ITestInvocationListener listener) {
- Map<String, String> runMetrics = new HashMap<>();
- Map<String, String> runScanMetrics = null;
- boolean isScanningTest = "WifiScanning".equals(test.mTestName);
- Integer iteration = null;
- BufferedReader br = null;
- try {
- br = new BufferedReader(new FileReader(dataFile));
- String line = null;
- while ((line = br.readLine()) != null) {
- List<List<String>> capture = new ArrayList<>(1);
- String key = test.mPatternMap.retrieve(capture, line);
- if (key != null) {
- CLog.d("In output file of test case %s: retrieve key: %s, " +
- "catpure: %s", test.mTestName, key, capture.toString());
- //Save results in the metrics
- if ("scan_quality".equals(key)) {
- // For scanning test, calculate the scan quality
- int count = Integer.parseInt(capture.get(0).get(0));
- int total = Integer.parseInt(capture.get(0).get(1));
- int quality = 0;
- if (total != 0) {
- quality = (100 * count) / total;
- }
- runMetrics.put(key, Integer.toString(quality));
- } else {
- runMetrics.put(key, capture.get(0).get(0));
- }
- } else {
- // For scanning test, iterations will also be counted.
- if (isScanningTest) {
- Matcher m = ITERATION_PATTERN.matcher(line);
- if (m.matches()) {
- iteration = Integer.parseInt(m.group(1));
- }
- }
- }
- }
- if (isScanningTest) {
- runScanMetrics = new HashMap<>(1);
- if (iteration == null) {
- // no matching is found
- CLog.d("No iteration logs found in %s, set to 0", mOutputFile);
- iteration = Integer.valueOf(0);
- }
- runScanMetrics.put("wifi_scan_stress", iteration.toString());
- }
-
- // Report results
- reportMetrics(test.mTestMetricsName, listener, runMetrics);
- if (isScanningTest) {
- reportMetrics("wifi_stress", listener, runScanMetrics);
- }
- } catch (IOException e) {
- CLog.e("IOException while reading from data stream");
- CLog.e(e);
- return;
- } finally {
- StreamUtil.close(br);
- }
- }
-
- /**
- * Report run metrics by creating an empty test run to stick them in
- * <p />
- * Exposed for unit testing
- */
- private void reportMetrics(String metricsName, ITestInvocationListener listener,
- Map<String, String> metrics) {
- // Create an empty testRun to report the parsed runMetrics
- CLog.d("About to report metrics to %s: %s", metricsName, metrics);
- listener.testRunStarted(metricsName, 0);
- listener.testRunEnded(0, TfMetricProtoUtil.upgradeConvert(metrics));
- }
-
- /**
- * Clean up output files from the last test run
- */
- private void cleanOutputFiles() throws DeviceNotAvailableException {
- CLog.d("Remove output file: %s", mOutputFile);
- String extStore = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
- mTestDevice.executeShellCommand(String.format("rm %s/%s", extStore, mOutputFile));
- }
-}
diff --git a/prod-tests/tests/.classpath b/prod-tests/tests/.classpath
deleted file mode 100644
index c472a9c..0000000
--- a/prod-tests/tests/.classpath
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="src" path="easymock"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry combineaccessrules="false" kind="src" path="/tf-prod-tests"/>
- <classpathentry combineaccessrules="false" kind="src" path="/tradefederation"/>
- <classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/>
- <classpathentry kind="var" path="TRADEFED_ROOT/out/host/common/obj/JAVA_LIBRARIES/host-libprotobuf-java-full_intermediates/classes.jar"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/prod-tests/tests/.project b/prod-tests/tests/.project
deleted file mode 100644
index b371502..0000000
--- a/prod-tests/tests/.project
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>tf-prod-tests-tests</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
- <linkedResources>
- <link>
- <name>easymock</name>
- <type>2</type>
- <location>TRADEFED_ROOT/external/easymock/src</location>
- </link>
- </linkedResources>
-</projectDescription>
diff --git a/prod-tests/tests/Android.mk b/prod-tests/tests/Android.mk
deleted file mode 100644
index cc059be..0000000
--- a/prod-tests/tests/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2012 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# Only compile source java files in this lib.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-#LOCAL_JAVA_RESOURCE_DIRS := res
-
-LOCAL_JAVACFLAGS += -g -Xlint
-
-LOCAL_MODULE := tf-prod-metatests
-LOCAL_MODULE_TAGS := optional
-LOCAL_JAVA_LIBRARIES := tradefed tf-prod-tests easymock
-
-LOCAL_JAR_MANIFEST := MANIFEST.mf
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# makefile rules to copy jars to HOST_OUT/tradefed
-# so tradefed.sh can automatically add to classpath
-
-DEST_JAR := $(HOST_OUT)/tradefed/$(LOCAL_MODULE).jar
-$(DEST_JAR): $(LOCAL_BUILT_MODULE)
- $(copy-file-to-new-target)
-
-# this dependency ensure the above rule will be executed if module is built
-$(LOCAL_INSTALLED_MODULE) : $(DEST_JAR)
-
-# Build all sub-directories
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/prod-tests/tests/MANIFEST.mf b/prod-tests/tests/MANIFEST.mf
deleted file mode 100644
index 19d17b0..0000000
--- a/prod-tests/tests/MANIFEST.mf
+++ /dev/null
@@ -1,2 +0,0 @@
-Manifest-Version: 1.0
-Implementation-Version: default
diff --git a/prod-tests/tests/src/com/android/build/tests/ImageStatsTest.java b/prod-tests/tests/src/com/android/build/tests/ImageStatsTest.java
deleted file mode 100644
index c8b8885..0000000
--- a/prod-tests/tests/src/com/android/build/tests/ImageStatsTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2018 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.build.tests;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.io.ByteArrayInputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Unit tests for {@link ImageStats}
- */
-@RunWith(JUnit4.class)
-public class ImageStatsTest {
-
- // data obtained from build 4597696, taimen-userdebug_fastbuild_linux
- private static final String TEST_DATA =
- " 164424453 /system/app/WallpapersBReel2017/WallpapersBReel2017.apk\n"
- + " 124082279 /system/app/Chrome/Chrome.apk\n"
- + " 92966112 /system/priv-app/Velvet/Velvet.apk\n"
- + " 1790897 /system/framework/ext.jar\n"
- + " 505436 /system/fonts/NotoSansEgyptianHieroglyphs-Regular.ttf\n"
- + " 500448 /system/bin/ip6tables\n"
- + " 500393 /system/usr/share/zoneinfo/tzdata\n"
- + " 500380 /system/fonts/NotoSansCuneiform-Regular.ttf\n"
- + " 126391 /system/framework/core-oj.jar\n"
- + " 122641 /system/framework/com.quicinc.cne.jar\n";
- private static final Map<String, Long> PARSED_TEST_DATA = new HashMap<>();
- static {
- PARSED_TEST_DATA.put("/system/app/WallpapersBReel2017/WallpapersBReel2017.apk",
- 164424453L);
- PARSED_TEST_DATA.put("/system/app/Chrome/Chrome.apk",
- 124082279L);
- PARSED_TEST_DATA.put("/system/priv-app/Velvet/Velvet.apk",
- 92966112L);
- PARSED_TEST_DATA.put("/system/framework/ext.jar",
- 1790897L);
- PARSED_TEST_DATA.put("/system/fonts/NotoSansEgyptianHieroglyphs-Regular.ttf",
- 505436L);
- PARSED_TEST_DATA.put("/system/bin/ip6tables",
- 500448L);
- PARSED_TEST_DATA.put("/system/usr/share/zoneinfo/tzdata",
- 500393L);
- PARSED_TEST_DATA.put("/system/fonts/NotoSansCuneiform-Regular.ttf",
- 500380L);
- PARSED_TEST_DATA.put("/system/framework/core-oj.jar",
- 126391L);
- PARSED_TEST_DATA.put("/system/framework/com.quicinc.cne.jar",
- 122641L);
- }
-
- private ImageStats mImageStats = null;
-
- @Before
- public void setup() throws Exception {
- mImageStats = new ImageStats();
- }
-
- @Test
- public void testParseFileSizes() throws Exception {
- Map<String, Long> ret = mImageStats.parseFileSizes(
- new ByteArrayInputStream(TEST_DATA.getBytes()));
- Assert.assertEquals("parsed test file sizes mismatches expectations",
- PARSED_TEST_DATA, ret);
- }
-
- /** Verifies that regular matching pattern without capturing group works as expected */
- @Test
- public void testGetAggregationLabel_regular() throws Exception {
- String fileName = "/system/app/WallpapersBReel2017/WallpapersBReel2017.apk";
- Pattern pattern = Pattern.compile("^.+\\.apk$");
- final String label = "foobar";
- Assert.assertEquals("unexpected label transformation output",
- label, mImageStats.getAggregationLabel(pattern.matcher(fileName), label));
- }
-
- /** Verifies that matching pattern with corresponding capturing groups works as expected */
- @Test
- public void testGetAggregationLabel_capturingGroups() throws Exception {
- String fileName = "/system/app/WallpapersBReel2017/WallpapersBReel2017.apk";
- Pattern pattern = Pattern.compile("^/system/(.+?)/.+\\.(.+)$");
- final String label = "folder-\\1-ext-\\2";
- Matcher m = pattern.matcher(fileName);
- Assert.assertTrue("this shouldn't fail unless test case isn't written correctly",
- m.matches());
- Assert.assertEquals("unexpected label transformation output",
- "folder-app-ext-apk",
- mImageStats.getAggregationLabel(m, label));
- }
-
- /**
- * Verifies that matching pattern with capturing groups but partial back references works
- * as expected
- **/
- @Test
- public void testGetAggregationLabel_capturingGroups_partialBackReference() throws Exception {
- String fileName = "/system/app/WallpapersBReel2017/WallpapersBReel2017.apk";
- Pattern pattern = Pattern.compile("^/system/(.+?)/.+\\.(.+)$");
- final String label = "ext-\\2";
- Matcher m = pattern.matcher(fileName);
- Assert.assertTrue("this shouldn't fail unless test case isn't written correctly",
- m.matches());
- Assert.assertEquals("unexpected label transformation output",
- "ext-apk",
- mImageStats.getAggregationLabel(m, label));
- }
-
- /**
- * Verifies that aggregating the sample input with patterns works as expected
- */
- @Test
- public void testPerformAggregation() throws Exception {
- Map<Pattern, String> mapping = new HashMap<>();
- mapping.put(Pattern.compile("^.+\\.(.+)"), "ext-\\1"); // aggregate by extension
- mapping.put(Pattern.compile("^/system/(.+?)/.+$"), "folder-\\1"); // aggregate by folder
- Map<String, String> ret = mImageStats.performAggregation(PARSED_TEST_DATA, mapping);
- Assert.assertEquals("failed to verify aggregated size for category 'ext-apk'",
- "381472844", ret.get("ext-apk"));
- Assert.assertEquals("failed to verify aggregated size for category 'ext-jar'",
- "2039929", ret.get("ext-jar"));
- Assert.assertEquals("failed to verify aggregated size for category 'ext-ttf'",
- "1005816", ret.get("ext-ttf"));
- Assert.assertEquals("failed to verify aggregated size for category 'uncategorized'",
- "0", ret.get("uncategorized"));
- Assert.assertEquals("failed to verify aggregated size for category 'total'",
- "385519430", ret.get("total"));
- }
-}
diff --git a/prod-tests/tests/src/com/android/continuous/SmokeTestFailureReporterTest.java b/prod-tests/tests/src/com/android/continuous/SmokeTestFailureReporterTest.java
deleted file mode 100644
index c05f938..0000000
--- a/prod-tests/tests/src/com/android/continuous/SmokeTestFailureReporterTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2012 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.continuous;
-
-import com.android.tradefed.build.BuildInfo;
-import com.android.tradefed.build.IBuildInfo;
-import com.android.tradefed.invoker.IInvocationContext;
-import com.android.tradefed.invoker.InvocationContext;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
-import com.android.tradefed.result.TestDescription;
-import com.android.tradefed.util.IEmail;
-import com.android.tradefed.util.IEmail.Message;
-
-import junit.framework.TestCase;
-
-import org.easymock.Capture;
-import org.easymock.EasyMock;
-
-import java.util.HashMap;
-
-/** Unit tests for {@link SmokeTestFailureReporter} */
-public class SmokeTestFailureReporterTest extends TestCase {
- private SmokeTestFailureReporter mReporter = null;
- private IEmail mMailer = null;
-
- private static final String TAG = "DeviceSmokeTests";
- private static final String BID = "123456";
- private static final String TARGET = "target?";
- private static final String FLAVOR = "generic-userdebug";
- private static final String BRANCH = "git_master";
-
- @Override
- public void setUp() {
- mMailer = EasyMock.createMock(IEmail.class);
- mReporter = new SmokeTestFailureReporter(mMailer);
- }
-
- public void testSingleFail() throws Exception {
- final String expSubject =
- "DeviceSmokeTests SmokeFAST failed on: BuildInfo{bid=123456, "
- + "target=target?, build_flavor=generic-userdebug, branch=git_master}";
- final String expBodyStart = "FooTest#testFoo failed\nStack trace:\nthis is a trace\n";
-
- final HashMap<String, Metric> emptyMap = new HashMap<>();
- final TestDescription testId = new TestDescription("FooTest", "testFoo");
- final String trace = "this is a trace";
-
- final Capture<Message> msgCapture = new Capture<Message>();
- mMailer.send(EasyMock.capture(msgCapture));
- EasyMock.replay(mMailer);
-
- final IBuildInfo build = new BuildInfo(BID, TARGET);
- build.setBuildFlavor(FLAVOR);
- build.setBuildBranch(BRANCH);
- IInvocationContext context = new InvocationContext();
- context.addDeviceBuildInfo("serial", build);
- context.setTestTag(TAG);
-
- mReporter.addDestination("dest.ination@email.com");
- mReporter.invocationStarted(context);
- mReporter.testRunStarted("testrun", 1);
- mReporter.testStarted(testId);
- mReporter.testFailed(testId, trace);
- mReporter.testEnded(testId, emptyMap);
- mReporter.testRunEnded(2, emptyMap);
- mReporter.invocationEnded(1);
-
- EasyMock.verify(mMailer);
-
- assertTrue(msgCapture.hasCaptured());
- final Message msg = msgCapture.getValue();
- final String subj = msg.getSubject();
- final String body = msg.getBody();
- CLog.i("subject: %s", subj);
- CLog.i("body:\n%s", body);
- assertEquals(expSubject, subj);
- assertTrue(String.format(
- "Expected body to start with \"\"\"%s\"\"\". Body was actually: %s\n",
- expBodyStart, body), body.startsWith(expBodyStart));
-
- }
-
- public void testTwoPassOneFail() throws Exception {
- final String expSubject =
- "DeviceSmokeTests SmokeFAST failed on: BuildInfo{bid=123456, "
- + "target=target?, build_flavor=generic-userdebug, branch=git_master}";
- final String expBodyStart = "FooTest#testFail failed\nStack trace:\nthis is a trace\n";
-
- final HashMap<String, Metric> emptyMap = new HashMap<>();
- final String trace = "this is a trace";
- final TestDescription testFail = new TestDescription("FooTest", "testFail");
- final TestDescription testPass1 = new TestDescription("FooTest", "testPass1");
- final TestDescription testPass2 = new TestDescription("FooTest", "testPass2");
-
- final Capture<Message> msgCapture = new Capture<Message>();
- mMailer.send(EasyMock.capture(msgCapture));
- EasyMock.replay(mMailer);
-
- IBuildInfo build = new BuildInfo(BID, TARGET);
- build.setBuildFlavor(FLAVOR);
- build.setBuildBranch(BRANCH);
- IInvocationContext context = new InvocationContext();
- context.addDeviceBuildInfo("serial", build);
- context.setTestTag(TAG);
-
- mReporter.addDestination("dest.ination@email.com");
- mReporter.invocationStarted(context);
- mReporter.testRunStarted("testrun", 1);
- mReporter.testStarted(testPass1);
- mReporter.testEnded(testPass1, emptyMap);
-
- mReporter.testStarted(testFail);
- mReporter.testFailed(testFail, trace);
- mReporter.testEnded(testFail, emptyMap);
-
- mReporter.testStarted(testPass2);
- mReporter.testEnded(testPass2, emptyMap);
- mReporter.testRunEnded(2, emptyMap);
- mReporter.invocationEnded(1);
-
- EasyMock.verify(mMailer);
-
- assertTrue(msgCapture.hasCaptured());
- final Message msg = msgCapture.getValue();
- final String subj = msg.getSubject();
- final String body = msg.getBody();
- CLog.i("subject: %s", subj);
- CLog.i("body:\n%s", body);
- assertEquals(expSubject, subj);
- assertTrue(String.format(
- "Expected body to start with \"\"\"%s\"\"\". Body was actually: %s\n",
- expBodyStart, body), body.startsWith(expBodyStart));
- }
-}
diff --git a/prod-tests/tests/src/com/android/continuous/SmokeTestTest.java b/prod-tests/tests/src/com/android/continuous/SmokeTestTest.java
deleted file mode 100644
index 8863b64..0000000
--- a/prod-tests/tests/src/com/android/continuous/SmokeTestTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2012 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.continuous;
-
-import com.android.continuous.SmokeTest.TrimListener;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.result.TestDescription;
-
-import junit.framework.TestCase;
-
-import org.easymock.EasyMock;
-
-/**
- * Unit tests for {@link SmokeTest}.
- */
-public class SmokeTestTest extends TestCase {
- private ITestInvocationListener mListener = null;
-
- @Override
- public void setUp() {
- mListener = EasyMock.createMock(ITestInvocationListener.class);
- }
-
- public void testRewrite() {
- TrimListener trim = new TrimListener(mListener);
- TestDescription in =
- new TestDescription(
- "com.android.smoketest.SmokeTestRunner$3",
- "com.android.voicedialer.VoiceDialerActivity");
- TestDescription out =
- new TestDescription("SmokeFAST", "com.android.voicedialer.VoiceDialerActivity");
- mListener.testStarted(EasyMock.eq(out));
-
- EasyMock.replay(mListener);
- trim.testStarted(in);
- EasyMock.verify(mListener);
- }
-}
-
diff --git a/prod-tests/tests/src/com/android/monkey/MonkeyBaseTest.java b/prod-tests/tests/src/com/android/monkey/MonkeyBaseTest.java
deleted file mode 100644
index 571d6a0..0000000
--- a/prod-tests/tests/src/com/android/monkey/MonkeyBaseTest.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2012 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.monkey;
-
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.util.ArrayUtil;
-
-import junit.framework.TestCase;
-
-import org.easymock.EasyMock;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-/**
- * Unit tests for {@link MonkeyBase}
- */
-public class MonkeyBaseTest extends TestCase {
-
- /**
- * Test that {@link MonkeyBase#setSubtract(Collection, Collection)} returns same object if
- * exclude is empty.
- */
- public void testSetSubtract_noExclude() {
- Collection<String> haystack = ArrayUtil.list("a", "b", "c");
- Collection<String> needles = new ArrayList<String>();
- // double-checking comparison assumptions
- assertFalse(haystack == needles);
- Collection<String> output = MonkeyBase.setSubtract(haystack, needles);
- assertTrue(haystack == output);
- }
-
- /**
- * Test that {@link MonkeyBase#setSubtract(Collection, Collection)} returns the set subtraction
- * if exclude is not empty.
- */
- public void testSetSubtract() {
- Collection<String> haystack = ArrayUtil.list("a", "b", "c");
- Collection<String> needles = ArrayUtil.list("b");
- Collection<String> output = MonkeyBase.setSubtract(haystack, needles);
- assertEquals(2, output.size());
- assertTrue(output.contains("a"));
- assertFalse(output.contains("b"));
- assertTrue(output.contains("c"));
- }
-
- /**
- * Test success case for {@link MonkeyBase#getUptime()}.
- */
- public void testUptime() throws Exception {
- MonkeyBase monkey = new MonkeyBase();
- ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
- monkey.setDevice(mockDevice);
- EasyMock.expect(mockDevice.executeShellCommand("cat /proc/uptime")).andReturn(
- "5278.73 1866.80");
- EasyMock.replay(mockDevice);
- assertEquals("5278.73", monkey.getUptime());
- }
-
- /**
- * Test case for {@link MonkeyBase#getUptime()} where device is initially unresponsive.
- */
- public void testUptime_fail() throws Exception {
- MonkeyBase monkey = new MonkeyBase();
- ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
- monkey.setDevice(mockDevice);
- EasyMock.expect(mockDevice.getSerialNumber()).andStubReturn("serial");
- EasyMock.expect(mockDevice.executeShellCommand("cat /proc/uptime")).andReturn(
- "");
- EasyMock.expect(mockDevice.executeShellCommand("cat /proc/uptime")).andReturn(
- "5278.73 1866.80");
- EasyMock.replay(mockDevice);
- assertEquals("5278.73", monkey.getUptime());
- }
-}
-
diff --git a/prod-tests/tests/src/com/android/tradefed/prodtests/UnitTests.java b/prod-tests/tests/src/com/android/tradefed/prodtests/UnitTests.java
deleted file mode 100644
index 4aec898..0000000
--- a/prod-tests/tests/src/com/android/tradefed/prodtests/UnitTests.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2018 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.tradefed.prodtests;
-
-import com.android.build.tests.ImageStatsTest;
-import com.android.continuous.SmokeTestFailureReporterTest;
-import com.android.continuous.SmokeTestTest;
-import com.android.monkey.MonkeyBaseTest;
-
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
-import org.junit.runners.Suite.SuiteClasses;
-
-/**
- * A test suite for all Trade Federation unit tests running under Junit4.
- *
- * <p>All tests listed here should be self-contained, and should not require any external
- * dependencies.
- */
-@RunWith(Suite.class)
-@SuiteClasses({
- // build.tests
- ImageStatsTest.class,
-
- // Continuous
- SmokeTestFailureReporterTest.class,
- SmokeTestTest.class,
-
- // monkey
- MonkeyBaseTest.class
-})
-public class UnitTests {
- // empty of purpose
-}
diff --git a/src/com/android/tradefed/result/InvocationStatus.java b/src/com/android/tradefed/result/InvocationStatus.java
index 3de082c..7f8e39b 100644
--- a/src/com/android/tradefed/result/InvocationStatus.java
+++ b/src/com/android/tradefed/result/InvocationStatus.java
@@ -20,15 +20,4 @@
*/
public enum InvocationStatus {
SUCCESS, FAILED, BUILD_ERROR;
-
- Throwable mThrowable = null;
-
-
- public void setThrowable(Throwable t) {
- mThrowable = t;
- }
-
- public Throwable getThrowable() {
- return mThrowable;
- }
}
diff --git a/src/com/android/tradefed/util/proto/TestRecordProtoUtil.java b/src/com/android/tradefed/util/proto/TestRecordProtoUtil.java
index 960fb1b..0ebe9c6 100644
--- a/src/com/android/tradefed/util/proto/TestRecordProtoUtil.java
+++ b/src/com/android/tradefed/util/proto/TestRecordProtoUtil.java
@@ -30,6 +30,12 @@
public class TestRecordProtoUtil {
/**
+ * Pick a 4MB default size to allow the buffer to grow for big protobuf. The default value could
+ * fail in some cases.
+ */
+ private static final int DEFAULT_SIZE_BYTES = 4 * 1024 * 1024;
+
+ /**
* Read {@link TestRecord} from a file and return it.
*
* @param protoFile The {@link File} containing the record
@@ -42,12 +48,14 @@
try (InputStream stream = new FileInputStream(protoFile)) {
CodedInputStream is = CodedInputStream.newInstance(stream);
is.setSizeLimit(Integer.MAX_VALUE);
- ByteArrayList data = new ByteArrayList();
+ ByteArrayList data = new ByteArrayList(DEFAULT_SIZE_BYTES);
while (!is.isAtEnd()) {
int size = is.readRawVarint32();
- data.addAll(is.readRawBytes(size));
+ byte[] dataByte = is.readRawBytes(size);
+ data.addAll(dataByte);
}
record = TestRecord.parseFrom(data.getContents());
+ data.clear();
}
return record;
}