1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * * This Source Code Form is subject to the terms of the Mozilla Public
3 * * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "GTestRunner.h"
7 #include "gtest/gtest.h"
8 #include "mozilla/Attributes.h"
9 #include "mozilla/FOG.h"
10 #include "mozilla/Preferences.h"
11 #include "nsICrashReporter.h"
13 #include "testing/TestHarness.h"
16 # include <android/log.h>
19 # include "mozilla/ipc/WindowsMessageLoop.h"
22 using ::testing::EmptyTestEventListener
;
23 using ::testing::InitGoogleTest
;
24 using ::testing::TestEventListeners
;
25 using ::testing::TestInfo
;
26 using ::testing::TestPartResult
;
27 using ::testing::UnitTest
;
32 # define MOZ_STDOUT_PRINT(...) \
33 __android_log_print(ANDROID_LOG_INFO, "gtest", __VA_ARGS__);
35 # define MOZ_STDOUT_PRINT(...) printf(__VA_ARGS__);
38 #define MOZ_PRINT(...) \
39 MOZ_STDOUT_PRINT(__VA_ARGS__); \
41 fprintf(mLogFile, __VA_ARGS__); \
44 // See gtest.h for method documentation
45 class MozillaPrinter
: public EmptyTestEventListener
{
47 MozillaPrinter() : mLogFile(nullptr) {
48 char* path
= PR_GetEnv("MOZ_GTEST_LOG_PATH");
50 mLogFile
= fopen(path
, "w");
53 virtual void OnTestProgramStart(const UnitTest
& /* aUnitTest */) override
{
54 MOZ_PRINT("TEST-INFO | GTest unit test starting\n");
56 virtual void OnTestProgramEnd(const UnitTest
& aUnitTest
) override
{
57 MOZ_PRINT("TEST-%s | GTest unit test: %s\n",
58 aUnitTest
.Passed() ? "PASS" : "UNEXPECTED-FAIL",
59 aUnitTest
.Passed() ? "passed" : "failed");
60 MOZ_PRINT("Passed: %d\n", aUnitTest
.successful_test_count());
61 MOZ_PRINT("Failed: %d\n", aUnitTest
.failed_test_count());
67 virtual void OnTestStart(const TestInfo
& aTestInfo
) override
{
68 mTestInfo
= &aTestInfo
;
69 MOZ_PRINT("TEST-START | %s.%s\n", mTestInfo
->test_case_name(),
72 virtual void OnTestPartResult(
73 const TestPartResult
& aTestPartResult
) override
{
74 MOZ_PRINT("TEST-%s | %s.%s | %s @ %s:%i\n",
75 !aTestPartResult
.failed() ? "PASS" : "UNEXPECTED-FAIL",
76 mTestInfo
? mTestInfo
->test_case_name() : "?",
77 mTestInfo
? mTestInfo
->name() : "?", aTestPartResult
.summary(),
78 aTestPartResult
.file_name(), aTestPartResult
.line_number());
80 virtual void OnTestEnd(const TestInfo
& aTestInfo
) override
{
81 MOZ_PRINT("TEST-%s | %s.%s | test completed (time: %" PRIi64
"ms)\n",
82 aTestInfo
.result()->Passed() ? "PASS" : "UNEXPECTED-FAIL",
83 aTestInfo
.test_case_name(), aTestInfo
.name(),
84 aTestInfo
.result()->elapsed_time());
85 MOZ_ASSERT(&aTestInfo
== mTestInfo
);
89 const TestInfo
* mTestInfo
;
93 static void ReplaceGTestLogger() {
94 // Replace the GTest logger so that it can be passed
95 // by the mozilla test parsers.
97 // http://googletest.googlecode.com/svn/trunk/samples/sample9_unittest.cc
98 UnitTest
& unitTest
= *UnitTest::GetInstance();
99 TestEventListeners
& listeners
= unitTest
.listeners();
100 delete listeners
.Release(listeners
.default_result_printer());
102 listeners
.Append(new MozillaPrinter
);
105 int RunGTestFunc(int* argc
, char** argv
) {
106 InitGoogleTest(argc
, argv
);
108 if (getenv("MOZ_TBPL_PARSER")) {
109 ReplaceGTestLogger();
112 PR_SetEnv("XPCOM_DEBUG_BREAK=stack-and-abort");
114 ScopedXPCOM
xpcom("GTest");
117 mozilla::ipc::windows::InitUIThread();
120 // On Android, gtest is running in an application, which uses a
121 // current working directory of '/' by default. Desktop tests
122 // sometimes assume that support files are in the current
123 // working directory. For compatibility with desktop, the Android
124 // harness pushes test support files to the device at the location
125 // specified by MOZ_GTEST_CWD and gtest changes the cwd to that
127 char* path
= PR_GetEnv("MOZ_GTEST_CWD");
130 nsCOMPtr
<nsICrashReporter
> crashreporter
;
131 char* crashreporterStr
= PR_GetEnv("MOZ_CRASHREPORTER");
132 if (crashreporterStr
&& !strcmp(crashreporterStr
, "1")) {
133 // TODO: move this to an even-more-common location to use in all
135 crashreporter
= do_GetService("@mozilla.org/toolkit/crash-reporter;1");
137 printf_stderr("Setting up crash reporting\n");
138 char* path
= PR_GetEnv("MOZ_GTEST_MINIDUMPS_PATH");
139 nsCOMPtr
<nsIFile
> file
;
141 nsresult rv
= NS_NewLocalFile(NS_ConvertUTF8toUTF16(path
), true,
142 getter_AddRefs(file
));
144 printf_stderr("Ignoring invalid MOZ_GTEST_MINIDUMPS_PATH\n");
148 nsCOMPtr
<nsIProperties
> dirsvc
=
149 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID
);
150 nsresult rv
= dirsvc
->Get(NS_OS_CURRENT_WORKING_DIR
,
151 NS_GET_IID(nsIFile
), getter_AddRefs(file
));
152 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv
));
154 crashreporter
->SetEnabled(true);
155 crashreporter
->SetMinidumpPath(file
);
159 // FOG should init exactly once, as early into running as possible, to enable
160 // instrumentation tests to work properly.
161 // However, at init, Glean may decide to send a ping. So let's first tell FOG
162 // that these pings shouldn't actually be uploaded.
163 Preferences::SetInt("telemetry.fog.test.localhost_port", -1);
164 const nsCString empty
;
165 RefPtr
<FOG
>(FOG::GetSingleton())->InitializeFOG(empty
, empty
);
167 return RUN_ALL_TESTS();
170 // We use a static var 'RunGTest' defined in nsAppRunner.cpp.
171 // RunGTest is initialized to nullptr but if GTest (this file)
172 // is linked in then RunGTest will be set here indicating
173 // GTest is supported.
174 class _InitRunGTest
{
176 _InitRunGTest() { RunGTest
= RunGTestFunc
; }
179 } // namespace mozilla