1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org
.chromium
.native_test
;
7 import android
.app
.Activity
;
8 import android
.app
.Instrumentation
;
9 import android
.content
.ComponentName
;
10 import android
.content
.Intent
;
11 import android
.os
.Bundle
;
12 import android
.util
.Log
;
14 import java
.io
.BufferedInputStream
;
15 import java
.io
.BufferedReader
;
17 import java
.io
.FileInputStream
;
18 import java
.io
.FileNotFoundException
;
19 import java
.io
.IOException
;
20 import java
.io
.InputStreamReader
;
21 import java
.util
.HashMap
;
23 import java
.util
.regex
.Matcher
;
24 import java
.util
.regex
.Pattern
;
27 * An Instrumentation that runs tests based on ChromeNativeTestActivity.
29 public class ChromiumNativeTestInstrumentationTestRunner
extends Instrumentation
{
31 private static final String TAG
= "ChromiumNativeTestInstrumentationTestRunner";
32 private static final Pattern RE_TEST_OUTPUT
= Pattern
.compile("\\[ *([^ ]*) *\\] ?([^ ]*) .*");
34 private static interface ResultsBundleGenerator
{
35 public Bundle
generate(Map
<String
, TestResult
> rawResults
);
38 private String mCommandLineFile
;
39 private String mCommandLineFlags
;
40 private Bundle mLogBundle
;
41 private ResultsBundleGenerator mBundleGenerator
;
44 public void onCreate(Bundle arguments
) {
45 mCommandLineFile
= arguments
.getString(ChromeNativeTestActivity
.EXTRA_COMMAND_LINE_FILE
);
46 mCommandLineFlags
= arguments
.getString(ChromeNativeTestActivity
.EXTRA_COMMAND_LINE_FLAGS
);
47 mLogBundle
= new Bundle();
48 mBundleGenerator
= new RobotiumBundleGenerator();
53 public void onStart() {
55 Bundle results
= runTests();
56 finish(Activity
.RESULT_OK
, results
);
59 /** Runs the tests in the ChromeNativeTestActivity and returns a Bundle containing the results.
61 private Bundle
runTests() {
62 Log
.i(TAG
, "Creating activity.");
63 Activity activityUnderTest
= startNativeTestActivity();
65 Log
.i(TAG
, "Getting results from FIFO.");
66 Map
<String
, TestResult
> results
= parseResultsFromFifo(activityUnderTest
);
68 Log
.i(TAG
, "Finishing activity.");
69 activityUnderTest
.finish();
71 Log
.i(TAG
, "Parsing results and generating output.");
72 return mBundleGenerator
.generate(results
);
75 /** Starts the ChromeNativeTestActivty.
77 private Activity
startNativeTestActivity() {
78 Intent i
= new Intent(Intent
.ACTION_MAIN
);
79 i
.setComponent(new ComponentName(
80 "org.chromium.native_test",
81 "org.chromium.native_test.ChromeNativeTestActivity"));
82 i
.setFlags(Intent
.FLAG_ACTIVITY_NEW_TASK
);
83 if (mCommandLineFile
!= null) {
84 Log
.i(TAG
, "Passing command line file extra: " + mCommandLineFile
);
85 i
.putExtra(ChromeNativeTestActivity
.EXTRA_COMMAND_LINE_FILE
, mCommandLineFile
);
87 if (mCommandLineFlags
!= null) {
88 Log
.i(TAG
, "Passing command line flag extra: " + mCommandLineFlags
);
89 i
.putExtra(ChromeNativeTestActivity
.EXTRA_COMMAND_LINE_FLAGS
, mCommandLineFlags
);
91 return startActivitySync(i
);
94 private static enum TestResult
{
95 PASSED
, FAILED
, ERROR
, UNKNOWN
99 * Generates a map between test names and test results from the instrumented Activity's FIFO.
101 private Map
<String
, TestResult
> parseResultsFromFifo(Activity activityUnderTest
) {
102 Map
<String
, TestResult
> results
= new HashMap
<String
, TestResult
>();
105 BufferedReader r
= null;
108 // Wait for the test to create the FIFO.
109 fifo
= new File(getTargetContext().getFilesDir().getAbsolutePath(), "test.fifo");
110 while (!fifo
.exists()) {
114 r
= new BufferedReader(
115 new InputStreamReader(new BufferedInputStream(new FileInputStream(fifo
))));
117 StringBuilder resultsStr
= new StringBuilder();
118 for (String l
= r
.readLine(); l
!= null && !l
.equals("<<ScopedMainEntryLogger");
120 Matcher m
= RE_TEST_OUTPUT
.matcher(l
);
122 if (m
.group(1).equals("RUN")) {
123 results
.put(m
.group(2), TestResult
.UNKNOWN
);
124 } else if (m
.group(1).equals("FAILED")) {
125 results
.put(m
.group(2), TestResult
.FAILED
);
126 } else if (m
.group(1).equals("OK")) {
127 results
.put(m
.group(2), TestResult
.PASSED
);
130 resultsStr
.append(l
);
131 resultsStr
.append("\n");
133 mLogBundle
.putString(Instrumentation
.REPORT_KEY_STREAMRESULT
, resultsStr
.toString());
134 sendStatus(0, mLogBundle
);
135 } catch (InterruptedException e
) {
136 Log
.e(TAG
, "Interrupted while waiting for FIFO file creation: " + e
.toString());
137 } catch (FileNotFoundException e
) {
138 Log
.e(TAG
, "Couldn't find FIFO file: " + e
.toString());
139 } catch (IOException e
) {
140 Log
.e(TAG
, "Error handling FIFO file: " + e
.toString());
145 } catch (IOException e
) {
146 Log
.e(TAG
, "Error while closing FIFO reader.");
150 if (!fifo
.delete()) {
151 Log
.e(TAG
, "Unable to delete " + fifo
.getAbsolutePath());
159 * Creates a results bundle that emulates the one created by Robotium.
161 private static class RobotiumBundleGenerator
implements ResultsBundleGenerator
{
162 public Bundle
generate(Map
<String
, TestResult
> rawResults
) {
163 Bundle resultsBundle
= new Bundle();
168 for (Map
.Entry
<String
, TestResult
> entry
: rawResults
.entrySet()) {
169 switch (entry
.getValue()) {
177 Log
.w(TAG
, "Unhandled: " + entry
.getKey() + ", "
178 + entry
.getValue().toString());
183 StringBuilder resultBuilder
= new StringBuilder();
184 resultBuilder
.append("\nOK (" + Integer
.toString(testsPassed
) + " tests)");
185 if (testsFailed
> 0) {
186 resultBuilder
.append(
187 "\nFAILURES!!! Tests run: " + Integer
.toString(rawResults
.size())
188 + ", Failures: " + Integer
.toString(testsFailed
) + ", Errors: 0");
190 resultsBundle
.putString(Instrumentation
.REPORT_KEY_STREAMRESULT
,
191 resultBuilder
.toString());
192 return resultsBundle
;