summaryrefslogtreecommitdiffstats
path: root/testing/gtest/mozilla
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--testing/gtest/mozilla/GTestRunner.cpp179
-rw-r--r--testing/gtest/mozilla/GTestRunner.h10
-rw-r--r--testing/gtest/mozilla/MozAssertions.cpp38
-rw-r--r--testing/gtest/mozilla/MozAssertions.h32
-rw-r--r--testing/gtest/mozilla/MozGTestBench.cpp58
-rw-r--r--testing/gtest/mozilla/MozGTestBench.h25
-rw-r--r--testing/gtest/mozilla/MozHelpers.cpp73
-rw-r--r--testing/gtest/mozilla/MozHelpers.h119
-rw-r--r--testing/gtest/mozilla/SanityTest.cpp30
-rw-r--r--testing/gtest/mozilla/gmock-custom/README.md16
-rw-r--r--testing/gtest/mozilla/gmock-custom/gmock-generated-actions.h10
-rw-r--r--testing/gtest/mozilla/gmock-custom/gmock-matchers.h36
-rw-r--r--testing/gtest/mozilla/gmock-custom/gmock-port.h39
-rw-r--r--testing/gtest/mozilla/gtest-custom/README.md56
-rw-r--r--testing/gtest/mozilla/gtest-custom/gtest-port.h39
-rw-r--r--testing/gtest/mozilla/gtest-custom/gtest-printers.h42
-rw-r--r--testing/gtest/mozilla/gtest-custom/gtest.h37
-rw-r--r--testing/gtest/mozilla/moz.build38
18 files changed, 877 insertions, 0 deletions
diff --git a/testing/gtest/mozilla/GTestRunner.cpp b/testing/gtest/mozilla/GTestRunner.cpp
new file mode 100644
index 0000000000..269adc39b3
--- /dev/null
+++ b/testing/gtest/mozilla/GTestRunner.cpp
@@ -0,0 +1,179 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * * This Source Code Form is subject to the terms of the Mozilla Public
+ * * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "GTestRunner.h"
+#include "gtest/gtest.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/FOG.h"
+#include "mozilla/Preferences.h"
+#include "nsICrashReporter.h"
+#include "nsString.h"
+#include "testing/TestHarness.h"
+#include "prenv.h"
+#ifdef ANDROID
+# include <android/log.h>
+#endif
+#ifdef XP_WIN
+# include "mozilla/ipc/WindowsMessageLoop.h"
+#endif
+
+using ::testing::EmptyTestEventListener;
+using ::testing::InitGoogleTest;
+using ::testing::TestEventListeners;
+using ::testing::TestInfo;
+using ::testing::TestPartResult;
+using ::testing::UnitTest;
+
+namespace mozilla {
+
+#ifdef ANDROID
+# define MOZ_STDOUT_PRINT(...) \
+ __android_log_print(ANDROID_LOG_INFO, "gtest", __VA_ARGS__);
+#else
+# define MOZ_STDOUT_PRINT(...) printf(__VA_ARGS__);
+#endif
+
+#define MOZ_PRINT(...) \
+ MOZ_STDOUT_PRINT(__VA_ARGS__); \
+ if (mLogFile) { \
+ fprintf(mLogFile, __VA_ARGS__); \
+ }
+
+// See gtest.h for method documentation
+class MozillaPrinter : public EmptyTestEventListener {
+ public:
+ MozillaPrinter() : mLogFile(nullptr) {
+ char* path = PR_GetEnv("MOZ_GTEST_LOG_PATH");
+ if (path) {
+ mLogFile = fopen(path, "w");
+ }
+ }
+ virtual void OnTestProgramStart(const UnitTest& /* aUnitTest */) override {
+ MOZ_PRINT("TEST-INFO | GTest unit test starting\n");
+ }
+ virtual void OnTestProgramEnd(const UnitTest& aUnitTest) override {
+ MOZ_PRINT("TEST-%s | GTest unit test: %s\n",
+ aUnitTest.Passed() ? "PASS" : "UNEXPECTED-FAIL",
+ aUnitTest.Passed() ? "passed" : "failed");
+ MOZ_PRINT("Passed: %d\n", aUnitTest.successful_test_count());
+ MOZ_PRINT("Failed: %d\n", aUnitTest.failed_test_count());
+ if (mLogFile) {
+ fclose(mLogFile);
+ mLogFile = nullptr;
+ }
+ }
+ virtual void OnTestStart(const TestInfo& aTestInfo) override {
+ mTestInfo = &aTestInfo;
+ MOZ_PRINT("TEST-START | %s.%s\n", mTestInfo->test_case_name(),
+ mTestInfo->name());
+ }
+ virtual void OnTestPartResult(
+ const TestPartResult& aTestPartResult) override {
+ MOZ_PRINT("TEST-%s | %s.%s | %s @ %s:%i\n",
+ !aTestPartResult.failed() ? "PASS" : "UNEXPECTED-FAIL",
+ mTestInfo ? mTestInfo->test_case_name() : "?",
+ mTestInfo ? mTestInfo->name() : "?", aTestPartResult.summary(),
+ aTestPartResult.file_name(), aTestPartResult.line_number());
+ }
+ virtual void OnTestEnd(const TestInfo& aTestInfo) override {
+ MOZ_PRINT("TEST-%s | %s.%s | test completed (time: %" PRIi64 "ms)\n",
+ aTestInfo.result()->Passed() ? "PASS" : "UNEXPECTED-FAIL",
+ aTestInfo.test_case_name(), aTestInfo.name(),
+ aTestInfo.result()->elapsed_time());
+ MOZ_ASSERT(&aTestInfo == mTestInfo);
+ mTestInfo = nullptr;
+ }
+
+ const TestInfo* mTestInfo;
+ FILE* mLogFile;
+};
+
+static void ReplaceGTestLogger() {
+ // Replace the GTest logger so that it can be passed
+ // by the mozilla test parsers.
+ // Code is based on:
+ // http://googletest.googlecode.com/svn/trunk/samples/sample9_unittest.cc
+ UnitTest& unitTest = *UnitTest::GetInstance();
+ TestEventListeners& listeners = unitTest.listeners();
+ delete listeners.Release(listeners.default_result_printer());
+
+ listeners.Append(new MozillaPrinter);
+}
+
+int RunGTestFunc(int* argc, char** argv) {
+ InitGoogleTest(argc, argv);
+
+ if (getenv("MOZ_TBPL_PARSER")) {
+ ReplaceGTestLogger();
+ }
+
+ PR_SetEnv("XPCOM_DEBUG_BREAK=stack-and-abort");
+
+ ScopedXPCOM xpcom("GTest");
+
+#ifdef XP_WIN
+ mozilla::ipc::windows::InitUIThread();
+#endif
+#ifdef ANDROID
+ // On Android, gtest is running in an application, which uses a
+ // current working directory of '/' by default. Desktop tests
+ // sometimes assume that support files are in the current
+ // working directory. For compatibility with desktop, the Android
+ // harness pushes test support files to the device at the location
+ // specified by MOZ_GTEST_CWD and gtest changes the cwd to that
+ // location.
+ char* path = PR_GetEnv("MOZ_GTEST_CWD");
+ chdir(path);
+#endif
+ nsCOMPtr<nsICrashReporter> crashreporter;
+ char* crashreporterStr = PR_GetEnv("MOZ_CRASHREPORTER");
+ if (crashreporterStr && !strcmp(crashreporterStr, "1")) {
+ // TODO: move this to an even-more-common location to use in all
+ // C++ unittests
+ crashreporter = do_GetService("@mozilla.org/toolkit/crash-reporter;1");
+ if (crashreporter) {
+ printf_stderr("Setting up crash reporting\n");
+ char* path = PR_GetEnv("MOZ_GTEST_MINIDUMPS_PATH");
+ nsCOMPtr<nsIFile> file;
+ if (path) {
+ nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(path), true,
+ getter_AddRefs(file));
+ if (NS_FAILED(rv)) {
+ printf_stderr("Ignoring invalid MOZ_GTEST_MINIDUMPS_PATH\n");
+ }
+ }
+ if (!file) {
+ nsCOMPtr<nsIProperties> dirsvc =
+ do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
+ nsresult rv = dirsvc->Get(NS_OS_CURRENT_WORKING_DIR,
+ NS_GET_IID(nsIFile), getter_AddRefs(file));
+ MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
+ }
+ crashreporter->SetEnabled(true);
+ crashreporter->SetMinidumpPath(file);
+ }
+ }
+
+ // FOG should init exactly once, as early into running as possible, to enable
+ // instrumentation tests to work properly.
+ // However, at init, Glean may decide to send a ping. So let's first tell FOG
+ // that these pings shouldn't actually be uploaded.
+ Preferences::SetInt("telemetry.fog.test.localhost_port", -1);
+ const nsCString empty;
+ RefPtr<FOG>(FOG::GetSingleton())->InitializeFOG(empty, empty);
+
+ return RUN_ALL_TESTS();
+}
+
+// We use a static var 'RunGTest' defined in nsAppRunner.cpp.
+// RunGTest is initialized to nullptr but if GTest (this file)
+// is linked in then RunGTest will be set here indicating
+// GTest is supported.
+class _InitRunGTest {
+ public:
+ _InitRunGTest() { RunGTest = RunGTestFunc; }
+} InitRunGTest;
+
+} // namespace mozilla
diff --git a/testing/gtest/mozilla/GTestRunner.h b/testing/gtest/mozilla/GTestRunner.h
new file mode 100644
index 0000000000..648a7959fa
--- /dev/null
+++ b/testing/gtest/mozilla/GTestRunner.h
@@ -0,0 +1,10 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * * This Source Code Form is subject to the terms of the Mozilla Public
+ * * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+namespace mozilla {
+
+extern int (*RunGTest)(int*, char**);
+
+} // namespace mozilla
diff --git a/testing/gtest/mozilla/MozAssertions.cpp b/testing/gtest/mozilla/MozAssertions.cpp
new file mode 100644
index 0000000000..ed9c68cb83
--- /dev/null
+++ b/testing/gtest/mozilla/MozAssertions.cpp
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "MozAssertions.h"
+#include "mozilla/ErrorNames.h"
+#include "nsString.h"
+
+namespace mozilla::gtest {
+
+static testing::AssertionResult NsresultFailureHelper(const char* expr,
+ const char* expected,
+ nsresult rv) {
+ nsAutoCString name;
+ GetErrorName(rv, name);
+
+ return testing::AssertionFailure()
+ << "Expected: " << expr << " " << expected << ".\n"
+ << " Actual: " << name << "\n";
+}
+
+testing::AssertionResult IsNsresultSuccess(const char* expr, nsresult rv) {
+ if (NS_SUCCEEDED(rv)) {
+ return testing::AssertionSuccess();
+ }
+ return NsresultFailureHelper(expr, "succeeds", rv);
+}
+
+testing::AssertionResult IsNsresultFailure(const char* expr, nsresult rv) {
+ if (NS_FAILED(rv)) {
+ return testing::AssertionSuccess();
+ }
+ return NsresultFailureHelper(expr, "failed", rv);
+}
+
+} // namespace mozilla::gtest
diff --git a/testing/gtest/mozilla/MozAssertions.h b/testing/gtest/mozilla/MozAssertions.h
new file mode 100644
index 0000000000..e65231692a
--- /dev/null
+++ b/testing/gtest/mozilla/MozAssertions.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_gtest_MozAssertions_h__
+#define mozilla_gtest_MozAssertions_h__
+
+#include "gtest/gtest.h"
+#include "nsError.h"
+
+namespace mozilla::gtest {
+
+testing::AssertionResult IsNsresultSuccess(const char* expr, nsresult rv);
+testing::AssertionResult IsNsresultFailure(const char* expr, nsresult rv);
+
+} // namespace mozilla::gtest
+
+#define EXPECT_NS_SUCCEEDED(expr) \
+ EXPECT_PRED_FORMAT1(::mozilla::gtest::IsNsresultSuccess, (expr))
+
+#define ASSERT_NS_SUCCEEDED(expr) \
+ ASSERT_PRED_FORMAT1(::mozilla::gtest::IsNsresultSuccess, (expr))
+
+#define EXPECT_NS_FAILED(expr) \
+ EXPECT_PRED_FORMAT1(::mozilla::gtest::IsNsresultFailure, (expr))
+
+#define ASSERT_NS_FAILED(expr) \
+ ASSERT_PRED_FORMAT1(::mozilla::gtest::IsNsresultFailure, (expr))
+
+#endif // mozilla_gtest_MozAssertions_h__
diff --git a/testing/gtest/mozilla/MozGTestBench.cpp b/testing/gtest/mozilla/MozGTestBench.cpp
new file mode 100644
index 0000000000..cc6898099e
--- /dev/null
+++ b/testing/gtest/mozilla/MozGTestBench.cpp
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "MozGTestBench.h"
+#include "mozilla/TimeStamp.h"
+#include <stdio.h>
+#include <string>
+#include <vector>
+
+#define MOZ_GTEST_BENCH_FRAMEWORK "platform_microbench"
+#define MOZ_GTEST_NUM_ITERATIONS 5
+
+namespace mozilla {
+void GTestBench(const char* aSuite, const char* aName,
+ const std::function<void()>& aTest) {
+#if defined(DEBUG) || defined(MOZ_ASAN)
+ // Run the test to make sure that it doesn't fail but don't log
+ // any measurements since it's not an optimized build.
+ aTest();
+#else
+ bool shouldAlert = bool(getenv("PERFHERDER_ALERTING_ENABLED"));
+ std::vector<int> durations;
+
+ for (int i = 0; i < MOZ_GTEST_NUM_ITERATIONS; i++) {
+ mozilla::TimeStamp start = TimeStamp::Now();
+
+ aTest();
+
+ durations.push_back((TimeStamp::Now() - start).ToMicroseconds());
+ }
+
+ std::string replicatesStr = "[" + std::to_string(durations[0]);
+ for (int i = 1; i < MOZ_GTEST_NUM_ITERATIONS; i++) {
+ replicatesStr += "," + std::to_string(durations[i]);
+ }
+ replicatesStr += "]";
+
+ // median is at index floor(i/2) if number of replicates is odd,
+ // (i/2-1) if even
+ std::sort(durations.begin(), durations.end());
+ int medianIndex =
+ (MOZ_GTEST_NUM_ITERATIONS / 2) + ((durations.size() % 2 == 0) ? (-1) : 0);
+
+ // Print the result for each test. Let perfherder aggregate for us
+ printf(
+ "PERFHERDER_DATA: {\"framework\": {\"name\": \"%s\"}, "
+ "\"suites\": [{\"name\": \"%s\", \"subtests\": "
+ "[{\"name\": \"%s\", \"value\": %i, \"replicates\": %s, "
+ "\"lowerIsBetter\": true, \"shouldAlert\": %s}]"
+ "}]}\n",
+ MOZ_GTEST_BENCH_FRAMEWORK, aSuite, aName, durations[medianIndex],
+ replicatesStr.c_str(), shouldAlert ? "true" : "false");
+#endif
+}
+
+} // namespace mozilla
diff --git a/testing/gtest/mozilla/MozGTestBench.h b/testing/gtest/mozilla/MozGTestBench.h
new file mode 100644
index 0000000000..438b977e4b
--- /dev/null
+++ b/testing/gtest/mozilla/MozGTestBench.h
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef GTEST_MOZGTESTBENCH_H
+#define GTEST_MOZGTESTBENCH_H
+
+#include <functional>
+
+namespace mozilla {
+
+void GTestBench(const char* aSuite, const char* aName,
+ const std::function<void()>& aTest);
+
+} // namespace mozilla
+
+#define MOZ_GTEST_BENCH(suite, test, lambdaOrFunc) \
+ TEST(suite, test) \
+ { mozilla::GTestBench(#suite, #test, lambdaOrFunc); }
+
+#define MOZ_GTEST_BENCH_F(suite, test, lambdaOrFunc) \
+ TEST_F(suite, test) { mozilla::GTestBench(#suite, #test, lambdaOrFunc); }
+
+#endif // GTEST_MOZGTESTBENCH_H
diff --git a/testing/gtest/mozilla/MozHelpers.cpp b/testing/gtest/mozilla/MozHelpers.cpp
new file mode 100644
index 0000000000..78fe614964
--- /dev/null
+++ b/testing/gtest/mozilla/MozHelpers.cpp
@@ -0,0 +1,73 @@
+#include "MozHelpers.h"
+
+#include <iostream>
+
+#include "gtest/gtest-spi.h"
+#include "mozilla/Mutex.h"
+#include "nsDebug.h"
+
+namespace mozilla::gtest {
+
+void DisableCrashReporter() {
+ nsCOMPtr<nsICrashReporter> crashreporter =
+ do_GetService("@mozilla.org/toolkit/crash-reporter;1");
+ if (crashreporter) {
+ crashreporter->SetEnabled(false);
+ }
+}
+
+class ScopedTestResultReporterImpl
+ : public ScopedTestResultReporter,
+ public testing::ScopedFakeTestPartResultReporter {
+ public:
+ explicit ScopedTestResultReporterImpl(ExitMode aExitMode)
+ : testing::ScopedFakeTestPartResultReporter(INTERCEPT_ALL_THREADS,
+ nullptr),
+ mExitMode(aExitMode) {}
+
+ ~ScopedTestResultReporterImpl() {
+ switch (mExitMode) {
+ case ExitMode::ExitOnDtor:
+ exit(ExitCode(Status()));
+ case ExitMode::NoExit:
+ break;
+ }
+ }
+
+ void ReportTestPartResult(const testing::TestPartResult& aResult) override {
+ {
+ MutexAutoLock lock(mMutex);
+ if (aResult.nonfatally_failed() &&
+ mStatus < TestResultStatus::NonFatalFailure) {
+ mStatus = TestResultStatus::NonFatalFailure;
+ }
+
+ if (aResult.fatally_failed() &&
+ mStatus < TestResultStatus::FatalFailure) {
+ mStatus = TestResultStatus::FatalFailure;
+ }
+ }
+
+ std::ostringstream stream;
+ stream << aResult;
+ printf_stderr("%s\n", stream.str().c_str());
+ }
+
+ TestResultStatus Status() const override {
+ MutexAutoLock lock(mMutex);
+ return mStatus;
+ }
+
+ private:
+ const ExitMode mExitMode;
+
+ mutable Mutex mMutex{"ScopedTestResultReporterImpl::mMutex"};
+ TestResultStatus mStatus MOZ_GUARDED_BY(mMutex) = TestResultStatus::Pass;
+};
+
+UniquePtr<ScopedTestResultReporter> ScopedTestResultReporter::Create(
+ ExitMode aExitMode) {
+ return MakeUnique<ScopedTestResultReporterImpl>(aExitMode);
+}
+
+} // namespace mozilla::gtest
diff --git a/testing/gtest/mozilla/MozHelpers.h b/testing/gtest/mozilla/MozHelpers.h
new file mode 100644
index 0000000000..0251f43634
--- /dev/null
+++ b/testing/gtest/mozilla/MozHelpers.h
@@ -0,0 +1,119 @@
+#ifndef TESTING_GTEST_MOZILLA_HELPERS_H_
+#define TESTING_GTEST_MOZILLA_HELPERS_H_
+
+#include "gtest/gtest.h"
+
+#include "mozilla/UniquePtr.h"
+#include "nsCOMPtr.h"
+#include "nsServiceManagerUtils.h"
+#include "nsICrashReporter.h"
+
+#if defined(DEBUG) && !defined(XP_WIN) && !defined(ANDROID)
+# define HAS_GDB_SLEEP_DURATION 1
+extern unsigned int _gdb_sleep_duration;
+#endif
+
+namespace mozilla::gtest {
+
+#if defined(HAS_GDB_SLEEP_DURATION)
+# define ZERO_GDB_SLEEP() _gdb_sleep_duration = 0;
+
+# define SAVE_GDB_SLEEP(v) \
+ v = _gdb_sleep_duration; \
+ ZERO_GDB_SLEEP();
+# define RESTORE_GDB_SLEEP(v) _gdb_sleep_duration = v;
+
+// Some use needs to be in the global namespace
+# define SAVE_GDB_SLEEP_GLOBAL(v) \
+ v = ::_gdb_sleep_duration; \
+ ZERO_GDB_SLEEP();
+# define RESTORE_GDB_SLEEP_GLOBAL(v) ::_gdb_sleep_duration = v;
+
+# define SAVE_GDB_SLEEP_LOCAL() \
+ unsigned int _old_gdb_sleep_duration; \
+ SAVE_GDB_SLEEP(_old_gdb_sleep_duration);
+# define RESTORE_GDB_SLEEP_LOCAL() RESTORE_GDB_SLEEP(_old_gdb_sleep_duration);
+
+#else // defined(HAS_GDB_SLEEP_DURATION)
+
+# define ZERO_GDB_SLEEP() ;
+
+# define SAVE_GDB_SLEEP(v)
+# define SAVE_GDB_SLEEP_GLOBAL(v)
+# define SAVE_GDB_SLEEP_LOCAL()
+# define RESTORE_GDB_SLEEP(v)
+# define RESTORE_GDB_SLEEP_GLOBAL(v)
+# define RESTORE_GDB_SLEEP_LOCAL()
+#endif // defined(HAS_GDB_SLEEP_DURATION)
+
+// Death tests are too slow on OSX because of the system crash reporter.
+#if !defined(XP_DARWIN)
+// Wrap ASSERT_DEATH_IF_SUPPORTED to disable the crash reporter
+// when entering the subprocess, so that the expected crashes don't
+// create a minidump that the gtest harness will interpret as an error.
+# define ASSERT_DEATH_WRAP(a, b) \
+ ASSERT_DEATH_IF_SUPPORTED( \
+ { \
+ mozilla::gtest::DisableCrashReporter(); \
+ a; \
+ }, \
+ b)
+#else
+# define ASSERT_DEATH_WRAP(a, b)
+#endif
+
+void DisableCrashReporter();
+
+/**
+ * Exit mode used for ScopedTestResultReporter.
+ */
+enum class ExitMode {
+ // The user of the reporter handles exit.
+ NoExit,
+ // As the reporter goes out of scope, exit with ExitCode().
+ ExitOnDtor,
+};
+
+/**
+ * Status used by ScopedTestResultReporter.
+ */
+enum class TestResultStatus : int {
+ Pass = 0,
+ NonFatalFailure = 1,
+ FatalFailure = 2,
+};
+
+inline int ExitCode(TestResultStatus aStatus) {
+ return static_cast<int>(aStatus);
+}
+
+/**
+ * This is a helper that reports test results to stderr in death test child
+ * processes, since that is normally disabled by default (with no way of
+ * enabling).
+ *
+ * Note that for this to work as intended the death test child has to, on
+ * failure, exit with an exit code that is unexpected to the death test parent,
+ * so the parent can mark the test case as failed.
+ *
+ * If the parent expects a graceful exit (code 0), ExitCode() can be used with
+ * Status() to exit the child process.
+ *
+ * For simplicity the reporter can exit automatically as it goes out of scope,
+ * when created with ExitMode::ExitOnDtor.
+ */
+class ScopedTestResultReporter {
+ public:
+ virtual ~ScopedTestResultReporter() = default;
+
+ /**
+ * The aggregate status of all observed test results.
+ */
+ virtual TestResultStatus Status() const = 0;
+
+ static UniquePtr<ScopedTestResultReporter> Create(ExitMode aExitMode);
+};
+
+} // namespace mozilla::gtest
+
+#endif // TESTING_GTEST_MOZILLA_HELPERS_H_
diff --git a/testing/gtest/mozilla/SanityTest.cpp b/testing/gtest/mozilla/SanityTest.cpp
new file mode 100644
index 0000000000..7274c43932
--- /dev/null
+++ b/testing/gtest/mozilla/SanityTest.cpp
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * * This Source Code Form is subject to the terms of the Mozilla Public
+ * * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+using ::testing::AtLeast;
+
+// Sanity test to make sure that GTest is hooked into
+// the mozilla build system correctly
+TEST(MozillaGTestSanity, Runs)
+{ EXPECT_EQ(1, 1); }
+namespace {
+class TestMock {
+ public:
+ TestMock() {}
+ MOCK_METHOD0(MockedCall, void());
+};
+} // namespace
+TEST(MozillaGMockSanity, Runs)
+{
+ TestMock mockedClass;
+ EXPECT_CALL(mockedClass, MockedCall()).Times(AtLeast(3));
+
+ mockedClass.MockedCall();
+ mockedClass.MockedCall();
+ mockedClass.MockedCall();
+}
diff --git a/testing/gtest/mozilla/gmock-custom/README.md b/testing/gtest/mozilla/gmock-custom/README.md
new file mode 100644
index 0000000000..f6c93f616d
--- /dev/null
+++ b/testing/gtest/mozilla/gmock-custom/README.md
@@ -0,0 +1,16 @@
+# Customization Points
+
+The custom directory is an injection point for custom user configurations.
+
+## Header `gmock-port.h`
+
+The following macros can be defined:
+
+### Flag related macros:
+
+* `GMOCK_DECLARE_bool_(name)`
+* `GMOCK_DECLARE_int32_(name)`
+* `GMOCK_DECLARE_string_(name)`
+* `GMOCK_DEFINE_bool_(name, default_val, doc)`
+* `GMOCK_DEFINE_int32_(name, default_val, doc)`
+* `GMOCK_DEFINE_string_(name, default_val, doc)`
diff --git a/testing/gtest/mozilla/gmock-custom/gmock-generated-actions.h b/testing/gtest/mozilla/gmock-custom/gmock-generated-actions.h
new file mode 100644
index 0000000000..92d910cf06
--- /dev/null
+++ b/testing/gtest/mozilla/gmock-custom/gmock-generated-actions.h
@@ -0,0 +1,10 @@
+// This file was GENERATED by command:
+// pump.py gmock-generated-actions.h.pump
+// DO NOT EDIT BY HAND!!!
+
+// GOOGLETEST_CM0002 DO NOT DELETE
+
+#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
+#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
+
+#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_
diff --git a/testing/gtest/mozilla/gmock-custom/gmock-matchers.h b/testing/gtest/mozilla/gmock-custom/gmock-matchers.h
new file mode 100644
index 0000000000..14aafaabe6
--- /dev/null
+++ b/testing/gtest/mozilla/gmock-custom/gmock-matchers.h
@@ -0,0 +1,36 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Injection point for custom user configurations. See README for details
+//
+// GOOGLETEST_CM0002 DO NOT DELETE
+
+#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
+#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
+#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_
diff --git a/testing/gtest/mozilla/gmock-custom/gmock-port.h b/testing/gtest/mozilla/gmock-custom/gmock-port.h
new file mode 100644
index 0000000000..0030fe9111
--- /dev/null
+++ b/testing/gtest/mozilla/gmock-custom/gmock-port.h
@@ -0,0 +1,39 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Injection point for custom user configurations. See README for details
+//
+// ** Custom implementation starts here **
+
+// GOOGLETEST_CM0002 DO NOT DELETE
+
+#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
+#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
+
+#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_
diff --git a/testing/gtest/mozilla/gtest-custom/README.md b/testing/gtest/mozilla/gtest-custom/README.md
new file mode 100644
index 0000000000..ff391fb4e2
--- /dev/null
+++ b/testing/gtest/mozilla/gtest-custom/README.md
@@ -0,0 +1,56 @@
+# Customization Points
+
+The custom directory is an injection point for custom user configurations.
+
+## Header `gtest.h`
+
+### The following macros can be defined:
+
+* `GTEST_OS_STACK_TRACE_GETTER_` - The name of an implementation of
+ `OsStackTraceGetterInterface`.
+* `GTEST_CUSTOM_TEMPDIR_FUNCTION_` - An override for `testing::TempDir()`. See
+ `testing::TempDir` for semantics and signature.
+
+## Header `gtest-port.h`
+
+The following macros can be defined:
+
+### Flag related macros:
+
+* `GTEST_FLAG(flag_name)`
+* `GTEST_USE_OWN_FLAGFILE_FLAG_` - Define to 0 when the system provides its
+ own flagfile flag parsing.
+* `GTEST_DECLARE_bool_(name)`
+* `GTEST_DECLARE_int32_(name)`
+* `GTEST_DECLARE_string_(name)`
+* `GTEST_DEFINE_bool_(name, default_val, doc)`
+* `GTEST_DEFINE_int32_(name, default_val, doc)`
+* `GTEST_DEFINE_string_(name, default_val, doc)`
+
+### Logging:
+
+* `GTEST_LOG_(severity)`
+* `GTEST_CHECK_(condition)`
+* Functions `LogToStderr()` and `FlushInfoLog()` have to be provided too.
+
+### Threading:
+
+* `GTEST_HAS_NOTIFICATION_` - Enabled if Notification is already provided.
+* `GTEST_HAS_MUTEX_AND_THREAD_LOCAL_` - Enabled if `Mutex` and `ThreadLocal`
+ are already provided. Must also provide `GTEST_DECLARE_STATIC_MUTEX_(mutex)`
+ and `GTEST_DEFINE_STATIC_MUTEX_(mutex)`
+* `GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks)`
+* `GTEST_LOCK_EXCLUDED_(locks)`
+
+### Underlying library support features
+
+* `GTEST_HAS_CXXABI_H_`
+
+### Exporting API symbols:
+
+* `GTEST_API_` - Specifier for exported symbols.
+
+## Header `gtest-printers.h`
+
+* See documentation at `gtest/gtest-printers.h` for details on how to define a
+ custom printer.
diff --git a/testing/gtest/mozilla/gtest-custom/gtest-port.h b/testing/gtest/mozilla/gtest-custom/gtest-port.h
new file mode 100644
index 0000000000..3159a6671a
--- /dev/null
+++ b/testing/gtest/mozilla/gtest-custom/gtest-port.h
@@ -0,0 +1,39 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Injection point for custom user configurations. See README for details
+//
+// ** Custom implementation starts here **
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
+
+#define GTEST_API_ /* nothing */
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
diff --git a/testing/gtest/mozilla/gtest-custom/gtest-printers.h b/testing/gtest/mozilla/gtest-custom/gtest-printers.h
new file mode 100644
index 0000000000..eb4467abca
--- /dev/null
+++ b/testing/gtest/mozilla/gtest-custom/gtest-printers.h
@@ -0,0 +1,42 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// This file provides an injection point for custom printers in a local
+// installation of gTest.
+// It will be included from gtest-printers.h and the overrides in this file
+// will be visible to everyone.
+//
+// Injection point for custom user configurations. See README for details
+//
+// ** Custom implementation starts here **
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
diff --git a/testing/gtest/mozilla/gtest-custom/gtest.h b/testing/gtest/mozilla/gtest-custom/gtest.h
new file mode 100644
index 0000000000..4c8e07be23
--- /dev/null
+++ b/testing/gtest/mozilla/gtest-custom/gtest.h
@@ -0,0 +1,37 @@
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Injection point for custom user configurations. See README for details
+//
+// ** Custom implementation starts here **
+
+#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
+#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
+
+#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
diff --git a/testing/gtest/mozilla/moz.build b/testing/gtest/mozilla/moz.build
new file mode 100644
index 0000000000..570d377533
--- /dev/null
+++ b/testing/gtest/mozilla/moz.build
@@ -0,0 +1,38 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+if CONFIG["ENABLE_TESTS"]:
+ # Export the gtest-custom files so we can override configuration options as
+ # recommended by gtest.
+ EXPORTS.gtest.internal.custom += [
+ "gtest-custom/gtest-port.h",
+ "gtest-custom/gtest-printers.h",
+ "gtest-custom/gtest.h",
+ ]
+ EXPORTS.gmock.internal.custom += [
+ "gmock-custom/gmock-generated-actions.h",
+ "gmock-custom/gmock-matchers.h",
+ "gmock-custom/gmock-port.h",
+ ]
+
+ EXPORTS.mozilla.gtest += [
+ "MozAssertions.h",
+ "MozHelpers.h",
+ ]
+
+ SOURCES += [
+ "GTestRunner.cpp",
+ "MozAssertions.cpp",
+ "MozGTestBench.cpp",
+ "MozHelpers.cpp",
+ "SanityTest.cpp",
+ ]
+
+ if CONFIG["OS_ARCH"] == "WINNT":
+ LOCAL_INCLUDES += [
+ "/security/sandbox/chromium",
+ ]
+
+ FINAL_LIBRARY = "xul-gtest"