Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: base/test/android/native_test_launcher.cc

Issue 9834037: apk-based test runner work. Not enabled yet. This CL is a combination of upstreaming, ndk/ant-ifi… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
bulach 2012/03/23 10:30:48 nit:2012
John Grabowski 2012/03/24 01:59:18 Done.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stdio.h>
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/android/path_utils.h"
10 #include "base/at_exit.h"
11 #include "base/command_line.h"
12 #include "base/file_path.h"
13 #include "base/file_util.h"
14 #include "base/logging.h"
15 #include "base/stringprintf.h"
16 #include "base/string_tokenizer.h"
17 #include "base/string_util.h"
18 #include "base/test/test_suite.h"
19 #include "jni/chrome_native_test_activity_jni.h"
20 #include "gtest/gtest.h"
21
22 // GTest's main function.
23 extern int main(int argc, char** argv);
24
25 namespace {
26
27 void ParseArgsFromString(const std::string& command_line,
28 std::vector<std::string>* args) {
29 StringTokenizer tokenizer(command_line, kWhitespaceASCII);
30 tokenizer.set_quote_chars("\"");
31 while (tokenizer.GetNext()) {
32 std::string token;
33 RemoveChars(tokenizer.token(), "\"", &token);
34 args->push_back(token);
35 }
36 }
37
38 void ParseArgsFromCommandLineFile(const FilePath& internal_data_path,
39 std::vector<std::string>* args) {
40 static const char kCommandLineFile[] = "chrome-native-tests-command-line";
41 FilePath command_line(internal_data_path.Append(FilePath(kCommandLineFile)));
42 std::string command_line_string;
43 if (file_util::ReadFileToString(command_line, &command_line_string)) {
44 ParseArgsFromString(command_line_string, args);
45 }
46 }
47
48 void ArgsToArgv(const std::vector<std::string>& args,
49 std::vector<char*>* argv) {
50 // We need to pass in a non-const char**.
51 int argc = args.size();
52 argv->resize(argc);
53 for (int i = 0; i < argc; ++i)
54 (*argv)[i] = const_cast<char*>(args[i].c_str());
55 }
56
57 // As we are the native side of an Android app, we don't have any 'console', so
58 // gtest's standard output goes nowhere.
59 // Instead, we inject an "EventListener" in gtest and then we print the results
60 // using LOG, which goes to adb logcat.
61 class AndroidLogPrinter : public ::testing::EmptyTestEventListener {
62 public:
63 void Init(int* argc, char** argv);
64
65 // EmptyTestEventListener
66 virtual void OnTestProgramStart(const ::testing::UnitTest& unit_test);
bulach 2012/03/23 10:30:48 nit: while at it, OVERRIDE on all these methods..
John Grabowski 2012/03/24 01:59:18 Done.
67 virtual void OnTestStart(const ::testing::TestInfo& test_info);
68 virtual void OnTestPartResult(
69 const ::testing::TestPartResult& test_part_result);
70 virtual void OnTestEnd(const ::testing::TestInfo& test_info);
71 virtual void OnTestProgramEnd(const ::testing::UnitTest& unit_test);
72 };
73
74 void AndroidLogPrinter::Init(int* argc, char** argv) {
75 // InitGoogleTest must be called befure we add ourselves as a listener.
76 ::testing::InitGoogleTest(argc, argv);
77 ::testing::TestEventListeners& listeners =
78 ::testing::UnitTest::GetInstance()->listeners();
79 // Adds a listener to the end. Google Test takes the ownership.
80 listeners.Append(this);
81 }
82
83 void AndroidLogPrinter::OnTestProgramStart(
84 const ::testing::UnitTest& unit_test) {
85 std::string msg = StringPrintf("[ START ] %d",
86 unit_test.test_to_run_count());
bulach 2012/03/23 10:30:48 nit: unindent
John Grabowski 2012/03/24 01:59:18 I think you mean "indent more to line up with open
87 LOG(ERROR) << msg;
88 }
89
90 void AndroidLogPrinter::OnTestStart(const ::testing::TestInfo& test_info) {
91 std::string msg = StringPrintf("[ RUN ] %s.%s",
92 test_info.test_case_name(), test_info.name());
bulach 2012/03/23 10:30:48 nit: unindent
John Grabowski 2012/03/24 01:59:18 I think you mean "indent more to line up with open
93 LOG(ERROR) << msg;
94 }
95
96 void AndroidLogPrinter::OnTestPartResult(
97 const ::testing::TestPartResult& test_part_result) {
98 std::string msg = StringPrintf("%s in %s:%d\n%s\n",
99 test_part_result.failed() ? "*** Failure" : "Success",
100 test_part_result.file_name(),
101 test_part_result.line_number(),
102 test_part_result.summary());
bulach 2012/03/23 10:30:48 nit: indent 99-102
John Grabowski 2012/03/24 01:59:18 Done.
103 LOG(ERROR) << msg;
104 }
105
106 void AndroidLogPrinter::OnTestEnd(const ::testing::TestInfo& test_info) {
107 std::string msg = StringPrintf("%s %s.%s",
108 test_info.result()->Failed() ? "[ FAILED ]" : "[ OK ]",
109 test_info.test_case_name(), test_info.name());
110 LOG(ERROR) << msg;
111 }
112
113 void AndroidLogPrinter::OnTestProgramEnd(
114 const ::testing::UnitTest& unit_test) {
115 std::string msg = StringPrintf("[ END ] %d",
116 unit_test.successful_test_count());
117 LOG(ERROR) << msg;
118 }
119
120 void LibraryLoadedOnMainThread(JNIEnv* env) {
121 static const char* const kInitialArgv[] = { "ChromeTestActivity" };
122
123 {
124 // We need a test suite to be created before we do any tracing or
125 // logging: it creates a global at_exit_manager and initializes
126 // internal gtest data structures based on the command line.
127 // It needs to be scoped as it also resets the CommandLine.
128 std::vector<std::string> args;
129 FilePath path("/data/user/0/org.chromium.native_tests/files/");
130 ParseArgsFromCommandLineFile(path, &args);
131 std::vector<char*> argv;
132 ArgsToArgv(args, &argv);
133 base::TestSuite test_suite(argv.size(), &argv[0]);
134 }
135
136 CommandLine::Init(arraysize(kInitialArgv), kInitialArgv);
137
138 logging::InitLogging(NULL,
139 logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG,
140 logging::DONT_LOCK_LOG_FILE,
141 logging::DELETE_OLD_LOG_FILE,
142 logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS);
143 // To view log output with IDs and timestamps use "adb logcat -v threadtime".
144 logging::SetLogItems(false, // Process ID
145 false, // Thread ID
146 false, // Timestamp
147 false); // Tick count
148 VLOG(0) << "Chromium logging enabled: level = " << logging::GetMinLogLevel()
149 << ", default verbosity = " << logging::GetVlogVerbosity();
150 base::android::RegisterPathUtils(env);
151 }
152
153 } // namespace
154
155 // This method is called on a separate java thread so that we won't trigger
156 // an ANR.
157 static void RunTests(JNIEnv* env, jobject obj, jstring jfiles_dir) {
158 FilePath files_dir(base::android::ConvertJavaStringToUTF8(env, jfiles_dir));
159 // A few options, such "--gtest_list_tests", will just use printf directly
160 // and won't use the "AndroidLogPrinter". Redirect stdout to a known file.
161 FilePath stdout_path(files_dir.Append(FilePath("stdout.txt")));
162 freopen(stdout_path.value().c_str(), "w", stdout);
163
164 std::vector<std::string> args;
165 ParseArgsFromCommandLineFile(files_dir, &args);
166
167 // We need to pass in a non-const char**.
168 std::vector<char*> argv;
169 ArgsToArgv(args, &argv);
170
171 int argc = argv.size();
172 // This object is owned by gtest.
173 AndroidLogPrinter* log = new AndroidLogPrinter();
174 log->Init(&argc, &argv[0]);
175
176 main(argc, &argv[0]);
177 }
178
179 // This is called by the VM when the shared library is first loaded.
180 JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
181 base::android::InitVM(vm);
182 JNIEnv* env = base::android::AttachCurrentThread();
183 if (!RegisterNativesImpl(env)) {
184 return -1;
185 }
186 LibraryLoadedOnMainThread(env);
187 return JNI_VERSION_1_4;
188 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698