1*6777b538SAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include <memory>
6*6777b538SAndroid Build Coastguard Worker #include <string_view>
7*6777b538SAndroid Build Coastguard Worker #include <tuple>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/process/process_metrics.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/test/perf_log.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/test/task_environment.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/timer/timer.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/types/expected.h"
21*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_channel_proxy.h"
22*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_perftest_messages.h"
23*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_perftest_util.h"
24*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_sync_channel.h"
25*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_test.mojom.h"
26*6777b538SAndroid Build Coastguard Worker #include "ipc/ipc_test_base.h"
27*6777b538SAndroid Build Coastguard Worker #include "mojo/core/test/mojo_test_base.h"
28*6777b538SAndroid Build Coastguard Worker #include "mojo/core/test/multiprocess_test_helper.h"
29*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/pending_remote.h"
30*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/bindings/remote.h"
31*6777b538SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/message_pipe.h"
32*6777b538SAndroid Build Coastguard Worker
33*6777b538SAndroid Build Coastguard Worker namespace IPC {
34*6777b538SAndroid Build Coastguard Worker namespace {
35*6777b538SAndroid Build Coastguard Worker
36*6777b538SAndroid Build Coastguard Worker struct TestParams {
37*6777b538SAndroid Build Coastguard Worker TestParams() = default;
TestParamsIPC::__anon4420150f0111::TestParams38*6777b538SAndroid Build Coastguard Worker TestParams(size_t in_message_size,
39*6777b538SAndroid Build Coastguard Worker size_t in_frames_per_second,
40*6777b538SAndroid Build Coastguard Worker size_t in_messages_per_frame,
41*6777b538SAndroid Build Coastguard Worker size_t in_duration_in_seconds)
42*6777b538SAndroid Build Coastguard Worker : message_size(in_message_size),
43*6777b538SAndroid Build Coastguard Worker frames_per_second(in_frames_per_second),
44*6777b538SAndroid Build Coastguard Worker messages_per_frame(in_messages_per_frame),
45*6777b538SAndroid Build Coastguard Worker duration_in_seconds(in_duration_in_seconds) {}
46*6777b538SAndroid Build Coastguard Worker
47*6777b538SAndroid Build Coastguard Worker size_t message_size;
48*6777b538SAndroid Build Coastguard Worker size_t frames_per_second;
49*6777b538SAndroid Build Coastguard Worker size_t messages_per_frame;
50*6777b538SAndroid Build Coastguard Worker size_t duration_in_seconds;
51*6777b538SAndroid Build Coastguard Worker };
52*6777b538SAndroid Build Coastguard Worker
GetDefaultTestParams()53*6777b538SAndroid Build Coastguard Worker std::vector<TestParams> GetDefaultTestParams() {
54*6777b538SAndroid Build Coastguard Worker std::vector<TestParams> list;
55*6777b538SAndroid Build Coastguard Worker list.push_back({144, 20, 10, 10});
56*6777b538SAndroid Build Coastguard Worker list.push_back({144, 60, 10, 10});
57*6777b538SAndroid Build Coastguard Worker return list;
58*6777b538SAndroid Build Coastguard Worker }
59*6777b538SAndroid Build Coastguard Worker
GetLogTitle(const std::string & label,const TestParams & params)60*6777b538SAndroid Build Coastguard Worker std::string GetLogTitle(const std::string& label, const TestParams& params) {
61*6777b538SAndroid Build Coastguard Worker return base::StringPrintf(
62*6777b538SAndroid Build Coastguard Worker "%s_MsgSize_%zu_FrmPerSec_%zu_MsgPerFrm_%zu", label.c_str(),
63*6777b538SAndroid Build Coastguard Worker params.message_size, params.frames_per_second, params.messages_per_frame);
64*6777b538SAndroid Build Coastguard Worker }
65*6777b538SAndroid Build Coastguard Worker
GetFrameTime(size_t frames_per_second)66*6777b538SAndroid Build Coastguard Worker base::TimeDelta GetFrameTime(size_t frames_per_second) {
67*6777b538SAndroid Build Coastguard Worker return base::Seconds(1.0 / frames_per_second);
68*6777b538SAndroid Build Coastguard Worker }
69*6777b538SAndroid Build Coastguard Worker
70*6777b538SAndroid Build Coastguard Worker class PerfCpuLogger {
71*6777b538SAndroid Build Coastguard Worker public:
PerfCpuLogger(std::string_view test_name)72*6777b538SAndroid Build Coastguard Worker explicit PerfCpuLogger(std::string_view test_name)
73*6777b538SAndroid Build Coastguard Worker : test_name_(test_name),
74*6777b538SAndroid Build Coastguard Worker process_metrics_(base::ProcessMetrics::CreateCurrentProcessMetrics()) {
75*6777b538SAndroid Build Coastguard Worker // Query the CPU usage once to start the recording interval.
76*6777b538SAndroid Build Coastguard Worker const double inital_cpu_usage =
77*6777b538SAndroid Build Coastguard Worker process_metrics_->GetPlatformIndependentCPUUsage().value_or(-1.0);
78*6777b538SAndroid Build Coastguard Worker // This should have been the first call so the reported cpu usage should be
79*6777b538SAndroid Build Coastguard Worker // exactly zero.
80*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(inital_cpu_usage, 0.0);
81*6777b538SAndroid Build Coastguard Worker }
82*6777b538SAndroid Build Coastguard Worker
83*6777b538SAndroid Build Coastguard Worker PerfCpuLogger(const PerfCpuLogger&) = delete;
84*6777b538SAndroid Build Coastguard Worker PerfCpuLogger& operator=(const PerfCpuLogger&) = delete;
85*6777b538SAndroid Build Coastguard Worker
~PerfCpuLogger()86*6777b538SAndroid Build Coastguard Worker ~PerfCpuLogger() {
87*6777b538SAndroid Build Coastguard Worker const double result =
88*6777b538SAndroid Build Coastguard Worker process_metrics_->GetPlatformIndependentCPUUsage().value_or(-1.0);
89*6777b538SAndroid Build Coastguard Worker base::LogPerfResult(test_name_.c_str(), result, "%");
90*6777b538SAndroid Build Coastguard Worker }
91*6777b538SAndroid Build Coastguard Worker
92*6777b538SAndroid Build Coastguard Worker private:
93*6777b538SAndroid Build Coastguard Worker std::string test_name_;
94*6777b538SAndroid Build Coastguard Worker std::unique_ptr<base::ProcessMetrics> process_metrics_;
95*6777b538SAndroid Build Coastguard Worker };
96*6777b538SAndroid Build Coastguard Worker
MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain)97*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain) {
98*6777b538SAndroid Build Coastguard Worker MojoPerfTestClient client;
99*6777b538SAndroid Build Coastguard Worker int rv = mojo::core::test::MultiprocessTestHelper::RunClientMain(
100*6777b538SAndroid Build Coastguard Worker base::BindOnce(&MojoPerfTestClient::Run, base::Unretained(&client)),
101*6777b538SAndroid Build Coastguard Worker true /* pass_pipe_ownership_to_main */);
102*6777b538SAndroid Build Coastguard Worker
103*6777b538SAndroid Build Coastguard Worker base::RunLoop run_loop;
104*6777b538SAndroid Build Coastguard Worker run_loop.RunUntilIdle();
105*6777b538SAndroid Build Coastguard Worker
106*6777b538SAndroid Build Coastguard Worker return rv;
107*6777b538SAndroid Build Coastguard Worker }
108*6777b538SAndroid Build Coastguard Worker
109*6777b538SAndroid Build Coastguard Worker class ChannelSteadyPingPongListener : public Listener {
110*6777b538SAndroid Build Coastguard Worker public:
111*6777b538SAndroid Build Coastguard Worker ChannelSteadyPingPongListener() = default;
112*6777b538SAndroid Build Coastguard Worker
113*6777b538SAndroid Build Coastguard Worker ~ChannelSteadyPingPongListener() override = default;
114*6777b538SAndroid Build Coastguard Worker
Init(Sender * sender)115*6777b538SAndroid Build Coastguard Worker void Init(Sender* sender) {
116*6777b538SAndroid Build Coastguard Worker DCHECK(!sender_);
117*6777b538SAndroid Build Coastguard Worker sender_ = sender;
118*6777b538SAndroid Build Coastguard Worker }
119*6777b538SAndroid Build Coastguard Worker
SetTestParams(const TestParams & params,const std::string & label,bool sync,base::OnceClosure quit_closure)120*6777b538SAndroid Build Coastguard Worker void SetTestParams(const TestParams& params,
121*6777b538SAndroid Build Coastguard Worker const std::string& label,
122*6777b538SAndroid Build Coastguard Worker bool sync,
123*6777b538SAndroid Build Coastguard Worker base::OnceClosure quit_closure) {
124*6777b538SAndroid Build Coastguard Worker params_ = params;
125*6777b538SAndroid Build Coastguard Worker label_ = label;
126*6777b538SAndroid Build Coastguard Worker sync_ = sync;
127*6777b538SAndroid Build Coastguard Worker quit_closure_ = std::move(quit_closure);
128*6777b538SAndroid Build Coastguard Worker payload_ = std::string(params.message_size, 'a');
129*6777b538SAndroid Build Coastguard Worker }
130*6777b538SAndroid Build Coastguard Worker
OnMessageReceived(const Message & message)131*6777b538SAndroid Build Coastguard Worker bool OnMessageReceived(const Message& message) override {
132*6777b538SAndroid Build Coastguard Worker CHECK(sender_);
133*6777b538SAndroid Build Coastguard Worker
134*6777b538SAndroid Build Coastguard Worker bool handled = true;
135*6777b538SAndroid Build Coastguard Worker IPC_BEGIN_MESSAGE_MAP(ChannelSteadyPingPongListener, message)
136*6777b538SAndroid Build Coastguard Worker IPC_MESSAGE_HANDLER(TestMsg_Hello, OnHello)
137*6777b538SAndroid Build Coastguard Worker IPC_MESSAGE_HANDLER(TestMsg_Ping, OnPing)
138*6777b538SAndroid Build Coastguard Worker IPC_MESSAGE_UNHANDLED(handled = false)
139*6777b538SAndroid Build Coastguard Worker IPC_END_MESSAGE_MAP()
140*6777b538SAndroid Build Coastguard Worker return handled;
141*6777b538SAndroid Build Coastguard Worker }
142*6777b538SAndroid Build Coastguard Worker
OnHello()143*6777b538SAndroid Build Coastguard Worker void OnHello() {
144*6777b538SAndroid Build Coastguard Worker cpu_logger_ = std::make_unique<PerfCpuLogger>(GetLogTitle(label_, params_));
145*6777b538SAndroid Build Coastguard Worker
146*6777b538SAndroid Build Coastguard Worker frame_count_down_ = params_.frames_per_second * params_.duration_in_seconds;
147*6777b538SAndroid Build Coastguard Worker
148*6777b538SAndroid Build Coastguard Worker timer_.Start(FROM_HERE, GetFrameTime(params_.frames_per_second), this,
149*6777b538SAndroid Build Coastguard Worker &ChannelSteadyPingPongListener::StartPingPong);
150*6777b538SAndroid Build Coastguard Worker }
151*6777b538SAndroid Build Coastguard Worker
StartPingPong()152*6777b538SAndroid Build Coastguard Worker void StartPingPong() {
153*6777b538SAndroid Build Coastguard Worker if (sync_) {
154*6777b538SAndroid Build Coastguard Worker base::TimeTicks before = base::TimeTicks::Now();
155*6777b538SAndroid Build Coastguard Worker for (count_down_ = params_.messages_per_frame; count_down_ > 0;
156*6777b538SAndroid Build Coastguard Worker --count_down_) {
157*6777b538SAndroid Build Coastguard Worker std::string response;
158*6777b538SAndroid Build Coastguard Worker sender_->Send(new TestMsg_SyncPing(payload_, &response));
159*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(response, payload_);
160*6777b538SAndroid Build Coastguard Worker }
161*6777b538SAndroid Build Coastguard Worker
162*6777b538SAndroid Build Coastguard Worker if (base::TimeTicks::Now() - before >
163*6777b538SAndroid Build Coastguard Worker GetFrameTime(params_.frames_per_second)) {
164*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << "Frame " << frame_count_down_
165*6777b538SAndroid Build Coastguard Worker << " wasn't able to complete on time!";
166*6777b538SAndroid Build Coastguard Worker }
167*6777b538SAndroid Build Coastguard Worker
168*6777b538SAndroid Build Coastguard Worker CHECK_GT(frame_count_down_, 0);
169*6777b538SAndroid Build Coastguard Worker frame_count_down_--;
170*6777b538SAndroid Build Coastguard Worker if (frame_count_down_ == 0)
171*6777b538SAndroid Build Coastguard Worker StopPingPong();
172*6777b538SAndroid Build Coastguard Worker } else {
173*6777b538SAndroid Build Coastguard Worker if (count_down_ != 0) {
174*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << "Frame " << frame_count_down_
175*6777b538SAndroid Build Coastguard Worker << " wasn't able to complete on time!";
176*6777b538SAndroid Build Coastguard Worker } else {
177*6777b538SAndroid Build Coastguard Worker SendPong();
178*6777b538SAndroid Build Coastguard Worker }
179*6777b538SAndroid Build Coastguard Worker count_down_ = params_.messages_per_frame;
180*6777b538SAndroid Build Coastguard Worker }
181*6777b538SAndroid Build Coastguard Worker }
182*6777b538SAndroid Build Coastguard Worker
StopPingPong()183*6777b538SAndroid Build Coastguard Worker void StopPingPong() {
184*6777b538SAndroid Build Coastguard Worker cpu_logger_.reset();
185*6777b538SAndroid Build Coastguard Worker timer_.AbandonAndStop();
186*6777b538SAndroid Build Coastguard Worker std::move(quit_closure_).Run();
187*6777b538SAndroid Build Coastguard Worker }
188*6777b538SAndroid Build Coastguard Worker
OnPing(const std::string & payload)189*6777b538SAndroid Build Coastguard Worker void OnPing(const std::string& payload) {
190*6777b538SAndroid Build Coastguard Worker // Include message deserialization in latency.
191*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(payload_.size(), payload.size());
192*6777b538SAndroid Build Coastguard Worker
193*6777b538SAndroid Build Coastguard Worker CHECK_GT(count_down_, 0);
194*6777b538SAndroid Build Coastguard Worker count_down_--;
195*6777b538SAndroid Build Coastguard Worker if (count_down_ > 0) {
196*6777b538SAndroid Build Coastguard Worker SendPong();
197*6777b538SAndroid Build Coastguard Worker } else {
198*6777b538SAndroid Build Coastguard Worker CHECK_GT(frame_count_down_, 0);
199*6777b538SAndroid Build Coastguard Worker frame_count_down_--;
200*6777b538SAndroid Build Coastguard Worker if (frame_count_down_ == 0)
201*6777b538SAndroid Build Coastguard Worker StopPingPong();
202*6777b538SAndroid Build Coastguard Worker }
203*6777b538SAndroid Build Coastguard Worker }
204*6777b538SAndroid Build Coastguard Worker
SendPong()205*6777b538SAndroid Build Coastguard Worker void SendPong() { sender_->Send(new TestMsg_Ping(payload_)); }
206*6777b538SAndroid Build Coastguard Worker
207*6777b538SAndroid Build Coastguard Worker private:
208*6777b538SAndroid Build Coastguard Worker raw_ptr<Sender> sender_ = nullptr;
209*6777b538SAndroid Build Coastguard Worker TestParams params_;
210*6777b538SAndroid Build Coastguard Worker std::string payload_;
211*6777b538SAndroid Build Coastguard Worker std::string label_;
212*6777b538SAndroid Build Coastguard Worker bool sync_ = false;
213*6777b538SAndroid Build Coastguard Worker
214*6777b538SAndroid Build Coastguard Worker int count_down_ = 0;
215*6777b538SAndroid Build Coastguard Worker int frame_count_down_ = 0;
216*6777b538SAndroid Build Coastguard Worker
217*6777b538SAndroid Build Coastguard Worker base::RepeatingTimer timer_;
218*6777b538SAndroid Build Coastguard Worker std::unique_ptr<PerfCpuLogger> cpu_logger_;
219*6777b538SAndroid Build Coastguard Worker
220*6777b538SAndroid Build Coastguard Worker base::OnceClosure quit_closure_;
221*6777b538SAndroid Build Coastguard Worker };
222*6777b538SAndroid Build Coastguard Worker
223*6777b538SAndroid Build Coastguard Worker class ChannelSteadyPingPongTest : public IPCChannelMojoTestBase {
224*6777b538SAndroid Build Coastguard Worker public:
225*6777b538SAndroid Build Coastguard Worker ChannelSteadyPingPongTest() = default;
226*6777b538SAndroid Build Coastguard Worker ~ChannelSteadyPingPongTest() override = default;
227*6777b538SAndroid Build Coastguard Worker
RunPingPongServer(const std::string & label,bool sync)228*6777b538SAndroid Build Coastguard Worker void RunPingPongServer(const std::string& label, bool sync) {
229*6777b538SAndroid Build Coastguard Worker Init("MojoPerfTestClient");
230*6777b538SAndroid Build Coastguard Worker
231*6777b538SAndroid Build Coastguard Worker // Set up IPC channel and start client.
232*6777b538SAndroid Build Coastguard Worker ChannelSteadyPingPongListener listener;
233*6777b538SAndroid Build Coastguard Worker
234*6777b538SAndroid Build Coastguard Worker std::unique_ptr<ChannelProxy> channel_proxy;
235*6777b538SAndroid Build Coastguard Worker std::unique_ptr<base::WaitableEvent> shutdown_event;
236*6777b538SAndroid Build Coastguard Worker
237*6777b538SAndroid Build Coastguard Worker if (sync) {
238*6777b538SAndroid Build Coastguard Worker shutdown_event = std::make_unique<base::WaitableEvent>(
239*6777b538SAndroid Build Coastguard Worker base::WaitableEvent::ResetPolicy::MANUAL,
240*6777b538SAndroid Build Coastguard Worker base::WaitableEvent::InitialState::NOT_SIGNALED);
241*6777b538SAndroid Build Coastguard Worker channel_proxy = IPC::SyncChannel::Create(
242*6777b538SAndroid Build Coastguard Worker TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,
243*6777b538SAndroid Build Coastguard Worker GetIOThreadTaskRunner(),
244*6777b538SAndroid Build Coastguard Worker base::SingleThreadTaskRunner::GetCurrentDefault(), false,
245*6777b538SAndroid Build Coastguard Worker shutdown_event.get());
246*6777b538SAndroid Build Coastguard Worker } else {
247*6777b538SAndroid Build Coastguard Worker channel_proxy = IPC::ChannelProxy::Create(
248*6777b538SAndroid Build Coastguard Worker TakeHandle().release(), IPC::Channel::MODE_SERVER, &listener,
249*6777b538SAndroid Build Coastguard Worker GetIOThreadTaskRunner(),
250*6777b538SAndroid Build Coastguard Worker base::SingleThreadTaskRunner::GetCurrentDefault());
251*6777b538SAndroid Build Coastguard Worker }
252*6777b538SAndroid Build Coastguard Worker listener.Init(channel_proxy.get());
253*6777b538SAndroid Build Coastguard Worker
254*6777b538SAndroid Build Coastguard Worker LockThreadAffinity thread_locker(kSharedCore);
255*6777b538SAndroid Build Coastguard Worker std::vector<TestParams> params_list = GetDefaultTestParams();
256*6777b538SAndroid Build Coastguard Worker for (const auto& params : params_list) {
257*6777b538SAndroid Build Coastguard Worker base::RunLoop run_loop;
258*6777b538SAndroid Build Coastguard Worker
259*6777b538SAndroid Build Coastguard Worker listener.SetTestParams(params, label, sync,
260*6777b538SAndroid Build Coastguard Worker run_loop.QuitWhenIdleClosure());
261*6777b538SAndroid Build Coastguard Worker
262*6777b538SAndroid Build Coastguard Worker // This initial message will kick-start the ping-pong of messages.
263*6777b538SAndroid Build Coastguard Worker channel_proxy->Send(new TestMsg_Hello);
264*6777b538SAndroid Build Coastguard Worker
265*6777b538SAndroid Build Coastguard Worker run_loop.Run();
266*6777b538SAndroid Build Coastguard Worker }
267*6777b538SAndroid Build Coastguard Worker
268*6777b538SAndroid Build Coastguard Worker // Send quit message.
269*6777b538SAndroid Build Coastguard Worker channel_proxy->Send(new TestMsg_Quit);
270*6777b538SAndroid Build Coastguard Worker
271*6777b538SAndroid Build Coastguard Worker EXPECT_TRUE(WaitForClientShutdown());
272*6777b538SAndroid Build Coastguard Worker channel_proxy.reset();
273*6777b538SAndroid Build Coastguard Worker }
274*6777b538SAndroid Build Coastguard Worker };
275*6777b538SAndroid Build Coastguard Worker
TEST_F(ChannelSteadyPingPongTest,AsyncPingPong)276*6777b538SAndroid Build Coastguard Worker TEST_F(ChannelSteadyPingPongTest, AsyncPingPong) {
277*6777b538SAndroid Build Coastguard Worker RunPingPongServer("IPC_CPU_Async", false);
278*6777b538SAndroid Build Coastguard Worker }
279*6777b538SAndroid Build Coastguard Worker
TEST_F(ChannelSteadyPingPongTest,SyncPingPong)280*6777b538SAndroid Build Coastguard Worker TEST_F(ChannelSteadyPingPongTest, SyncPingPong) {
281*6777b538SAndroid Build Coastguard Worker RunPingPongServer("IPC_CPU_Sync", true);
282*6777b538SAndroid Build Coastguard Worker }
283*6777b538SAndroid Build Coastguard Worker
284*6777b538SAndroid Build Coastguard Worker class MojoSteadyPingPongTest : public mojo::core::test::MojoTestBase {
285*6777b538SAndroid Build Coastguard Worker public:
286*6777b538SAndroid Build Coastguard Worker MojoSteadyPingPongTest() = default;
287*6777b538SAndroid Build Coastguard Worker
288*6777b538SAndroid Build Coastguard Worker MojoSteadyPingPongTest(const MojoSteadyPingPongTest&) = delete;
289*6777b538SAndroid Build Coastguard Worker MojoSteadyPingPongTest& operator=(const MojoSteadyPingPongTest&) = delete;
290*6777b538SAndroid Build Coastguard Worker
291*6777b538SAndroid Build Coastguard Worker protected:
RunPingPongServer(MojoHandle mp,const std::string & label,bool sync)292*6777b538SAndroid Build Coastguard Worker void RunPingPongServer(MojoHandle mp, const std::string& label, bool sync) {
293*6777b538SAndroid Build Coastguard Worker label_ = label;
294*6777b538SAndroid Build Coastguard Worker sync_ = sync;
295*6777b538SAndroid Build Coastguard Worker
296*6777b538SAndroid Build Coastguard Worker mojo::MessagePipeHandle mp_handle(mp);
297*6777b538SAndroid Build Coastguard Worker mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
298*6777b538SAndroid Build Coastguard Worker ping_receiver_.Bind(
299*6777b538SAndroid Build Coastguard Worker mojo::PendingRemote<IPC::mojom::Reflector>(std::move(scoped_mp), 0u));
300*6777b538SAndroid Build Coastguard Worker
301*6777b538SAndroid Build Coastguard Worker LockThreadAffinity thread_locker(kSharedCore);
302*6777b538SAndroid Build Coastguard Worker std::vector<TestParams> params_list = GetDefaultTestParams();
303*6777b538SAndroid Build Coastguard Worker for (const auto& params : params_list) {
304*6777b538SAndroid Build Coastguard Worker params_ = params;
305*6777b538SAndroid Build Coastguard Worker payload_ = std::string(params.message_size, 'a');
306*6777b538SAndroid Build Coastguard Worker
307*6777b538SAndroid Build Coastguard Worker ping_receiver_->Ping("hello",
308*6777b538SAndroid Build Coastguard Worker base::BindOnce(&MojoSteadyPingPongTest::OnHello,
309*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
310*6777b538SAndroid Build Coastguard Worker base::RunLoop run_loop;
311*6777b538SAndroid Build Coastguard Worker quit_closure_ = run_loop.QuitWhenIdleClosure();
312*6777b538SAndroid Build Coastguard Worker run_loop.Run();
313*6777b538SAndroid Build Coastguard Worker }
314*6777b538SAndroid Build Coastguard Worker
315*6777b538SAndroid Build Coastguard Worker ping_receiver_->Quit();
316*6777b538SAndroid Build Coastguard Worker
317*6777b538SAndroid Build Coastguard Worker std::ignore = ping_receiver_.Unbind().PassPipe().release();
318*6777b538SAndroid Build Coastguard Worker }
319*6777b538SAndroid Build Coastguard Worker
OnHello(const std::string & value)320*6777b538SAndroid Build Coastguard Worker void OnHello(const std::string& value) {
321*6777b538SAndroid Build Coastguard Worker cpu_logger_ = std::make_unique<PerfCpuLogger>(GetLogTitle(label_, params_));
322*6777b538SAndroid Build Coastguard Worker
323*6777b538SAndroid Build Coastguard Worker frame_count_down_ = params_.frames_per_second * params_.duration_in_seconds;
324*6777b538SAndroid Build Coastguard Worker
325*6777b538SAndroid Build Coastguard Worker timer_.Start(FROM_HERE, GetFrameTime(params_.frames_per_second), this,
326*6777b538SAndroid Build Coastguard Worker &MojoSteadyPingPongTest::StartPingPong);
327*6777b538SAndroid Build Coastguard Worker }
328*6777b538SAndroid Build Coastguard Worker
StartPingPong()329*6777b538SAndroid Build Coastguard Worker void StartPingPong() {
330*6777b538SAndroid Build Coastguard Worker if (sync_) {
331*6777b538SAndroid Build Coastguard Worker base::TimeTicks before = base::TimeTicks::Now();
332*6777b538SAndroid Build Coastguard Worker for (count_down_ = params_.messages_per_frame; count_down_ > 0;
333*6777b538SAndroid Build Coastguard Worker --count_down_) {
334*6777b538SAndroid Build Coastguard Worker std::string response;
335*6777b538SAndroid Build Coastguard Worker ping_receiver_->SyncPing(payload_, &response);
336*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(response, payload_);
337*6777b538SAndroid Build Coastguard Worker }
338*6777b538SAndroid Build Coastguard Worker
339*6777b538SAndroid Build Coastguard Worker if (base::TimeTicks::Now() - before >
340*6777b538SAndroid Build Coastguard Worker GetFrameTime(params_.frames_per_second)) {
341*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << "Frame " << frame_count_down_
342*6777b538SAndroid Build Coastguard Worker << " wasn't able to complete on time!";
343*6777b538SAndroid Build Coastguard Worker }
344*6777b538SAndroid Build Coastguard Worker
345*6777b538SAndroid Build Coastguard Worker CHECK_GT(frame_count_down_, 0);
346*6777b538SAndroid Build Coastguard Worker frame_count_down_--;
347*6777b538SAndroid Build Coastguard Worker if (frame_count_down_ == 0)
348*6777b538SAndroid Build Coastguard Worker StopPingPong();
349*6777b538SAndroid Build Coastguard Worker } else {
350*6777b538SAndroid Build Coastguard Worker if (count_down_ != 0) {
351*6777b538SAndroid Build Coastguard Worker LOG(ERROR) << "Frame " << frame_count_down_
352*6777b538SAndroid Build Coastguard Worker << " wasn't able to complete on time!";
353*6777b538SAndroid Build Coastguard Worker } else {
354*6777b538SAndroid Build Coastguard Worker SendPing();
355*6777b538SAndroid Build Coastguard Worker }
356*6777b538SAndroid Build Coastguard Worker count_down_ = params_.messages_per_frame;
357*6777b538SAndroid Build Coastguard Worker }
358*6777b538SAndroid Build Coastguard Worker }
359*6777b538SAndroid Build Coastguard Worker
StopPingPong()360*6777b538SAndroid Build Coastguard Worker void StopPingPong() {
361*6777b538SAndroid Build Coastguard Worker cpu_logger_.reset();
362*6777b538SAndroid Build Coastguard Worker timer_.AbandonAndStop();
363*6777b538SAndroid Build Coastguard Worker std::move(quit_closure_).Run();
364*6777b538SAndroid Build Coastguard Worker }
365*6777b538SAndroid Build Coastguard Worker
OnPong(const std::string & value)366*6777b538SAndroid Build Coastguard Worker void OnPong(const std::string& value) {
367*6777b538SAndroid Build Coastguard Worker // Include message deserialization in latency.
368*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(payload_.size(), value.size());
369*6777b538SAndroid Build Coastguard Worker
370*6777b538SAndroid Build Coastguard Worker CHECK_GT(count_down_, 0);
371*6777b538SAndroid Build Coastguard Worker count_down_--;
372*6777b538SAndroid Build Coastguard Worker if (count_down_ > 0) {
373*6777b538SAndroid Build Coastguard Worker SendPing();
374*6777b538SAndroid Build Coastguard Worker } else {
375*6777b538SAndroid Build Coastguard Worker CHECK_GT(frame_count_down_, 0);
376*6777b538SAndroid Build Coastguard Worker frame_count_down_--;
377*6777b538SAndroid Build Coastguard Worker if (frame_count_down_ == 0)
378*6777b538SAndroid Build Coastguard Worker StopPingPong();
379*6777b538SAndroid Build Coastguard Worker }
380*6777b538SAndroid Build Coastguard Worker }
381*6777b538SAndroid Build Coastguard Worker
SendPing()382*6777b538SAndroid Build Coastguard Worker void SendPing() {
383*6777b538SAndroid Build Coastguard Worker ping_receiver_->Ping(payload_,
384*6777b538SAndroid Build Coastguard Worker base::BindOnce(&MojoSteadyPingPongTest::OnPong,
385*6777b538SAndroid Build Coastguard Worker base::Unretained(this)));
386*6777b538SAndroid Build Coastguard Worker }
387*6777b538SAndroid Build Coastguard Worker
RunPingPongClient(MojoHandle mp)388*6777b538SAndroid Build Coastguard Worker static int RunPingPongClient(MojoHandle mp) {
389*6777b538SAndroid Build Coastguard Worker mojo::MessagePipeHandle mp_handle(mp);
390*6777b538SAndroid Build Coastguard Worker mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
391*6777b538SAndroid Build Coastguard Worker
392*6777b538SAndroid Build Coastguard Worker LockThreadAffinity thread_locker(kSharedCore);
393*6777b538SAndroid Build Coastguard Worker base::RunLoop run_loop;
394*6777b538SAndroid Build Coastguard Worker ReflectorImpl impl(std::move(scoped_mp), run_loop.QuitWhenIdleClosure());
395*6777b538SAndroid Build Coastguard Worker run_loop.Run();
396*6777b538SAndroid Build Coastguard Worker return 0;
397*6777b538SAndroid Build Coastguard Worker }
398*6777b538SAndroid Build Coastguard Worker
399*6777b538SAndroid Build Coastguard Worker private:
400*6777b538SAndroid Build Coastguard Worker TestParams params_;
401*6777b538SAndroid Build Coastguard Worker std::string payload_;
402*6777b538SAndroid Build Coastguard Worker std::string label_;
403*6777b538SAndroid Build Coastguard Worker bool sync_ = false;
404*6777b538SAndroid Build Coastguard Worker
405*6777b538SAndroid Build Coastguard Worker mojo::Remote<IPC::mojom::Reflector> ping_receiver_;
406*6777b538SAndroid Build Coastguard Worker
407*6777b538SAndroid Build Coastguard Worker int count_down_ = 0;
408*6777b538SAndroid Build Coastguard Worker int frame_count_down_ = 0;
409*6777b538SAndroid Build Coastguard Worker
410*6777b538SAndroid Build Coastguard Worker base::RepeatingTimer timer_;
411*6777b538SAndroid Build Coastguard Worker std::unique_ptr<PerfCpuLogger> cpu_logger_;
412*6777b538SAndroid Build Coastguard Worker
413*6777b538SAndroid Build Coastguard Worker base::OnceClosure quit_closure_;
414*6777b538SAndroid Build Coastguard Worker };
415*6777b538SAndroid Build Coastguard Worker
DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient,MojoSteadyPingPongTest,h)416*6777b538SAndroid Build Coastguard Worker DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient, MojoSteadyPingPongTest, h) {
417*6777b538SAndroid Build Coastguard Worker base::test::SingleThreadTaskEnvironment task_environment;
418*6777b538SAndroid Build Coastguard Worker return RunPingPongClient(h);
419*6777b538SAndroid Build Coastguard Worker }
420*6777b538SAndroid Build Coastguard Worker
421*6777b538SAndroid Build Coastguard Worker // Similar to ChannelSteadyPingPongTest above, but uses a Mojo interface
422*6777b538SAndroid Build Coastguard Worker // instead of raw IPC::Messages.
TEST_F(MojoSteadyPingPongTest,AsyncPingPong)423*6777b538SAndroid Build Coastguard Worker TEST_F(MojoSteadyPingPongTest, AsyncPingPong) {
424*6777b538SAndroid Build Coastguard Worker RunTestClient("PingPongClient", [&](MojoHandle h) {
425*6777b538SAndroid Build Coastguard Worker base::test::SingleThreadTaskEnvironment task_environment;
426*6777b538SAndroid Build Coastguard Worker RunPingPongServer(h, "Mojo_CPU_Async", false);
427*6777b538SAndroid Build Coastguard Worker });
428*6777b538SAndroid Build Coastguard Worker }
429*6777b538SAndroid Build Coastguard Worker
TEST_F(MojoSteadyPingPongTest,SyncPingPong)430*6777b538SAndroid Build Coastguard Worker TEST_F(MojoSteadyPingPongTest, SyncPingPong) {
431*6777b538SAndroid Build Coastguard Worker RunTestClient("PingPongClient", [&](MojoHandle h) {
432*6777b538SAndroid Build Coastguard Worker base::test::SingleThreadTaskEnvironment task_environment;
433*6777b538SAndroid Build Coastguard Worker RunPingPongServer(h, "Mojo_CPU_Sync", true);
434*6777b538SAndroid Build Coastguard Worker });
435*6777b538SAndroid Build Coastguard Worker }
436*6777b538SAndroid Build Coastguard Worker
437*6777b538SAndroid Build Coastguard Worker } // namespace
438*6777b538SAndroid Build Coastguard Worker } // namespace IPC
439