OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // This class sets up the environment for running the native tests inside an | 5 // This class sets up the environment for running the native tests inside an |
6 // android application. It outputs (to a fifo) markers identifying the | 6 // android application. It outputs (to a fifo) markers identifying the |
7 // START/PASSED/CRASH of the test suite, FAILURE/SUCCESS of individual tests, | 7 // START/PASSED/CRASH of the test suite, FAILURE/SUCCESS of individual tests, |
8 // etc. | 8 // etc. |
9 // These markers are read by the test runner script to generate test results. | 9 // These markers are read by the test runner script to generate test results. |
10 // It installs signal handlers to detect crashes. | 10 // It installs signal handlers to detect crashes. |
(...skipping 20 matching lines...) Expand all Loading... |
31 using testing::native_test_util::ArgsToArgv; | 31 using testing::native_test_util::ArgsToArgv; |
32 using testing::native_test_util::ParseArgsFromCommandLineFile; | 32 using testing::native_test_util::ParseArgsFromCommandLineFile; |
33 using testing::native_test_util::ParseArgsFromString; | 33 using testing::native_test_util::ParseArgsFromString; |
34 using testing::native_test_util::ScopedMainEntryLogger; | 34 using testing::native_test_util::ScopedMainEntryLogger; |
35 | 35 |
36 // The main function of the program to be wrapped as a test apk. | 36 // The main function of the program to be wrapped as a test apk. |
37 extern int main(int argc, char** argv); | 37 extern int main(int argc, char** argv); |
38 | 38 |
39 namespace { | 39 namespace { |
40 | 40 |
41 // These two command line flags are supported for DumpRenderTree, which needs | |
42 // three fifos rather than a combined one: one for stderr, stdin and stdout. | |
43 const char kSeparateStderrFifo[] = "separate-stderr-fifo"; | |
44 const char kCreateStdinFifo[] = "create-stdin-fifo"; | |
45 | |
46 // The test runner script writes the command line file in | 41 // The test runner script writes the command line file in |
47 // "/data/local/tmp". | 42 // "/data/local/tmp". |
48 static const char kCommandLineFilePath[] = | 43 static const char kCommandLineFilePath[] = |
49 "/data/local/tmp/chrome-native-tests-command-line"; | 44 "/data/local/tmp/chrome-native-tests-command-line"; |
50 | 45 |
51 const char kLogTag[] = "chromium"; | 46 const char kLogTag[] = "chromium"; |
52 const char kCrashedMarker[] = "[ CRASHED ]\n"; | 47 const char kCrashedMarker[] = "[ CRASHED ]\n"; |
53 | 48 |
54 // The list of signals which are considered to be crashes. | 49 // The list of signals which are considered to be crashes. |
55 const int kExceptionSignals[] = { | 50 const int kExceptionSignals[] = { |
(...skipping 25 matching lines...) Expand all Loading... |
81 | 76 |
82 // Writes printf() style string to Android's logger where |priority| is one of | 77 // Writes printf() style string to Android's logger where |priority| is one of |
83 // the levels defined in <android/log.h>. | 78 // the levels defined in <android/log.h>. |
84 void AndroidLog(int priority, const char* format, ...) { | 79 void AndroidLog(int priority, const char* format, ...) { |
85 va_list args; | 80 va_list args; |
86 va_start(args, format); | 81 va_start(args, format); |
87 __android_log_vprint(priority, kLogTag, format, args); | 82 __android_log_vprint(priority, kLogTag, format, args); |
88 va_end(args); | 83 va_end(args); |
89 } | 84 } |
90 | 85 |
91 // Ensures that the fifo at |path| is created by deleting whatever is at |path| | |
92 // prior to (re)creating the fifo, otherwise logs the error and terminates the | |
93 // program. | |
94 void EnsureCreateFIFO(const base::FilePath& path) { | |
95 unlink(path.value().c_str()); | |
96 if (base::android::CreateFIFO(path, 0666)) | |
97 return; | |
98 | |
99 AndroidLog(ANDROID_LOG_ERROR, "Failed to create fifo %s: %s\n", | |
100 path.value().c_str(), strerror(errno)); | |
101 exit(EXIT_FAILURE); | |
102 } | |
103 | |
104 // Ensures that |stream| is redirected to |path|, otherwise logs the error and | |
105 // terminates the program. | |
106 void EnsureRedirectStream(FILE* stream, | |
107 const base::FilePath& path, | |
108 const char* mode) { | |
109 if (base::android::RedirectStream(stream, path, mode)) | |
110 return; | |
111 | |
112 AndroidLog(ANDROID_LOG_ERROR, "Failed to redirect stream to file: %s: %s\n", | |
113 path.value().c_str(), strerror(errno)); | |
114 exit(EXIT_FAILURE); | |
115 } | |
116 | |
117 } // namespace | 86 } // namespace |
118 | 87 |
119 static void RunTests(JNIEnv* env, | 88 static void RunTests(JNIEnv* env, |
120 jobject obj, | 89 jobject obj, |
121 jstring jcommand_line_flags, | 90 jstring jcommand_line_flags, |
122 jstring jcommand_line_file_path, | 91 jstring jcommand_line_file_path, |
123 jstring jfiles_dir, | 92 jstring jstdout_file_path, |
| 93 jboolean jstdout_fifo, |
124 jobject app_context) { | 94 jobject app_context) { |
125 base::AtExitManager exit_manager; | 95 base::AtExitManager exit_manager; |
126 | 96 |
127 // Command line initialized basically, will be fully initialized later. | 97 // Command line initialized basically, will be fully initialized later. |
128 static const char* const kInitialArgv[] = { "ChromeTestActivity" }; | 98 static const char* const kInitialArgv[] = { "ChromeTestActivity" }; |
129 base::CommandLine::Init(arraysize(kInitialArgv), kInitialArgv); | 99 base::CommandLine::Init(arraysize(kInitialArgv), kInitialArgv); |
130 | 100 |
131 // Set the application context in base. | 101 // Set the application context in base. |
132 base::android::ScopedJavaLocalRef<jobject> scoped_context( | 102 base::android::ScopedJavaLocalRef<jobject> scoped_context( |
133 env, env->NewLocalRef(app_context)); | 103 env, env->NewLocalRef(app_context)); |
(...skipping 15 matching lines...) Expand all Loading... |
149 | 119 |
150 std::vector<char*> argv; | 120 std::vector<char*> argv; |
151 int argc = ArgsToArgv(args, &argv); | 121 int argc = ArgsToArgv(args, &argv); |
152 | 122 |
153 // Fully initialize command line with arguments. | 123 // Fully initialize command line with arguments. |
154 base::CommandLine::ForCurrentProcess()->AppendArguments( | 124 base::CommandLine::ForCurrentProcess()->AppendArguments( |
155 base::CommandLine(argc, &argv[0]), false); | 125 base::CommandLine(argc, &argv[0]), false); |
156 const base::CommandLine& command_line = | 126 const base::CommandLine& command_line = |
157 *base::CommandLine::ForCurrentProcess(); | 127 *base::CommandLine::ForCurrentProcess(); |
158 | 128 |
159 base::FilePath files_dir( | 129 base::FilePath stdout_file_path( |
160 base::android::ConvertJavaStringToUTF8(env, jfiles_dir)); | 130 base::android::ConvertJavaStringToUTF8(env, jstdout_file_path)); |
161 | 131 |
162 // A few options, such "--gtest_list_tests", will just use printf directly | 132 // A few options, such "--gtest_list_tests", will just use printf directly |
163 // Always redirect stdout to a known file. | 133 // Always redirect stdout to a known file. |
164 base::FilePath fifo_path(files_dir.Append(base::FilePath("test.fifo"))); | 134 unlink(stdout_file_path.value().c_str()); |
165 EnsureCreateFIFO(fifo_path); | 135 if (jstdout_fifo) { |
166 | 136 if (!base::android::CreateFIFO(stdout_file_path, 0666)) { |
167 base::FilePath stderr_fifo_path, stdin_fifo_path; | 137 AndroidLog(ANDROID_LOG_ERROR, "Failed to create fifo %s: %s\n", |
168 | 138 stdout_file_path.value().c_str(), strerror(errno)); |
169 // DumpRenderTree needs a separate fifo for the stderr output. For all | 139 exit(EXIT_FAILURE); |
170 // other tests, insert stderr content to the same fifo we use for stdout. | 140 } |
171 if (command_line.HasSwitch(kSeparateStderrFifo)) { | |
172 stderr_fifo_path = files_dir.Append(base::FilePath("stderr.fifo")); | |
173 EnsureCreateFIFO(stderr_fifo_path); | |
174 } | 141 } |
175 | 142 if (!base::android::RedirectStream(stdout, stdout_file_path, "w")) { |
176 // DumpRenderTree uses stdin to receive input about which test to run. | 143 AndroidLog(ANDROID_LOG_ERROR, "Failed to redirect stream to file: %s: %s\n", |
177 if (command_line.HasSwitch(kCreateStdinFifo)) { | 144 stdout_file_path.value().c_str(), strerror(errno)); |
178 stdin_fifo_path = files_dir.Append(base::FilePath("stdin.fifo")); | 145 exit(EXIT_FAILURE); |
179 EnsureCreateFIFO(stdin_fifo_path); | |
180 } | 146 } |
181 | 147 dup2(STDOUT_FILENO, STDERR_FILENO); |
182 // Only redirect the streams after all fifos have been created. | |
183 EnsureRedirectStream(stdout, fifo_path, "w"); | |
184 if (!stdin_fifo_path.empty()) | |
185 EnsureRedirectStream(stdin, stdin_fifo_path, "r"); | |
186 if (!stderr_fifo_path.empty()) | |
187 EnsureRedirectStream(stderr, stderr_fifo_path, "w"); | |
188 else | |
189 dup2(STDOUT_FILENO, STDERR_FILENO); | |
190 | 148 |
191 if (command_line.HasSwitch(switches::kWaitForDebugger)) { | 149 if (command_line.HasSwitch(switches::kWaitForDebugger)) { |
192 AndroidLog(ANDROID_LOG_VERBOSE, | 150 AndroidLog(ANDROID_LOG_VERBOSE, |
193 "Native test waiting for GDB because flag %s was supplied", | 151 "Native test waiting for GDB because flag %s was supplied", |
194 switches::kWaitForDebugger); | 152 switches::kWaitForDebugger); |
195 base::debug::WaitForDebugger(24 * 60 * 60, false); | 153 base::debug::WaitForDebugger(24 * 60 * 60, false); |
196 } | 154 } |
197 | 155 |
198 ScopedMainEntryLogger scoped_main_entry_logger; | 156 ScopedMainEntryLogger scoped_main_entry_logger; |
199 main(argc, &argv[0]); | 157 main(argc, &argv[0]); |
200 } | 158 } |
201 | 159 |
202 // This is called by the VM when the shared library is first loaded. | 160 // This is called by the VM when the shared library is first loaded. |
203 JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { | 161 JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { |
204 // Install signal handlers to detect crashes. | 162 // Install signal handlers to detect crashes. |
205 InstallHandlers(); | 163 InstallHandlers(); |
206 | 164 |
207 base::android::InitVM(vm); | 165 base::android::InitVM(vm); |
208 JNIEnv* env = base::android::AttachCurrentThread(); | 166 JNIEnv* env = base::android::AttachCurrentThread(); |
209 if (!RegisterNativesImpl(env)) { | 167 if (!RegisterNativesImpl(env)) { |
210 return -1; | 168 return -1; |
211 } | 169 } |
212 | 170 |
213 return JNI_VERSION_1_4; | 171 return JNI_VERSION_1_4; |
214 } | 172 } |
OLD | NEW |