OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.native_test; | 5 package org.chromium.native_test; |
6 | 6 |
7 import android.app.Activity; | 7 import android.app.Activity; |
8 import android.app.Instrumentation; | 8 import android.app.Instrumentation; |
9 import android.content.ComponentName; | 9 import android.content.ComponentName; |
10 import android.content.Intent; | 10 import android.content.Intent; |
11 import android.os.Bundle; | 11 import android.os.Bundle; |
12 import android.os.Environment; | 12 import android.os.Environment; |
13 import android.util.Log; | 13 import android.util.Log; |
14 | 14 |
| 15 import org.chromium.test.support.ResultsBundleGenerator; |
| 16 import org.chromium.test.support.RobotiumBundleGenerator; |
| 17 |
15 import java.io.BufferedInputStream; | 18 import java.io.BufferedInputStream; |
16 import java.io.BufferedReader; | 19 import java.io.BufferedReader; |
17 import java.io.File; | 20 import java.io.File; |
18 import java.io.FileInputStream; | 21 import java.io.FileInputStream; |
19 import java.io.FileNotFoundException; | 22 import java.io.FileNotFoundException; |
20 import java.io.IOException; | 23 import java.io.IOException; |
21 import java.io.InputStreamReader; | 24 import java.io.InputStreamReader; |
22 import java.util.HashMap; | 25 import java.util.HashMap; |
23 import java.util.Map; | 26 import java.util.Map; |
24 import java.util.regex.Matcher; | 27 import java.util.regex.Matcher; |
25 import java.util.regex.Pattern; | 28 import java.util.regex.Pattern; |
26 | 29 |
27 /** | 30 /** |
28 * An Instrumentation that runs tests based on ChromeNativeTestActivity. | 31 * An Instrumentation that runs tests based on ChromeNativeTestActivity. |
29 */ | 32 */ |
30 public class ChromeNativeTestInstrumentationTestRunner extends Instrumentation { | 33 public class ChromeNativeTestInstrumentationTestRunner extends Instrumentation { |
31 // TODO(jbudorick): Remove this extra when b/18981674 is fixed. | 34 // TODO(jbudorick): Remove this extra when b/18981674 is fixed. |
32 public static final String EXTRA_ONLY_OUTPUT_FAILURES = | 35 public static final String EXTRA_ONLY_OUTPUT_FAILURES = |
33 "org.chromium.native_test.ChromeNativeTestInstrumentationTestRunner.
" | 36 "org.chromium.native_test.ChromeNativeTestInstrumentationTestRunner.
" |
34 + "OnlyOutputFailures"; | 37 + "OnlyOutputFailures"; |
35 | 38 |
36 private static final String TAG = "ChromeNativeTestInstrumentationTestRunner
"; | 39 private static final String TAG = "ChromeNativeTestInstrumentationTestRunner
"; |
37 | 40 |
38 private static final int ACCEPT_TIMEOUT_MS = 5000; | 41 private static final int ACCEPT_TIMEOUT_MS = 5000; |
39 private static final Pattern RE_TEST_OUTPUT = Pattern.compile("\\[ *([^ ]*)
*\\] ?([^ ]+) .*"); | 42 private static final Pattern RE_TEST_OUTPUT = Pattern.compile("\\[ *([^ ]*)
*\\] ?([^ ]+) .*"); |
40 | 43 |
41 private static interface ResultsBundleGenerator { | |
42 public Bundle generate(Map<String, TestResult> rawResults); | |
43 } | |
44 | |
45 private String mCommandLineFile; | 44 private String mCommandLineFile; |
46 private String mCommandLineFlags; | 45 private String mCommandLineFlags; |
47 private File mStdoutFile; | 46 private File mStdoutFile; |
48 private Bundle mLogBundle; | 47 private Bundle mLogBundle; |
49 private ResultsBundleGenerator mBundleGenerator; | 48 private ResultsBundleGenerator mBundleGenerator; |
50 private boolean mOnlyOutputFailures; | 49 private boolean mOnlyOutputFailures; |
51 | 50 |
52 @Override | 51 @Override |
53 public void onCreate(Bundle arguments) { | 52 public void onCreate(Bundle arguments) { |
54 mCommandLineFile = arguments.getString(ChromeNativeTestActivity.EXTRA_CO
MMAND_LINE_FILE); | 53 mCommandLineFile = arguments.getString(ChromeNativeTestActivity.EXTRA_CO
MMAND_LINE_FILE); |
(...skipping 29 matching lines...) Expand all Loading... |
84 Log.i(TAG, "Waiting for tests to finish."); | 83 Log.i(TAG, "Waiting for tests to finish."); |
85 try { | 84 try { |
86 while (!activityUnderTest.isFinishing()) { | 85 while (!activityUnderTest.isFinishing()) { |
87 Thread.sleep(100); | 86 Thread.sleep(100); |
88 } | 87 } |
89 } catch (InterruptedException e) { | 88 } catch (InterruptedException e) { |
90 Log.e(TAG, "Interrupted while waiting for activity to be destroyed:
" + e.toString()); | 89 Log.e(TAG, "Interrupted while waiting for activity to be destroyed:
" + e.toString()); |
91 } | 90 } |
92 | 91 |
93 Log.i(TAG, "Getting results."); | 92 Log.i(TAG, "Getting results."); |
94 Map<String, TestResult> results = parseResults(activityUnderTest); | 93 Map<String, ResultsBundleGenerator.TestResult> results = parseResults(ac
tivityUnderTest); |
95 | 94 |
96 Log.i(TAG, "Parsing results and generating output."); | 95 Log.i(TAG, "Parsing results and generating output."); |
97 return mBundleGenerator.generate(results); | 96 return mBundleGenerator.generate(results); |
98 } | 97 } |
99 | 98 |
100 /** Starts the ChromeNativeTestActivty. | 99 /** Starts the ChromeNativeTestActivty. |
101 */ | 100 */ |
102 private Activity startNativeTestActivity() { | 101 private Activity startNativeTestActivity() { |
103 Intent i = new Intent(Intent.ACTION_MAIN); | 102 Intent i = new Intent(Intent.ACTION_MAIN); |
104 i.setComponent(new ComponentName( | 103 i.setComponent(new ComponentName( |
105 "org.chromium.native_test", | 104 "org.chromium.native_test", |
106 "org.chromium.native_test.ChromeNativeTestActivity")); | 105 "org.chromium.native_test.ChromeNativeTestActivity")); |
107 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | 106 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
108 if (mCommandLineFile != null) { | 107 if (mCommandLineFile != null) { |
109 Log.i(TAG, "Passing command line file extra: " + mCommandLineFile); | 108 Log.i(TAG, "Passing command line file extra: " + mCommandLineFile); |
110 i.putExtra(ChromeNativeTestActivity.EXTRA_COMMAND_LINE_FILE, mComman
dLineFile); | 109 i.putExtra(ChromeNativeTestActivity.EXTRA_COMMAND_LINE_FILE, mComman
dLineFile); |
111 } | 110 } |
112 if (mCommandLineFlags != null) { | 111 if (mCommandLineFlags != null) { |
113 Log.i(TAG, "Passing command line flag extra: " + mCommandLineFlags); | 112 Log.i(TAG, "Passing command line flag extra: " + mCommandLineFlags); |
114 i.putExtra(ChromeNativeTestActivity.EXTRA_COMMAND_LINE_FLAGS, mComma
ndLineFlags); | 113 i.putExtra(ChromeNativeTestActivity.EXTRA_COMMAND_LINE_FLAGS, mComma
ndLineFlags); |
115 } | 114 } |
116 i.putExtra(ChromeNativeTestActivity.EXTRA_STDOUT_FILE, mStdoutFile.getAb
solutePath()); | 115 i.putExtra(ChromeNativeTestActivity.EXTRA_STDOUT_FILE, mStdoutFile.getAb
solutePath()); |
117 return startActivitySync(i); | 116 return startActivitySync(i); |
118 } | 117 } |
119 | 118 |
120 private static enum TestResult { | |
121 PASSED, FAILED, ERROR, UNKNOWN | |
122 } | |
123 | |
124 /** | 119 /** |
125 * Generates a map between test names and test results from the instrumente
d Activity's | 120 * Generates a map between test names and test results from the instrumente
d Activity's |
126 * output. | 121 * output. |
127 */ | 122 */ |
128 private Map<String, TestResult> parseResults(Activity activityUnderTest) { | 123 private Map<String, ResultsBundleGenerator.TestResult> parseResults( |
129 Map<String, TestResult> results = new HashMap<String, TestResult>(); | 124 Activity activityUnderTest) { |
| 125 Map<String, ResultsBundleGenerator.TestResult> results = |
| 126 new HashMap<String, ResultsBundleGenerator.TestResult>(); |
130 | 127 |
131 BufferedReader r = null; | 128 BufferedReader r = null; |
132 | 129 |
133 try { | 130 try { |
134 if (mStdoutFile == null || !mStdoutFile.exists()) { | 131 if (mStdoutFile == null || !mStdoutFile.exists()) { |
135 Log.e(TAG, "Unable to find stdout file."); | 132 Log.e(TAG, "Unable to find stdout file."); |
136 return results; | 133 return results; |
137 } | 134 } |
138 | 135 |
139 r = new BufferedReader(new InputStreamReader( | 136 r = new BufferedReader(new InputStreamReader( |
140 new BufferedInputStream(new FileInputStream(mStdoutFile)))); | 137 new BufferedInputStream(new FileInputStream(mStdoutFile)))); |
141 | 138 |
142 for (String l = r.readLine(); l != null && !l.equals("<<ScopedMainEn
tryLogger"); | 139 for (String l = r.readLine(); l != null && !l.equals("<<ScopedMainEn
tryLogger"); |
143 l = r.readLine()) { | 140 l = r.readLine()) { |
144 Matcher m = RE_TEST_OUTPUT.matcher(l); | 141 Matcher m = RE_TEST_OUTPUT.matcher(l); |
145 boolean isFailure = false; | 142 boolean isFailure = false; |
146 if (m.matches()) { | 143 if (m.matches()) { |
147 if (m.group(1).equals("RUN")) { | 144 if (m.group(1).equals("RUN")) { |
148 results.put(m.group(2), TestResult.UNKNOWN); | 145 results.put(m.group(2), ResultsBundleGenerator.TestResul
t.UNKNOWN); |
149 } else if (m.group(1).equals("FAILED")) { | 146 } else if (m.group(1).equals("FAILED")) { |
150 results.put(m.group(2), TestResult.FAILED); | 147 results.put(m.group(2), ResultsBundleGenerator.TestResul
t.FAILED); |
151 isFailure = true; | 148 isFailure = true; |
152 mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRE
SULT, l + "\n"); | 149 mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRE
SULT, l + "\n"); |
153 sendStatus(0, mLogBundle); | 150 sendStatus(0, mLogBundle); |
154 } else if (m.group(1).equals("OK")) { | 151 } else if (m.group(1).equals("OK")) { |
155 results.put(m.group(2), TestResult.PASSED); | 152 results.put(m.group(2), ResultsBundleGenerator.TestResul
t.PASSED); |
156 } | 153 } |
157 } | 154 } |
158 | 155 |
159 // TODO(jbudorick): mOnlyOutputFailures is a workaround for b/18
981674. Remove it | 156 // TODO(jbudorick): mOnlyOutputFailures is a workaround for b/18
981674. Remove it |
160 // once that issue is fixed. | 157 // once that issue is fixed. |
161 if (!mOnlyOutputFailures || isFailure) { | 158 if (!mOnlyOutputFailures || isFailure) { |
162 mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT
, l + "\n"); | 159 mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT
, l + "\n"); |
163 sendStatus(0, mLogBundle); | 160 sendStatus(0, mLogBundle); |
164 } | 161 } |
165 Log.i(TAG, l); | 162 Log.i(TAG, l); |
(...skipping 12 matching lines...) Expand all Loading... |
178 } | 175 } |
179 if (mStdoutFile != null) { | 176 if (mStdoutFile != null) { |
180 if (!mStdoutFile.delete()) { | 177 if (!mStdoutFile.delete()) { |
181 Log.e(TAG, "Unable to delete " + mStdoutFile.getAbsolutePath
()); | 178 Log.e(TAG, "Unable to delete " + mStdoutFile.getAbsolutePath
()); |
182 } | 179 } |
183 } | 180 } |
184 } | 181 } |
185 return results; | 182 return results; |
186 } | 183 } |
187 | 184 |
188 /** | |
189 * Creates a results bundle that emulates the one created by Robotium. | |
190 */ | |
191 private static class RobotiumBundleGenerator implements ResultsBundleGenerat
or { | |
192 public Bundle generate(Map<String, TestResult> rawResults) { | |
193 Bundle resultsBundle = new Bundle(); | |
194 | |
195 int testsPassed = 0; | |
196 int testsFailed = 0; | |
197 | |
198 for (Map.Entry<String, TestResult> entry : rawResults.entrySet()) { | |
199 switch (entry.getValue()) { | |
200 case PASSED: | |
201 ++testsPassed; | |
202 break; | |
203 case FAILED: | |
204 // TODO(jbudorick): Remove this log message once AMP exe
cution and | |
205 // results handling has been stabilized. | |
206 Log.d(TAG, "FAILED: " + entry.getKey()); | |
207 ++testsFailed; | |
208 break; | |
209 default: | |
210 Log.w(TAG, "Unhandled: " + entry.getKey() + ", " | |
211 + entry.getValue().toString()); | |
212 break; | |
213 } | |
214 } | |
215 | |
216 StringBuilder resultBuilder = new StringBuilder(); | |
217 if (testsFailed > 0) { | |
218 resultBuilder.append( | |
219 "\nFAILURES!!! Tests run: " + Integer.toString(rawResult
s.size()) | |
220 + ", Failures: " + Integer.toString(testsFailed) + ", Er
rors: 0"); | |
221 } else { | |
222 resultBuilder.append("\nOK (" + Integer.toString(testsPassed) +
" tests)"); | |
223 } | |
224 resultsBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT, | |
225 resultBuilder.toString()); | |
226 return resultsBundle; | |
227 } | |
228 } | |
229 | 185 |
230 } | 186 } |
OLD | NEW |