1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker *
4*6dbdd20aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker *
8*6dbdd20aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker *
10*6dbdd20aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker */
16*6dbdd20aSAndroid Build Coastguard Worker
17*6dbdd20aSAndroid Build Coastguard Worker #include "src/ipc/host_impl.h"
18*6dbdd20aSAndroid Build Coastguard Worker
19*6dbdd20aSAndroid Build Coastguard Worker #include <memory>
20*6dbdd20aSAndroid Build Coastguard Worker
21*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/file_utils.h"
22*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/scoped_file.h"
23*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/sys_types.h"
24*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/temp_file.h"
25*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/unix_socket.h"
26*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/utils.h"
27*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/ipc/service.h"
28*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/ipc/service_descriptor.h"
29*6dbdd20aSAndroid Build Coastguard Worker #include "src/base/test/test_task_runner.h"
30*6dbdd20aSAndroid Build Coastguard Worker #include "src/ipc/buffered_frame_deserializer.h"
31*6dbdd20aSAndroid Build Coastguard Worker #include "src/ipc/test/test_socket.h"
32*6dbdd20aSAndroid Build Coastguard Worker #include "test/gtest_and_gmock.h"
33*6dbdd20aSAndroid Build Coastguard Worker
34*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/ipc/wire_protocol.gen.h"
35*6dbdd20aSAndroid Build Coastguard Worker #include "src/ipc/test/client_unittest_messages.gen.h"
36*6dbdd20aSAndroid Build Coastguard Worker
37*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
38*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
39*6dbdd20aSAndroid Build Coastguard Worker #include <sys/socket.h>
40*6dbdd20aSAndroid Build Coastguard Worker #endif
41*6dbdd20aSAndroid Build Coastguard Worker
42*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
43*6dbdd20aSAndroid Build Coastguard Worker namespace ipc {
44*6dbdd20aSAndroid Build Coastguard Worker namespace {
45*6dbdd20aSAndroid Build Coastguard Worker
46*6dbdd20aSAndroid Build Coastguard Worker using ::perfetto::ipc::Frame;
47*6dbdd20aSAndroid Build Coastguard Worker using ::perfetto::ipc::gen::ReplyProto;
48*6dbdd20aSAndroid Build Coastguard Worker using ::perfetto::ipc::gen::RequestProto;
49*6dbdd20aSAndroid Build Coastguard Worker using ::testing::_;
50*6dbdd20aSAndroid Build Coastguard Worker using ::testing::Invoke;
51*6dbdd20aSAndroid Build Coastguard Worker using ::testing::InvokeWithoutArgs;
52*6dbdd20aSAndroid Build Coastguard Worker using ::testing::Return;
53*6dbdd20aSAndroid Build Coastguard Worker
54*6dbdd20aSAndroid Build Coastguard Worker ipc::TestSocket kTestSocket{"host_impl_unittest"};
55*6dbdd20aSAndroid Build Coastguard Worker
56*6dbdd20aSAndroid Build Coastguard Worker // RequestProto and ReplyProto are defined in client_unittest_messages.proto.
57*6dbdd20aSAndroid Build Coastguard Worker
58*6dbdd20aSAndroid Build Coastguard Worker class FakeService : public Service {
59*6dbdd20aSAndroid Build Coastguard Worker public:
60*6dbdd20aSAndroid Build Coastguard Worker MOCK_METHOD(void, OnFakeMethod1, (const RequestProto&, DeferredBase*));
61*6dbdd20aSAndroid Build Coastguard Worker
Invoker(Service * service,const ProtoMessage & req,DeferredBase deferred_reply)62*6dbdd20aSAndroid Build Coastguard Worker static void Invoker(Service* service,
63*6dbdd20aSAndroid Build Coastguard Worker const ProtoMessage& req,
64*6dbdd20aSAndroid Build Coastguard Worker DeferredBase deferred_reply) {
65*6dbdd20aSAndroid Build Coastguard Worker static_cast<FakeService*>(service)->OnFakeMethod1(
66*6dbdd20aSAndroid Build Coastguard Worker static_cast<const RequestProto&>(req), &deferred_reply);
67*6dbdd20aSAndroid Build Coastguard Worker }
68*6dbdd20aSAndroid Build Coastguard Worker
RequestDecoder(const std::string & proto)69*6dbdd20aSAndroid Build Coastguard Worker static std::unique_ptr<ProtoMessage> RequestDecoder(
70*6dbdd20aSAndroid Build Coastguard Worker const std::string& proto) {
71*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ProtoMessage> reply(new RequestProto());
72*6dbdd20aSAndroid Build Coastguard Worker EXPECT_TRUE(reply->ParseFromString(proto));
73*6dbdd20aSAndroid Build Coastguard Worker return reply;
74*6dbdd20aSAndroid Build Coastguard Worker }
75*6dbdd20aSAndroid Build Coastguard Worker
FakeService(const char * service_name)76*6dbdd20aSAndroid Build Coastguard Worker explicit FakeService(const char* service_name) {
77*6dbdd20aSAndroid Build Coastguard Worker descriptor_.service_name = service_name;
78*6dbdd20aSAndroid Build Coastguard Worker descriptor_.methods.push_back(
79*6dbdd20aSAndroid Build Coastguard Worker {"FakeMethod1", &RequestDecoder, nullptr, &Invoker});
80*6dbdd20aSAndroid Build Coastguard Worker }
81*6dbdd20aSAndroid Build Coastguard Worker
GetDescriptor()82*6dbdd20aSAndroid Build Coastguard Worker const ServiceDescriptor& GetDescriptor() override { return descriptor_; }
83*6dbdd20aSAndroid Build Coastguard Worker
TakeReceivedFD()84*6dbdd20aSAndroid Build Coastguard Worker base::ScopedFile TakeReceivedFD() { return ipc::Service::TakeReceivedFD(); }
85*6dbdd20aSAndroid Build Coastguard Worker
86*6dbdd20aSAndroid Build Coastguard Worker base::ScopedFile received_fd_;
87*6dbdd20aSAndroid Build Coastguard Worker ServiceDescriptor descriptor_;
88*6dbdd20aSAndroid Build Coastguard Worker };
89*6dbdd20aSAndroid Build Coastguard Worker
90*6dbdd20aSAndroid Build Coastguard Worker class FakeClient : public base::UnixSocket::EventListener {
91*6dbdd20aSAndroid Build Coastguard Worker public:
92*6dbdd20aSAndroid Build Coastguard Worker MOCK_METHOD(void, OnConnect, ());
93*6dbdd20aSAndroid Build Coastguard Worker MOCK_METHOD(void, OnDisconnect, ());
94*6dbdd20aSAndroid Build Coastguard Worker MOCK_METHOD(void, OnServiceBound, (const Frame::BindServiceReply&));
95*6dbdd20aSAndroid Build Coastguard Worker MOCK_METHOD(void, OnInvokeMethodReply, (const Frame::InvokeMethodReply&));
96*6dbdd20aSAndroid Build Coastguard Worker MOCK_METHOD(void, OnFileDescriptorReceived, (int));
97*6dbdd20aSAndroid Build Coastguard Worker MOCK_METHOD(void, OnRequestError, ());
98*6dbdd20aSAndroid Build Coastguard Worker
FakeClient(base::TaskRunner * task_runner)99*6dbdd20aSAndroid Build Coastguard Worker explicit FakeClient(base::TaskRunner* task_runner) {
100*6dbdd20aSAndroid Build Coastguard Worker sock_ = base::UnixSocket::Connect(kTestSocket.name(), this, task_runner,
101*6dbdd20aSAndroid Build Coastguard Worker kTestSocket.family(),
102*6dbdd20aSAndroid Build Coastguard Worker base::SockType::kStream);
103*6dbdd20aSAndroid Build Coastguard Worker }
104*6dbdd20aSAndroid Build Coastguard Worker
FakeClient(const char * sock_name,base::TaskRunner * task_runner)105*6dbdd20aSAndroid Build Coastguard Worker FakeClient(const char* sock_name, base::TaskRunner* task_runner) {
106*6dbdd20aSAndroid Build Coastguard Worker auto sock_family = base::GetSockFamily(sock_name);
107*6dbdd20aSAndroid Build Coastguard Worker sock_ = base::UnixSocket::Connect(sock_name, this, task_runner, sock_family,
108*6dbdd20aSAndroid Build Coastguard Worker base::SockType::kStream);
109*6dbdd20aSAndroid Build Coastguard Worker }
110*6dbdd20aSAndroid Build Coastguard Worker
FakeClient(base::ScopedSocketHandle connected_socket,base::TaskRunner * task_runner)111*6dbdd20aSAndroid Build Coastguard Worker FakeClient(base::ScopedSocketHandle connected_socket,
112*6dbdd20aSAndroid Build Coastguard Worker base::TaskRunner* task_runner) {
113*6dbdd20aSAndroid Build Coastguard Worker sock_ = base::UnixSocket::AdoptConnected(std::move(connected_socket), this,
114*6dbdd20aSAndroid Build Coastguard Worker task_runner, kTestSocket.family(),
115*6dbdd20aSAndroid Build Coastguard Worker base::SockType::kStream);
116*6dbdd20aSAndroid Build Coastguard Worker task_runner->PostTask([this]() { OnConnect(); });
117*6dbdd20aSAndroid Build Coastguard Worker }
118*6dbdd20aSAndroid Build Coastguard Worker
119*6dbdd20aSAndroid Build Coastguard Worker ~FakeClient() override = default;
120*6dbdd20aSAndroid Build Coastguard Worker
BindService(const std::string & service_name)121*6dbdd20aSAndroid Build Coastguard Worker void BindService(const std::string& service_name) {
122*6dbdd20aSAndroid Build Coastguard Worker Frame frame;
123*6dbdd20aSAndroid Build Coastguard Worker uint64_t request_id = requests_.empty() ? 1 : requests_.rbegin()->first + 1;
124*6dbdd20aSAndroid Build Coastguard Worker requests_.emplace(request_id, 0);
125*6dbdd20aSAndroid Build Coastguard Worker frame.set_request_id(request_id);
126*6dbdd20aSAndroid Build Coastguard Worker frame.mutable_msg_bind_service()->set_service_name(service_name);
127*6dbdd20aSAndroid Build Coastguard Worker SendFrame(frame);
128*6dbdd20aSAndroid Build Coastguard Worker }
129*6dbdd20aSAndroid Build Coastguard Worker
130*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
131*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
SetPeerIdentity(uid_t uid,pid_t pid,const std::string & machine_id_hint)132*6dbdd20aSAndroid Build Coastguard Worker void SetPeerIdentity(uid_t uid,
133*6dbdd20aSAndroid Build Coastguard Worker pid_t pid,
134*6dbdd20aSAndroid Build Coastguard Worker const std::string& machine_id_hint) {
135*6dbdd20aSAndroid Build Coastguard Worker Frame ipc_frame;
136*6dbdd20aSAndroid Build Coastguard Worker ipc_frame.set_request_id(0);
137*6dbdd20aSAndroid Build Coastguard Worker auto* set_peer_identity = ipc_frame.mutable_set_peer_identity();
138*6dbdd20aSAndroid Build Coastguard Worker set_peer_identity->set_pid(pid);
139*6dbdd20aSAndroid Build Coastguard Worker set_peer_identity->set_uid(static_cast<int32_t>(uid));
140*6dbdd20aSAndroid Build Coastguard Worker set_peer_identity->set_machine_id_hint(machine_id_hint);
141*6dbdd20aSAndroid Build Coastguard Worker SendFrame(ipc_frame);
142*6dbdd20aSAndroid Build Coastguard Worker }
143*6dbdd20aSAndroid Build Coastguard Worker #endif
144*6dbdd20aSAndroid Build Coastguard Worker
InvokeMethod(ServiceID service_id,MethodID method_id,const ProtoMessage & args,bool drop_reply=false,int fd=-1)145*6dbdd20aSAndroid Build Coastguard Worker void InvokeMethod(ServiceID service_id,
146*6dbdd20aSAndroid Build Coastguard Worker MethodID method_id,
147*6dbdd20aSAndroid Build Coastguard Worker const ProtoMessage& args,
148*6dbdd20aSAndroid Build Coastguard Worker bool drop_reply = false,
149*6dbdd20aSAndroid Build Coastguard Worker int fd = -1) {
150*6dbdd20aSAndroid Build Coastguard Worker Frame frame;
151*6dbdd20aSAndroid Build Coastguard Worker uint64_t request_id = requests_.empty() ? 1 : requests_.rbegin()->first + 1;
152*6dbdd20aSAndroid Build Coastguard Worker requests_.emplace(request_id, 0);
153*6dbdd20aSAndroid Build Coastguard Worker frame.set_request_id(request_id);
154*6dbdd20aSAndroid Build Coastguard Worker frame.mutable_msg_invoke_method()->set_service_id(service_id);
155*6dbdd20aSAndroid Build Coastguard Worker frame.mutable_msg_invoke_method()->set_method_id(method_id);
156*6dbdd20aSAndroid Build Coastguard Worker frame.mutable_msg_invoke_method()->set_drop_reply(drop_reply);
157*6dbdd20aSAndroid Build Coastguard Worker frame.mutable_msg_invoke_method()->set_args_proto(args.SerializeAsString());
158*6dbdd20aSAndroid Build Coastguard Worker SendFrame(frame, fd);
159*6dbdd20aSAndroid Build Coastguard Worker }
160*6dbdd20aSAndroid Build Coastguard Worker
161*6dbdd20aSAndroid Build Coastguard Worker // base::UnixSocket::EventListener implementation.
OnConnect(base::UnixSocket *,bool success)162*6dbdd20aSAndroid Build Coastguard Worker void OnConnect(base::UnixSocket*, bool success) override {
163*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(success);
164*6dbdd20aSAndroid Build Coastguard Worker OnConnect();
165*6dbdd20aSAndroid Build Coastguard Worker }
166*6dbdd20aSAndroid Build Coastguard Worker
OnDisconnect(base::UnixSocket *)167*6dbdd20aSAndroid Build Coastguard Worker void OnDisconnect(base::UnixSocket*) override { OnDisconnect(); }
168*6dbdd20aSAndroid Build Coastguard Worker
OnDataAvailable(base::UnixSocket * sock)169*6dbdd20aSAndroid Build Coastguard Worker void OnDataAvailable(base::UnixSocket* sock) override {
170*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(sock_.get(), sock);
171*6dbdd20aSAndroid Build Coastguard Worker auto buf = frame_deserializer_.BeginReceive();
172*6dbdd20aSAndroid Build Coastguard Worker base::ScopedFile fd;
173*6dbdd20aSAndroid Build Coastguard Worker size_t rsize = sock->Receive(buf.data, buf.size, &fd);
174*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(frame_deserializer_.EndReceive(rsize));
175*6dbdd20aSAndroid Build Coastguard Worker if (fd)
176*6dbdd20aSAndroid Build Coastguard Worker OnFileDescriptorReceived(*fd);
177*6dbdd20aSAndroid Build Coastguard Worker while (std::unique_ptr<Frame> frame = frame_deserializer_.PopNextFrame()) {
178*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(1u, requests_.count(frame->request_id()));
179*6dbdd20aSAndroid Build Coastguard Worker EXPECT_EQ(0, requests_[frame->request_id()]++);
180*6dbdd20aSAndroid Build Coastguard Worker if (frame->has_msg_bind_service_reply()) {
181*6dbdd20aSAndroid Build Coastguard Worker if (frame->msg_bind_service_reply().success())
182*6dbdd20aSAndroid Build Coastguard Worker last_bound_service_id_ = frame->msg_bind_service_reply().service_id();
183*6dbdd20aSAndroid Build Coastguard Worker return OnServiceBound(frame->msg_bind_service_reply());
184*6dbdd20aSAndroid Build Coastguard Worker }
185*6dbdd20aSAndroid Build Coastguard Worker if (frame->has_msg_invoke_method_reply())
186*6dbdd20aSAndroid Build Coastguard Worker return OnInvokeMethodReply(frame->msg_invoke_method_reply());
187*6dbdd20aSAndroid Build Coastguard Worker if (frame->has_msg_request_error())
188*6dbdd20aSAndroid Build Coastguard Worker return OnRequestError();
189*6dbdd20aSAndroid Build Coastguard Worker FAIL() << "Unexpected frame received from host";
190*6dbdd20aSAndroid Build Coastguard Worker }
191*6dbdd20aSAndroid Build Coastguard Worker }
192*6dbdd20aSAndroid Build Coastguard Worker
SendFrame(const Frame & frame,int fd=-1)193*6dbdd20aSAndroid Build Coastguard Worker void SendFrame(const Frame& frame, int fd = -1) {
194*6dbdd20aSAndroid Build Coastguard Worker std::string buf = BufferedFrameDeserializer::Serialize(frame);
195*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(sock_->Send(buf.data(), buf.size(), fd));
196*6dbdd20aSAndroid Build Coastguard Worker }
197*6dbdd20aSAndroid Build Coastguard Worker
198*6dbdd20aSAndroid Build Coastguard Worker BufferedFrameDeserializer frame_deserializer_;
199*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<base::UnixSocket> sock_;
200*6dbdd20aSAndroid Build Coastguard Worker std::map<uint64_t /* request_id */, int /* num_replies_received */> requests_;
201*6dbdd20aSAndroid Build Coastguard Worker ServiceID last_bound_service_id_;
202*6dbdd20aSAndroid Build Coastguard Worker };
203*6dbdd20aSAndroid Build Coastguard Worker
204*6dbdd20aSAndroid Build Coastguard Worker class HostImplTest : public ::testing::Test {
205*6dbdd20aSAndroid Build Coastguard Worker public:
SetUp()206*6dbdd20aSAndroid Build Coastguard Worker void SetUp() override {
207*6dbdd20aSAndroid Build Coastguard Worker kTestSocket.Destroy();
208*6dbdd20aSAndroid Build Coastguard Worker task_runner_.reset(new base::TestTaskRunner());
209*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
210*6dbdd20aSAndroid Build Coastguard Worker Host* host = Host::CreateInstance_Fuchsia(task_runner_.get()).release();
211*6dbdd20aSAndroid Build Coastguard Worker auto socket_pair = base::UnixSocketRaw::CreatePairPosix(
212*6dbdd20aSAndroid Build Coastguard Worker base::SockFamily::kUnix, base::SockType::kStream);
213*6dbdd20aSAndroid Build Coastguard Worker host->AdoptConnectedSocket_Fuchsia(
214*6dbdd20aSAndroid Build Coastguard Worker base::ScopedSocketHandle(socket_pair.first.ReleaseFd()),
215*6dbdd20aSAndroid Build Coastguard Worker [](int) { return false; });
216*6dbdd20aSAndroid Build Coastguard Worker cli_.reset(
217*6dbdd20aSAndroid Build Coastguard Worker new FakeClient(base::ScopedSocketHandle(socket_pair.second.ReleaseFd()),
218*6dbdd20aSAndroid Build Coastguard Worker task_runner_.get()));
219*6dbdd20aSAndroid Build Coastguard Worker #else
220*6dbdd20aSAndroid Build Coastguard Worker Host* host =
221*6dbdd20aSAndroid Build Coastguard Worker Host::CreateInstance(kTestSocket.name(), task_runner_.get()).release();
222*6dbdd20aSAndroid Build Coastguard Worker cli_.reset(new FakeClient(task_runner_.get()));
223*6dbdd20aSAndroid Build Coastguard Worker #endif
224*6dbdd20aSAndroid Build Coastguard Worker ASSERT_NE(nullptr, host);
225*6dbdd20aSAndroid Build Coastguard Worker host_.reset(static_cast<HostImpl*>(host));
226*6dbdd20aSAndroid Build Coastguard Worker auto on_connect = task_runner_->CreateCheckpoint("on_connect");
227*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnConnect()).WillOnce(Invoke(on_connect));
228*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_connect");
229*6dbdd20aSAndroid Build Coastguard Worker }
230*6dbdd20aSAndroid Build Coastguard Worker
TearDown()231*6dbdd20aSAndroid Build Coastguard Worker void TearDown() override {
232*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilIdle();
233*6dbdd20aSAndroid Build Coastguard Worker cli_.reset();
234*6dbdd20aSAndroid Build Coastguard Worker host_.reset();
235*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilIdle();
236*6dbdd20aSAndroid Build Coastguard Worker task_runner_.reset();
237*6dbdd20aSAndroid Build Coastguard Worker kTestSocket.Destroy();
238*6dbdd20aSAndroid Build Coastguard Worker }
239*6dbdd20aSAndroid Build Coastguard Worker
240*6dbdd20aSAndroid Build Coastguard Worker // ::testing::StrictMock<MockEventListener> proxy_events_;
241*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<base::TestTaskRunner> task_runner_;
242*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<HostImpl> host_;
243*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<FakeClient> cli_;
244*6dbdd20aSAndroid Build Coastguard Worker };
245*6dbdd20aSAndroid Build Coastguard Worker
TEST_F(HostImplTest,BindService)246*6dbdd20aSAndroid Build Coastguard Worker TEST_F(HostImplTest, BindService) {
247*6dbdd20aSAndroid Build Coastguard Worker // First bind the service when it doesn't exists yet and check that the
248*6dbdd20aSAndroid Build Coastguard Worker // BindService() request fails.
249*6dbdd20aSAndroid Build Coastguard Worker cli_->BindService("FakeService"); // FakeService does not exist yet.
250*6dbdd20aSAndroid Build Coastguard Worker auto on_bind_failure = task_runner_->CreateCheckpoint("on_bind_failure");
251*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnServiceBound(_))
252*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(Invoke([on_bind_failure](const Frame::BindServiceReply& reply) {
253*6dbdd20aSAndroid Build Coastguard Worker ASSERT_FALSE(reply.success());
254*6dbdd20aSAndroid Build Coastguard Worker on_bind_failure();
255*6dbdd20aSAndroid Build Coastguard Worker }));
256*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_bind_failure");
257*6dbdd20aSAndroid Build Coastguard Worker
258*6dbdd20aSAndroid Build Coastguard Worker // Now expose the service and bind it.
259*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(host_->ExposeService(
260*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<Service>(new FakeService("FakeService"))));
261*6dbdd20aSAndroid Build Coastguard Worker auto on_bind_success = task_runner_->CreateCheckpoint("on_bind_success");
262*6dbdd20aSAndroid Build Coastguard Worker cli_->BindService("FakeService");
263*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnServiceBound(_))
264*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(Invoke([on_bind_success](const Frame::BindServiceReply& reply) {
265*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(reply.success());
266*6dbdd20aSAndroid Build Coastguard Worker on_bind_success();
267*6dbdd20aSAndroid Build Coastguard Worker }));
268*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_bind_success");
269*6dbdd20aSAndroid Build Coastguard Worker }
270*6dbdd20aSAndroid Build Coastguard Worker
TEST_F(HostImplTest,InvokeNonExistingMethod)271*6dbdd20aSAndroid Build Coastguard Worker TEST_F(HostImplTest, InvokeNonExistingMethod) {
272*6dbdd20aSAndroid Build Coastguard Worker FakeService* fake_service = new FakeService("FakeService");
273*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
274*6dbdd20aSAndroid Build Coastguard Worker auto on_bind = task_runner_->CreateCheckpoint("on_bind");
275*6dbdd20aSAndroid Build Coastguard Worker cli_->BindService("FakeService");
276*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
277*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_bind");
278*6dbdd20aSAndroid Build Coastguard Worker
279*6dbdd20aSAndroid Build Coastguard Worker auto on_invoke_failure = task_runner_->CreateCheckpoint("on_invoke_failure");
280*6dbdd20aSAndroid Build Coastguard Worker cli_->InvokeMethod(cli_->last_bound_service_id_, 42, RequestProto());
281*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnInvokeMethodReply(_))
282*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(
283*6dbdd20aSAndroid Build Coastguard Worker Invoke([on_invoke_failure](const Frame::InvokeMethodReply& reply) {
284*6dbdd20aSAndroid Build Coastguard Worker ASSERT_FALSE(reply.success());
285*6dbdd20aSAndroid Build Coastguard Worker ASSERT_FALSE(reply.has_more());
286*6dbdd20aSAndroid Build Coastguard Worker on_invoke_failure();
287*6dbdd20aSAndroid Build Coastguard Worker }));
288*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_invoke_failure");
289*6dbdd20aSAndroid Build Coastguard Worker }
290*6dbdd20aSAndroid Build Coastguard Worker
TEST_F(HostImplTest,InvokeMethod)291*6dbdd20aSAndroid Build Coastguard Worker TEST_F(HostImplTest, InvokeMethod) {
292*6dbdd20aSAndroid Build Coastguard Worker FakeService* fake_service = new FakeService("FakeService");
293*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
294*6dbdd20aSAndroid Build Coastguard Worker auto on_bind = task_runner_->CreateCheckpoint("on_bind");
295*6dbdd20aSAndroid Build Coastguard Worker cli_->BindService("FakeService");
296*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
297*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_bind");
298*6dbdd20aSAndroid Build Coastguard Worker
299*6dbdd20aSAndroid Build Coastguard Worker RequestProto req_args;
300*6dbdd20aSAndroid Build Coastguard Worker req_args.set_data("foo");
301*6dbdd20aSAndroid Build Coastguard Worker cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
302*6dbdd20aSAndroid Build Coastguard Worker auto on_reply_sent = task_runner_->CreateCheckpoint("on_reply_sent");
303*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
304*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(
305*6dbdd20aSAndroid Build Coastguard Worker Invoke([on_reply_sent](const RequestProto& req, DeferredBase* reply) {
306*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ("foo", req.data());
307*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
308*6dbdd20aSAndroid Build Coastguard Worker reply_args->set_data("bar");
309*6dbdd20aSAndroid Build Coastguard Worker reply->Resolve(AsyncResult<ProtoMessage>(
310*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ProtoMessage>(reply_args.release())));
311*6dbdd20aSAndroid Build Coastguard Worker on_reply_sent();
312*6dbdd20aSAndroid Build Coastguard Worker }));
313*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_reply_sent");
314*6dbdd20aSAndroid Build Coastguard Worker
315*6dbdd20aSAndroid Build Coastguard Worker auto on_reply_received = task_runner_->CreateCheckpoint("on_reply_received");
316*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnInvokeMethodReply(_))
317*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(
318*6dbdd20aSAndroid Build Coastguard Worker Invoke([on_reply_received](const Frame::InvokeMethodReply& reply) {
319*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(reply.success());
320*6dbdd20aSAndroid Build Coastguard Worker ASSERT_FALSE(reply.has_more());
321*6dbdd20aSAndroid Build Coastguard Worker ReplyProto reply_args;
322*6dbdd20aSAndroid Build Coastguard Worker reply_args.ParseFromString(reply.reply_proto());
323*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ("bar", reply_args.data());
324*6dbdd20aSAndroid Build Coastguard Worker on_reply_received();
325*6dbdd20aSAndroid Build Coastguard Worker }));
326*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_reply_received");
327*6dbdd20aSAndroid Build Coastguard Worker }
328*6dbdd20aSAndroid Build Coastguard Worker
TEST_F(HostImplTest,InvokeMethodDropReply)329*6dbdd20aSAndroid Build Coastguard Worker TEST_F(HostImplTest, InvokeMethodDropReply) {
330*6dbdd20aSAndroid Build Coastguard Worker FakeService* fake_service = new FakeService("FakeService");
331*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
332*6dbdd20aSAndroid Build Coastguard Worker auto on_bind = task_runner_->CreateCheckpoint("on_bind");
333*6dbdd20aSAndroid Build Coastguard Worker cli_->BindService("FakeService");
334*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
335*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_bind");
336*6dbdd20aSAndroid Build Coastguard Worker
337*6dbdd20aSAndroid Build Coastguard Worker // OnFakeMethod1 will:
338*6dbdd20aSAndroid Build Coastguard Worker // - Do nothing on the 1st call, when |drop_reply| == true.
339*6dbdd20aSAndroid Build Coastguard Worker // - Reply on the 2nd call, when |drop_reply| == false.
340*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
341*6dbdd20aSAndroid Build Coastguard Worker .Times(2)
342*6dbdd20aSAndroid Build Coastguard Worker .WillRepeatedly(Invoke([](const RequestProto& req, DeferredBase* reply) {
343*6dbdd20aSAndroid Build Coastguard Worker if (req.data() == "drop_reply")
344*6dbdd20aSAndroid Build Coastguard Worker return;
345*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
346*6dbdd20aSAndroid Build Coastguard Worker reply_args->set_data("the_reply");
347*6dbdd20aSAndroid Build Coastguard Worker reply->Resolve(AsyncResult<ProtoMessage>(
348*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ProtoMessage>(reply_args.release())));
349*6dbdd20aSAndroid Build Coastguard Worker }));
350*6dbdd20aSAndroid Build Coastguard Worker
351*6dbdd20aSAndroid Build Coastguard Worker auto on_reply_received = task_runner_->CreateCheckpoint("on_reply_received");
352*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnInvokeMethodReply(_))
353*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(
354*6dbdd20aSAndroid Build Coastguard Worker Invoke([on_reply_received](const Frame::InvokeMethodReply& reply) {
355*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(reply.success());
356*6dbdd20aSAndroid Build Coastguard Worker ReplyProto reply_args;
357*6dbdd20aSAndroid Build Coastguard Worker reply_args.ParseFromString(reply.reply_proto());
358*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ("the_reply", reply_args.data());
359*6dbdd20aSAndroid Build Coastguard Worker on_reply_received();
360*6dbdd20aSAndroid Build Coastguard Worker }));
361*6dbdd20aSAndroid Build Coastguard Worker
362*6dbdd20aSAndroid Build Coastguard Worker // Invoke the method first with |drop_reply|=true, then |drop_reply|=false.
363*6dbdd20aSAndroid Build Coastguard Worker RequestProto rp;
364*6dbdd20aSAndroid Build Coastguard Worker rp.set_data("drop_reply");
365*6dbdd20aSAndroid Build Coastguard Worker cli_->InvokeMethod(cli_->last_bound_service_id_, 1, rp, true /*drop_reply*/);
366*6dbdd20aSAndroid Build Coastguard Worker rp.set_data("do_reply");
367*6dbdd20aSAndroid Build Coastguard Worker cli_->InvokeMethod(cli_->last_bound_service_id_, 1, rp, false /*drop_reply*/);
368*6dbdd20aSAndroid Build Coastguard Worker
369*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_reply_received");
370*6dbdd20aSAndroid Build Coastguard Worker }
371*6dbdd20aSAndroid Build Coastguard Worker
372*6dbdd20aSAndroid Build Coastguard Worker #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
373*6dbdd20aSAndroid Build Coastguard Worker !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
374*6dbdd20aSAndroid Build Coastguard Worker // File descriptor sending over IPC is not supported on Windows.
TEST_F(HostImplTest,SendFileDescriptor)375*6dbdd20aSAndroid Build Coastguard Worker TEST_F(HostImplTest, SendFileDescriptor) {
376*6dbdd20aSAndroid Build Coastguard Worker FakeService* fake_service = new FakeService("FakeService");
377*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
378*6dbdd20aSAndroid Build Coastguard Worker auto on_bind = task_runner_->CreateCheckpoint("on_bind");
379*6dbdd20aSAndroid Build Coastguard Worker cli_->BindService("FakeService");
380*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
381*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_bind");
382*6dbdd20aSAndroid Build Coastguard Worker
383*6dbdd20aSAndroid Build Coastguard Worker static constexpr char kFileContent[] = "shared file";
384*6dbdd20aSAndroid Build Coastguard Worker RequestProto req_args;
385*6dbdd20aSAndroid Build Coastguard Worker cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
386*6dbdd20aSAndroid Build Coastguard Worker auto on_reply_sent = task_runner_->CreateCheckpoint("on_reply_sent");
387*6dbdd20aSAndroid Build Coastguard Worker base::TempFile tx_file = base::TempFile::CreateUnlinked();
388*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(base::WriteAll(tx_file.fd(), kFileContent,
389*6dbdd20aSAndroid Build Coastguard Worker sizeof(kFileContent))),
390*6dbdd20aSAndroid Build Coastguard Worker sizeof(kFileContent));
391*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
392*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(Invoke(
393*6dbdd20aSAndroid Build Coastguard Worker [on_reply_sent, &tx_file](const RequestProto&, DeferredBase* reply) {
394*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
395*6dbdd20aSAndroid Build Coastguard Worker auto async_res = AsyncResult<ProtoMessage>(
396*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ProtoMessage>(reply_args.release()));
397*6dbdd20aSAndroid Build Coastguard Worker async_res.set_fd(tx_file.fd());
398*6dbdd20aSAndroid Build Coastguard Worker reply->Resolve(std::move(async_res));
399*6dbdd20aSAndroid Build Coastguard Worker on_reply_sent();
400*6dbdd20aSAndroid Build Coastguard Worker }));
401*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_reply_sent");
402*6dbdd20aSAndroid Build Coastguard Worker tx_file.ReleaseFD();
403*6dbdd20aSAndroid Build Coastguard Worker
404*6dbdd20aSAndroid Build Coastguard Worker auto on_fd_received = task_runner_->CreateCheckpoint("on_fd_received");
405*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnFileDescriptorReceived(_))
406*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(Invoke([on_fd_received](int fd) {
407*6dbdd20aSAndroid Build Coastguard Worker char buf[sizeof(kFileContent)] = {};
408*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(0, lseek(fd, 0, SEEK_SET));
409*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(static_cast<int32_t>(sizeof(buf)),
410*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_EINTR(read(fd, buf, sizeof(buf))));
411*6dbdd20aSAndroid Build Coastguard Worker ASSERT_STREQ(kFileContent, buf);
412*6dbdd20aSAndroid Build Coastguard Worker on_fd_received();
413*6dbdd20aSAndroid Build Coastguard Worker }));
414*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnInvokeMethodReply(_));
415*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_fd_received");
416*6dbdd20aSAndroid Build Coastguard Worker }
417*6dbdd20aSAndroid Build Coastguard Worker
TEST_F(HostImplTest,ReceiveFileDescriptor)418*6dbdd20aSAndroid Build Coastguard Worker TEST_F(HostImplTest, ReceiveFileDescriptor) {
419*6dbdd20aSAndroid Build Coastguard Worker auto received = task_runner_->CreateCheckpoint("received");
420*6dbdd20aSAndroid Build Coastguard Worker FakeService* fake_service = new FakeService("FakeService");
421*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
422*6dbdd20aSAndroid Build Coastguard Worker auto on_bind = task_runner_->CreateCheckpoint("on_bind");
423*6dbdd20aSAndroid Build Coastguard Worker cli_->BindService("FakeService");
424*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
425*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_bind");
426*6dbdd20aSAndroid Build Coastguard Worker
427*6dbdd20aSAndroid Build Coastguard Worker static constexpr char kFileContent[] = "shared file";
428*6dbdd20aSAndroid Build Coastguard Worker RequestProto req_args;
429*6dbdd20aSAndroid Build Coastguard Worker base::TempFile tx_file = base::TempFile::CreateUnlinked();
430*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(static_cast<size_t>(base::WriteAll(tx_file.fd(), kFileContent,
431*6dbdd20aSAndroid Build Coastguard Worker sizeof(kFileContent))),
432*6dbdd20aSAndroid Build Coastguard Worker sizeof(kFileContent));
433*6dbdd20aSAndroid Build Coastguard Worker cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args, false,
434*6dbdd20aSAndroid Build Coastguard Worker tx_file.fd());
435*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnInvokeMethodReply(_));
436*6dbdd20aSAndroid Build Coastguard Worker base::ScopedFile rx_fd;
437*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
438*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(Invoke([received, &fake_service, &rx_fd](const RequestProto&,
439*6dbdd20aSAndroid Build Coastguard Worker DeferredBase*) {
440*6dbdd20aSAndroid Build Coastguard Worker rx_fd = fake_service->TakeReceivedFD();
441*6dbdd20aSAndroid Build Coastguard Worker received();
442*6dbdd20aSAndroid Build Coastguard Worker }));
443*6dbdd20aSAndroid Build Coastguard Worker
444*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("received");
445*6dbdd20aSAndroid Build Coastguard Worker
446*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(rx_fd);
447*6dbdd20aSAndroid Build Coastguard Worker char buf[sizeof(kFileContent)] = {};
448*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(0, lseek(*rx_fd, 0, SEEK_SET));
449*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(static_cast<int32_t>(sizeof(buf)),
450*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_EINTR(read(*rx_fd, buf, sizeof(buf))));
451*6dbdd20aSAndroid Build Coastguard Worker ASSERT_STREQ(kFileContent, buf);
452*6dbdd20aSAndroid Build Coastguard Worker }
453*6dbdd20aSAndroid Build Coastguard Worker #endif // !OS_WIN
454*6dbdd20aSAndroid Build Coastguard Worker
455*6dbdd20aSAndroid Build Coastguard Worker // Invoke a method and immediately after disconnect the client.
TEST_F(HostImplTest,OnClientDisconnect)456*6dbdd20aSAndroid Build Coastguard Worker TEST_F(HostImplTest, OnClientDisconnect) {
457*6dbdd20aSAndroid Build Coastguard Worker FakeService* fake_service = new FakeService("FakeService");
458*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
459*6dbdd20aSAndroid Build Coastguard Worker auto on_bind = task_runner_->CreateCheckpoint("on_bind");
460*6dbdd20aSAndroid Build Coastguard Worker cli_->BindService("FakeService");
461*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
462*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_bind");
463*6dbdd20aSAndroid Build Coastguard Worker
464*6dbdd20aSAndroid Build Coastguard Worker RequestProto req_args;
465*6dbdd20aSAndroid Build Coastguard Worker req_args.set_data("foo");
466*6dbdd20aSAndroid Build Coastguard Worker cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
467*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnInvokeMethodReply(_)).Times(0);
468*6dbdd20aSAndroid Build Coastguard Worker cli_.reset(); // Disconnect the client.
469*6dbdd20aSAndroid Build Coastguard Worker auto on_host_method = task_runner_->CreateCheckpoint("on_host_method");
470*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
471*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(
472*6dbdd20aSAndroid Build Coastguard Worker Invoke([on_host_method](const RequestProto& req, DeferredBase*) {
473*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ("foo", req.data());
474*6dbdd20aSAndroid Build Coastguard Worker on_host_method();
475*6dbdd20aSAndroid Build Coastguard Worker }));
476*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_host_method");
477*6dbdd20aSAndroid Build Coastguard Worker }
478*6dbdd20aSAndroid Build Coastguard Worker
479*6dbdd20aSAndroid Build Coastguard Worker // Like InvokeMethod, but instead of resolving the Deferred reply within the
480*6dbdd20aSAndroid Build Coastguard Worker // call stack, std::move()-s it outside an replies
TEST_F(HostImplTest,MoveReplyObjectAndReplyAsynchronously)481*6dbdd20aSAndroid Build Coastguard Worker TEST_F(HostImplTest, MoveReplyObjectAndReplyAsynchronously) {
482*6dbdd20aSAndroid Build Coastguard Worker FakeService* fake_service = new FakeService("FakeService");
483*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
484*6dbdd20aSAndroid Build Coastguard Worker auto on_bind = task_runner_->CreateCheckpoint("on_bind");
485*6dbdd20aSAndroid Build Coastguard Worker cli_->BindService("FakeService");
486*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
487*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_bind");
488*6dbdd20aSAndroid Build Coastguard Worker
489*6dbdd20aSAndroid Build Coastguard Worker // Invokes the remote method and waits that the FakeService sees it. The reply
490*6dbdd20aSAndroid Build Coastguard Worker // is not resolved but just moved into |moved_reply|.
491*6dbdd20aSAndroid Build Coastguard Worker RequestProto req_args;
492*6dbdd20aSAndroid Build Coastguard Worker cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
493*6dbdd20aSAndroid Build Coastguard Worker auto on_invoke = task_runner_->CreateCheckpoint("on_invoke");
494*6dbdd20aSAndroid Build Coastguard Worker DeferredBase moved_reply;
495*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
496*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(Invoke(
497*6dbdd20aSAndroid Build Coastguard Worker [on_invoke, &moved_reply](const RequestProto&, DeferredBase* reply) {
498*6dbdd20aSAndroid Build Coastguard Worker moved_reply = std::move(*reply);
499*6dbdd20aSAndroid Build Coastguard Worker on_invoke();
500*6dbdd20aSAndroid Build Coastguard Worker }));
501*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_invoke");
502*6dbdd20aSAndroid Build Coastguard Worker
503*6dbdd20aSAndroid Build Coastguard Worker // Check that the FakeClient doesn't see any reply yet.
504*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnInvokeMethodReply(_)).Times(0);
505*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilIdle();
506*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(cli_.get()));
507*6dbdd20aSAndroid Build Coastguard Worker
508*6dbdd20aSAndroid Build Coastguard Worker // Resolve the reply asynchronously in a deferred task.
509*6dbdd20aSAndroid Build Coastguard Worker task_runner_->PostTask([&moved_reply] {
510*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
511*6dbdd20aSAndroid Build Coastguard Worker reply_args->set_data("bar");
512*6dbdd20aSAndroid Build Coastguard Worker moved_reply.Resolve(AsyncResult<ProtoMessage>(
513*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ProtoMessage>(reply_args.release())));
514*6dbdd20aSAndroid Build Coastguard Worker });
515*6dbdd20aSAndroid Build Coastguard Worker
516*6dbdd20aSAndroid Build Coastguard Worker auto on_reply_received = task_runner_->CreateCheckpoint("on_reply_received");
517*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnInvokeMethodReply(_))
518*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(
519*6dbdd20aSAndroid Build Coastguard Worker Invoke([on_reply_received](const Frame::InvokeMethodReply& reply) {
520*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(reply.success());
521*6dbdd20aSAndroid Build Coastguard Worker ASSERT_FALSE(reply.has_more());
522*6dbdd20aSAndroid Build Coastguard Worker ReplyProto reply_args;
523*6dbdd20aSAndroid Build Coastguard Worker reply_args.ParseFromString(reply.reply_proto());
524*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ("bar", reply_args.data());
525*6dbdd20aSAndroid Build Coastguard Worker on_reply_received();
526*6dbdd20aSAndroid Build Coastguard Worker }));
527*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_reply_received");
528*6dbdd20aSAndroid Build Coastguard Worker }
529*6dbdd20aSAndroid Build Coastguard Worker
530*6dbdd20aSAndroid Build Coastguard Worker #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
531*6dbdd20aSAndroid Build Coastguard Worker PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
532*6dbdd20aSAndroid Build Coastguard Worker // Check ClientInfo of the service.
TEST_F(HostImplTest,ServiceClientInfo)533*6dbdd20aSAndroid Build Coastguard Worker TEST_F(HostImplTest, ServiceClientInfo) {
534*6dbdd20aSAndroid Build Coastguard Worker FakeService* fake_service = new FakeService("FakeService");
535*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
536*6dbdd20aSAndroid Build Coastguard Worker auto on_bind = task_runner_->CreateCheckpoint("on_bind");
537*6dbdd20aSAndroid Build Coastguard Worker cli_->BindService("FakeService");
538*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
539*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_bind");
540*6dbdd20aSAndroid Build Coastguard Worker
541*6dbdd20aSAndroid Build Coastguard Worker RequestProto req_args;
542*6dbdd20aSAndroid Build Coastguard Worker req_args.set_data("foo");
543*6dbdd20aSAndroid Build Coastguard Worker cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
544*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
545*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(
546*6dbdd20aSAndroid Build Coastguard Worker Invoke([fake_service](const RequestProto& req, DeferredBase* reply) {
547*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ("foo", req.data());
548*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
549*6dbdd20aSAndroid Build Coastguard Worker reply_args->set_data("bar");
550*6dbdd20aSAndroid Build Coastguard Worker reply->Resolve(AsyncResult<ProtoMessage>(
551*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ProtoMessage>(reply_args.release())));
552*6dbdd20aSAndroid Build Coastguard Worker // Verifies the pid() and uid() values in ClientInfo.
553*6dbdd20aSAndroid Build Coastguard Worker const auto& client_info = fake_service->client_info();
554*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(client_info.uid(), getuid());
555*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(client_info.pid(), getpid());
556*6dbdd20aSAndroid Build Coastguard Worker }));
557*6dbdd20aSAndroid Build Coastguard Worker
558*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnInvokeMethodReply(_)).WillOnce(Return());
559*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilIdle();
560*6dbdd20aSAndroid Build Coastguard Worker }
561*6dbdd20aSAndroid Build Coastguard Worker
TEST_F(HostImplTest,SetPeerIdentityUnixSocket)562*6dbdd20aSAndroid Build Coastguard Worker TEST_F(HostImplTest, SetPeerIdentityUnixSocket) {
563*6dbdd20aSAndroid Build Coastguard Worker FakeService* fake_service = new FakeService("FakeService");
564*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
565*6dbdd20aSAndroid Build Coastguard Worker // SetPeerIdentity must be the first message. Use getpid()+1/geteuid+1 to
566*6dbdd20aSAndroid Build Coastguard Worker // check that this message doesn't take effect for Unix socket.
567*6dbdd20aSAndroid Build Coastguard Worker cli_->SetPeerIdentity(geteuid() + 1, getpid() + 1, "test_machine_id_hint");
568*6dbdd20aSAndroid Build Coastguard Worker
569*6dbdd20aSAndroid Build Coastguard Worker auto on_bind = task_runner_->CreateCheckpoint("on_bind");
570*6dbdd20aSAndroid Build Coastguard Worker cli_->BindService("FakeService");
571*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
572*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilCheckpoint("on_bind");
573*6dbdd20aSAndroid Build Coastguard Worker
574*6dbdd20aSAndroid Build Coastguard Worker RequestProto req_args;
575*6dbdd20aSAndroid Build Coastguard Worker req_args.set_data("foo");
576*6dbdd20aSAndroid Build Coastguard Worker cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
577*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
578*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(
579*6dbdd20aSAndroid Build Coastguard Worker Invoke([fake_service](const RequestProto& req, DeferredBase* reply) {
580*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ("foo", req.data());
581*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
582*6dbdd20aSAndroid Build Coastguard Worker reply_args->set_data("bar");
583*6dbdd20aSAndroid Build Coastguard Worker reply->Resolve(AsyncResult<ProtoMessage>(
584*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ProtoMessage>(reply_args.release())));
585*6dbdd20aSAndroid Build Coastguard Worker // Verifies the pid() and uid() values in ClientInfo.
586*6dbdd20aSAndroid Build Coastguard Worker const auto& client_info = fake_service->client_info();
587*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(client_info.uid(), getuid());
588*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(client_info.pid(), getpid());
589*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(client_info.machine_id(), base::kDefaultMachineID);
590*6dbdd20aSAndroid Build Coastguard Worker }));
591*6dbdd20aSAndroid Build Coastguard Worker
592*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli_, OnInvokeMethodReply(_)).WillOnce(Return());
593*6dbdd20aSAndroid Build Coastguard Worker task_runner_->RunUntilIdle();
594*6dbdd20aSAndroid Build Coastguard Worker }
595*6dbdd20aSAndroid Build Coastguard Worker
TEST(HostImpl,SetPeerIdentityTcpSocket)596*6dbdd20aSAndroid Build Coastguard Worker TEST(HostImpl, SetPeerIdentityTcpSocket) {
597*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<base::TestTaskRunner> task_runner(new base::TestTaskRunner());
598*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<HostImpl> host_impl;
599*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<FakeClient> cli;
600*6dbdd20aSAndroid Build Coastguard Worker
601*6dbdd20aSAndroid Build Coastguard Worker auto tear_down = base::OnScopeExit([&]() {
602*6dbdd20aSAndroid Build Coastguard Worker task_runner->RunUntilIdle();
603*6dbdd20aSAndroid Build Coastguard Worker cli.reset();
604*6dbdd20aSAndroid Build Coastguard Worker host_impl.reset();
605*6dbdd20aSAndroid Build Coastguard Worker task_runner->RunUntilIdle();
606*6dbdd20aSAndroid Build Coastguard Worker task_runner.reset();
607*6dbdd20aSAndroid Build Coastguard Worker });
608*6dbdd20aSAndroid Build Coastguard Worker
609*6dbdd20aSAndroid Build Coastguard Worker Host* host = Host::CreateInstance("127.0.0.1:0", task_runner.get()).release();
610*6dbdd20aSAndroid Build Coastguard Worker ASSERT_NE(nullptr, host);
611*6dbdd20aSAndroid Build Coastguard Worker host_impl.reset(static_cast<HostImpl*>(host));
612*6dbdd20aSAndroid Build Coastguard Worker
613*6dbdd20aSAndroid Build Coastguard Worker auto sock_name = host_impl->sock()->GetSockAddr();
614*6dbdd20aSAndroid Build Coastguard Worker cli.reset(new FakeClient(sock_name.c_str(), task_runner.get()));
615*6dbdd20aSAndroid Build Coastguard Worker
616*6dbdd20aSAndroid Build Coastguard Worker auto on_connect = task_runner->CreateCheckpoint("on_connect");
617*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli, OnConnect()).WillOnce(Invoke(on_connect));
618*6dbdd20aSAndroid Build Coastguard Worker task_runner->RunUntilCheckpoint("on_connect");
619*6dbdd20aSAndroid Build Coastguard Worker
620*6dbdd20aSAndroid Build Coastguard Worker FakeService* fake_service = new FakeService("FakeService");
621*6dbdd20aSAndroid Build Coastguard Worker ASSERT_TRUE(host->ExposeService(std::unique_ptr<Service>(fake_service)));
622*6dbdd20aSAndroid Build Coastguard Worker // Set peer identity with fake values.
623*6dbdd20aSAndroid Build Coastguard Worker cli->SetPeerIdentity(123, 456, "test_machine_id_hint");
624*6dbdd20aSAndroid Build Coastguard Worker
625*6dbdd20aSAndroid Build Coastguard Worker auto on_bind = task_runner->CreateCheckpoint("on_bind");
626*6dbdd20aSAndroid Build Coastguard Worker cli->BindService("FakeService");
627*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
628*6dbdd20aSAndroid Build Coastguard Worker task_runner->RunUntilCheckpoint("on_bind");
629*6dbdd20aSAndroid Build Coastguard Worker
630*6dbdd20aSAndroid Build Coastguard Worker RequestProto req_args;
631*6dbdd20aSAndroid Build Coastguard Worker req_args.set_data("foo");
632*6dbdd20aSAndroid Build Coastguard Worker cli->InvokeMethod(cli->last_bound_service_id_, 1, req_args);
633*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
634*6dbdd20aSAndroid Build Coastguard Worker .WillOnce(
635*6dbdd20aSAndroid Build Coastguard Worker Invoke([fake_service](const RequestProto& req, DeferredBase* reply) {
636*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ("foo", req.data());
637*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
638*6dbdd20aSAndroid Build Coastguard Worker reply_args->set_data("bar");
639*6dbdd20aSAndroid Build Coastguard Worker reply->Resolve(AsyncResult<ProtoMessage>(
640*6dbdd20aSAndroid Build Coastguard Worker std::unique_ptr<ProtoMessage>(reply_args.release())));
641*6dbdd20aSAndroid Build Coastguard Worker // Verify peer identity.
642*6dbdd20aSAndroid Build Coastguard Worker const auto& client_info = fake_service->client_info();
643*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(client_info.uid(), 123u);
644*6dbdd20aSAndroid Build Coastguard Worker ASSERT_EQ(client_info.pid(), 456);
645*6dbdd20aSAndroid Build Coastguard Worker // ClientInfo contains non-default raw machine ID.
646*6dbdd20aSAndroid Build Coastguard Worker ASSERT_NE(client_info.machine_id(), base::kDefaultMachineID);
647*6dbdd20aSAndroid Build Coastguard Worker }));
648*6dbdd20aSAndroid Build Coastguard Worker
649*6dbdd20aSAndroid Build Coastguard Worker EXPECT_CALL(*cli, OnInvokeMethodReply(_)).WillOnce(Return());
650*6dbdd20aSAndroid Build Coastguard Worker task_runner->RunUntilIdle();
651*6dbdd20aSAndroid Build Coastguard Worker }
652*6dbdd20aSAndroid Build Coastguard Worker #endif // PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||
653*6dbdd20aSAndroid Build Coastguard Worker // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
654*6dbdd20aSAndroid Build Coastguard Worker
655*6dbdd20aSAndroid Build Coastguard Worker // TODO(primiano): add the tests below in next CLs.
656*6dbdd20aSAndroid Build Coastguard Worker // TEST(HostImplTest, ManyClients) {}
657*6dbdd20aSAndroid Build Coastguard Worker // TEST(HostImplTest, OverlappingRequstsOutOfOrder) {}
658*6dbdd20aSAndroid Build Coastguard Worker // TEST(HostImplTest, StreamingRequest) {}
659*6dbdd20aSAndroid Build Coastguard Worker // TEST(HostImplTest, ManyDropReplyRequestsDontLeakMemory) {}
660*6dbdd20aSAndroid Build Coastguard Worker
661*6dbdd20aSAndroid Build Coastguard Worker } // namespace
662*6dbdd20aSAndroid Build Coastguard Worker } // namespace ipc
663*6dbdd20aSAndroid Build Coastguard Worker } // namespace perfetto
664