Files
frameworks_base/tests/DumpRenderTree2/src/com/android/dumprendertree2/LayoutTestsRunnerThread.java
Maksymilian Osowski 650893b676 Build fix.
Change-Id: Ie2baa3d7d32fd382e8ecb2a811669f50aa26fdc9
2010-07-21 16:21:06 +01:00

292 lines
10 KiB
Java

/*
* 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.dumprendertree2;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import java.io.File;
import java.util.LinkedList;
/**
* A Thread that is responsible for finding and loading the tests, starting them and
* generating summaries. The actual running of the test is delegated to LayoutTestsRunner
* activity (a UI thread) because of a WebView object that need to be created in UI thread
* so it can be displayed on the screen. However, the logic for doing this remains in
* this class (in handler created in constructor).
*/
public class LayoutTestsRunnerThread extends Thread {
private static final String LOG_TAG = "LayoutTestsRunnerThread";
/** Messages for handler on this thread */
public static final int MSG_TEST_FINISHED = 0;
/** Messages for our handler running on UI thread */
public static final int MSG_RUN_TEST = 0;
/** TODO: make it a setting */
private static final String TESTS_ROOT_DIR_PATH =
Environment.getExternalStorageDirectory() +
File.separator + "android" +
File.separator + "LayoutTests";
/** TODO: make it a setting */
private static final String RESULTS_ROOT_DIR_PATH =
Environment.getExternalStorageDirectory() +
File.separator + "android" +
File.separator + "LayoutTests-results";
/** TODO: Make it a setting */
private static final String EXPECTED_RESULT_SECONDARY_LOCATION_RELATIVE_DIR_PREFIX =
"platform" + File.separator +
"android-v8" + File.separator;
/** TODO: Make these settings */
private static final String TEXT_RESULT_EXTENSION = "txt";
private static final String IMAGE_RESULT_EXTENSION = "png";
/** A list containing relative paths of tests to run */
private LinkedList<String> mTestsList = new LinkedList<String>();
private FileFilter mFileFilter;
private Summarizer mSummarizer;
/** Our handler running on this thread. Created in run() method. */
private Handler mHandler;
/** Our handler running on UI thread. Created in constructor of this thread. */
private Handler mHandlerOnUiThread;
/**
* A relative path to the folder with the tests we want to run or particular test.
* Used up to and including preloadTests().
*/
private String mRelativePath;
private LayoutTestsRunner mActivity;
private LayoutTest mCurrentTest;
private String mCurrentTestPath;
private int mCurrentTestCount = 0;
private int mTotalTestCount;
/**
* The given path must be relative to the root dir. The given handler must be
* able to handle messages that update the display (UI thread).
*
* @param path
* @param uiDisplayHandler
*/
public LayoutTestsRunnerThread(String path, LayoutTestsRunner activity) {
mFileFilter = new FileFilter(TESTS_ROOT_DIR_PATH);
mRelativePath = path;
mActivity = activity;
/** This creates a handler that runs on the thread that _created_ this thread */
mHandlerOnUiThread = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_RUN_TEST:
((LayoutTest) msg.obj).run();
break;
}
}
};
}
@Override
public void run() {
Looper.prepare();
mSummarizer = new Summarizer(mFileFilter, RESULTS_ROOT_DIR_PATH);
/** A handler obtained from UI thread to handle messages concerning updating the display */
final Handler uiDisplayHandler = mActivity.getHandler();
/** Creates a new handler in _this_ thread */
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_TEST_FINISHED:
onTestFinished(mCurrentTest);
uiDisplayHandler.obtainMessage(LayoutTestsRunner.MSG_UPDATE_PROGRESS,
mCurrentTestCount, mTotalTestCount).sendToTarget();
runNextTest();
break;
}
}
};
/** Check if the path is correct */
File file = new File(TESTS_ROOT_DIR_PATH, mRelativePath);
if (!file.exists()) {
Log.e(LOG_TAG + "::run", "Path does not exist: " + mRelativePath);
return;
}
/** Populate the tests' list accordingly */
if (file.isDirectory()) {
uiDisplayHandler.sendEmptyMessage(LayoutTestsRunner.MSG_SHOW_PROGRESS_DIALOG);
preloadTests(mRelativePath);
uiDisplayHandler.sendEmptyMessage(LayoutTestsRunner.MSG_DISMISS_PROGRESS_DIALOG);
} else {
mTestsList.addLast(mRelativePath);
mTotalTestCount = 1;
}
runNextTest();
Looper.loop();
}
/**
* Loads all the tests from the given folders and all the subfolders
* into mTestsList.
*
* @param dirRelativePath
*/
private void preloadTests(String dirRelativePath) {
LinkedList<String> foldersList = new LinkedList<String>();
foldersList.add(dirRelativePath);
String relativePath;
String currentDirRelativePath;
String itemName;
File[] items;
while (!foldersList.isEmpty()) {
currentDirRelativePath = foldersList.removeFirst();
items = new File(TESTS_ROOT_DIR_PATH, currentDirRelativePath).listFiles();
for (File item : items) {
itemName = item.getName();
relativePath = currentDirRelativePath + File.separator + itemName;
if (item.isDirectory() && FileFilter.isTestDir(itemName)) {
foldersList.add(relativePath);
continue;
}
if (FileFilter.isTestFile(itemName)) {
if (!mFileFilter.isSkip(relativePath)) {
mTestsList.addLast(relativePath);
} else {
mSummarizer.addSkippedTest(relativePath);
}
}
}
}
mTotalTestCount = mTestsList.size();
}
private void runNextTest() {
if (mTestsList.isEmpty()) {
onFinishedTests();
return;
}
mCurrentTestCount++;
mCurrentTestPath = mTestsList.removeFirst();
mCurrentTest = new LayoutTest(mCurrentTestPath, TESTS_ROOT_DIR_PATH,
mHandler.obtainMessage(MSG_TEST_FINISHED), mActivity);
/**
* This will run the test on UI thread. The reason why we need to run the test
* on UI thread is because of the WebView. If we want to display the webview on
* the screen it needs to be in the UI thread. WebView should be created as
* part of the LayoutTest.run() method.
*/
mHandlerOnUiThread.obtainMessage(MSG_RUN_TEST, mCurrentTest).sendToTarget();
}
private void onTestFinished(LayoutTest test) {
String testPath = test.getRelativePath();
/** Obtain the result */
AbstractResult result = test.getResult();
if (result == null) {
Log.e(LOG_TAG + "::runTests", testPath + ": result NULL!!");
return;
}
dumpResultData(result, testPath);
mSummarizer.appendTest(test);
}
private void dumpResultData(AbstractResult result, String testPath) {
dumpActualTextResult(result, testPath);
dumpActualImageResult(result, testPath);
}
private void dumpActualTextResult(AbstractResult result, String testPath) {
String actualTextResult = result.getActualTextResult();
if (actualTextResult == null) {
return;
}
String resultPath = FileFilter.setPathEnding(testPath, "-actual." + TEXT_RESULT_EXTENSION);
FsUtils.writeDataToStorage(new File(RESULTS_ROOT_DIR_PATH, resultPath),
actualTextResult.getBytes(), false);
}
private void dumpActualImageResult(AbstractResult result, String testPath) {
byte[] actualImageResult = result.getActualImageResult();
if (actualImageResult == null) {
return;
}
String resultPath = FileFilter.setPathEnding(testPath, "-actual." + IMAGE_RESULT_EXTENSION);
FsUtils.writeDataToStorage(new File(RESULTS_ROOT_DIR_PATH, resultPath),
actualImageResult, false);
}
private void onFinishedTests() {
Log.d(LOG_TAG + "::onFinishedTests", "Begin.");
Looper.myLooper().quit();
mSummarizer.summarize();
/** TODO: Present some kind of notification to the user that
* allows to chose next action, e.g:
* - go to html view of results
* - zip results
* - run more tests before zipping */
}
public static String getExpectedTextResult(String relativePath) {
return new String(getExpectedResult(relativePath, TEXT_RESULT_EXTENSION));
}
public static byte[] getExpectedImageResult(String relativePath) {
return getExpectedResult(relativePath, IMAGE_RESULT_EXTENSION);
}
private static byte[] getExpectedResult(String relativePath, String extension) {
relativePath = FileFilter.setPathEnding(relativePath, "-expected." + extension);
byte[] bytes = FsUtils.readDataFromStorage(new File(TESTS_ROOT_DIR_PATH, relativePath));
if (bytes == null) {
relativePath = EXPECTED_RESULT_SECONDARY_LOCATION_RELATIVE_DIR_PREFIX + relativePath;
bytes = FsUtils.readDataFromStorage(new File(TESTS_ROOT_DIR_PATH, relativePath));
}
return bytes;
}
}