summaryrefslogtreecommitdiffstats
path: root/ipc/glue/test/utility_process_xpcom
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /ipc/glue/test/utility_process_xpcom
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ipc/glue/test/utility_process_xpcom')
-rw-r--r--ipc/glue/test/utility_process_xpcom/UtilityProcessTest.cpp164
-rw-r--r--ipc/glue/test/utility_process_xpcom/UtilityProcessTest.h29
-rw-r--r--ipc/glue/test/utility_process_xpcom/components.conf15
-rw-r--r--ipc/glue/test/utility_process_xpcom/moz.build21
-rw-r--r--ipc/glue/test/utility_process_xpcom/nsIUtilityProcessTest.idl44
5 files changed, 273 insertions, 0 deletions
diff --git a/ipc/glue/test/utility_process_xpcom/UtilityProcessTest.cpp b/ipc/glue/test/utility_process_xpcom/UtilityProcessTest.cpp
new file mode 100644
index 0000000000..3828c6971b
--- /dev/null
+++ b/ipc/glue/test/utility_process_xpcom/UtilityProcessTest.cpp
@@ -0,0 +1,164 @@
+/* -*- 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/. */
+
+#if defined(ENABLE_TESTS)
+# include "mozilla/ipc/UtilityProcessTest.h"
+# include "mozilla/ipc/UtilityProcessManager.h"
+# include "mozilla/dom/Promise.h"
+# include "mozilla/ProcInfo.h"
+# include "mozilla/IntentionalCrash.h"
+
+namespace mozilla::ipc {
+
+static UtilityActorName UtilityActorNameFromString(
+ const nsACString& aStringName) {
+ using namespace mozilla::dom;
+
+ // We use WebIDLUtilityActorNames because UtilityActorNames is not designed
+ // for iteration.
+ for (size_t i = 0; i < WebIDLUtilityActorNameValues::Count; ++i) {
+ auto idlName = static_cast<UtilityActorName>(i);
+ const nsDependentCSubstring idlNameString(
+ WebIDLUtilityActorNameValues::GetString(idlName));
+ if (idlNameString.Equals(aStringName)) {
+ return idlName;
+ }
+ }
+ MOZ_CRASH("Unknown utility actor name");
+}
+
+// Find the utility process with the given actor or any utility process if
+// the actor is UtilityActorName::EndGuard_.
+static SandboxingKind FindUtilityProcessWithActor(UtilityActorName aActorName) {
+ RefPtr<UtilityProcessManager> utilityProc =
+ UtilityProcessManager::GetSingleton();
+ MOZ_ASSERT(utilityProc, "No UtilityprocessManager?");
+
+ for (size_t i = 0; i < SandboxingKind::COUNT; ++i) {
+ auto sbKind = static_cast<SandboxingKind>(i);
+ if (!utilityProc->Process(sbKind)) {
+ continue;
+ }
+ if (aActorName == UtilityActorName::EndGuard_) {
+ return sbKind;
+ }
+ for (auto actor : utilityProc->GetActors(sbKind)) {
+ if (actor == aActorName) {
+ return sbKind;
+ }
+ }
+ }
+
+ return SandboxingKind::COUNT;
+}
+
+NS_IMETHODIMP
+UtilityProcessTest::StartProcess(const nsTArray<nsCString>& aActorsToRegister,
+ JSContext* aCx,
+ mozilla::dom::Promise** aOutPromise) {
+ NS_ENSURE_ARG(aOutPromise);
+ *aOutPromise = nullptr;
+ nsIGlobalObject* global = xpc::CurrentNativeGlobal(aCx);
+ if (NS_WARN_IF(!global)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ ErrorResult erv;
+ RefPtr<dom::Promise> promise = dom::Promise::Create(global, erv);
+ if (NS_WARN_IF(erv.Failed())) {
+ return erv.StealNSResult();
+ }
+
+ RefPtr<UtilityProcessManager> utilityProc =
+ UtilityProcessManager::GetSingleton();
+ MOZ_ASSERT(utilityProc, "No UtilityprocessManager?");
+
+ auto actors = aActorsToRegister.Clone();
+
+ utilityProc->LaunchProcess(SandboxingKind::GENERIC_UTILITY)
+ ->Then(
+ GetCurrentSerialEventTarget(), __func__,
+ [promise, utilityProc, actors = std::move(actors)] {
+ RefPtr<UtilityProcessParent> utilityParent =
+ utilityProc->GetProcessParent(SandboxingKind::GENERIC_UTILITY);
+ Maybe<int32_t> utilityPid =
+ utilityProc->ProcessPid(SandboxingKind::GENERIC_UTILITY);
+ for (size_t i = 0; i < actors.Length(); ++i) {
+ auto uan = UtilityActorNameFromString(actors[i]);
+ utilityProc->RegisterActor(utilityParent, uan);
+ }
+ if (utilityPid.isSome()) {
+ promise->MaybeResolve(*utilityPid);
+ } else {
+ promise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
+ }
+ },
+ [promise](nsresult aError) {
+ MOZ_ASSERT_UNREACHABLE(
+ "UtilityProcessTest; failure to get Utility process");
+ promise->MaybeReject(aError);
+ });
+
+ promise.forget(aOutPromise);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+UtilityProcessTest::NoteIntentionalCrash(uint32_t aPid) {
+ mozilla::NoteIntentionalCrash("utility", aPid);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+UtilityProcessTest::StopProcess(const char* aActorName) {
+ using namespace mozilla::dom;
+
+ SandboxingKind sbKind;
+ if (aActorName) {
+ const nsDependentCString actorStringName(aActorName);
+ UtilityActorName actorName = UtilityActorNameFromString(actorStringName);
+ sbKind = FindUtilityProcessWithActor(actorName);
+ } else {
+ sbKind = FindUtilityProcessWithActor(UtilityActorName::EndGuard_);
+ }
+
+ if (sbKind == SandboxingKind::COUNT) {
+ MOZ_ASSERT_UNREACHABLE(
+ "Attempted to stop process for actor when no "
+ "such process exists");
+ return NS_ERROR_FAILURE;
+ }
+
+ RefPtr<UtilityProcessManager> utilityProc =
+ UtilityProcessManager::GetSingleton();
+ MOZ_ASSERT(utilityProc, "No UtilityprocessManager?");
+
+ utilityProc->CleanShutdown(sbKind);
+ Maybe<int32_t> utilityPid = utilityProc->ProcessPid(sbKind);
+ MOZ_RELEASE_ASSERT(utilityPid.isNothing(),
+ "Should not have a utility process PID anymore");
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+UtilityProcessTest::TestTelemetryProbes() {
+ RefPtr<UtilityProcessManager> utilityProc =
+ UtilityProcessManager::GetSingleton();
+ MOZ_ASSERT(utilityProc, "No UtilityprocessManager?");
+
+ for (RefPtr<UtilityProcessParent>& parent :
+ utilityProc->GetAllProcessesProcessParent()) {
+ Unused << parent->SendTestTelemetryProbes();
+ }
+
+ return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS(UtilityProcessTest, nsIUtilityProcessTest)
+
+} // namespace mozilla::ipc
+#endif // defined(ENABLE_TESTS)
diff --git a/ipc/glue/test/utility_process_xpcom/UtilityProcessTest.h b/ipc/glue/test/utility_process_xpcom/UtilityProcessTest.h
new file mode 100644
index 0000000000..6c80fce71b
--- /dev/null
+++ b/ipc/glue/test/utility_process_xpcom/UtilityProcessTest.h
@@ -0,0 +1,29 @@
+/* -*- 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 _include_ipc_glue_UtilityProcessTest_h_
+#define _include_ipc_glue_UtilityProcessTest_h_
+
+#if defined(ENABLE_TESTS)
+# include "nsServiceManagerUtils.h"
+# include "nsIUtilityProcessTest.h"
+
+namespace mozilla::ipc {
+
+class UtilityProcessTest final : public nsIUtilityProcessTest {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIUTILITYPROCESSTEST
+
+ UtilityProcessTest() = default;
+
+ private:
+ ~UtilityProcessTest() = default;
+};
+
+} // namespace mozilla::ipc
+#endif // defined(ENABLE_TESTS)
+
+#endif // _include_ipc_glue_UtilityProcessTest_h_
diff --git a/ipc/glue/test/utility_process_xpcom/components.conf b/ipc/glue/test/utility_process_xpcom/components.conf
new file mode 100644
index 0000000000..25208ba7fc
--- /dev/null
+++ b/ipc/glue/test/utility_process_xpcom/components.conf
@@ -0,0 +1,15 @@
+# -*- 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/.
+
+Classes = [
+ {
+ 'cid': '{0a4478f4-c5ae-4fb1-8686-d5b09fb99afb}',
+ 'contract_ids': ['@mozilla.org/utility-process-test;1'],
+ 'type': 'mozilla::ipc::UtilityProcessTest',
+ 'headers': ['mozilla/ipc/UtilityProcessTest.h'],
+ 'processes': ProcessSelector.MAIN_PROCESS_ONLY,
+ },
+]
diff --git a/ipc/glue/test/utility_process_xpcom/moz.build b/ipc/glue/test/utility_process_xpcom/moz.build
new file mode 100644
index 0000000000..f04b436cbe
--- /dev/null
+++ b/ipc/glue/test/utility_process_xpcom/moz.build
@@ -0,0 +1,21 @@
+# -*- 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/.
+
+EXPORTS.mozilla.ipc += ["UtilityProcessTest.h"]
+
+UNIFIED_SOURCES += ["UtilityProcessTest.cpp"]
+
+XPCOM_MANIFESTS += ["components.conf"]
+
+XPIDL_MODULE = "utility_process_xpcom_test"
+
+XPIDL_SOURCES += [
+ "nsIUtilityProcessTest.idl",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+FINAL_LIBRARY = "xul"
diff --git a/ipc/glue/test/utility_process_xpcom/nsIUtilityProcessTest.idl b/ipc/glue/test/utility_process_xpcom/nsIUtilityProcessTest.idl
new file mode 100644
index 0000000000..839c4f3673
--- /dev/null
+++ b/ipc/glue/test/utility_process_xpcom/nsIUtilityProcessTest.idl
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* 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 "nsISupports.idl"
+
+[scriptable, uuid(0a4478f4-c5ae-4fb1-8686-d5b09fb99afb)]
+interface nsIUtilityProcessTest : nsISupports
+{
+ /**
+ * ** Test-only Method **
+ *
+ * Allowing to start Utility Process from JS code.
+ *
+ * actorsToAdd: An array of actor names, taken from WebIDLUtilityActorName.
+ * Unlike normal utility processes, test processes launched this way do not
+ * have any associated actor names unless specified here. Empty by default.
+ */
+ [implicit_jscontext]
+ Promise startProcess([optional] in Array<ACString> actorsToAdd);
+
+ /**
+ * ** Test-only Method **
+ *
+ * Note that we are going to manually crash a process
+ */
+ void noteIntentionalCrash(in unsigned long pid);
+
+ /**
+ * ** Test-only Method **
+ *
+ * Allowing to stop Utility Process from JS code.
+ * Default behavior is to stop any utility process.
+ */
+ void stopProcess([optional] in string utilityActorName);
+
+ /**
+ * ** Test-only Method **
+ *
+ * Sending Telemetry probes
+ */
+ void testTelemetryProbes();
+};