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.util.Log; | 13 import android.util.Log; |
13 | 14 |
14 import java.io.BufferedInputStream; | 15 import java.io.BufferedInputStream; |
15 import java.io.BufferedReader; | 16 import java.io.BufferedReader; |
16 import java.io.File; | 17 import java.io.File; |
17 import java.io.FileInputStream; | 18 import java.io.FileInputStream; |
18 import java.io.FileNotFoundException; | 19 import java.io.FileNotFoundException; |
19 import java.io.IOException; | 20 import java.io.IOException; |
20 import java.io.InputStreamReader; | 21 import java.io.InputStreamReader; |
21 import java.util.HashMap; | 22 import java.util.HashMap; |
(...skipping 12 matching lines...) Expand all Loading... |
34 | 35 |
35 private static final String TAG = "ChromeNativeTestInstrumentationTestRunner
"; | 36 private static final String TAG = "ChromeNativeTestInstrumentationTestRunner
"; |
36 private static final Pattern RE_TEST_OUTPUT = Pattern.compile("\\[ *([^ ]*)
*\\] ?([^ ]+) .*"); | 37 private static final Pattern RE_TEST_OUTPUT = Pattern.compile("\\[ *([^ ]*)
*\\] ?([^ ]+) .*"); |
37 | 38 |
38 private static interface ResultsBundleGenerator { | 39 private static interface ResultsBundleGenerator { |
39 public Bundle generate(Map<String, TestResult> rawResults); | 40 public Bundle generate(Map<String, TestResult> rawResults); |
40 } | 41 } |
41 | 42 |
42 private String mCommandLineFile; | 43 private String mCommandLineFile; |
43 private String mCommandLineFlags; | 44 private String mCommandLineFlags; |
| 45 private File mStdoutFile; |
44 private Bundle mLogBundle; | 46 private Bundle mLogBundle; |
45 private ResultsBundleGenerator mBundleGenerator; | 47 private ResultsBundleGenerator mBundleGenerator; |
46 private boolean mOnlyOutputFailures; | 48 private boolean mOnlyOutputFailures; |
47 | 49 |
48 @Override | 50 @Override |
49 public void onCreate(Bundle arguments) { | 51 public void onCreate(Bundle arguments) { |
50 mCommandLineFile = arguments.getString(ChromeNativeTestActivity.EXTRA_CO
MMAND_LINE_FILE); | 52 mCommandLineFile = arguments.getString(ChromeNativeTestActivity.EXTRA_CO
MMAND_LINE_FILE); |
51 mCommandLineFlags = arguments.getString(ChromeNativeTestActivity.EXTRA_C
OMMAND_LINE_FLAGS); | 53 mCommandLineFlags = arguments.getString(ChromeNativeTestActivity.EXTRA_C
OMMAND_LINE_FLAGS); |
| 54 try { |
| 55 mStdoutFile = File.createTempFile( |
| 56 ".temp_stdout_", ".txt", Environment.getExternalStorageDirec
tory()); |
| 57 Log.i(TAG, "stdout file created: " + mStdoutFile.getAbsolutePath()); |
| 58 } catch (IOException e) { |
| 59 Log.e(TAG, "Unable to create temporary stdout file." + e.toString())
; |
| 60 finish(Activity.RESULT_CANCELED, new Bundle()); |
| 61 return; |
| 62 } |
52 mLogBundle = new Bundle(); | 63 mLogBundle = new Bundle(); |
53 mBundleGenerator = new RobotiumBundleGenerator(); | 64 mBundleGenerator = new RobotiumBundleGenerator(); |
54 mOnlyOutputFailures = arguments.containsKey(EXTRA_ONLY_OUTPUT_FAILURES); | 65 mOnlyOutputFailures = arguments.containsKey(EXTRA_ONLY_OUTPUT_FAILURES); |
55 start(); | 66 start(); |
56 } | 67 } |
57 | 68 |
58 @Override | 69 @Override |
59 public void onStart() { | 70 public void onStart() { |
60 super.onStart(); | 71 super.onStart(); |
61 Bundle results = runTests(); | 72 Bundle results = runTests(); |
62 finish(Activity.RESULT_OK, results); | 73 finish(Activity.RESULT_OK, results); |
63 } | 74 } |
64 | 75 |
65 /** Runs the tests in the ChromeNativeTestActivity and returns a Bundle cont
aining the results. | 76 /** Runs the tests in the ChromeNativeTestActivity and returns a Bundle cont
aining the results. |
66 */ | 77 */ |
67 private Bundle runTests() { | 78 private Bundle runTests() { |
68 Log.i(TAG, "Creating activity."); | 79 Log.i(TAG, "Creating activity."); |
69 Activity activityUnderTest = startNativeTestActivity(); | 80 Activity activityUnderTest = startNativeTestActivity(); |
70 | 81 |
71 Log.i(TAG, "Getting results from FIFO."); | 82 Log.i(TAG, "Waiting for tests to finish."); |
72 Map<String, TestResult> results = parseResultsFromFifo(activityUnderTest
); | 83 try { |
| 84 while (!activityUnderTest.isFinishing()) { |
| 85 Thread.sleep(100); |
| 86 } |
| 87 } catch (InterruptedException e) { |
| 88 Log.e(TAG, "Interrupted while waiting for activity to be destroyed:
" + e.toString()); |
| 89 } |
73 | 90 |
74 Log.i(TAG, "Finishing activity."); | 91 Log.i(TAG, "Getting results."); |
75 activityUnderTest.finish(); | 92 Map<String, TestResult> results = parseResults(activityUnderTest); |
76 | 93 |
77 Log.i(TAG, "Parsing results and generating output."); | 94 Log.i(TAG, "Parsing results and generating output."); |
78 return mBundleGenerator.generate(results); | 95 return mBundleGenerator.generate(results); |
79 } | 96 } |
80 | 97 |
81 /** Starts the ChromeNativeTestActivty. | 98 /** Starts the ChromeNativeTestActivty. |
82 */ | 99 */ |
83 private Activity startNativeTestActivity() { | 100 private Activity startNativeTestActivity() { |
84 Intent i = new Intent(Intent.ACTION_MAIN); | 101 Intent i = new Intent(Intent.ACTION_MAIN); |
85 i.setComponent(new ComponentName( | 102 i.setComponent(new ComponentName( |
86 "org.chromium.native_test", | 103 "org.chromium.native_test", |
87 "org.chromium.native_test.ChromeNativeTestActivity")); | 104 "org.chromium.native_test.ChromeNativeTestActivity")); |
88 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); | 105 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
89 if (mCommandLineFile != null) { | 106 if (mCommandLineFile != null) { |
90 Log.i(TAG, "Passing command line file extra: " + mCommandLineFile); | 107 Log.i(TAG, "Passing command line file extra: " + mCommandLineFile); |
91 i.putExtra(ChromeNativeTestActivity.EXTRA_COMMAND_LINE_FILE, mComman
dLineFile); | 108 i.putExtra(ChromeNativeTestActivity.EXTRA_COMMAND_LINE_FILE, mComman
dLineFile); |
92 } | 109 } |
93 if (mCommandLineFlags != null) { | 110 if (mCommandLineFlags != null) { |
94 Log.i(TAG, "Passing command line flag extra: " + mCommandLineFlags); | 111 Log.i(TAG, "Passing command line flag extra: " + mCommandLineFlags); |
95 i.putExtra(ChromeNativeTestActivity.EXTRA_COMMAND_LINE_FLAGS, mComma
ndLineFlags); | 112 i.putExtra(ChromeNativeTestActivity.EXTRA_COMMAND_LINE_FLAGS, mComma
ndLineFlags); |
96 } | 113 } |
| 114 i.putExtra(ChromeNativeTestActivity.EXTRA_STDOUT_FILE, mStdoutFile.getAb
solutePath()); |
97 return startActivitySync(i); | 115 return startActivitySync(i); |
98 } | 116 } |
99 | 117 |
100 private static enum TestResult { | 118 private static enum TestResult { |
101 PASSED, FAILED, ERROR, UNKNOWN | 119 PASSED, FAILED, ERROR, UNKNOWN |
102 } | 120 } |
103 | 121 |
104 /** | 122 /** |
105 * Generates a map between test names and test results from the instrumente
d Activity's FIFO. | 123 * Generates a map between test names and test results from the instrumente
d Activity's |
| 124 * output. |
106 */ | 125 */ |
107 private Map<String, TestResult> parseResultsFromFifo(Activity activityUnderT
est) { | 126 private Map<String, TestResult> parseResults(Activity activityUnderTest) { |
108 Map<String, TestResult> results = new HashMap<String, TestResult>(); | 127 Map<String, TestResult> results = new HashMap<String, TestResult>(); |
109 | 128 |
110 File fifo = null; | |
111 BufferedReader r = null; | 129 BufferedReader r = null; |
112 | 130 |
113 try { | 131 try { |
114 // Wait for the test to create the FIFO. | 132 if (mStdoutFile == null || !mStdoutFile.exists()) { |
115 fifo = new File(getTargetContext().getFilesDir().getAbsolutePath(),
"test.fifo"); | 133 Log.e(TAG, "Unable to find stdout file."); |
116 while (!fifo.exists()) { | 134 return results; |
117 Thread.sleep(1000); | |
118 } | 135 } |
119 | 136 |
120 r = new BufferedReader( | 137 r = new BufferedReader(new InputStreamReader( |
121 new InputStreamReader(new BufferedInputStream(new FileInputS
tream(fifo)))); | 138 new BufferedInputStream(new FileInputStream(mStdoutFile)))); |
122 | 139 |
123 for (String l = r.readLine(); l != null && !l.equals("<<ScopedMainEn
tryLogger"); | 140 for (String l = r.readLine(); l != null && !l.equals("<<ScopedMainEn
tryLogger"); |
124 l = r.readLine()) { | 141 l = r.readLine()) { |
125 Matcher m = RE_TEST_OUTPUT.matcher(l); | 142 Matcher m = RE_TEST_OUTPUT.matcher(l); |
126 boolean isFailure = false; | 143 boolean isFailure = false; |
127 if (m.matches()) { | 144 if (m.matches()) { |
128 if (m.group(1).equals("RUN")) { | 145 if (m.group(1).equals("RUN")) { |
129 results.put(m.group(2), TestResult.UNKNOWN); | 146 results.put(m.group(2), TestResult.UNKNOWN); |
130 } else if (m.group(1).equals("FAILED")) { | 147 } else if (m.group(1).equals("FAILED")) { |
131 results.put(m.group(2), TestResult.FAILED); | 148 results.put(m.group(2), TestResult.FAILED); |
132 isFailure = true; | 149 isFailure = true; |
133 mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRE
SULT, l + "\n"); | 150 mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRE
SULT, l + "\n"); |
134 sendStatus(0, mLogBundle); | 151 sendStatus(0, mLogBundle); |
135 } else if (m.group(1).equals("OK")) { | 152 } else if (m.group(1).equals("OK")) { |
136 results.put(m.group(2), TestResult.PASSED); | 153 results.put(m.group(2), TestResult.PASSED); |
137 } | 154 } |
138 } | 155 } |
139 | 156 |
140 // TODO(jbudorick): mOnlyOutputFailures is a workaround for b/18
981674. Remove it | 157 // TODO(jbudorick): mOnlyOutputFailures is a workaround for b/18
981674. Remove it |
141 // once that issue is fixed. | 158 // once that issue is fixed. |
142 if (!mOnlyOutputFailures || isFailure) { | 159 if (!mOnlyOutputFailures || isFailure) { |
143 mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT
, l + "\n"); | 160 mLogBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT
, l + "\n"); |
144 sendStatus(0, mLogBundle); | 161 sendStatus(0, mLogBundle); |
145 } | 162 } |
146 Log.i(TAG, l); | 163 Log.i(TAG, l); |
147 } | 164 } |
148 } catch (InterruptedException e) { | |
149 Log.e(TAG, "Interrupted while waiting for FIFO file creation: " + e.
toString()); | |
150 } catch (FileNotFoundException e) { | 165 } catch (FileNotFoundException e) { |
151 Log.e(TAG, "Couldn't find FIFO file: " + e.toString()); | 166 Log.e(TAG, "Couldn't find stdout file file: " + e.toString()); |
152 } catch (IOException e) { | 167 } catch (IOException e) { |
153 Log.e(TAG, "Error handling FIFO file: " + e.toString()); | 168 Log.e(TAG, "Error handling stdout file: " + e.toString()); |
154 } finally { | 169 } finally { |
155 if (r != null) { | 170 if (r != null) { |
156 try { | 171 try { |
157 r.close(); | 172 r.close(); |
158 } catch (IOException e) { | 173 } catch (IOException e) { |
159 Log.e(TAG, "Error while closing FIFO reader."); | 174 Log.e(TAG, "Error while closing stdout reader."); |
160 } | 175 } |
161 } | 176 } |
162 if (fifo != null) { | 177 if (mStdoutFile != null) { |
163 if (!fifo.delete()) { | 178 if (!mStdoutFile.delete()) { |
164 Log.e(TAG, "Unable to delete " + fifo.getAbsolutePath()); | 179 Log.e(TAG, "Unable to delete " + mStdoutFile.getAbsolutePath
()); |
165 } | 180 } |
166 } | 181 } |
167 } | 182 } |
168 return results; | 183 return results; |
169 } | 184 } |
170 | 185 |
171 /** | 186 /** |
172 * Creates a results bundle that emulates the one created by Robotium. | 187 * Creates a results bundle that emulates the one created by Robotium. |
173 */ | 188 */ |
174 private static class RobotiumBundleGenerator implements ResultsBundleGenerat
or { | 189 private static class RobotiumBundleGenerator implements ResultsBundleGenerat
or { |
(...skipping 29 matching lines...) Expand all Loading... |
204 } else { | 219 } else { |
205 resultBuilder.append("\nOK (" + Integer.toString(testsPassed) +
" tests)"); | 220 resultBuilder.append("\nOK (" + Integer.toString(testsPassed) +
" tests)"); |
206 } | 221 } |
207 resultsBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT, | 222 resultsBundle.putString(Instrumentation.REPORT_KEY_STREAMRESULT, |
208 resultBuilder.toString()); | 223 resultBuilder.toString()); |
209 return resultsBundle; | 224 return resultsBundle; |
210 } | 225 } |
211 } | 226 } |
212 | 227 |
213 } | 228 } |
OLD | NEW |