#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "mojo/public/c/system/invitation.h"
#include <cstdint>
#include <cstring>
#include <optional>
#include <string>
#include <string_view>
#include "base/base_paths.h"
#include "base/base_switches.h"
#include "base/check_op.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/memory/shared_memory_mapping.h"
#include "base/memory/writable_shared_memory_region.h"
#include "base/notreached.h"
#include "base/path_service.h"
#include "base/process/process.h"
#include "base/run_loop.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "base/test/bind.h"
#include "base/test/multiprocess_test.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "mojo/buildflags.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/core/ipcz_api.h"
#include "mojo/core/test/mojo_test_base.h"
#include "mojo/core/test/test_switches.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/invitation.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "mojo/public/cpp/system/platform_handle.h"
#if BUILDFLAG(MOJO_SUPPORT_LEGACY_CORE)
#include "mojo/core/core.h"
#include "mojo/core/node_controller.h"
#endif
#if BUILDFLAG(MOJO_USE_APPLE_CHANNEL)
#include "base/mac/mach_port_rendezvous.h"
#endif
namespace mojo {
namespace core {
namespace {
const char kSecondaryChannelHandleSwitch[] = …;
#if defined(THREAD_SANITIZER)
#define MAYBE_InvitationTest …
#else
#define MAYBE_InvitationTest …
#endif
class MAYBE_InvitationTest : public test::MojoTestBase { … };
void PrepareToPassRemoteEndpoint(PlatformChannel* channel,
base::LaunchOptions* options,
base::CommandLine* command_line,
std::string_view switch_name = { … }
TEST_F(MAYBE_InvitationTest, Create) { … }
TEST_F(MAYBE_InvitationTest, InvalidArguments) { … }
TEST_F(MAYBE_InvitationTest, AttachAndExtractLocally) { … }
TEST_F(MAYBE_InvitationTest, ClosedInvitationClosesAttachments) { … }
TEST_F(MAYBE_InvitationTest, AttachNameInUse) { … }
base::Process MAYBE_InvitationTest::LaunchChildTestClient(
const std::string& test_client_name,
MojoHandle* primordial_pipes,
size_t num_primordial_pipes,
MojoSendInvitationFlags send_flags,
MojoProcessErrorHandler error_handler,
uintptr_t error_handler_context,
base::CommandLine* custom_command_line,
base::LaunchOptions* custom_launch_options) { … }
void MAYBE_InvitationTest::SendInvitationToClient(
PlatformHandle endpoint_handle,
base::ProcessHandle process,
MojoHandle* primordial_pipes,
size_t num_primordial_pipes,
MojoSendInvitationFlags flags,
MojoProcessErrorHandler error_handler,
uintptr_t error_handler_context,
std::string_view isolated_invitation_name) { … }
class TestClientBase : public MAYBE_InvitationTest { … };
#define DEFINE_TEST_CLIENT(name) …
const std::string kTestMessage1 = …;
const std::string kTestMessage2 = …;
const std::string kTestMessage3 = …;
const std::string kTestMessage4 = …;
TEST_F(MAYBE_InvitationTest, SendInvitation) { … }
DEFINE_TEST_CLIENT(SendInvitationClient) { … }
TEST_F(MAYBE_InvitationTest, SendInvitationMultiplePipes) { … }
DEFINE_TEST_CLIENT(SendInvitationMultiplePipesClient) { … }
const char kErrorMessage[] = …;
const char kDisconnectMessage[] = …;
class RemoteProcessState { … };
void TestProcessErrorHandler(uintptr_t context,
const MojoProcessErrorDetails* details) { … }
TEST_F(MAYBE_InvitationTest, ProcessErrors) { … }
DEFINE_TEST_CLIENT(ProcessErrorsClient) { … }
#if BUILDFLAG(MOJO_SUPPORT_LEGACY_CORE)
TEST_F(MAYBE_InvitationTest, DISABLED_Reinvitation) {
PlatformChannel secondary_channel;
auto command_line = base::GetMultiProcessTestChildBaseCommandLine();
base::LaunchOptions launch_options;
PrepareToPassRemoteEndpoint(&secondary_channel, &launch_options,
&command_line, kSecondaryChannelHandleSwitch);
MojoHandle pipe;
base::Process child_process = LaunchChildTestClient(
"ReinvitationClient", &pipe, 1, MOJO_SEND_INVITATION_FLAG_NONE, nullptr,
0, &command_line, &launch_options);
secondary_channel.RemoteProcessLaunchAttempted();
WriteMessage(pipe, kTestMessage1);
EXPECT_EQ(kTestMessage2, ReadMessage(pipe));
Core::Get()->GetNodeController()->ForceDisconnectProcessForTesting(
child_process.Pid());
WaitForSignals(pipe, MOJO_HANDLE_SIGNAL_PEER_CLOSED);
MojoClose(pipe);
mojo::OutgoingInvitation new_invitation;
auto new_pipe = new_invitation.AttachMessagePipe(0);
mojo::OutgoingInvitation::Send(std::move(new_invitation),
child_process.Handle(),
secondary_channel.TakeLocalEndpoint());
WriteMessage(new_pipe.get().value(), kTestMessage3);
EXPECT_EQ(kTestMessage4, ReadMessage(new_pipe.get().value()));
WriteMessage(new_pipe.get().value(), kDisconnectMessage);
WaitForProcessToTerminate(child_process);
}
#endif
DEFINE_TEST_CLIENT(ReinvitationClient) { … }
TEST_F(MAYBE_InvitationTest, SendIsolatedInvitation) { … }
DEFINE_TEST_CLIENT(SendIsolatedInvitationClient) { … }
TEST_F(MAYBE_InvitationTest, SendMultipleIsolatedInvitations) { … }
DEFINE_TEST_CLIENT(SendMultipleIsolatedInvitationsClient) { … }
TEST_F(MAYBE_InvitationTest, SendIsolatedInvitationWithDuplicateName) { … }
TEST_F(MAYBE_InvitationTest, SendIsolatedInvitationToSelf) { … }
TEST_F(MAYBE_InvitationTest, BrokenInvitationTransportBreaksAttachedPipe) { … }
TEST_F(MAYBE_InvitationTest,
BrokenIsolatedInvitationTransportBreaksAttachedPipe) { … }
DEFINE_TEST_CLIENT(BrokenTransportClient) {
}
TEST_F(MAYBE_InvitationTest, NonBrokerToNonBroker) { … }
DEFINE_TEST_CLIENT(NonBrokerToNonBrokerHost) { … }
DEFINE_TEST_CLIENT(NonBrokerToNonBrokerClient) { … }
TEST_F(MAYBE_InvitationTest, MultiBrokerNetwork) { … }
MojoHandle CreateMemory(std::string_view contents) { … }
std::string ReadMemory(MojoHandle handle) { … }
constexpr size_t kNumMultiBrokerMessageIterations = …;
DEFINE_TEST_CLIENT(SecondaryBroker) { … }
DEFINE_TEST_CLIENT(MultiBrokerNetworkClient) { … }
}
}
}