blob: e14cf50be03ec626fe3fc1f6732dea1050de61ed [file] [log] [blame]
/*
* 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.tradefed.device;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
import com.android.ddmlib.testrunner.TestResult.TestStatus;
import com.android.tradefed.TestAppConstants;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.result.CollectingTestListener;
import com.android.tradefed.result.FileInputStreamSource;
import com.android.tradefed.result.InputStreamSource;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.IDeviceTest;
import com.android.tradefed.util.CommandStatus;
import com.android.tradefed.util.FileUtil;
import com.android.tradefed.util.KeyguardControllerState;
import com.android.tradefed.util.RunUtil;
import com.android.tradefed.util.StreamUtil;
import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* Functional tests for {@link TestDevice}.
*
* <p>Requires a physical device to be connected.
*/
@RunWith(DeviceJUnit4ClassRunner.class)
public class TestDeviceFuncTest implements IDeviceTest {
private static final String LOG_TAG = "TestDeviceFuncTest";
private TestDevice mTestDevice;
private IDeviceStateMonitor mMonitor;
/** Expect bugreports to be at least a meg. */
private static final int MIN_BUGREPORT_BYTES = 1024 * 1024;
@Override
public void setDevice(ITestDevice device) {
mTestDevice = (TestDevice) device;
}
@Override
public ITestDevice getDevice() {
return mTestDevice;
}
@Before
public void setUp() throws Exception {
mMonitor = mTestDevice.getDeviceStateMonitor();
// Ensure at set-up that the device is available.
mTestDevice.waitForDeviceAvailable();
}
/** Simple testcase to ensure that the grabbing a bugreport from a real TestDevice works. */
@Test
public void testBugreport() throws Exception {
InputStreamSource bugreport = mTestDevice.getBugreport();
try {
String data = StreamUtil.getStringFromStream(bugreport.createInputStream());
assertTrue(
String.format(
"Expected at least %d characters; only saw %d",
MIN_BUGREPORT_BYTES, data.length()),
data.length() >= MIN_BUGREPORT_BYTES);
} finally {
StreamUtil.cancel(bugreport);
}
}
/** Simple testcase to ensure that the grabbing a bugreportz from a real TestDevice works. */
@Test
public void testBugreportz() throws Exception {
if (mTestDevice.getApiLevel() < 24) {
CLog.i("testBugreportz() not supported by this device, skipping.");
return;
}
FileInputStreamSource f = null;
try {
f = (FileInputStreamSource) mTestDevice.getBugreportz();
assertNotNull(f);
FileInputStream contents = (FileInputStream) f.createInputStream();
assertTrue(
String.format(
"Expected at least %d characters; only saw %d",
MIN_BUGREPORT_BYTES, contents.available()),
contents.available() >= MIN_BUGREPORT_BYTES);
} finally {
StreamUtil.cancel(f);
if (f != null) {
f.cleanFile();
}
}
}
/**
* Simple normal case test for {@link TestDevice#executeShellCommand(String)}.
*
* <p>Do a 'shell ls' command, and verify /data and /system are listed in result.
*/
@Test
public void testExecuteShellCommand() throws 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"));
}
/** Test install and uninstall of package */
@Test
public void testInstallUninstall() throws IOException, DeviceNotAvailableException {
Log.i(LOG_TAG, "testInstallUninstall");
// use the wifi util apk
File tmpFile = WifiHelper.extractWifiUtilApk();
try {
assertWifiApkInstall(tmpFile);
} finally {
FileUtil.deleteFile(tmpFile);
}
}
/**
* Verifies that the given wifi util apk can be installed and uninstalled successfully
*/
void assertWifiApkInstall(File tmpFile) throws DeviceNotAvailableException {
try {
mTestDevice.uninstallPackage(WifiHelper.INSTRUMENTATION_PKG);
assertFalse(mTestDevice.getInstalledPackageNames().contains(
WifiHelper.INSTRUMENTATION_PKG));
assertNull(mTestDevice.installPackage(tmpFile, false));
assertTrue(mTestDevice.getInstalledPackageNames().contains(
WifiHelper.INSTRUMENTATION_PKG));
assertFalse("apk file was not cleaned up after install",
mTestDevice.doesFileExist(String.format("/data/local/tmp/%s",
tmpFile.getName())));
} finally {
FileUtil.deleteFile(tmpFile);
}
}
/** Test install and uninstall of package with spaces in file name */
@Test
public void testInstallUninstall_space() throws IOException, DeviceNotAvailableException {
Log.i(LOG_TAG, "testInstallUninstall_space");
File tmpFile = WifiHelper.extractWifiUtilApk();
File tmpFileSpaces = null;
try {
tmpFileSpaces = FileUtil.createTempFile("wifi util (3)", ".apk");
FileUtil.copyFile(tmpFile, tmpFileSpaces);
assertWifiApkInstall(tmpFileSpaces);
} finally {
FileUtil.deleteFile(tmpFile);
FileUtil.deleteFile(tmpFileSpaces);
}
}
/** Push and then pull a file from device, and verify contents are as expected. */
@Test
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 {
FileUtil.deleteFile(tmpFile);
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.
*/
@Test
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 {
FileUtil.deleteFile(tmpFile);
FileUtil.deleteFile(tmpDestFile);
FileUtil.deleteFile(tmpDestFile2);
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>
*/
@Test
public void testPull_noexist() throws 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));
}
/**
* Test pulling a file from device into a local file that cannot be written to.
*
* <p>Expect {@link TestDevice#pullFile(String, File)} to return <code>false</code>
*/
@Test
public void testPull_nopermissions() throws IOException, DeviceNotAvailableException {
CLog.i("testPull_nopermissions");
// make sure the root path is valid
String externalStorePath = mTestDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
assertNotNull(externalStorePath);
String deviceFilePath = String.format("%s/%s", externalStorePath, "testPull_nopermissions");
// first push a file so we have something to retrieve
assertTrue(mTestDevice.pushString("test data", deviceFilePath));
assertTrue(String.format("%s does not exist", deviceFilePath),
mTestDevice.doesFileExist(deviceFilePath));
File tmpFile = null;
try {
tmpFile = FileUtil.createTempFile("testPull_nopermissions", ".txt");
tmpFile.setReadOnly();
assertFalse(mTestDevice.pullFile(deviceFilePath, tmpFile));
} finally {
if (tmpFile != null) {
tmpFile.setWritable(true);
FileUtil.deleteFile(tmpFile);
}
}
}
/**
* Test pushing a file onto device that does not exist.
*
* <p>Expect {@link TestDevice#pushFile(File, String)} to return <code>false</code>
*/
@Test
public void testPush_noexist() throws DeviceNotAvailableException {
Log.i(LOG_TAG, "testPush_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, "remotepath");
assertFalse(mTestDevice.pushFile(new File("idontexist"), 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 {
StreamUtil.close(stream1);
StreamUtil.close(stream2);
}
}
/**
* Make sure that we can correctly index directories that have a symlink in the middle. This
* verifies a ddmlib bugfix which added/fixed this functionality.
*/
@Test
public void testListSymlinkDir() throws Exception {
final String extStore = "/data/local";
// Clean up after potential failed run
mTestDevice.executeShellCommand(String.format("rm %s/testdir", extStore));
mTestDevice.executeShellCommand(String.format("rm %s/testdir2/foo.txt", extStore));
mTestDevice.executeShellCommand(String.format("rmdir %s/testdir2", extStore));
try {
assertEquals("",
mTestDevice.executeShellCommand(String.format("mkdir %s/testdir2",
extStore)));
assertEquals("", mTestDevice.executeShellCommand(
String.format("touch %s/testdir2/foo.txt", extStore)));
assertEquals("",
mTestDevice.executeShellCommand(String.format("ln -s %s/testdir2 %s/testdir",
extStore, extStore)));
assertNotNull(mTestDevice.getFileEntry(String.format("%s/testdir/foo.txt", extStore)));
} finally {
mTestDevice.executeShellCommand(String.format("rm %s/testdir", extStore));
mTestDevice.executeShellCommand(String.format("rm %s/testdir2/foo.txt", extStore));
mTestDevice.executeShellCommand(String.format("rmdir %s/testdir2", extStore));
}
}
/** Test syncing a single file using {@link TestDevice#syncFiles(File, String)}. */
@Test
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.
*/
@Test
public void testSyncFiles_extStorageVariable() throws Exception {
doTestSyncFiles("${EXTERNAL_STORAGE}");
}
/** Test syncing a single file using {@link TestDevice#syncFiles(File, String)}. */
private 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 */
@Test
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);
}
}
/**
* Test {@link TestDevice#executeFastbootCommand(String...)} when device is in adb mode.
*
* <p>Expect fastboot recovery to be invoked, which will boot device back to fastboot mode and
* command will succeed.
*/
@Test
public void testExecuteFastbootCommand_deviceInAdb() throws DeviceNotAvailableException {
Log.i(LOG_TAG, "testExecuteFastbootCommand_deviceInAdb");
if (!mTestDevice.isFastbootEnabled()) {
Log.i(LOG_TAG, "Fastboot not enabled skipping testExecuteFastbootCommand_deviceInAdb");
return;
}
long origTimeout = mTestDevice.getCommandTimeout();
try {
assertEquals(TestDeviceState.ONLINE, mMonitor.getDeviceState());
// reset operation timeout to small value to make test run quicker
mTestDevice.setCommandTimeout(5*1000);
assertEquals(CommandStatus.SUCCESS,
mTestDevice.executeFastbootCommand("getvar", "product").getStatus());
assertEquals(TestDeviceState.FASTBOOT, mMonitor.getDeviceState());
} finally {
mTestDevice.setCommandTimeout(origTimeout);
mTestDevice.reboot();
assertEquals(TestDeviceState.ONLINE, mMonitor.getDeviceState());
}
}
/**
* Test {@link TestDevice#executeFastbootCommand(String...)} when an invalid command is passed.
*
* <p>Expect the result indicate failure, and recovery not to be invoked.
*/
@Test
public void testExecuteFastbootCommand_badCommand() throws DeviceNotAvailableException {
Log.i(LOG_TAG, "testExecuteFastbootCommand_badCommand");
if (!mTestDevice.isFastbootEnabled()) {
Log.i(LOG_TAG, "Fastboot not enabled skipping testExecuteFastbootCommand_badCommand");
return;
}
IDeviceRecovery origRecovery = mTestDevice.getRecovery();
try {
mTestDevice.rebootIntoBootloader();
assertEquals(TestDeviceState.FASTBOOT, mMonitor.getDeviceState());
// substitute recovery mechanism to ensure recovery is not called when bad command
// is passed
IDeviceRecovery mockRecovery = EasyMock.createStrictMock(IDeviceRecovery.class);
mTestDevice.setRecovery(mockRecovery);
EasyMock.replay(mockRecovery);
assertEquals(CommandStatus.FAILED,
mTestDevice.executeFastbootCommand("badcommand").getStatus());
} finally {
mTestDevice.setRecovery(origRecovery);
mTestDevice.reboot();
assertEquals(TestDeviceState.ONLINE, mMonitor.getDeviceState());
}
}
/** Verify device can be rebooted into bootloader and back to adb. */
@Test
public void testRebootIntoBootloader() throws DeviceNotAvailableException {
Log.i(LOG_TAG, "testRebootIntoBootloader");
if (!mTestDevice.isFastbootEnabled()) {
Log.i(LOG_TAG, "Fastboot not enabled skipping testRebootInBootloader");
return;
}
try {
mTestDevice.rebootIntoBootloader();
assertEquals(TestDeviceState.FASTBOOT, mMonitor.getDeviceState());
} finally {
mTestDevice.reboot();
assertEquals(TestDeviceState.ONLINE, mMonitor.getDeviceState());
}
}
/** Verify device can be rebooted into adb. */
@Test
public void testReboot() throws DeviceNotAvailableException {
Log.i(LOG_TAG, "testReboot");
mTestDevice.reboot();
assertEquals(TestDeviceState.ONLINE, mMonitor.getDeviceState());
// check that device has root
assertTrue(mTestDevice.executeShellCommand("id").contains("root"));
}
/** Verify device can be rebooted into adb recovery. */
@Test
public void testRebootIntoRecovery() throws Exception {
Log.i(LOG_TAG, "testRebootIntoRecovery");
if (!mTestDevice.isFastbootEnabled()) {
Log.i(LOG_TAG, "Fastboot not enabled skipping testRebootInRecovery");
return;
}
try {
mTestDevice.rebootIntoRecovery();
assertEquals(TestDeviceState.RECOVERY, mMonitor.getDeviceState());
} finally {
// Recovery is a special case to recover from, we need to call reboot on the idevice.
RunUtil.getDefault().sleep(15 * 1000);
getDevice().getIDevice().reboot(null);
}
}
/**
* Verify that {@link TestDevice#clearErrorDialogs()} can successfully clear an error dialog
* from screen.
*
* <p>This is done by running a test app which will crash, then running another app that does UI
* based tests.
*
* <p>Assumes DevTools and TradeFedUiApp are currently installed.
*/
@Test
public void testClearErrorDialogs_crash() throws DeviceNotAvailableException {
Log.i(LOG_TAG, "testClearErrorDialogs_crash");
// Ensure device is in a known state, we doing extra care here otherwise it may be flaky
int retry = 5;
mTestDevice.disableKeyguard();
while (!runUITests()) {
getDevice().reboot();
mTestDevice.waitForDeviceAvailable();
mTestDevice.disableKeyguard();
RunUtil.getDefault().sleep(2000);
if (retry == 0) {
fail("Fail to setup the device in a known state");
}
retry--;
}
// now cause a crash dialog to appear
getDevice().executeShellCommand("am start -n " + TestAppConstants.CRASH_ACTIVITY);
RunUtil.getDefault().sleep(2000);
// Ensure the error dialogue is here
assertFalse(runUITests());
RunUtil.getDefault().sleep(2000);
assertTrue("Clear dialogs did not clear anything", getDevice().clearErrorDialogs());
assertTrue(runUITests());
}
/**
* Verify the steps taken to disable keyguard after reboot are successfully
*
* <p>This is done by rebooting then run a app that does UI based tests.
*
* <p>Assumes DevTools and TradeFedUiApp are currently installed.
*/
@Test
public void testDisableKeyguard() throws DeviceNotAvailableException {
Log.i(LOG_TAG, "testDisableKeyguard");
getDevice().reboot();
mTestDevice.waitForDeviceAvailable();
RunUtil.getDefault().sleep(3000);
KeyguardControllerState keyguard = mTestDevice.getKeyguardState();
if (keyguard == null) {
// If the getKeyguardState is not supported.
assertTrue(runUITests());
} else {
assertFalse(keyguard.isKeyguardShowing());
}
}
/** Test that TradeFed can successfully recover from the adb host daemon process being killed */
@Test
public void testExecuteShellCommand_adbKilled() {
// FIXME: adb typically does not recover, and this causes rest of tests to fail
//Log.i(LOG_TAG, "testExecuteShellCommand_adbKilled");
//CommandResult result = RunUtil.getInstance().runTimedCmd(30*1000, "adb", "kill-server");
//assertEquals(CommandStatus.SUCCESS, result.getStatus());
//assertSimpleShellCommand();
}
/**
* 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.
*/
@Test
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());
// Decode the content, will return null if not an image.
BufferedImage image = ImageIO.read(tmpPngFile);
assertNotNull(image);
// All our device screenshot should be bigger than 200px
assertTrue(image.getWidth() > 200);
assertTrue(image.getHeight() > 200);
} finally {
FileUtil.deleteFile(tmpPngFile);
source.close();
}
}
/**
* Basic test for {@link TestDevice#getLogcat(int)}.
*
* <p>Dumps a bunch of messages to logcat, calls getLogcat(), and verifies size of capture file
* is equal to provided data.
*/
@Test
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(500);
File tmpTxtFile = FileUtil.createTempFile("logcat", ".txt");
try (InputStreamSource source = getDevice().getLogcatDump()) {
assertNotNull(source);
FileUtil.writeToFile(source.createInputStream(), tmpTxtFile);
CLog.i("Created file at %s", tmpTxtFile.getAbsolutePath());
// Check we have at least our 100 lines.
assertTrue("Saved text file is smaller than expected",
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);
}
}
/**
* Basic test for encryption if encryption is supported.
*
* <p>Calls {@link TestDevice#encryptDevice(boolean)}, {@link TestDevice#unlockDevice()}, and
* {@link TestDevice#unencryptDevice()}, as well as reboots the device while the device is
* encrypted.
*
* @throws DeviceNotAvailableException
*/
@Test
public void testEncryption() throws DeviceNotAvailableException {
CLog.i("testEncryption");
if (!getDevice().isEncryptionSupported()) {
CLog.i("Encrypting userdata is not supported. Skipping test.");
return;
}
assertTrue(getDevice().unencryptDevice());
assertFalse(getDevice().isDeviceEncrypted());
assertTrue(getDevice().encryptDevice(false));
assertTrue(getDevice().isDeviceEncrypted());
assertTrue(getDevice().unlockDevice());
// TODO: decryptUserData() can be called more than once, the framework should only be
// restarted on the first call.
assertTrue(getDevice().unlockDevice());
getDevice().reboot();
assertTrue(getDevice().unencryptDevice());
assertFalse(getDevice().isDeviceEncrypted());
}
/** Test that {@link TestDevice#getProperty(String)} works after a reboot. */
@Test
public void testGetProperty() throws Exception {
assertNotNull(getDevice().getProperty(DeviceProperties.BOARD));
getDevice().rebootUntilOnline();
assertNotNull(getDevice().getProperty(DeviceProperties.BOARD));
}
/** Test that {@link TestDevice#getProperty(String)} works for volatile properties. */
@Test
public void testGetProperty_volatile() throws Exception {
getDevice().executeShellCommand("setprop prop.test 0");
assertEquals("0", getDevice().getProperty("prop.test"));
getDevice().executeShellCommand("setprop prop.test 1");
assertEquals("1", getDevice().getProperty("prop.test"));
}
/** Test that the recovery mechanism works in {@link TestDevice#getFileEntry(String)} */
@Test
public void testGetFileEntry_recovery() throws Exception {
if (!mTestDevice.isFastbootEnabled()) {
Log.i(LOG_TAG, "Fastboot not enabled skipping testGetFileEntry_recovery");
return;
}
try {
getDevice().rebootIntoBootloader();
// expect recovery to kick in, and reboot device back to adb so the call works
IFileEntry entry = getDevice().getFileEntry("/data");
assertNotNull(entry);
} finally {
getDevice().reboot();
}
}
/**
* Run the test app UI tests and return true if they all pass.
*/
private boolean runUITests() throws DeviceNotAvailableException {
RemoteAndroidTestRunner uirunner = new RemoteAndroidTestRunner(
TestAppConstants.UITESTAPP_PACKAGE, getDevice().getIDevice());
CollectingTestListener uilistener = new CollectingTestListener();
getDevice().runInstrumentationTests(uirunner, uilistener);
return TestAppConstants.UI_TOTAL_TESTS == uilistener.getNumTestsInState(TestStatus.PASSED);
}
/** Test for {@link NativeDevice#setSetting(int, String, String, String)} */
@Test
public void testPutSettings() throws Exception {
String initValue = mTestDevice.getSetting(0, "system", "screen_brightness");
CLog.i("initial value was: %s", initValue);
assertTrue(!initValue.equals("50"));
mTestDevice.setSetting(0, "system", "screen_brightness", "50");
String secondValue = mTestDevice.getSetting(0, "system", "screen_brightness");
assertEquals("50", secondValue);
// restore initial value
mTestDevice.setSetting(0, "system", "screen_brightness", initValue);
}
}