tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

GTestRunner.cpp (6715B)


      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/. */
      5 
      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"
     12 #include "nsString.h"
     13 #include "testing/TestHarness.h"
     14 #include "prenv.h"
     15 #ifdef ANDROID
     16 #  include <android/log.h>
     17 #endif
     18 #ifdef XP_WIN
     19 #  include "mozilla/ipc/WindowsMessageLoop.h"
     20 #endif
     21 
     22 using ::testing::EmptyTestEventListener;
     23 using ::testing::InitGoogleTest;
     24 using ::testing::TestEventListeners;
     25 using ::testing::TestInfo;
     26 using ::testing::TestPartResult;
     27 using ::testing::UnitTest;
     28 
     29 namespace mozilla {
     30 
     31 #ifdef ANDROID
     32 #  define MOZ_STDOUT_PRINT(...) \
     33    __android_log_print(ANDROID_LOG_INFO, "gtest", __VA_ARGS__);
     34 #else
     35 #  define MOZ_STDOUT_PRINT(...) printf(__VA_ARGS__);
     36 #endif
     37 
     38 #define MOZ_PRINT(...)              \
     39  MOZ_STDOUT_PRINT(__VA_ARGS__);    \
     40  if (mLogFile) {                   \
     41    fprintf(mLogFile, __VA_ARGS__); \
     42  }
     43 
     44 // See gtest.h for method documentation
     45 class MozillaPrinter : public EmptyTestEventListener {
     46 public:
     47  MozillaPrinter() : mLogFile(nullptr) {
     48    char* path = PR_GetEnv("MOZ_GTEST_LOG_PATH");
     49    if (path) {
     50      mLogFile = fopen(path, "w");
     51    }
     52  }
     53  virtual void OnTestProgramStart(const UnitTest& /* aUnitTest */) override {
     54    MOZ_PRINT("TEST-INFO | GTest unit test starting\n");
     55  }
     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("Skipped: %d\n", aUnitTest.skipped_test_count());
     61    MOZ_PRINT("Passed: %d\n", aUnitTest.successful_test_count());
     62    MOZ_PRINT("Failed: %d\n", aUnitTest.failed_test_count());
     63    if (mLogFile) {
     64      fclose(mLogFile);
     65      mLogFile = nullptr;
     66    }
     67  }
     68  virtual void OnTestStart(const TestInfo& aTestInfo) override {
     69    mTestInfo = &aTestInfo;
     70    MOZ_PRINT("TEST-START | %s.%s\n", mTestInfo->test_case_name(),
     71              mTestInfo->name());
     72  }
     73  virtual void OnTestPartResult(
     74      const TestPartResult& aTestPartResult) override {
     75    MOZ_PRINT("TEST-%s | %s.%s | %s @ %s:%i\n",
     76              !aTestPartResult.failed() ? "PASS" : "UNEXPECTED-FAIL",
     77              mTestInfo ? mTestInfo->test_case_name() : "?",
     78              mTestInfo ? mTestInfo->name() : "?", aTestPartResult.summary(),
     79              aTestPartResult.file_name(), aTestPartResult.line_number());
     80  }
     81  virtual void OnTestEnd(const TestInfo& aTestInfo) override {
     82    MOZ_PRINT(
     83        "TEST-%s | %s.%s | test completed (time: %" PRIi64 "ms)\n",
     84        aTestInfo.result()->Passed()
     85            ? "PASS"
     86            : (aTestInfo.result()->Skipped() ? "FAIL" : "UNEXPECTED-FAIL"),
     87        aTestInfo.test_case_name(), aTestInfo.name(),
     88        aTestInfo.result()->elapsed_time());
     89    MOZ_ASSERT(&aTestInfo == mTestInfo);
     90    mTestInfo = nullptr;
     91  }
     92 
     93  const TestInfo* mTestInfo;
     94  FILE* mLogFile;
     95 };
     96 
     97 static void ReplaceGTestLogger() {
     98  // Replace the GTest logger so that it can be passed
     99  // by the mozilla test parsers.
    100  // Code is based on:
    101  // http://googletest.googlecode.com/svn/trunk/samples/sample9_unittest.cc
    102  UnitTest& unitTest = *UnitTest::GetInstance();
    103  TestEventListeners& listeners = unitTest.listeners();
    104  delete listeners.Release(listeners.default_result_printer());
    105 
    106  listeners.Append(new MozillaPrinter);
    107 }
    108 
    109 int RunGTestFunc(int* argc, char** argv) {
    110  InitGoogleTest(argc, argv);
    111 
    112  if (getenv("MOZ_TBPL_PARSER")) {
    113    ReplaceGTestLogger();
    114  }
    115 
    116  PR_SetEnv("XPCOM_DEBUG_BREAK=stack-and-abort");
    117 
    118  ScopedXPCOM xpcom("GTest");
    119 
    120 #ifdef XP_WIN
    121  mozilla::ipc::windows::InitUIThread();
    122 #endif
    123 #ifdef ANDROID
    124  // On Android, gtest is running in an application, which uses a
    125  // current working directory of '/' by default. Desktop tests
    126  // sometimes assume that support files are in the current
    127  // working directory. For compatibility with desktop, the Android
    128  // harness pushes test support files to the device at the location
    129  // specified by MOZ_GTEST_CWD and gtest changes the cwd to that
    130  // location.
    131  char* path = PR_GetEnv("MOZ_GTEST_CWD");
    132  chdir(path);
    133 #endif
    134  nsCOMPtr<nsICrashReporter> crashreporter;
    135  char* crashreporterStr = PR_GetEnv("MOZ_CRASHREPORTER");
    136  if (crashreporterStr && !strcmp(crashreporterStr, "1")) {
    137    // TODO: move this to an even-more-common location to use in all
    138    // C++ unittests
    139    crashreporter = do_GetService("@mozilla.org/toolkit/crash-reporter;1");
    140    if (crashreporter) {
    141      printf_stderr("Setting up crash reporting\n");
    142      char* path = PR_GetEnv("MOZ_GTEST_MINIDUMPS_PATH");
    143      nsCOMPtr<nsIFile> file;
    144      if (path) {
    145        nsresult rv =
    146            NS_NewUTF8LocalFile(nsDependentCString(path), getter_AddRefs(file));
    147        if (NS_FAILED(rv)) {
    148          printf_stderr("Ignoring invalid MOZ_GTEST_MINIDUMPS_PATH\n");
    149        }
    150      }
    151      if (!file) {
    152        nsCOMPtr<nsIProperties> dirsvc =
    153            do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
    154        nsresult rv = dirsvc->Get(NS_OS_CURRENT_WORKING_DIR,
    155                                  NS_GET_IID(nsIFile), getter_AddRefs(file));
    156        MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
    157      }
    158      crashreporter->SetEnabled(true);
    159      crashreporter->SetMinidumpPath(file);
    160    }
    161  }
    162 
    163  // FOG should init exactly once, as early into running as possible, to enable
    164  // instrumentation tests to work properly.
    165  // However, at init, Glean may decide to send a ping. So let's first tell FOG
    166  // that these pings shouldn't actually be uploaded.
    167  Preferences::SetInt("telemetry.fog.test.localhost_port", -1);
    168  // Though the default user-activity limits ought to be longer than a test,
    169  // ensure that they don't trigger unnecessary ping submission (which clears
    170  // storage, making it hard to test instrumentation).
    171  Preferences::SetInt("telemetry.fog.test.activity_limit", -1);
    172  Preferences::SetInt("telemetry.fog.test.inactivity_limit", -1);
    173  const nsCString empty;
    174  RefPtr<FOG>(FOG::GetSingleton())->InitializeFOG(empty, empty, false);
    175 
    176  return RUN_ALL_TESTS();
    177 }
    178 
    179 // We use a static var 'RunGTest' defined in nsAppRunner.cpp.
    180 // RunGTest is initialized to nullptr but if GTest (this file)
    181 // is linked in then RunGTest will be set here indicating
    182 // GTest is supported.
    183 MOZ_RUNINIT class _InitRunGTest {
    184 public:
    185  _InitRunGTest() { RunGTest = RunGTestFunc; }
    186 } InitRunGTest;
    187 
    188 }  // namespace mozilla