summaryrefslogtreecommitdiffstats
path: root/ipc/glue/test/gtest
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/glue/test/gtest')
-rw-r--r--ipc/glue/test/gtest/TestAsyncBlockers.cpp166
-rw-r--r--ipc/glue/test/gtest/TestUtilityProcess.cpp155
-rw-r--r--ipc/glue/test/gtest/moz.build21
3 files changed, 342 insertions, 0 deletions
diff --git a/ipc/glue/test/gtest/TestAsyncBlockers.cpp b/ipc/glue/test/gtest/TestAsyncBlockers.cpp
new file mode 100644
index 0000000000..6f8d298621
--- /dev/null
+++ b/ipc/glue/test/gtest/TestAsyncBlockers.cpp
@@ -0,0 +1,166 @@
+/* -*- 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 "mozilla/SpinEventLoopUntil.h"
+#include "mozilla/ipc/AsyncBlockers.h"
+#include "mozilla/gtest/MozHelpers.h"
+
+#include "nsCOMPtr.h"
+#include "nsITimer.h"
+#include "nsINamed.h"
+
+using namespace mozilla;
+using namespace mozilla::ipc;
+
+#define PROCESS_EVENTS_UNTIL(_done) \
+ SpinEventLoopUntil("TestAsyncBlockers"_ns, [&]() { return _done; });
+
+class TestAsyncBlockers : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ SAVE_GDB_SLEEP(mOldSleepDuration);
+ return;
+ }
+
+ void TearDown() final { RESTORE_GDB_SLEEP(mOldSleepDuration); }
+
+ private:
+#if defined(HAS_GDB_SLEEP_DURATION)
+ unsigned int mOldSleepDuration = 0;
+#endif // defined(HAS_GDB_SLEEP_DURATION)
+};
+
+class Blocker {};
+
+TEST_F(TestAsyncBlockers, Register) {
+ AsyncBlockers blockers;
+ Blocker* blocker = new Blocker();
+ blockers.Register(blocker);
+ EXPECT_TRUE(true);
+}
+
+TEST_F(TestAsyncBlockers, Register_Deregister) {
+ AsyncBlockers blockers;
+ Blocker* blocker = new Blocker();
+ blockers.Register(blocker);
+ blockers.Deregister(blocker);
+ EXPECT_TRUE(true);
+}
+
+TEST_F(TestAsyncBlockers, Register_WaitUntilClear) {
+ AsyncBlockers blockers;
+ bool done = false;
+
+ Blocker* blocker = new Blocker();
+ blockers.Register(blocker);
+
+ blockers.WaitUntilClear(5 * 1000)->Then(GetCurrentSerialEventTarget(),
+ __func__, [&]() {
+ EXPECT_TRUE(true);
+ done = true;
+ });
+
+ NS_ProcessPendingEvents(nullptr);
+
+ blockers.Deregister(blocker);
+
+ PROCESS_EVENTS_UNTIL(done);
+}
+
+class AsyncBlockerTimerCallback : public nsITimerCallback, public nsINamed {
+ protected:
+ virtual ~AsyncBlockerTimerCallback();
+
+ public:
+ explicit AsyncBlockerTimerCallback() {}
+
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSITIMERCALLBACK
+ NS_DECL_NSINAMED
+};
+
+NS_IMPL_ISUPPORTS(AsyncBlockerTimerCallback, nsITimerCallback, nsINamed)
+
+AsyncBlockerTimerCallback::~AsyncBlockerTimerCallback() = default;
+
+NS_IMETHODIMP
+AsyncBlockerTimerCallback::Notify(nsITimer* timer) {
+ // If we resolve through this, it means
+ // blockers.WaitUntilClear() started to wait for
+ // the completion of the timeout which is not
+ // good.
+ EXPECT_TRUE(false);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+AsyncBlockerTimerCallback::GetName(nsACString& aName) {
+ aName.AssignLiteral("AsyncBlockerTimerCallback");
+ return NS_OK;
+}
+
+TEST_F(TestAsyncBlockers, NoRegister_WaitUntilClear) {
+ AsyncBlockers blockers;
+ bool done = false;
+
+ nsCOMPtr<nsITimer> timer = NS_NewTimer();
+ ASSERT_TRUE(timer);
+
+ RefPtr<AsyncBlockerTimerCallback> timerCb = new AsyncBlockerTimerCallback();
+ timer->InitWithCallback(timerCb, 1 * 1000, nsITimer::TYPE_ONE_SHOT);
+
+ blockers.WaitUntilClear(10 * 1000)->Then(GetCurrentSerialEventTarget(),
+ __func__, [&]() {
+ // If we resolve through this
+ // before the nsITimer it means we
+ // have been resolved before the 5s
+ // timeout
+ EXPECT_TRUE(true);
+ timer->Cancel();
+ done = true;
+ });
+
+ PROCESS_EVENTS_UNTIL(done);
+}
+
+TEST_F(TestAsyncBlockers, Register_WaitUntilClear_0s) {
+ AsyncBlockers blockers;
+ bool done = false;
+
+ Blocker* blocker = new Blocker();
+ blockers.Register(blocker);
+
+ blockers.WaitUntilClear(0)->Then(GetCurrentSerialEventTarget(), __func__,
+ [&]() {
+ EXPECT_TRUE(true);
+ done = true;
+ });
+
+ NS_ProcessPendingEvents(nullptr);
+
+ blockers.Deregister(blocker);
+
+ PROCESS_EVENTS_UNTIL(done);
+}
+
+#if defined(MOZ_DIAGNOSTIC_ASSERT_ENABLED) && !defined(ANDROID) && \
+ !(defined(XP_DARWIN) && !defined(MOZ_DEBUG))
+static void DeregisterEmpty_Test() {
+ mozilla::gtest::DisableCrashReporter();
+
+ AsyncBlockers blockers;
+ Blocker* blocker = new Blocker();
+ blockers.Deregister(blocker);
+}
+
+TEST_F(TestAsyncBlockers, DeregisterEmpty) {
+ ASSERT_DEATH_IF_SUPPORTED(DeregisterEmpty_Test(), "");
+}
+#endif // defined(MOZ_DIAGNOSTIC_ASSERT_ENABLED) && !defined(ANDROID) &&
+ // !(defined(XP_DARWIN) && !defined(MOZ_DEBUG))
+
+#undef PROCESS_EVENTS_UNTIL
diff --git a/ipc/glue/test/gtest/TestUtilityProcess.cpp b/ipc/glue/test/gtest/TestUtilityProcess.cpp
new file mode 100644
index 0000000000..c5d19c992f
--- /dev/null
+++ b/ipc/glue/test/gtest/TestUtilityProcess.cpp
@@ -0,0 +1,155 @@
+/* -*- 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 "mozilla/SpinEventLoopUntil.h"
+
+#include "mozilla/ipc/UtilityProcessManager.h"
+
+#if defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX)
+# include "nsIAppShellService.h"
+# include "nsServiceManagerUtils.h"
+#endif // defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX)
+
+#if defined(XP_WIN)
+# include "mozilla/gtest/MozHelpers.h"
+# include "mozilla/ipc/UtilityProcessImpl.h"
+#endif // defined(XP_WIN)
+
+#ifdef MOZ_WIDGET_ANDROID
+# define NS_APPSHELLSERVICE_CONTRACTID "@mozilla.org/widget/appshell/android;1"
+#endif // MOZ_WIDGET_ANDROID
+
+#ifdef XP_MACOSX
+# define NS_APPSHELLSERVICE_CONTRACTID "@mozilla.org/widget/appshell/mac;1"
+#endif // XP_MACOSX
+
+using namespace mozilla;
+using namespace mozilla::ipc;
+
+#define WAIT_FOR_EVENTS \
+ SpinEventLoopUntil("UtilityProcess::emptyUtil"_ns, [&]() { return done; });
+
+bool setupDone = false;
+
+class UtilityProcess : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ if (setupDone) {
+ return;
+ }
+
+#if defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX)
+ appShell = do_GetService(NS_APPSHELLSERVICE_CONTRACTID);
+#endif // defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX)
+
+#if defined(XP_WIN) && defined(MOZ_SANDBOX)
+ mozilla::SandboxBroker::GeckoDependentInitialize();
+#endif // defined(XP_WIN) && defined(MOZ_SANDBOX)
+
+ setupDone = true;
+ }
+
+#if defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX)
+ nsCOMPtr<nsIAppShellService> appShell;
+#endif // defined(MOZ_WIDGET_ANDROID) || defined(XP_MACOSX)
+};
+
+TEST_F(UtilityProcess, ProcessManager) {
+ RefPtr<UtilityProcessManager> utilityProc =
+ UtilityProcessManager::GetSingleton();
+ ASSERT_NE(utilityProc, nullptr);
+}
+
+TEST_F(UtilityProcess, NoProcess) {
+ RefPtr<UtilityProcessManager> utilityProc =
+ UtilityProcessManager::GetSingleton();
+ EXPECT_NE(utilityProc, nullptr);
+
+ Maybe<int32_t> noPid =
+ utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY);
+ ASSERT_TRUE(noPid.isNothing());
+}
+
+TEST_F(UtilityProcess, LaunchProcess) {
+ bool done = false;
+
+ RefPtr<UtilityProcessManager> utilityProc =
+ UtilityProcessManager::GetSingleton();
+ EXPECT_NE(utilityProc, nullptr);
+
+ int32_t thisPid = base::GetCurrentProcId();
+ EXPECT_GE(thisPid, 1);
+
+ utilityProc->LaunchProcess(SandboxingKind::GENERIC_UTILITY)
+ ->Then(
+ GetCurrentSerialEventTarget(), __func__,
+ [&]() mutable {
+ EXPECT_TRUE(true);
+
+ Maybe<int32_t> utilityPid =
+ utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY);
+ EXPECT_TRUE(utilityPid.isSome());
+ EXPECT_GE(*utilityPid, 1);
+ EXPECT_NE(*utilityPid, thisPid);
+
+ printf_stderr("UtilityProcess running as %d\n", *utilityPid);
+
+ done = true;
+ },
+ [&](nsresult aError) mutable {
+ EXPECT_TRUE(false);
+ done = true;
+ });
+
+ WAIT_FOR_EVENTS;
+}
+
+TEST_F(UtilityProcess, DestroyProcess) {
+ bool done = false;
+
+ RefPtr<UtilityProcessManager> utilityProc =
+ UtilityProcessManager::GetSingleton();
+
+ utilityProc->LaunchProcess(SandboxingKind::GENERIC_UTILITY)
+ ->Then(
+ GetCurrentSerialEventTarget(), __func__,
+ [&]() {
+ Maybe<int32_t> utilityPid =
+ utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY);
+ EXPECT_TRUE(utilityPid.isSome());
+ EXPECT_GE(*utilityPid, 1);
+
+ utilityProc->CleanShutdown(SandboxingKind::GENERIC_UTILITY);
+
+ utilityPid =
+ utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY);
+ EXPECT_TRUE(utilityPid.isNothing());
+
+ EXPECT_TRUE(true);
+ done = true;
+ },
+ [&](nsresult aError) {
+ EXPECT_TRUE(false);
+ done = true;
+ });
+
+ WAIT_FOR_EVENTS;
+}
+
+#if defined(XP_WIN)
+static void LoadLibraryCrash_Test() {
+ mozilla::gtest::DisableCrashReporter();
+ // Just a uuidgen name to have something random
+ UtilityProcessImpl::LoadLibraryOrCrash(
+ L"2b49036e-6ba3-400c-a297-38fa1f6c5255.dll");
+}
+
+TEST_F(UtilityProcess, LoadLibraryCrash) {
+ ASSERT_DEATH_IF_SUPPORTED(LoadLibraryCrash_Test(), "");
+}
+#endif // defined(XP_WIN)
+
+#undef WAIT_FOR_EVENTS
diff --git a/ipc/glue/test/gtest/moz.build b/ipc/glue/test/gtest/moz.build
new file mode 100644
index 0000000000..7b72cc7fe1
--- /dev/null
+++ b/ipc/glue/test/gtest/moz.build
@@ -0,0 +1,21 @@
+# -*- Mode: python; c-basic-offset: 4; 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/.
+
+Library("ipcgluetest")
+
+UNIFIED_SOURCES = [
+ "TestAsyncBlockers.cpp",
+ "TestUtilityProcess.cpp",
+]
+
+LOCAL_INCLUDES += [
+ "/widget",
+ "/widget/android",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+FINAL_LIBRARY = "xul-gtest"