| 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 |