Merge change 2816 into donut
* changes: Update reliability test code. Use a separate activity with simpler calback mechanism.
This commit is contained in:
@@ -23,8 +23,8 @@
|
|||||||
<category android:name="android.intent.category.TEST" />
|
<category android:name="android.intent.category.TEST" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name="TestShellActivity" android:launchMode="singleTop">
|
<activity android:name="TestShellActivity" android:launchMode="singleTop" />
|
||||||
</activity>
|
<activity android:name="ReliabilityTestActivity" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<instrumentation android:name=".LayoutTestsAutoRunner"
|
<instrumentation android:name=".LayoutTestsAutoRunner"
|
||||||
@@ -32,5 +32,5 @@
|
|||||||
android:label="Layout test automation runner"
|
android:label="Layout test automation runner"
|
||||||
/>
|
/>
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_SDCARD" />
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -10,10 +10,8 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import optparse
|
import optparse
|
||||||
import random
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
|
||||||
|
|
||||||
TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt"
|
TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt"
|
||||||
TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt"
|
TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt"
|
||||||
@@ -41,40 +39,16 @@ def DumpRenderTreeFinished(adb_cmd):
|
|||||||
return adb_output.strip() == "#DONE"
|
return adb_output.strip() == "#DONE"
|
||||||
|
|
||||||
|
|
||||||
def RandomPick(file_name, approx_size, num_needed):
|
def RemoveDeviceFile(adb_cmd, file_name):
|
||||||
"""Randomly pick lines from the text file specifed.
|
shell_cmd_str = adb_cmd + " shell rm " + file_name
|
||||||
|
subprocess.Popen(shell_cmd_str,
|
||||||
Args:
|
shell=True, stdout=subprocess.PIPE,
|
||||||
file_name: the text file where lines should be picked from
|
stderr=subprocess.PIPE).communicate()
|
||||||
approx_size: an approximate size of the text file
|
|
||||||
num_needed: how many lines are needed from the file
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
an array of string
|
|
||||||
"""
|
|
||||||
p = float(num_needed) / approx_size
|
|
||||||
num_picked = 0
|
|
||||||
lines = []
|
|
||||||
random.seed()
|
|
||||||
|
|
||||||
while num_picked < num_needed:
|
|
||||||
file_handle = open(file_name, "r")
|
|
||||||
for line in file_handle:
|
|
||||||
line = line.strip()
|
|
||||||
if float(random.randint(0, approx_size)) / approx_size < p:
|
|
||||||
lines.append(line)
|
|
||||||
num_picked += 1
|
|
||||||
if num_picked == num_needed:
|
|
||||||
break
|
|
||||||
file_handle.close()
|
|
||||||
return lines
|
|
||||||
|
|
||||||
|
|
||||||
def main(options, args):
|
def main(options, args):
|
||||||
"""Send the url list to device and start testing, restart if crashed."""
|
"""Send the url list to device and start testing, restart if crashed."""
|
||||||
|
|
||||||
generate_url = False
|
|
||||||
|
|
||||||
# Set up logging format.
|
# Set up logging format.
|
||||||
log_level = logging.INFO
|
log_level = logging.INFO
|
||||||
if options.verbose:
|
if options.verbose:
|
||||||
@@ -84,34 +58,23 @@ def main(options, args):
|
|||||||
|
|
||||||
# Include all tests if none are specified.
|
# Include all tests if none are specified.
|
||||||
if not args:
|
if not args:
|
||||||
path = "/tmp/url_list_%d.txt" % time.time()
|
print "Missing URL list file"
|
||||||
generate_url = True
|
sys.exit(1)
|
||||||
logging.info("A URL list is not provided, will be automatically generated.")
|
|
||||||
else:
|
else:
|
||||||
path = args[0]
|
path = args[0]
|
||||||
|
|
||||||
if not options.crash_file:
|
if not options.crash_file:
|
||||||
print "missing crash file name, use --crash-file to specify"
|
print "Missing crash file name, use --crash-file to specify"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
crashed_file = options.crash_file
|
crashed_file = options.crash_file
|
||||||
|
|
||||||
if not options.timeout_file:
|
if not options.timeout_file:
|
||||||
print "missing timeout file, use --timeout-file to specify"
|
print "Missing timeout file, use --timeout-file to specify"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
timedout_file = options.timeout_file
|
timedout_file = options.timeout_file
|
||||||
|
|
||||||
http = RandomPick(HTTP_URL_FILE, 500000, NUM_URLS)
|
|
||||||
https = RandomPick(HTTPS_URL_FILE, 45000, NUM_URLS)
|
|
||||||
|
|
||||||
if generate_url:
|
|
||||||
file_handle = open(path, "w")
|
|
||||||
for i in range(0, NUM_URLS):
|
|
||||||
file_handle.write(http[i] + "\n")
|
|
||||||
file_handle.write(https[i] + "\n")
|
|
||||||
file_handle.close()
|
|
||||||
|
|
||||||
adb_cmd = "adb "
|
adb_cmd = "adb "
|
||||||
if options.adb_options:
|
if options.adb_options:
|
||||||
adb_cmd += options.adb_options + " "
|
adb_cmd += options.adb_options + " "
|
||||||
@@ -128,6 +91,10 @@ def main(options, args):
|
|||||||
logging.error(adb_error)
|
logging.error(adb_error)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
# clean up previous results
|
||||||
|
RemoveDeviceFile(adb_cmd, TEST_STATUS_FILE)
|
||||||
|
RemoveDeviceFile(adb_cmd, TEST_TIMEOUT_FILE)
|
||||||
|
|
||||||
logging.info("Running the test ...")
|
logging.info("Running the test ...")
|
||||||
|
|
||||||
# Count crashed tests.
|
# Count crashed tests.
|
||||||
@@ -142,11 +109,10 @@ def main(options, args):
|
|||||||
|
|
||||||
# Call ReliabilityTestsAutoTest#startReliabilityTests
|
# Call ReliabilityTestsAutoTest#startReliabilityTests
|
||||||
test_cmd = (test_cmd_prefix + " -e class "
|
test_cmd = (test_cmd_prefix + " -e class "
|
||||||
"com.android.dumprendertree.ReliabilityTestsAutoTest#"
|
"com.android.dumprendertree.ReliabilityTest#"
|
||||||
"startReliabilityTests -e timeout " + timeout_ms
|
"runTest -e timeout %d %s" %
|
||||||
+ test_cmd_postfix)
|
(timeout_ms, test_cmd_postfix))
|
||||||
|
|
||||||
time_start = time.time()
|
|
||||||
adb_output = subprocess.Popen(test_cmd, shell=True,
|
adb_output = subprocess.Popen(test_cmd, shell=True,
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE).communicate()[0]
|
stderr=subprocess.PIPE).communicate()[0]
|
||||||
@@ -160,16 +126,12 @@ def main(options, args):
|
|||||||
logging.info("Resuming reliability test runner...")
|
logging.info("Resuming reliability test runner...")
|
||||||
|
|
||||||
test_cmd = (test_cmd_prefix + " -e class "
|
test_cmd = (test_cmd_prefix + " -e class "
|
||||||
"com.android.dumprendertree.ReliabilityTestsAutoTest#"
|
"com.android.dumprendertree.ReliabilityTest#"
|
||||||
"resumeReliabilityTests -e timeout " + timeout_ms
|
"runTest -e timeout %d %s" %
|
||||||
+ test_cmd_postfix)
|
(timeout_ms, test_cmd_postfix))
|
||||||
adb_output = subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
|
adb_output = subprocess.Popen(test_cmd, shell=True, stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE).communicate()[0]
|
stderr=subprocess.PIPE).communicate()[0]
|
||||||
|
|
||||||
time_end = time.time()
|
|
||||||
fp = open("time_stat", "a")
|
|
||||||
fp.writelines("%.2f\n" % ((time_end - time_start) / NUM_URLS / 2))
|
|
||||||
fp.close()
|
|
||||||
if (adb_output.find("INSTRUMENTATION_FAILED") != -1 or
|
if (adb_output.find("INSTRUMENTATION_FAILED") != -1 or
|
||||||
adb_output.find("Process crashed.") != -1):
|
adb_output.find("Process crashed.") != -1):
|
||||||
logging.error("Error happened : " + adb_output)
|
logging.error("Error happened : " + adb_output)
|
||||||
|
|||||||
@@ -0,0 +1,170 @@
|
|||||||
|
package com.android.dumprendertree;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class ReliabilityTest extends ActivityInstrumentationTestCase2<ReliabilityTestActivity> {
|
||||||
|
|
||||||
|
private static final String LOGTAG = "ReliabilityTest";
|
||||||
|
private static final String PKG_NAME = "com.android.dumprendertree";
|
||||||
|
private static final String TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt";
|
||||||
|
private static final String TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt";
|
||||||
|
private static final String TEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt";
|
||||||
|
private static final String TEST_DONE = "#DONE";
|
||||||
|
static final String RELIABILITY_TEST_RUNNER_FILES[] = {
|
||||||
|
"run_reliability_tests.py"
|
||||||
|
};
|
||||||
|
|
||||||
|
public ReliabilityTest() {
|
||||||
|
super(PKG_NAME, ReliabilityTestActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void runTest() throws Throwable {
|
||||||
|
ReliabilityTestActivity activity = getActivity();
|
||||||
|
LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner)getInstrumentation();
|
||||||
|
|
||||||
|
File testListFile = new File(TEST_LIST_FILE);
|
||||||
|
if(!testListFile.exists())
|
||||||
|
throw new FileNotFoundException("test list file not found.");
|
||||||
|
|
||||||
|
BufferedReader listReader = new BufferedReader(
|
||||||
|
new FileReader(testListFile));
|
||||||
|
|
||||||
|
//always try to resume first, hence cleaning up status will be the
|
||||||
|
//responsibility of driver scripts
|
||||||
|
String lastUrl = readTestStatus();
|
||||||
|
if(lastUrl != null && !TEST_DONE.equals(lastUrl))
|
||||||
|
fastForward(listReader, lastUrl);
|
||||||
|
|
||||||
|
String url = null;
|
||||||
|
Handler handler = null;
|
||||||
|
boolean timeoutFlag = false;
|
||||||
|
long start, elapsed;
|
||||||
|
//read from BufferedReader instead of populating a list in advance,
|
||||||
|
//this will avoid excessive memory usage in case of a large list
|
||||||
|
while((url = listReader.readLine()) != null) {
|
||||||
|
start = System.currentTimeMillis();
|
||||||
|
Log.v(LOGTAG, "Testing URL: " + url);
|
||||||
|
updateTestStatus(url);
|
||||||
|
activity.reset();
|
||||||
|
//use message to send new URL to avoid interacting with
|
||||||
|
//WebView in non-UI thread
|
||||||
|
handler = activity.getHandler();
|
||||||
|
handler.sendMessage(handler.obtainMessage(
|
||||||
|
ReliabilityTestActivity.MSG_NAVIGATE,
|
||||||
|
runner.mTimeoutInMillis, 0, url));
|
||||||
|
timeoutFlag = activity.waitUntilDone();
|
||||||
|
elapsed = System.currentTimeMillis() - start;
|
||||||
|
if(elapsed < 1000) {
|
||||||
|
Log.w(LOGTAG, "Page load finished in " + elapsed
|
||||||
|
+ "ms, too soon?");
|
||||||
|
} else {
|
||||||
|
Log.v(LOGTAG, "Page load finished in " + elapsed + "ms");
|
||||||
|
}
|
||||||
|
if(timeoutFlag) {
|
||||||
|
writeTimeoutFile(url);
|
||||||
|
}
|
||||||
|
System.runFinalization();
|
||||||
|
System.gc();
|
||||||
|
System.gc();
|
||||||
|
}
|
||||||
|
activity.finish();
|
||||||
|
listReader.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void copyRunnerAssetsToCache() {
|
||||||
|
try {
|
||||||
|
String out_dir = getActivity().getApplicationContext()
|
||||||
|
.getCacheDir().getPath() + "/";
|
||||||
|
|
||||||
|
for( int i=0; i< RELIABILITY_TEST_RUNNER_FILES.length; i++) {
|
||||||
|
InputStream in = getActivity().getAssets().open(
|
||||||
|
RELIABILITY_TEST_RUNNER_FILES[i]);
|
||||||
|
OutputStream out = new FileOutputStream(
|
||||||
|
out_dir + RELIABILITY_TEST_RUNNER_FILES[i]);
|
||||||
|
|
||||||
|
byte[] buf = new byte[2048];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
while ((len = in.read(buf)) >= 0 ) {
|
||||||
|
out.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
}catch (IOException e) {
|
||||||
|
Log.e(LOGTAG, "Cannot extract scripts for testing.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTestStatus(String s) {
|
||||||
|
// write last tested url into status file
|
||||||
|
try {
|
||||||
|
BufferedOutputStream bos = new BufferedOutputStream(
|
||||||
|
new FileOutputStream(TEST_STATUS_FILE));
|
||||||
|
bos.write(s.getBytes());
|
||||||
|
bos.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(LOGTAG, "Cannot update file " + TEST_STATUS_FILE, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readTestStatus() {
|
||||||
|
// read out the test name it stopped last time.
|
||||||
|
String status = null;
|
||||||
|
File testStatusFile = new File(TEST_STATUS_FILE);
|
||||||
|
if(testStatusFile.exists()) {
|
||||||
|
try {
|
||||||
|
BufferedReader inReader = new BufferedReader(
|
||||||
|
new FileReader(testStatusFile));
|
||||||
|
status = inReader.readLine();
|
||||||
|
inReader.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(LOGTAG, "Error reading test status.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fastForward(BufferedReader testListReader, String lastUrl) {
|
||||||
|
//fastforward the BufferedReader to the position right after last url
|
||||||
|
if(lastUrl == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
String line = null;
|
||||||
|
try {
|
||||||
|
while((line = testListReader.readLine()) != null) {
|
||||||
|
if(lastUrl.equals(line))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
Log.e(LOGTAG, "Error while reading test list.", ioe);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeTimeoutFile(String s) {
|
||||||
|
//append to the file containing the list of timeout urls
|
||||||
|
try {
|
||||||
|
BufferedOutputStream bos = new BufferedOutputStream(
|
||||||
|
new FileOutputStream(TEST_TIMEOUT_FILE, true));
|
||||||
|
bos.write(s.getBytes());
|
||||||
|
bos.write('\n');
|
||||||
|
bos.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(LOGTAG, "Cannot update file " + TEST_TIMEOUT_FILE, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,257 @@
|
|||||||
|
package com.android.dumprendertree;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.ActivityThread;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.net.http.SslError;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.webkit.HttpAuthHandler;
|
||||||
|
import android.webkit.JsPromptResult;
|
||||||
|
import android.webkit.JsResult;
|
||||||
|
import android.webkit.SslErrorHandler;
|
||||||
|
import android.webkit.WebChromeClient;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import android.webkit.WebViewClient;
|
||||||
|
import android.webkit.WebSettings.LayoutAlgorithm;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.LinearLayout.LayoutParams;
|
||||||
|
|
||||||
|
public class ReliabilityTestActivity extends Activity {
|
||||||
|
|
||||||
|
public static final String TEST_URL_ACTION = "com.andrdoid.dumprendertree.TestUrlAction";
|
||||||
|
public static final String PARAM_URL = "URL";
|
||||||
|
public static final String PARAM_TIMEOUT = "Timeout";
|
||||||
|
public static final int RESULT_TIMEOUT = 0xDEAD;
|
||||||
|
public static final int MSG_TIMEOUT = 0xC001;
|
||||||
|
public static final int MSG_NAVIGATE = 0xC002;
|
||||||
|
|
||||||
|
private static final String LOGTAG = "ReliabilityTestActivity";
|
||||||
|
|
||||||
|
private WebView webView;
|
||||||
|
private SimpleWebViewClient webViewClient;
|
||||||
|
private SimpleChromeClient chromeClient;
|
||||||
|
private Handler handler;
|
||||||
|
private boolean timeoutFlag;
|
||||||
|
private boolean pageDone;
|
||||||
|
private Object pageDoneLock;
|
||||||
|
private int pageStartCount;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
Log.v(LOGTAG, "onCreate, inst=" + Integer.toHexString(hashCode()));
|
||||||
|
|
||||||
|
LinearLayout contentView = new LinearLayout(this);
|
||||||
|
contentView.setOrientation(LinearLayout.VERTICAL);
|
||||||
|
setContentView(contentView);
|
||||||
|
setTitle("Idle");
|
||||||
|
|
||||||
|
webView = new WebView(this);
|
||||||
|
webView.getSettings().setJavaScriptEnabled(true);
|
||||||
|
webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(false);
|
||||||
|
webView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
|
||||||
|
|
||||||
|
webViewClient = new SimpleWebViewClient();
|
||||||
|
chromeClient = new SimpleChromeClient();
|
||||||
|
webView.setWebViewClient(webViewClient);
|
||||||
|
webView.setWebChromeClient(chromeClient);
|
||||||
|
|
||||||
|
contentView.addView(webView, new LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.FILL_PARENT,
|
||||||
|
ViewGroup.LayoutParams.FILL_PARENT, 0.0f));
|
||||||
|
|
||||||
|
handler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case MSG_TIMEOUT:
|
||||||
|
handleTimeout();
|
||||||
|
return;
|
||||||
|
case MSG_NAVIGATE:
|
||||||
|
navigate((String)msg.obj, msg.arg1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pageDoneLock = new Object();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
synchronized (pageDoneLock) {
|
||||||
|
pageDone = false;
|
||||||
|
}
|
||||||
|
timeoutFlag = false;
|
||||||
|
pageStartCount = 0;
|
||||||
|
chromeClient.resetJsTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigate(String url, int timeout) {
|
||||||
|
if(url == null) {
|
||||||
|
Log.v(LOGTAG, "URL is null, cancelling...");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
webView.stopLoading();
|
||||||
|
Log.v(LOGTAG, "Navigating to URL: " + url);
|
||||||
|
webView.loadUrl(url);
|
||||||
|
|
||||||
|
if(timeout != 0) {
|
||||||
|
//set a timer with specified timeout (in ms)
|
||||||
|
handler.sendMessageDelayed(handler.obtainMessage(MSG_TIMEOUT),
|
||||||
|
timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
Log.v(LOGTAG, "onDestroy, inst=" + Integer.toHexString(hashCode()));
|
||||||
|
super.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPageDone() {
|
||||||
|
synchronized (pageDoneLock) {
|
||||||
|
return pageDone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPageDone(boolean pageDone) {
|
||||||
|
synchronized (pageDoneLock) {
|
||||||
|
this.pageDone = pageDone;
|
||||||
|
pageDoneLock.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleTimeout() {
|
||||||
|
int progress = webView.getProgress();
|
||||||
|
webView.stopLoading();
|
||||||
|
Log.v(LOGTAG, "Page timeout triggered, progress = " + progress);
|
||||||
|
timeoutFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean waitUntilDone() {
|
||||||
|
validateNotAppThread();
|
||||||
|
synchronized (pageDoneLock) {
|
||||||
|
while(!isPageDone()) {
|
||||||
|
try {
|
||||||
|
pageDoneLock.wait();
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
//no-op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return timeoutFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Handler getHandler() {
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void validateNotAppThread() {
|
||||||
|
if (ActivityThread.currentActivityThread() != null) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"This method can not be called from the main application thread");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SimpleWebViewClient extends WebViewClient {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceivedError(WebView view, int errorCode, String description,
|
||||||
|
String failingUrl) {
|
||||||
|
Log.v(LOGTAG, "Received WebCore error: code=" + errorCode
|
||||||
|
+ ", description=" + description
|
||||||
|
+ ", url=" + failingUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
|
||||||
|
//ignore certificate error
|
||||||
|
Log.v(LOGTAG, "Received SSL error: " + error.toString());
|
||||||
|
handler.proceed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,
|
||||||
|
String realm) {
|
||||||
|
//cancel http auth request
|
||||||
|
handler.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
||||||
|
pageStartCount++;
|
||||||
|
Log.v(LOGTAG, "onPageStarted: " + url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPageFinished(WebView view, String url) {
|
||||||
|
Log.v(LOGTAG, "onPageFinished: " + url);
|
||||||
|
handler.postDelayed(new WebViewStatusChecker(), 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SimpleChromeClient extends WebChromeClient {
|
||||||
|
|
||||||
|
private int timeoutCounter = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
|
||||||
|
result.confirm();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
|
||||||
|
result.confirm();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
|
||||||
|
JsPromptResult result) {
|
||||||
|
result.confirm();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onJsTimeout() {
|
||||||
|
timeoutCounter++;
|
||||||
|
Log.v(LOGTAG, "JavaScript timeout, count=" + timeoutCounter);
|
||||||
|
return timeoutCounter > 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetJsTimeout() {
|
||||||
|
timeoutCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceivedTitle(WebView view, String title) {
|
||||||
|
ReliabilityTestActivity.this.setTitle(title);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WebViewStatusChecker implements Runnable {
|
||||||
|
|
||||||
|
private int initialStartCount;
|
||||||
|
|
||||||
|
public WebViewStatusChecker() {
|
||||||
|
initialStartCount = pageStartCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (initialStartCount == pageStartCount) {
|
||||||
|
//perform cleanup
|
||||||
|
webView.stopLoading();
|
||||||
|
Log.v(LOGTAG, "Finishing URL: " + webView.getUrl());
|
||||||
|
handler.removeMessages(MSG_TIMEOUT);
|
||||||
|
setPageDone(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,209 +0,0 @@
|
|||||||
package com.android.dumprendertree;
|
|
||||||
|
|
||||||
import com.android.dumprendertree.TestShellActivity.DumpDataType;
|
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.test.ActivityInstrumentationTestCase2;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
public class ReliabilityTestsAutoTest extends ActivityInstrumentationTestCase2<TestShellActivity> {
|
|
||||||
|
|
||||||
private static final String LOGTAG = "ReliabilityTests";
|
|
||||||
private static final String TEST_LIST_FILE = "/sdcard/android/reliability_tests_list.txt";
|
|
||||||
private static final String TEST_STATUS_FILE = "/sdcard/android/reliability_running_test.txt";
|
|
||||||
private static final String TEST_TIMEOUT_FILE = "/sdcard/android/reliability_timeout_test.txt";
|
|
||||||
static final String RELIABILITY_TEST_RUNNER_FILES[] = {
|
|
||||||
"run_reliability_tests.py"
|
|
||||||
};
|
|
||||||
|
|
||||||
private boolean finished;
|
|
||||||
private List<String> testList;
|
|
||||||
|
|
||||||
public ReliabilityTestsAutoTest() {
|
|
||||||
super("com.android.dumprendertree", TestShellActivity.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getTestList() {
|
|
||||||
// Read test list.
|
|
||||||
testList = new Vector<String>();
|
|
||||||
try {
|
|
||||||
BufferedReader inReader = new BufferedReader(new FileReader(TEST_LIST_FILE));
|
|
||||||
String line;
|
|
||||||
while ((line = inReader.readLine()) != null) {
|
|
||||||
testList.add(line);
|
|
||||||
}
|
|
||||||
inReader.close();
|
|
||||||
Log.v(LOGTAG, "Test list has " + testList.size() + " test(s).");
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(LOGTAG, "Error while reading test list : " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resumeTestList() {
|
|
||||||
// read out the test name it stopped last time.
|
|
||||||
try {
|
|
||||||
BufferedReader inReader = new BufferedReader(new FileReader(TEST_STATUS_FILE));
|
|
||||||
String line = inReader.readLine();
|
|
||||||
for (int i = 0; i < testList.size(); i++) {
|
|
||||||
if (testList.get(i).equals(line)) {
|
|
||||||
testList = new Vector<String>(testList.subList(i+1, testList.size()));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inReader.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(LOGTAG, "Error reading " + TEST_STATUS_FILE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearTestStatus() {
|
|
||||||
// Delete TEST_STATUS_FILE
|
|
||||||
try {
|
|
||||||
File f = new File(TEST_STATUS_FILE);
|
|
||||||
if (f.delete())
|
|
||||||
Log.v(LOGTAG, "Deleted " + TEST_STATUS_FILE);
|
|
||||||
else
|
|
||||||
Log.e(LOGTAG, "Fail to delete " + TEST_STATUS_FILE);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(LOGTAG, "Fail to delete " + TEST_STATUS_FILE + " : " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void clearTestTimeout() {
|
|
||||||
// Delete TEST_TIMEOUT_FILE
|
|
||||||
try {
|
|
||||||
File f = new File(TEST_TIMEOUT_FILE);
|
|
||||||
if (f.delete())
|
|
||||||
Log.v(LOGTAG, "Deleted " + TEST_TIMEOUT_FILE);
|
|
||||||
else
|
|
||||||
Log.e(LOGTAG, "Fail to delete " + TEST_TIMEOUT_FILE);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(LOGTAG, "Fail to delete " + TEST_TIMEOUT_FILE + " : " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateTestStatus(String s) {
|
|
||||||
// Write TEST_STATUS_FILE
|
|
||||||
try {
|
|
||||||
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(TEST_STATUS_FILE));
|
|
||||||
bos.write(s.getBytes());
|
|
||||||
bos.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(LOGTAG, "Cannot update file " + TEST_STATUS_FILE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeTimeoutFile(String s) {
|
|
||||||
// Write TEST_TIMEOUT_FILE
|
|
||||||
try {
|
|
||||||
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(TEST_TIMEOUT_FILE, true));
|
|
||||||
bos.write(s.getBytes());
|
|
||||||
bos.write('\n');
|
|
||||||
bos.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(LOGTAG, "Cannot update file " + TEST_TIMEOUT_FILE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runReliabilityTest(boolean resume) {
|
|
||||||
LayoutTestsAutoRunner runner = (LayoutTestsAutoRunner) getInstrumentation();
|
|
||||||
|
|
||||||
getTestList();
|
|
||||||
if(!resume)
|
|
||||||
clearTestStatus();
|
|
||||||
else
|
|
||||||
resumeTestList();
|
|
||||||
|
|
||||||
TestShellActivity activity = getActivity();
|
|
||||||
activity.setDefaultDumpDataType(DumpDataType.NO_OP);
|
|
||||||
// Run tests.
|
|
||||||
for (int i = 0; i < testList.size(); i++) {
|
|
||||||
String s = testList.get(i);
|
|
||||||
updateTestStatus(s);
|
|
||||||
// Run tests
|
|
||||||
runTestAndWaitUntilDone(activity, s, runner.mTimeoutInMillis);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTestStatus("#DONE");
|
|
||||||
|
|
||||||
activity.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runTestAndWaitUntilDone(TestShellActivity activity, String url, int timeout) {
|
|
||||||
activity.setCallback(new TestShellCallback() {
|
|
||||||
public void finished() {
|
|
||||||
synchronized (ReliabilityTestsAutoTest.this) {
|
|
||||||
finished = true;
|
|
||||||
ReliabilityTestsAutoTest.this.notifyAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void timedOut(String url) {
|
|
||||||
writeTimeoutFile(url);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
finished = false;
|
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
intent.setClass(activity, TestShellActivity.class);
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
|
||||||
intent.putExtra(TestShellActivity.TEST_URL, url);
|
|
||||||
intent.putExtra(TestShellActivity.TIMEOUT_IN_MILLIS, timeout);
|
|
||||||
activity.startActivity(intent);
|
|
||||||
|
|
||||||
// Wait until done.
|
|
||||||
synchronized (this) {
|
|
||||||
while(!finished){
|
|
||||||
try {
|
|
||||||
this.wait();
|
|
||||||
} catch (InterruptedException e) { }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startReliabilityTests() {
|
|
||||||
clearTestTimeout();
|
|
||||||
runReliabilityTest(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void resumeReliabilityTests() {
|
|
||||||
runReliabilityTest(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void copyRunnerAssetsToCache() {
|
|
||||||
try {
|
|
||||||
String out_dir = getActivity().getApplicationContext()
|
|
||||||
.getCacheDir().getPath() + "/";
|
|
||||||
|
|
||||||
for( int i=0; i< RELIABILITY_TEST_RUNNER_FILES.length; i++) {
|
|
||||||
InputStream in = getActivity().getAssets().open(
|
|
||||||
RELIABILITY_TEST_RUNNER_FILES[i]);
|
|
||||||
OutputStream out = new FileOutputStream(
|
|
||||||
out_dir + RELIABILITY_TEST_RUNNER_FILES[i]);
|
|
||||||
|
|
||||||
byte[] buf = new byte[2048];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
while ((len = in.read(buf)) >= 0 ) {
|
|
||||||
out.write(buf, 0, len);
|
|
||||||
}
|
|
||||||
out.close();
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
}catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user