TestUtilityProcess.cpp (4521B)
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 "gtest/gtest.h" 7 #include "mozilla/SpinEventLoopUntil.h" 8 9 #include "mozilla/ipc/UtilityProcessManager.h" 10 11 #if defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX) 12 # include "nsIAppShellService.h" 13 # include "nsServiceManagerUtils.h" 14 #endif // defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX) 15 16 #if defined(XP_WIN) 17 # include "mozilla/gtest/MozHelpers.h" 18 # include "mozilla/ipc/UtilityProcessImpl.h" 19 #endif // defined(XP_WIN) 20 21 #ifdef MOZ_WIDGET_ANDROID 22 # define NS_APPSHELLSERVICE_CONTRACTID "@mozilla.org/widget/appshell/android;1" 23 #endif // MOZ_WIDGET_ANDROID 24 25 #ifdef XP_MACOSX 26 # define NS_APPSHELLSERVICE_CONTRACTID "@mozilla.org/widget/appshell/mac;1" 27 #endif // XP_MACOSX 28 29 using namespace mozilla; 30 using namespace mozilla::ipc; 31 32 #define WAIT_FOR_EVENTS \ 33 SpinEventLoopUntil("UtilityProcess::emptyUtil"_ns, [&]() { return done; }); 34 35 bool setupDone = false; 36 37 class UtilityProcess : public ::testing::Test { 38 protected: 39 void SetUp() override { 40 if (setupDone) { 41 return; 42 } 43 44 #if defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX) 45 appShell = do_GetService(NS_APPSHELLSERVICE_CONTRACTID); 46 #endif // defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX) 47 48 #if defined(XP_WIN) && defined(MOZ_SANDBOX) 49 mozilla::SandboxBroker::GeckoDependentInitialize(); 50 #endif // defined(XP_WIN) && defined(MOZ_SANDBOX) 51 52 setupDone = true; 53 } 54 55 #if defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX) 56 nsCOMPtr<nsIAppShellService> appShell; 57 #endif // defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX) 58 }; 59 60 TEST_F(UtilityProcess, ProcessManager) { 61 RefPtr<UtilityProcessManager> utilityProc = 62 UtilityProcessManager::GetSingleton(); 63 ASSERT_NE(utilityProc, nullptr); 64 } 65 66 TEST_F(UtilityProcess, NoProcess) { 67 RefPtr<UtilityProcessManager> utilityProc = 68 UtilityProcessManager::GetSingleton(); 69 EXPECT_NE(utilityProc, nullptr); 70 71 Maybe<int32_t> noPid = 72 utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY); 73 ASSERT_TRUE(noPid.isNothing()); 74 } 75 76 TEST_F(UtilityProcess, LaunchProcess) { 77 bool done = false; 78 79 RefPtr<UtilityProcessManager> utilityProc = 80 UtilityProcessManager::GetSingleton(); 81 EXPECT_NE(utilityProc, nullptr); 82 83 int32_t thisPid = base::GetCurrentProcId(); 84 EXPECT_GE(thisPid, 1); 85 86 utilityProc->LaunchProcess(SandboxingKind::GENERIC_UTILITY) 87 ->Then( 88 GetCurrentSerialEventTarget(), __func__, 89 [&]() mutable { 90 EXPECT_TRUE(true); 91 92 Maybe<int32_t> utilityPid = 93 utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY); 94 EXPECT_TRUE(utilityPid.isSome()); 95 EXPECT_GE(*utilityPid, 1); 96 EXPECT_NE(*utilityPid, thisPid); 97 98 printf_stderr("UtilityProcess running as %d\n", *utilityPid); 99 100 done = true; 101 }, 102 [&](LaunchError const&) { 103 EXPECT_TRUE(false); 104 done = true; 105 }); 106 107 WAIT_FOR_EVENTS; 108 } 109 110 TEST_F(UtilityProcess, DestroyProcess) { 111 bool done = false; 112 113 RefPtr<UtilityProcessManager> utilityProc = 114 UtilityProcessManager::GetSingleton(); 115 116 utilityProc->LaunchProcess(SandboxingKind::GENERIC_UTILITY) 117 ->Then( 118 GetCurrentSerialEventTarget(), __func__, 119 [&]() { 120 Maybe<int32_t> utilityPid = 121 utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY); 122 EXPECT_TRUE(utilityPid.isSome()); 123 EXPECT_GE(*utilityPid, 1); 124 125 utilityProc->CleanShutdown(SandboxingKind::GENERIC_UTILITY); 126 127 utilityPid = 128 utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY); 129 EXPECT_TRUE(utilityPid.isNothing()); 130 131 EXPECT_TRUE(true); 132 done = true; 133 }, 134 [&](LaunchError const&) { 135 EXPECT_TRUE(false); 136 done = true; 137 }); 138 139 WAIT_FOR_EVENTS; 140 } 141 142 #if defined(XP_WIN) 143 static void LoadLibraryCrash_Test() { 144 mozilla::gtest::DisableCrashReporter(); 145 // Just a uuidgen name to have something random 146 UtilityProcessImpl::LoadLibraryOrCrash( 147 L"2b49036e-6ba3-400c-a297-38fa1f6c5255.dll"); 148 } 149 150 TEST_F(UtilityProcess, LoadLibraryCrash) { 151 ASSERT_DEATH_IF_SUPPORTED(LoadLibraryCrash_Test(), ""); 152 } 153 #endif // defined(XP_WIN) 154 155 #undef WAIT_FOR_EVENTS