1*b7c941bbSAndroid Build Coastguard Worker /*
2*b7c941bbSAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*b7c941bbSAndroid Build Coastguard Worker *
4*b7c941bbSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*b7c941bbSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*b7c941bbSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*b7c941bbSAndroid Build Coastguard Worker *
8*b7c941bbSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*b7c941bbSAndroid Build Coastguard Worker *
10*b7c941bbSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*b7c941bbSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*b7c941bbSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*b7c941bbSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*b7c941bbSAndroid Build Coastguard Worker * limitations under the License.
15*b7c941bbSAndroid Build Coastguard Worker */
16*b7c941bbSAndroid Build Coastguard Worker
17*b7c941bbSAndroid Build Coastguard Worker #include <sstream>
18*b7c941bbSAndroid Build Coastguard Worker #include <unordered_map>
19*b7c941bbSAndroid Build Coastguard Worker #include <vector>
20*b7c941bbSAndroid Build Coastguard Worker
21*b7c941bbSAndroid Build Coastguard Worker #include <jni.h>
22*b7c941bbSAndroid Build Coastguard Worker #include <nativehelper/ScopedLocalRef.h>
23*b7c941bbSAndroid Build Coastguard Worker #include <nativetesthelper_jni/utils.h>
24*b7c941bbSAndroid Build Coastguard Worker #include <gtest/gtest.h>
25*b7c941bbSAndroid Build Coastguard Worker
26*b7c941bbSAndroid Build Coastguard Worker static JavaVM* gVm = nullptr;
GetJavaVM()27*b7c941bbSAndroid Build Coastguard Worker JavaVM* GetJavaVM() {
28*b7c941bbSAndroid Build Coastguard Worker return gVm;
29*b7c941bbSAndroid Build Coastguard Worker }
RegisterJavaVm(JNIEnv * env)30*b7c941bbSAndroid Build Coastguard Worker static void RegisterJavaVm(JNIEnv* env) {
31*b7c941bbSAndroid Build Coastguard Worker (void)env->GetJavaVM(&gVm);
32*b7c941bbSAndroid Build Coastguard Worker }
33*b7c941bbSAndroid Build Coastguard Worker
34*b7c941bbSAndroid Build Coastguard Worker namespace {
35*b7c941bbSAndroid Build Coastguard Worker
36*b7c941bbSAndroid Build Coastguard Worker struct {
37*b7c941bbSAndroid Build Coastguard Worker jclass clazz;
38*b7c941bbSAndroid Build Coastguard Worker
39*b7c941bbSAndroid Build Coastguard Worker /** static methods **/
40*b7c941bbSAndroid Build Coastguard Worker jmethodID createTestDescription;
41*b7c941bbSAndroid Build Coastguard Worker
42*b7c941bbSAndroid Build Coastguard Worker /** methods **/
43*b7c941bbSAndroid Build Coastguard Worker jmethodID addChild;
44*b7c941bbSAndroid Build Coastguard Worker } gDescription;
45*b7c941bbSAndroid Build Coastguard Worker
46*b7c941bbSAndroid Build Coastguard Worker struct {
47*b7c941bbSAndroid Build Coastguard Worker jclass clazz;
48*b7c941bbSAndroid Build Coastguard Worker
49*b7c941bbSAndroid Build Coastguard Worker jmethodID fireTestStarted;
50*b7c941bbSAndroid Build Coastguard Worker jmethodID fireTestIgnored;
51*b7c941bbSAndroid Build Coastguard Worker jmethodID fireTestFailure;
52*b7c941bbSAndroid Build Coastguard Worker jmethodID fireTestFinished;
53*b7c941bbSAndroid Build Coastguard Worker
54*b7c941bbSAndroid Build Coastguard Worker } gRunNotifier;
55*b7c941bbSAndroid Build Coastguard Worker
56*b7c941bbSAndroid Build Coastguard Worker struct {
57*b7c941bbSAndroid Build Coastguard Worker jclass clazz;
58*b7c941bbSAndroid Build Coastguard Worker jmethodID ctor;
59*b7c941bbSAndroid Build Coastguard Worker } gAssertionFailure;
60*b7c941bbSAndroid Build Coastguard Worker
61*b7c941bbSAndroid Build Coastguard Worker struct {
62*b7c941bbSAndroid Build Coastguard Worker jclass clazz;
63*b7c941bbSAndroid Build Coastguard Worker jmethodID ctor;
64*b7c941bbSAndroid Build Coastguard Worker } gFailure;
65*b7c941bbSAndroid Build Coastguard Worker
66*b7c941bbSAndroid Build Coastguard Worker jobject gEmptyAnnotationsArray;
67*b7c941bbSAndroid Build Coastguard Worker
68*b7c941bbSAndroid Build Coastguard Worker struct TestNameInfo {
69*b7c941bbSAndroid Build Coastguard Worker std::string nativeName;
70*b7c941bbSAndroid Build Coastguard Worker bool run;
71*b7c941bbSAndroid Build Coastguard Worker };
72*b7c941bbSAndroid Build Coastguard Worker // Maps mangled test names to native test names.
73*b7c941bbSAndroid Build Coastguard Worker std::unordered_map<std::string, TestNameInfo> gNativeTestNames;
74*b7c941bbSAndroid Build Coastguard Worker
75*b7c941bbSAndroid Build Coastguard Worker // Return the full native test name as a Java method name, which does not allow
76*b7c941bbSAndroid Build Coastguard Worker // slashes or dots. Store the original name for later lookup.
registerAndMangleTestName(const std::string & nativeName)77*b7c941bbSAndroid Build Coastguard Worker std::string registerAndMangleTestName(const std::string& nativeName) {
78*b7c941bbSAndroid Build Coastguard Worker std::string mangledName = nativeName;
79*b7c941bbSAndroid Build Coastguard Worker std::replace(mangledName.begin(), mangledName.end(), '.', '_');
80*b7c941bbSAndroid Build Coastguard Worker std::replace(mangledName.begin(), mangledName.end(), '/', '_');
81*b7c941bbSAndroid Build Coastguard Worker gNativeTestNames.insert(std::make_pair(mangledName, TestNameInfo{nativeName, false}));
82*b7c941bbSAndroid Build Coastguard Worker return mangledName;
83*b7c941bbSAndroid Build Coastguard Worker }
84*b7c941bbSAndroid Build Coastguard Worker
85*b7c941bbSAndroid Build Coastguard Worker // Creates org.junit.runner.Description object for a GTest given its name.
createTestDescription(JNIEnv * env,jstring className,const std::string & mangledName)86*b7c941bbSAndroid Build Coastguard Worker jobject createTestDescription(JNIEnv* env, jstring className, const std::string& mangledName) {
87*b7c941bbSAndroid Build Coastguard Worker ScopedLocalRef<jstring> jTestName(env, env->NewStringUTF(mangledName.c_str()));
88*b7c941bbSAndroid Build Coastguard Worker return env->CallStaticObjectMethod(gDescription.clazz, gDescription.createTestDescription,
89*b7c941bbSAndroid Build Coastguard Worker className, jTestName.get(), gEmptyAnnotationsArray);
90*b7c941bbSAndroid Build Coastguard Worker }
91*b7c941bbSAndroid Build Coastguard Worker
createTestDescription(JNIEnv * env,jstring className,const char * testCaseName,const char * testName)92*b7c941bbSAndroid Build Coastguard Worker jobject createTestDescription(JNIEnv* env, jstring className, const char* testCaseName, const char* testName) {
93*b7c941bbSAndroid Build Coastguard Worker std::ostringstream nativeNameStream;
94*b7c941bbSAndroid Build Coastguard Worker nativeNameStream << testCaseName << "." << testName;
95*b7c941bbSAndroid Build Coastguard Worker std::string mangledName = registerAndMangleTestName(nativeNameStream.str());
96*b7c941bbSAndroid Build Coastguard Worker return createTestDescription(env, className, mangledName);
97*b7c941bbSAndroid Build Coastguard Worker }
98*b7c941bbSAndroid Build Coastguard Worker
addChild(JNIEnv * env,jobject description,jobject childDescription)99*b7c941bbSAndroid Build Coastguard Worker void addChild(JNIEnv* env, jobject description, jobject childDescription) {
100*b7c941bbSAndroid Build Coastguard Worker env->CallVoidMethod(description, gDescription.addChild, childDescription);
101*b7c941bbSAndroid Build Coastguard Worker }
102*b7c941bbSAndroid Build Coastguard Worker
103*b7c941bbSAndroid Build Coastguard Worker
104*b7c941bbSAndroid Build Coastguard Worker class JUnitNotifyingListener : public ::testing::EmptyTestEventListener {
105*b7c941bbSAndroid Build Coastguard Worker public:
106*b7c941bbSAndroid Build Coastguard Worker
JUnitNotifyingListener(JNIEnv * env,jstring className,jobject runNotifier)107*b7c941bbSAndroid Build Coastguard Worker JUnitNotifyingListener(JNIEnv* env, jstring className, jobject runNotifier)
108*b7c941bbSAndroid Build Coastguard Worker : mEnv(env)
109*b7c941bbSAndroid Build Coastguard Worker , mRunNotifier(runNotifier)
110*b7c941bbSAndroid Build Coastguard Worker , mClassName(className)
111*b7c941bbSAndroid Build Coastguard Worker , mCurrentTestDescription{env, nullptr}
112*b7c941bbSAndroid Build Coastguard Worker {}
~JUnitNotifyingListener()113*b7c941bbSAndroid Build Coastguard Worker virtual ~JUnitNotifyingListener() {}
114*b7c941bbSAndroid Build Coastguard Worker
OnTestStart(const testing::TestInfo & testInfo)115*b7c941bbSAndroid Build Coastguard Worker virtual void OnTestStart(const testing::TestInfo &testInfo) override {
116*b7c941bbSAndroid Build Coastguard Worker mCurrentTestDescription.reset(
117*b7c941bbSAndroid Build Coastguard Worker createTestDescription(mEnv, mClassName, testInfo.test_case_name(), testInfo.name()));
118*b7c941bbSAndroid Build Coastguard Worker notify(gRunNotifier.fireTestStarted);
119*b7c941bbSAndroid Build Coastguard Worker }
120*b7c941bbSAndroid Build Coastguard Worker
OnTestPartResult(const testing::TestPartResult & testPartResult)121*b7c941bbSAndroid Build Coastguard Worker virtual void OnTestPartResult(const testing::TestPartResult &testPartResult) override {
122*b7c941bbSAndroid Build Coastguard Worker if (!testPartResult.passed()) {
123*b7c941bbSAndroid Build Coastguard Worker mCurrentTestError << "\n" << testPartResult.file_name() << ":" << testPartResult.line_number()
124*b7c941bbSAndroid Build Coastguard Worker << "\n" << testPartResult.message() << "\n";
125*b7c941bbSAndroid Build Coastguard Worker }
126*b7c941bbSAndroid Build Coastguard Worker }
127*b7c941bbSAndroid Build Coastguard Worker
OnTestEnd(const testing::TestInfo &)128*b7c941bbSAndroid Build Coastguard Worker virtual void OnTestEnd(const testing::TestInfo&) override {
129*b7c941bbSAndroid Build Coastguard Worker const std::string error = mCurrentTestError.str();
130*b7c941bbSAndroid Build Coastguard Worker
131*b7c941bbSAndroid Build Coastguard Worker if (!error.empty()) {
132*b7c941bbSAndroid Build Coastguard Worker ScopedLocalRef<jstring> jmessage(mEnv, mEnv->NewStringUTF(error.c_str()));
133*b7c941bbSAndroid Build Coastguard Worker ScopedLocalRef<jobject> jthrowable(mEnv, mEnv->NewObject(gAssertionFailure.clazz,
134*b7c941bbSAndroid Build Coastguard Worker gAssertionFailure.ctor, jmessage.get()));
135*b7c941bbSAndroid Build Coastguard Worker ScopedLocalRef<jobject> jfailure(mEnv, mEnv->NewObject(gFailure.clazz,
136*b7c941bbSAndroid Build Coastguard Worker gFailure.ctor, mCurrentTestDescription.get(), jthrowable.get()));
137*b7c941bbSAndroid Build Coastguard Worker mEnv->CallVoidMethod(mRunNotifier, gRunNotifier.fireTestFailure, jfailure.get());
138*b7c941bbSAndroid Build Coastguard Worker }
139*b7c941bbSAndroid Build Coastguard Worker
140*b7c941bbSAndroid Build Coastguard Worker notify(gRunNotifier.fireTestFinished);
141*b7c941bbSAndroid Build Coastguard Worker mCurrentTestDescription.reset();
142*b7c941bbSAndroid Build Coastguard Worker mCurrentTestError.str("");
143*b7c941bbSAndroid Build Coastguard Worker mCurrentTestError.clear();
144*b7c941bbSAndroid Build Coastguard Worker }
145*b7c941bbSAndroid Build Coastguard Worker
reportDisabledTests(const std::vector<std::string> & mangledNames)146*b7c941bbSAndroid Build Coastguard Worker void reportDisabledTests(const std::vector<std::string>& mangledNames) {
147*b7c941bbSAndroid Build Coastguard Worker for (const std::string& mangledName : mangledNames) {
148*b7c941bbSAndroid Build Coastguard Worker mCurrentTestDescription.reset(createTestDescription(mEnv, mClassName, mangledName));
149*b7c941bbSAndroid Build Coastguard Worker notify(gRunNotifier.fireTestIgnored);
150*b7c941bbSAndroid Build Coastguard Worker mCurrentTestDescription.reset();
151*b7c941bbSAndroid Build Coastguard Worker }
152*b7c941bbSAndroid Build Coastguard Worker }
153*b7c941bbSAndroid Build Coastguard Worker
154*b7c941bbSAndroid Build Coastguard Worker private:
notify(jmethodID method)155*b7c941bbSAndroid Build Coastguard Worker void notify(jmethodID method) {
156*b7c941bbSAndroid Build Coastguard Worker mEnv->CallVoidMethod(mRunNotifier, method, mCurrentTestDescription.get());
157*b7c941bbSAndroid Build Coastguard Worker }
158*b7c941bbSAndroid Build Coastguard Worker
159*b7c941bbSAndroid Build Coastguard Worker JNIEnv* mEnv;
160*b7c941bbSAndroid Build Coastguard Worker jobject mRunNotifier;
161*b7c941bbSAndroid Build Coastguard Worker jstring mClassName;
162*b7c941bbSAndroid Build Coastguard Worker ScopedLocalRef<jobject> mCurrentTestDescription;
163*b7c941bbSAndroid Build Coastguard Worker std::ostringstream mCurrentTestError;
164*b7c941bbSAndroid Build Coastguard Worker };
165*b7c941bbSAndroid Build Coastguard Worker
166*b7c941bbSAndroid Build Coastguard Worker } // namespace
167*b7c941bbSAndroid Build Coastguard Worker
168*b7c941bbSAndroid Build Coastguard Worker extern "C"
169*b7c941bbSAndroid Build Coastguard Worker JNIEXPORT void JNICALL
Java_com_android_gtestrunner_GtestRunner_nInitialize(JNIEnv * env,jclass,jstring className,jobject suite)170*b7c941bbSAndroid Build Coastguard Worker Java_com_android_gtestrunner_GtestRunner_nInitialize(JNIEnv *env, jclass, jstring className, jobject suite) {
171*b7c941bbSAndroid Build Coastguard Worker RegisterJavaVm(env);
172*b7c941bbSAndroid Build Coastguard Worker
173*b7c941bbSAndroid Build Coastguard Worker // Initialize gtest, removing the default result printer
174*b7c941bbSAndroid Build Coastguard Worker int argc = 1;
175*b7c941bbSAndroid Build Coastguard Worker const char* argv[] = { "gtest_wrapper" };
176*b7c941bbSAndroid Build Coastguard Worker ::testing::InitGoogleTest(&argc, (char**) argv);
177*b7c941bbSAndroid Build Coastguard Worker
178*b7c941bbSAndroid Build Coastguard Worker auto& listeners = ::testing::UnitTest::GetInstance()->listeners();
179*b7c941bbSAndroid Build Coastguard Worker delete listeners.Release(listeners.default_result_printer());
180*b7c941bbSAndroid Build Coastguard Worker
181*b7c941bbSAndroid Build Coastguard Worker gDescription.clazz = (jclass) env->NewGlobalRef(env->FindClass("org/junit/runner/Description"));
182*b7c941bbSAndroid Build Coastguard Worker gDescription.createTestDescription = env->GetStaticMethodID(gDescription.clazz, "createTestDescription",
183*b7c941bbSAndroid Build Coastguard Worker "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/annotation/Annotation;)Lorg/junit/runner/Description;");
184*b7c941bbSAndroid Build Coastguard Worker gDescription.addChild = env->GetMethodID(gDescription.clazz, "addChild",
185*b7c941bbSAndroid Build Coastguard Worker "(Lorg/junit/runner/Description;)V");
186*b7c941bbSAndroid Build Coastguard Worker
187*b7c941bbSAndroid Build Coastguard Worker jclass annotations = env->FindClass("java/lang/annotation/Annotation");
188*b7c941bbSAndroid Build Coastguard Worker gEmptyAnnotationsArray = env->NewGlobalRef(env->NewObjectArray(0, annotations, nullptr));
189*b7c941bbSAndroid Build Coastguard Worker gNativeTestNames.clear();
190*b7c941bbSAndroid Build Coastguard Worker
191*b7c941bbSAndroid Build Coastguard Worker gAssertionFailure.clazz = (jclass) env->NewGlobalRef(env->FindClass("java/lang/AssertionError"));
192*b7c941bbSAndroid Build Coastguard Worker gAssertionFailure.ctor = env->GetMethodID(gAssertionFailure.clazz, "<init>", "(Ljava/lang/Object;)V");
193*b7c941bbSAndroid Build Coastguard Worker
194*b7c941bbSAndroid Build Coastguard Worker gFailure.clazz = (jclass) env->NewGlobalRef(env->FindClass("org/junit/runner/notification/Failure"));
195*b7c941bbSAndroid Build Coastguard Worker gFailure.ctor = env->GetMethodID(gFailure.clazz, "<init>",
196*b7c941bbSAndroid Build Coastguard Worker "(Lorg/junit/runner/Description;Ljava/lang/Throwable;)V");
197*b7c941bbSAndroid Build Coastguard Worker
198*b7c941bbSAndroid Build Coastguard Worker gRunNotifier.clazz = (jclass) env->NewGlobalRef(
199*b7c941bbSAndroid Build Coastguard Worker env->FindClass("org/junit/runner/notification/RunNotifier"));
200*b7c941bbSAndroid Build Coastguard Worker gRunNotifier.fireTestStarted = env->GetMethodID(gRunNotifier.clazz, "fireTestStarted",
201*b7c941bbSAndroid Build Coastguard Worker "(Lorg/junit/runner/Description;)V");
202*b7c941bbSAndroid Build Coastguard Worker gRunNotifier.fireTestIgnored = env->GetMethodID(gRunNotifier.clazz, "fireTestIgnored",
203*b7c941bbSAndroid Build Coastguard Worker "(Lorg/junit/runner/Description;)V");
204*b7c941bbSAndroid Build Coastguard Worker gRunNotifier.fireTestFinished = env->GetMethodID(gRunNotifier.clazz, "fireTestFinished",
205*b7c941bbSAndroid Build Coastguard Worker "(Lorg/junit/runner/Description;)V");
206*b7c941bbSAndroid Build Coastguard Worker gRunNotifier.fireTestFailure = env->GetMethodID(gRunNotifier.clazz, "fireTestFailure",
207*b7c941bbSAndroid Build Coastguard Worker "(Lorg/junit/runner/notification/Failure;)V");
208*b7c941bbSAndroid Build Coastguard Worker
209*b7c941bbSAndroid Build Coastguard Worker auto unitTest = ::testing::UnitTest::GetInstance();
210*b7c941bbSAndroid Build Coastguard Worker for (int testCaseIndex = 0; testCaseIndex < unitTest->total_test_case_count(); testCaseIndex++) {
211*b7c941bbSAndroid Build Coastguard Worker auto testCase = unitTest->GetTestCase(testCaseIndex);
212*b7c941bbSAndroid Build Coastguard Worker for (int testIndex = 0; testIndex < testCase->total_test_count(); testIndex++) {
213*b7c941bbSAndroid Build Coastguard Worker auto testInfo = testCase->GetTestInfo(testIndex);
214*b7c941bbSAndroid Build Coastguard Worker ScopedLocalRef<jobject> testDescription(env,
215*b7c941bbSAndroid Build Coastguard Worker createTestDescription(env, className, testCase->name(), testInfo->name()));
216*b7c941bbSAndroid Build Coastguard Worker addChild(env, suite, testDescription.get());
217*b7c941bbSAndroid Build Coastguard Worker }
218*b7c941bbSAndroid Build Coastguard Worker }
219*b7c941bbSAndroid Build Coastguard Worker }
220*b7c941bbSAndroid Build Coastguard Worker
221*b7c941bbSAndroid Build Coastguard Worker extern "C"
222*b7c941bbSAndroid Build Coastguard Worker JNIEXPORT void JNICALL
Java_com_android_gtestrunner_GtestRunner_nAddTest(JNIEnv * env,jclass,jstring testName)223*b7c941bbSAndroid Build Coastguard Worker Java_com_android_gtestrunner_GtestRunner_nAddTest(JNIEnv *env, jclass, jstring testName) {
224*b7c941bbSAndroid Build Coastguard Worker const char* testNameChars = env->GetStringUTFChars(testName, JNI_FALSE);
225*b7c941bbSAndroid Build Coastguard Worker auto found = gNativeTestNames.find(testNameChars);
226*b7c941bbSAndroid Build Coastguard Worker if (found != gNativeTestNames.end()) {
227*b7c941bbSAndroid Build Coastguard Worker found->second.run = true;
228*b7c941bbSAndroid Build Coastguard Worker }
229*b7c941bbSAndroid Build Coastguard Worker env->ReleaseStringUTFChars(testName, testNameChars);
230*b7c941bbSAndroid Build Coastguard Worker }
231*b7c941bbSAndroid Build Coastguard Worker
232*b7c941bbSAndroid Build Coastguard Worker extern "C"
233*b7c941bbSAndroid Build Coastguard Worker JNIEXPORT jboolean JNICALL
Java_com_android_gtestrunner_GtestRunner_nRun(JNIEnv * env,jclass,jstring className,jobject notifier)234*b7c941bbSAndroid Build Coastguard Worker Java_com_android_gtestrunner_GtestRunner_nRun(JNIEnv *env, jclass, jstring className, jobject notifier) {
235*b7c941bbSAndroid Build Coastguard Worker // Apply the test filter computed in Java-land. The filter is just a list of test names.
236*b7c941bbSAndroid Build Coastguard Worker std::ostringstream filterStream;
237*b7c941bbSAndroid Build Coastguard Worker std::vector<std::string> mangledNamesOfDisabledTests;
238*b7c941bbSAndroid Build Coastguard Worker for (const auto& entry : gNativeTestNames) {
239*b7c941bbSAndroid Build Coastguard Worker // If the test was not selected for running by the Java layer, ignore it completely.
240*b7c941bbSAndroid Build Coastguard Worker if (!entry.second.run) continue;
241*b7c941bbSAndroid Build Coastguard Worker // If the test has DISABLED_ at the beginning of its name, after a slash or after a dot,
242*b7c941bbSAndroid Build Coastguard Worker // report it as ignored (disabled) to the Java layer.
243*b7c941bbSAndroid Build Coastguard Worker if (entry.second.nativeName.find("DISABLED_") == 0 ||
244*b7c941bbSAndroid Build Coastguard Worker entry.second.nativeName.find("/DISABLED_") != std::string::npos ||
245*b7c941bbSAndroid Build Coastguard Worker entry.second.nativeName.find(".DISABLED_") != std::string::npos) {
246*b7c941bbSAndroid Build Coastguard Worker mangledNamesOfDisabledTests.push_back(entry.first);
247*b7c941bbSAndroid Build Coastguard Worker continue;
248*b7c941bbSAndroid Build Coastguard Worker }
249*b7c941bbSAndroid Build Coastguard Worker filterStream << entry.second.nativeName << ":";
250*b7c941bbSAndroid Build Coastguard Worker }
251*b7c941bbSAndroid Build Coastguard Worker std::string filter = filterStream.str();
252*b7c941bbSAndroid Build Coastguard Worker if (filter.empty()) {
253*b7c941bbSAndroid Build Coastguard Worker // If the string we built is empty, we don't want to run any tests, but GTest runs all tests
254*b7c941bbSAndroid Build Coastguard Worker // when an empty filter is passed. Replace an empty filter with a filter that matches nothing.
255*b7c941bbSAndroid Build Coastguard Worker filter = "-*";
256*b7c941bbSAndroid Build Coastguard Worker } else {
257*b7c941bbSAndroid Build Coastguard Worker // Removes the trailing colon.
258*b7c941bbSAndroid Build Coastguard Worker filter.pop_back();
259*b7c941bbSAndroid Build Coastguard Worker }
260*b7c941bbSAndroid Build Coastguard Worker ::testing::GTEST_FLAG(filter) = filter;
261*b7c941bbSAndroid Build Coastguard Worker
262*b7c941bbSAndroid Build Coastguard Worker auto& listeners = ::testing::UnitTest::GetInstance()->listeners();
263*b7c941bbSAndroid Build Coastguard Worker JUnitNotifyingListener junitListener{env, className, notifier};
264*b7c941bbSAndroid Build Coastguard Worker listeners.Append(&junitListener);
265*b7c941bbSAndroid Build Coastguard Worker int success = RUN_ALL_TESTS();
266*b7c941bbSAndroid Build Coastguard Worker listeners.Release(&junitListener);
267*b7c941bbSAndroid Build Coastguard Worker junitListener.reportDisabledTests(mangledNamesOfDisabledTests);
268*b7c941bbSAndroid Build Coastguard Worker return success == 0;
269*b7c941bbSAndroid Build Coastguard Worker }
270