diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /ipc/glue/test/utility_process_xpcom | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ipc/glue/test/utility_process_xpcom')
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(); +}; |