perfetto_integration_unittest.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. // Copyright 2018 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <memory>
  5. #include <string>
  6. #include <thread>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/run_loop.h"
  10. #include "base/strings/strcat.h"
  11. #include "base/test/bind.h"
  12. #include "base/threading/thread.h"
  13. #include "base/tracing/perfetto_platform.h"
  14. #include "services/tracing/perfetto/perfetto_service.h"
  15. #include "services/tracing/perfetto/producer_host.h"
  16. #include "services/tracing/perfetto/test_utils.h"
  17. #include "services/tracing/public/cpp/perfetto/producer_client.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. #include "third_party/perfetto/include/perfetto/tracing/tracing.h"
  20. #include "third_party/perfetto/protos/perfetto/common/commit_data_request.pb.h"
  21. // TODO(crbug.com/961066): Fix memory leaks in tests and re-enable on LSAN.
  22. #ifdef LEAK_SANITIZER
  23. #define MAYBE_DifferentSharedMemoryBuffersForDifferentAgents \
  24. DISABLED_DifferentSharedMemoryBuffersForDifferentAgents
  25. #else
  26. #define MAYBE_DifferentSharedMemoryBuffersForDifferentAgents \
  27. DifferentSharedMemoryBuffersForDifferentAgents
  28. #endif
  29. namespace tracing {
  30. namespace {
  31. const char kPerfettoTestDataSourceName[] =
  32. "org.chromium.chrome_integration_unittest";
  33. std::string GetPerfettoProducerName() {
  34. return base::StrCat({mojom::kPerfettoProducerNamePrefix, "123"});
  35. }
  36. class PerfettoIntegrationTest : public TracingUnitTest {
  37. public:
  38. void SetUp() override {
  39. TracingUnitTest::SetUp();
  40. data_source_ = TestDataSource::CreateAndRegisterDataSource(
  41. kPerfettoTestDataSourceName, 0);
  42. perfetto_service_ = std::make_unique<PerfettoService>();
  43. RunUntilIdle();
  44. }
  45. void TearDown() override {
  46. perfetto_service_.reset();
  47. TracingUnitTest::TearDown();
  48. }
  49. PerfettoService* perfetto_service() const { return perfetto_service_.get(); }
  50. protected:
  51. std::unique_ptr<TestDataSource> data_source_;
  52. std::unique_ptr<PerfettoService> perfetto_service_;
  53. };
  54. TEST_F(PerfettoIntegrationTest, ProducerDatasourceInitialized) {
  55. std::unique_ptr<MockProducerClient::Handle> dummy_client =
  56. MockProducerClient::Create();
  57. base::RunLoop producer_initialized_runloop;
  58. auto new_producer = std::make_unique<MockProducerHost>(
  59. GetPerfettoProducerName(), kPerfettoTestDataSourceName, perfetto_service(),
  60. **dummy_client, producer_initialized_runloop.QuitClosure());
  61. producer_initialized_runloop.Run();
  62. }
  63. TEST_F(PerfettoIntegrationTest, ClientEnabledAndDisabled) {
  64. base::RunLoop on_trace_packets;
  65. MockConsumer consumer({kPerfettoTestDataSourceName},
  66. perfetto_service()->GetService(),
  67. [&on_trace_packets](bool has_more) {
  68. EXPECT_FALSE(has_more);
  69. on_trace_packets.Quit();
  70. });
  71. base::RunLoop client_enabled_callback;
  72. base::RunLoop client_disabled_callback;
  73. std::unique_ptr<MockProducerClient::Handle> client =
  74. MockProducerClient::Create(
  75. /* num_data_sources = */ 1, client_enabled_callback.QuitClosure(),
  76. client_disabled_callback.QuitClosure());
  77. auto producer = std::make_unique<MockProducerHost>(
  78. GetPerfettoProducerName(), kPerfettoTestDataSourceName, perfetto_service(),
  79. **client);
  80. client_enabled_callback.Run();
  81. RunUntilIdle();
  82. consumer.StopTracing();
  83. client_disabled_callback.Run();
  84. on_trace_packets.Run();
  85. EXPECT_EQ(0u, consumer.received_test_packets());
  86. }
  87. TEST_F(PerfettoIntegrationTest, PacketsEndToEndProducerFirst) {
  88. const size_t kNumPackets = 10;
  89. data_source_->set_send_packet_count(kNumPackets);
  90. base::RunLoop client_enabled_callback;
  91. base::RunLoop client_disabled_callback;
  92. std::unique_ptr<MockProducerClient::Handle> client =
  93. MockProducerClient::Create(
  94. /* num_data_sources = */ 1, client_enabled_callback.QuitClosure(),
  95. client_disabled_callback.QuitClosure());
  96. auto producer = std::make_unique<MockProducerHost>(
  97. GetPerfettoProducerName(), kPerfettoTestDataSourceName, perfetto_service(),
  98. **client);
  99. base::RunLoop no_more_packets_runloop;
  100. MockConsumer consumer({kPerfettoTestDataSourceName},
  101. perfetto_service()->GetService(),
  102. [&no_more_packets_runloop](bool has_more) {
  103. if (!has_more) {
  104. no_more_packets_runloop.Quit();
  105. }
  106. });
  107. client_enabled_callback.Run();
  108. RunUntilIdle();
  109. consumer.StopTracing();
  110. client_disabled_callback.Run();
  111. no_more_packets_runloop.Run();
  112. EXPECT_EQ(kNumPackets, consumer.received_test_packets());
  113. }
  114. TEST_F(PerfettoIntegrationTest, PacketsEndToEndConsumerFirst) {
  115. const size_t kNumPackets = 10;
  116. data_source_->set_send_packet_count(kNumPackets);
  117. base::RunLoop no_more_packets_runloop;
  118. MockConsumer consumer({kPerfettoTestDataSourceName},
  119. perfetto_service()->GetService(),
  120. [&no_more_packets_runloop](bool has_more) {
  121. if (!has_more) {
  122. no_more_packets_runloop.Quit();
  123. }
  124. });
  125. base::RunLoop client_enabled_callback;
  126. std::unique_ptr<MockProducerClient::Handle> client =
  127. MockProducerClient::Create(
  128. /* num_data_sources = */ 1, client_enabled_callback.QuitClosure());
  129. auto new_producer = std::make_unique<MockProducerHost>(
  130. GetPerfettoProducerName(), kPerfettoTestDataSourceName, perfetto_service(),
  131. **client);
  132. client_enabled_callback.Run();
  133. RunUntilIdle();
  134. consumer.StopTracing();
  135. no_more_packets_runloop.Run();
  136. EXPECT_EQ(kNumPackets, consumer.received_test_packets());
  137. }
  138. TEST_F(PerfettoIntegrationTest, CommitDataRequestIsMaybeComplete) {
  139. const size_t kNumPackets = 100;
  140. data_source_->set_send_packet_count(kNumPackets);
  141. base::RunLoop no_more_packets_runloop;
  142. MockConsumer consumer({kPerfettoTestDataSourceName},
  143. perfetto_service()->GetService(),
  144. [&no_more_packets_runloop](bool has_more) {
  145. if (!has_more) {
  146. no_more_packets_runloop.Quit();
  147. }
  148. });
  149. base::RunLoop client_enabled_callback;
  150. std::unique_ptr<MockProducerClient::Handle> client =
  151. MockProducerClient::Create(
  152. /* num_data_sources = */ 1, client_enabled_callback.QuitClosure());
  153. auto new_producer = std::make_unique<MockProducerHost>(
  154. GetPerfettoProducerName(), kPerfettoTestDataSourceName, perfetto_service(),
  155. **client);
  156. client_enabled_callback.Run();
  157. base::RunLoop wait_for_packet_write;
  158. PerfettoTracedProcess::Get()
  159. ->GetTaskRunner()
  160. ->GetOrCreateTaskRunner()
  161. ->PostTaskAndReply(FROM_HERE,
  162. base::BindOnce(&TestDataSource::WritePacketBigly,
  163. base::Unretained(data_source_.get())),
  164. wait_for_packet_write.QuitClosure());
  165. wait_for_packet_write.Run();
  166. RunUntilIdle();
  167. consumer.StopTracing();
  168. no_more_packets_runloop.Run();
  169. // {cli,host}_reqs are a std::vector<std::string>. Each entry of the vector
  170. // is a proto-serialized CommitDataRequest.
  171. const auto& cli_reqs = (*client)->all_client_commit_data_requests();
  172. const auto& host_reqs = new_producer->all_host_commit_data_requests();
  173. ASSERT_EQ(cli_reqs.size(), host_reqs.size());
  174. for (size_t i = 0; i < cli_reqs.size(); i++) {
  175. // Note that the proto-encoded strings are not identical. This is because
  176. // perfetto doesn't emit unset fields. But then when going over mojo these
  177. // unset fields get copied as 0-value (it's fine), so on the host side we
  178. // see extra fields being explicitly zero-initialized. Here we force a
  179. // re-encode using the libprotobuf message for the sake of the comparison.
  180. // libprotobuf will re-normalize messages before serializing.
  181. perfetto::protos::CommitDataRequest cli_req;
  182. ASSERT_TRUE(cli_req.ParseFromString(cli_reqs[i]));
  183. perfetto::protos::CommitDataRequest host_req;
  184. ASSERT_TRUE(host_req.ParseFromString(cli_reqs[i]));
  185. ASSERT_EQ(cli_req.SerializeAsString(), host_req.SerializeAsString());
  186. }
  187. }
  188. TEST_F(PerfettoIntegrationTest, TracingRestarted) {
  189. const size_t kNumPackets = 10;
  190. data_source_->set_send_packet_count(kNumPackets);
  191. base::RunLoop no_more_packets_runloop;
  192. MockConsumer consumer({kPerfettoTestDataSourceName},
  193. perfetto_service()->GetService(),
  194. [&no_more_packets_runloop](bool has_more) {
  195. if (!has_more) {
  196. no_more_packets_runloop.Quit();
  197. }
  198. });
  199. base::RunLoop client_enabled_callback;
  200. base::RunLoop client_disabled_callback;
  201. std::unique_ptr<MockProducerClient::Handle> client =
  202. MockProducerClient::Create(
  203. /* num_data_sources = */ 1, client_enabled_callback.QuitClosure(),
  204. client_disabled_callback.QuitClosure());
  205. auto new_producer = std::make_unique<MockProducerHost>(
  206. GetPerfettoProducerName(), kPerfettoTestDataSourceName, perfetto_service(),
  207. **client);
  208. client_enabled_callback.Run();
  209. RunUntilIdle();
  210. perfetto::SharedMemory* first_session_shm =
  211. (*client)->shared_memory_for_testing();
  212. consumer.StopTracing();
  213. client_disabled_callback.Run();
  214. no_more_packets_runloop.Run();
  215. EXPECT_EQ(kNumPackets, consumer.received_test_packets());
  216. consumer.FreeBuffers();
  217. base::RunLoop client_reenabled_callback;
  218. (*client)->SetAgentEnabledCallback(client_reenabled_callback.QuitClosure());
  219. consumer.StartTracing();
  220. client_reenabled_callback.Run();
  221. RunUntilIdle();
  222. // We should still be using the same shared memory.
  223. EXPECT_EQ(first_session_shm, (*client)->shared_memory_for_testing());
  224. base::RunLoop client_redisabled_callback;
  225. (*client)->SetAgentDisabledCallback(client_redisabled_callback.QuitClosure());
  226. consumer.StopTracing();
  227. client_redisabled_callback.Run();
  228. EXPECT_EQ(kNumPackets * 2, consumer.received_test_packets());
  229. }
  230. TEST_F(PerfettoIntegrationTest, NoPacketsReceivedOnWrongSourceName) {
  231. const size_t kNumPackets = 10;
  232. data_source_->set_send_packet_count(kNumPackets);
  233. base::RunLoop client_enabled_callback;
  234. base::RunLoop client_disabled_callback;
  235. std::unique_ptr<MockProducerClient::Handle> client =
  236. MockProducerClient::Create(
  237. /* num_data_sources = */ 0, client_enabled_callback.QuitClosure(),
  238. client_disabled_callback.QuitClosure());
  239. base::RunLoop producer_initialized_runloop;
  240. auto new_producer = std::make_unique<MockProducerHost>(
  241. GetPerfettoProducerName(), "fake_data_source", perfetto_service(), **client);
  242. base::RunLoop no_more_packets_runloop;
  243. MockConsumer consumer({"fake_data_source"}, perfetto_service()->GetService(),
  244. [&no_more_packets_runloop](bool has_more) {
  245. if (!has_more) {
  246. no_more_packets_runloop.Quit();
  247. }
  248. });
  249. RunUntilIdle();
  250. consumer.StopTracing();
  251. no_more_packets_runloop.Run();
  252. EXPECT_EQ(0u, consumer.received_test_packets());
  253. }
  254. TEST_F(PerfettoIntegrationTest,
  255. MAYBE_DifferentSharedMemoryBuffersForDifferentAgents) {
  256. base::RunLoop client1_enabled_callback;
  257. base::RunLoop client2_enabled_callback;
  258. std::unique_ptr<MockProducerClient::Handle> client1 =
  259. MockProducerClient::Create(
  260. /* num_data_sources = */ 1, client1_enabled_callback.QuitClosure());
  261. auto producer1 = std::make_unique<MockProducerHost>(
  262. GetPerfettoProducerName(), kPerfettoTestDataSourceName, perfetto_service(),
  263. **client1);
  264. // Start the trace here, this is because we need to send the EnableTracing
  265. // call to client1, but constructing client2 will override the
  266. // |producer_client_| pointer in PerfettoTracedProcess::Get() so we wait until
  267. // client1 has been enabled before constructing the second producer client.
  268. MockConsumer consumer({kPerfettoTestDataSourceName},
  269. perfetto_service()->GetService(), nullptr);
  270. client1_enabled_callback.Run();
  271. // client2 will trigger a StartTracing call without shutting down the data
  272. // source first, to prevent this hitting a DCHECK set the previous producer to
  273. // null.
  274. data_source_->ClearProducerForTesting();
  275. std::unique_ptr<MockProducerClient::Handle> client2 =
  276. MockProducerClient::Create(
  277. /* num_data_sources = */ 1, client2_enabled_callback.QuitClosure());
  278. auto producer2 = std::make_unique<MockProducerHost>(
  279. GetPerfettoProducerName(), kPerfettoTestDataSourceName, perfetto_service(),
  280. **client2);
  281. client2_enabled_callback.Run();
  282. EXPECT_TRUE((*client1)->shared_memory_for_testing());
  283. EXPECT_TRUE((*client2)->shared_memory_for_testing());
  284. EXPECT_NE((*client1)->shared_memory_for_testing(),
  285. (*client2)->shared_memory_for_testing());
  286. }
  287. TEST_F(PerfettoIntegrationTest, PerfettoPlatformTest) {
  288. auto* platform =
  289. PerfettoTracedProcess::Get()->perfetto_platform_for_testing();
  290. auto* tls = platform->GetOrCreateThreadLocalObject();
  291. EXPECT_TRUE(tls);
  292. EXPECT_EQ(tls, platform->GetOrCreateThreadLocalObject());
  293. base::Thread thread("TestThread");
  294. thread.Start();
  295. thread.task_runner()->PostTask(
  296. FROM_HERE, base::BindLambdaForTesting([&platform, &tls] {
  297. auto* thread_tls = platform->GetOrCreateThreadLocalObject();
  298. EXPECT_TRUE(thread_tls);
  299. EXPECT_NE(tls, thread_tls);
  300. }));
  301. thread.Stop();
  302. }
  303. TEST_F(PerfettoIntegrationTest, PerfettoClientLibraryTest) {
  304. // Check that PerfettoTracedProcess initialized the client library. Functional
  305. // client library tests are in TracingServiceTest.
  306. EXPECT_TRUE(perfetto::Tracing::IsInitialized());
  307. }
  308. } // namespace
  309. } // namespace tracing