merge adb unit / stress tests
- cases involving reboot and fastboot all removed.
- cases involving device APK removed. can be added later.
- failing cases for user image also removed.
- package name aadb is intentional to run it first.
bug: 8400629
Change-Id: I488573b69bbd1a3a07b18bb4be3c0bd4403ccc3c
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 1e794f9..ed155c0 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -114,9 +114,11 @@
# Host side only tests
cts_host_libraries := \
$(PTS_HOST_CASES) \
+ CtsAdbTests \
CtsAppSecurityTests \
CtsMonkeyTestCases
+
# Native test executables that need to have associated test XMLs.
cts_native_exes := \
NativeMediaTest_SL \
diff --git a/hostsidetests/aadb/Android.mk b/hostsidetests/aadb/Android.mk
new file mode 100644
index 0000000..2f2113c
--- /dev/null
+++ b/hostsidetests/aadb/Android.mk
@@ -0,0 +1,31 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_MODULE := CtsAdbTests
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt ddmlib-prebuilt junit
+
+LOCAL_CTS_TEST_PACKAGE := android.aadb
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+# Build the test APKs using their own makefiles
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java
new file mode 100644
index 0000000..5e2e8e0
--- /dev/null
+++ b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java
@@ -0,0 +1,380 @@
+/*
+ * 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.cts.aadb;
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.Log;
+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 com.android.tradefed.result.InputStreamSource;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.util.CommandStatus;
+import com.android.tradefed.util.FileUtil;
+import com.android.tradefed.util.RunUtil;
+import com.android.tradefed.util.StreamUtil;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Functional tests for adb connection
+ * <p/>
+ * Requires a physical device to be connected.
+ */
+public class TestDeviceFuncTest extends DeviceTestCase {
+
+ private static final String LOG_TAG = "TestDeviceFuncTest";
+ private ITestDevice mTestDevice;
+ /** Expect bugreports to be at least a meg. */
+ private static final int mMinBugreportBytes = 1024 * 1024;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTestDevice = getDevice();
+ }
+
+ /**
+ * Simple testcase to ensure that the grabbing a bugreport from a real TestDevice works.
+ */
+ public void testBugreport() throws Exception {
+ String data = StreamUtil.getStringFromStream(
+ mTestDevice.getBugreport().createInputStream());
+ assertTrue(String.format("Expected at least %d characters; only saw %d", mMinBugreportBytes,
+ data.length()), data.length() >= mMinBugreportBytes);
+ // TODO: check the captured report more extensively, perhaps using loganalysis
+ }
+
+ /**
+ * Simple normal case test for
+ * {@link TestDevice#executeShellCommand(String)}.
+ * <p/>
+ * Do a 'shell ls' command, and verify /data and /system are listed in result.
+ */
+ public void testExecuteShellCommand() throws IOException, DeviceNotAvailableException {
+ Log.i(LOG_TAG, "testExecuteShellCommand");
+ assertSimpleShellCommand();
+ }
+
+ /**
+ * Verify that a simple {@link TestDevice#executeShellCommand(String)} command is successful.
+ */
+ private void assertSimpleShellCommand() throws DeviceNotAvailableException {
+ final String output = mTestDevice.executeShellCommand("ls");
+ assertTrue(output.contains("data"));
+ assertTrue(output.contains("system"));
+ }
+
+
+ /**
+ * Push and then pull a file from device, and verify contents are as expected.
+ */
+ public void testPushPull_normal() throws IOException, DeviceNotAvailableException {
+ Log.i(LOG_TAG, "testPushPull");
+ File tmpFile = null;
+ File tmpDestFile = null;
+ String deviceFilePath = null;
+
+ try {
+ tmpFile = createTempTestFile(null);
+ String externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+ assertNotNull(externalStorePath);
+ deviceFilePath = String.format("%s/%s", externalStorePath, "tmp_testPushPull.txt");
+ // ensure file does not already exist
+ mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+ assertFalse(String.format("%s exists", deviceFilePath),
+ mTestDevice.doesFileExist(deviceFilePath));
+
+ assertTrue(mTestDevice.pushFile(tmpFile, deviceFilePath));
+ assertTrue(mTestDevice.doesFileExist(deviceFilePath));
+ tmpDestFile = FileUtil.createTempFile("tmp", "txt");
+ assertTrue(mTestDevice.pullFile(deviceFilePath, tmpDestFile));
+ assertTrue(compareFiles(tmpFile, tmpDestFile));
+ } finally {
+ if (tmpDestFile != null) {
+ tmpDestFile.delete();
+ }
+ if (deviceFilePath != null) {
+ mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+ }
+ }
+ }
+
+ /**
+ * Push and then pull a file from device, and verify contents are as expected.
+ * <p />
+ * This variant of the test uses "${EXTERNAL_STORAGE}" in the pathname.
+ */
+ public void testPushPull_extStorageVariable() throws IOException, DeviceNotAvailableException {
+ Log.i(LOG_TAG, "testPushPull");
+ File tmpFile = null;
+ File tmpDestFile = null;
+ File tmpDestFile2 = null;
+ String deviceFilePath = null;
+ final String filename = "tmp_testPushPull.txt";
+
+ try {
+ tmpFile = createTempTestFile(null);
+ String externalStorePath = "${EXTERNAL_STORAGE}";
+ assertNotNull(externalStorePath);
+ deviceFilePath = String.format("%s/%s", externalStorePath, filename);
+ // ensure file does not already exist
+ mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+ assertFalse(String.format("%s exists", deviceFilePath),
+ mTestDevice.doesFileExist(deviceFilePath));
+
+ assertTrue(mTestDevice.pushFile(tmpFile, deviceFilePath));
+ assertTrue(mTestDevice.doesFileExist(deviceFilePath));
+ tmpDestFile = FileUtil.createTempFile("tmp", "txt");
+ assertTrue(mTestDevice.pullFile(deviceFilePath, tmpDestFile));
+ assertTrue(compareFiles(tmpFile, tmpDestFile));
+
+ tmpDestFile2 = mTestDevice.pullFileFromExternal(filename);
+ assertNotNull(tmpDestFile2);
+ assertTrue(compareFiles(tmpFile, tmpDestFile2));
+ } finally {
+ if (tmpDestFile != null) {
+ tmpDestFile.delete();
+ }
+ if (tmpDestFile2 != null) {
+ tmpDestFile2.delete();
+ }
+ if (deviceFilePath != null) {
+ mTestDevice.executeShellCommand(String.format("rm %s", deviceFilePath));
+ }
+ }
+ }
+
+ /**
+ * Test pulling a file from device that does not exist.
+ * <p/>
+ * Expect {@link TestDevice#pullFile(String)} to return <code>false</code>
+ */
+ public void testPull_noexist() throws IOException, DeviceNotAvailableException {
+ Log.i(LOG_TAG, "testPull_noexist");
+
+ // make sure the root path is valid
+ String externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+ assertNotNull(externalStorePath);
+ String deviceFilePath = String.format("%s/%s", externalStorePath, "thisfiledoesntexist");
+ assertFalse(String.format("%s exists", deviceFilePath),
+ mTestDevice.doesFileExist(deviceFilePath));
+ assertNull(mTestDevice.pullFile(deviceFilePath));
+ }
+
+ private File createTempTestFile(File dir) throws IOException {
+ File tmpFile = null;
+ try {
+ final String fileContents = "this is the test file contents";
+ tmpFile = FileUtil.createTempFile("tmp", ".txt", dir);
+ FileUtil.writeToFile(fileContents, tmpFile);
+ return tmpFile;
+ } catch (IOException e) {
+ if (tmpFile != null) {
+ tmpFile.delete();
+ }
+ throw e;
+ }
+ }
+
+ /**
+ * Utility method to do byte-wise content comparison of two files.
+ */
+ private boolean compareFiles(File file1, File file2) throws IOException {
+ BufferedInputStream stream1 = null;
+ BufferedInputStream stream2 = null;
+
+ try {
+ stream1 = new BufferedInputStream(new FileInputStream(file1));
+ stream2 = new BufferedInputStream(new FileInputStream(file2));
+ boolean eof = false;
+ while (!eof) {
+ int byte1 = stream1.read();
+ int byte2 = stream2.read();
+ if (byte1 != byte2) {
+ return false;
+ }
+ eof = byte1 == -1;
+ }
+ return true;
+ } finally {
+ if (stream1 != null) {
+ stream1.close();
+ }
+ if (stream2 != null) {
+ stream2.close();
+ }
+ }
+ }
+
+ /**
+ * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
+ */
+ public void testSyncFiles_normal() throws Exception {
+ doTestSyncFiles(mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE));
+ }
+
+ /**
+ * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
+ * <p />
+ * This variant of the test uses "${EXTERNAL_STORAGE}" in the pathname.
+ */
+ public void testSyncFiles_extStorageVariable() throws Exception {
+ doTestSyncFiles("${EXTERNAL_STORAGE}");
+ }
+
+ /**
+ * Test syncing a single file using {@link TestDevice#syncFiles(File, String)}.
+ */
+ public void doTestSyncFiles(String externalStorePath) throws Exception {
+ String expectedDeviceFilePath = null;
+
+ // create temp dir with one temp file
+ File tmpDir = FileUtil.createTempDir("tmp");
+ try {
+ File tmpFile = createTempTestFile(tmpDir);
+ // set last modified to 10 minutes ago
+ tmpFile.setLastModified(System.currentTimeMillis() - 10*60*1000);
+ assertNotNull(externalStorePath);
+ expectedDeviceFilePath = String.format("%s/%s/%s", externalStorePath,
+ tmpDir.getName(), tmpFile.getName());
+
+ assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
+ assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath));
+
+ // get 'ls -l' attributes of file which includes timestamp
+ String origTmpFileStamp = mTestDevice.executeShellCommand(String.format("ls -l %s",
+ expectedDeviceFilePath));
+ // now create another file and verify that is synced
+ File tmpFile2 = createTempTestFile(tmpDir);
+ tmpFile2.setLastModified(System.currentTimeMillis() - 10*60*1000);
+ assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
+ String expectedDeviceFilePath2 = String.format("%s/%s/%s", externalStorePath,
+ tmpDir.getName(), tmpFile2.getName());
+ assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath2));
+
+ // verify 1st file timestamp did not change
+ String unchangedTmpFileStamp = mTestDevice.executeShellCommand(String.format("ls -l %s",
+ expectedDeviceFilePath));
+ assertEquals(origTmpFileStamp, unchangedTmpFileStamp);
+
+ // now modify 1st file and verify it does change remotely
+ String testString = "blah";
+ FileOutputStream stream = new FileOutputStream(tmpFile);
+ stream.write(testString.getBytes());
+ stream.close();
+
+ assertTrue(mTestDevice.syncFiles(tmpDir, externalStorePath));
+ String tmpFileContents = mTestDevice.executeShellCommand(String.format("cat %s",
+ expectedDeviceFilePath));
+ assertTrue(tmpFileContents.contains(testString));
+ } finally {
+ if (expectedDeviceFilePath != null && externalStorePath != null) {
+ // note that expectedDeviceFilePath has externalStorePath prepended at definition
+ mTestDevice.executeShellCommand(String.format("rm -r %s", expectedDeviceFilePath));
+ }
+ FileUtil.recursiveDelete(tmpDir);
+ }
+ }
+
+ /**
+ * Test pushing a directory
+ */
+ public void testPushDir() throws IOException, DeviceNotAvailableException {
+ String expectedDeviceFilePath = null;
+ String externalStorePath = null;
+ File rootDir = FileUtil.createTempDir("tmp");
+ // create temp dir with one temp file
+ try {
+ File tmpDir = FileUtil.createTempDir("tmp", rootDir);
+ File tmpFile = createTempTestFile(tmpDir);
+ externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+ assertNotNull(externalStorePath);
+ expectedDeviceFilePath = String.format("%s/%s/%s", externalStorePath,
+ tmpDir.getName(), tmpFile.getName());
+
+ assertTrue(mTestDevice.pushDir(rootDir, externalStorePath));
+ assertTrue(mTestDevice.doesFileExist(expectedDeviceFilePath));
+
+ } finally {
+ if (expectedDeviceFilePath != null && externalStorePath != null) {
+ mTestDevice.executeShellCommand(String.format("rm -r %s/%s", externalStorePath,
+ expectedDeviceFilePath));
+ }
+ FileUtil.recursiveDelete(rootDir);
+ }
+ }
+
+ /**
+ * Basic test for {@link TestDevice#getScreenshot()}.
+ * <p/>
+ * Grab a screenshot, save it to a file, and perform a cursory size check to ensure its valid.
+ */
+ public void testGetScreenshot() throws DeviceNotAvailableException, IOException {
+ CLog.i(LOG_TAG, "testGetScreenshot");
+ InputStreamSource source = getDevice().getScreenshot();
+ assertNotNull(source);
+ File tmpPngFile = FileUtil.createTempFile("screenshot", ".png");
+ try {
+ FileUtil.writeToFile(source.createInputStream(), tmpPngFile);
+ CLog.i("Created file at %s", tmpPngFile.getAbsolutePath());
+ assertTrue("Saved png file is less than 16K - is it invalid?",
+ tmpPngFile.length() > 16*1024);
+ // TODO: add more stringent checks
+ } finally {
+ FileUtil.deleteFile(tmpPngFile);
+ source.cancel();
+ }
+ }
+
+ /**
+ * Basic test for {@link TestDevice#getLogcat(long)}.
+ * <p/>
+ * Dumps a bunch of messages to logcat, calls getLogcat(), and verifies size of capture file is
+ * equal to provided data.
+ */
+ public void testGetLogcat_size() throws DeviceNotAvailableException, IOException {
+ CLog.i(LOG_TAG, "testGetLogcat_size");
+ for (int i = 0; i < 100; i++) {
+ getDevice().executeShellCommand(String.format("log testGetLogcat_size log dump %d", i));
+ }
+ // sleep a small amount of time to ensure last log message makes it into capture
+ RunUtil.getDefault().sleep(10);
+ InputStreamSource source = getDevice().getLogcat(100 * 1024);
+ assertNotNull(source);
+ File tmpTxtFile = FileUtil.createTempFile("logcat", ".txt");
+ try {
+ FileUtil.writeToFile(source.createInputStream(), tmpTxtFile);
+ CLog.i("Created file at %s", tmpTxtFile.getAbsolutePath());
+ assertEquals("Saved text file is not equal to buffer size", 100 * 1024,
+ tmpTxtFile.length());
+ // ensure last log message is present in log
+ String s = FileUtil.readStringFromFile(tmpTxtFile);
+ assertTrue("last log message is not in captured logcat",
+ s.contains("testGetLogcat_size log dump 99"));
+ } finally {
+ FileUtil.deleteFile(tmpTxtFile);
+ source.cancel();
+ }
+ }
+}
diff --git a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java
new file mode 100644
index 0000000..c780fb9
--- /dev/null
+++ b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceStressTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.cts.aadb;
+
+import com.android.ddmlib.IDevice;
+import com.android.ddmlib.Log;
+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.result.CollectingTestListener;
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.util.FileUtil;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Long running functional tests for {@link TestDevice} that verify an operation can be run
+ * many times in sequence
+ * <p/>
+ * Requires a physical device to be connected.
+ */
+public class TestDeviceStressTest extends DeviceTestCase {
+
+ private int mIterations = 50;
+
+ private static final String LOG_TAG = "TestDeviceStressTest";
+ private static final int TEST_FILE_COUNT= 200;
+ private ITestDevice mTestDevice;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTestDevice = getDevice();
+ }
+
+ private File createTempTestFiles() throws IOException {
+ File tmpDir = null;
+ File tmpFile = null;
+
+ tmpDir = FileUtil.createTempDir("testDir");
+
+ final String fileContents = "this is the test file contents";
+ for (int i = 0; i < TEST_FILE_COUNT; i++) {
+ tmpFile = FileUtil.createTempFile(String.format("tmp_%d", i), ".txt", tmpDir);
+ FileUtil.writeToFile(fileContents, tmpFile);
+ }
+ return tmpDir;
+
+ }
+
+ /**
+ * Stress test to push a folder which contains 200 text file to device
+ * internal storage.
+ */
+ public void testPushFolderWithManyFiles() throws IOException, DeviceNotAvailableException {
+ File tmpDir = null;
+ String deviceFilePath = null;
+ String externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+ assertNotNull(externalStorePath);
+ deviceFilePath = String.format("%s/%s", externalStorePath, "testDir");
+
+ // start the stress test
+ try {
+ // Create the test folder and make sure the test folder doesn't exist in
+ // device before the test start.
+ tmpDir = createTempTestFiles();
+ for (int i = 0; i < mIterations; i++) {
+ mTestDevice.executeShellCommand(String.format("rm -r %s", deviceFilePath));
+ assertFalse(String.format("%s exists", deviceFilePath),
+ mTestDevice.doesFileExist(deviceFilePath));
+ assertTrue(mTestDevice.pushDir(tmpDir, deviceFilePath));
+ assertTrue(mTestDevice.doesFileExist(deviceFilePath));
+ }
+ } finally {
+ if (tmpDir != null) {
+ FileUtil.recursiveDelete(tmpDir);
+ }
+ mTestDevice.executeShellCommand(String.format("rm -r %s", deviceFilePath));
+ assertFalse(String.format("%s exists", deviceFilePath),
+ mTestDevice.doesFileExist(deviceFilePath));
+ }
+ }
+}
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 3cb986f..95d60ac 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -143,6 +143,7 @@
# hard-coded white list for PDK plan
plan.Exclude('.*')
+ plan.Include('android\.aadb')
plan.Include('android\.bluetooth')
plan.Include('android\.graphics.*')
plan.Include('android\.hardware')