system_test_utils.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // Copyright 2019 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 "services/tracing/perfetto/system_test_utils.h"
  5. #include <cstdio>
  6. #include "base/files/scoped_temp_dir.h"
  7. #include "services/tracing/perfetto/test_utils.h"
  8. #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
  9. #include "third_party/perfetto/include/perfetto/ext/tracing/core/commit_data_request.h"
  10. #include "third_party/perfetto/include/perfetto/ext/tracing/ipc/service_ipc_host.h"
  11. #include "third_party/perfetto/protos/perfetto/common/commit_data_request.pb.h"
  12. namespace tracing {
  13. MockSystemService::MockSystemService(const std::string& consumer_socket,
  14. const std::string& producer_socket)
  15. : used_tmpdir_(false),
  16. consumer_(consumer_socket),
  17. producer_(producer_socket),
  18. task_runner_(std::make_unique<base::tracing::PerfettoTaskRunner>(
  19. base::SequencedTaskRunnerHandle::Get())) {
  20. StartService();
  21. }
  22. MockSystemService::MockSystemService(const base::ScopedTempDir& tmp_dir)
  23. : MockSystemService(tmp_dir,
  24. std::make_unique<base::tracing::PerfettoTaskRunner>(
  25. base::SequencedTaskRunnerHandle::Get())) {}
  26. MockSystemService::MockSystemService(
  27. const base::ScopedTempDir& tmp_dir,
  28. std::unique_ptr<perfetto::base::TaskRunner> task_runner)
  29. : used_tmpdir_(true), task_runner_(std::move(task_runner)) {
  30. // We need to set TMPDIR environment variable because when a new producer
  31. // connects to the perfetto service it needs to create a memmap'd file for
  32. // the shared memory buffer. Setting TMPDIR allows the service to know
  33. // where this should be.
  34. //
  35. // Finally since environment variables are leaked into other tests if
  36. // multiple tests run we need to restore the value so each test is
  37. // hermetic.
  38. old_tmpdir_ = getenv("TMPDIR");
  39. setenv("TMPDIR", tmp_dir.GetPath().value().c_str(), true);
  40. // Set up the system socket locations in a valid tmp directory.
  41. producer_ = tmp_dir.GetPath().Append(FILE_PATH_LITERAL("producer")).value();
  42. consumer_ = tmp_dir.GetPath().Append(FILE_PATH_LITERAL("consumer")).value();
  43. StartService();
  44. }
  45. MockSystemService::~MockSystemService() {
  46. service_.reset();
  47. remove(producer().c_str());
  48. remove(consumer().c_str());
  49. if (used_tmpdir_) {
  50. if (old_tmpdir_) {
  51. // Restore the old value back to its initial value.
  52. setenv("TMPDIR", old_tmpdir_, true);
  53. } else {
  54. // TMPDIR wasn't set originally so unset it.
  55. unsetenv("TMPDIR");
  56. }
  57. }
  58. }
  59. void MockSystemService::StartService() {
  60. service_ = perfetto::ServiceIPCHost::CreateInstance(task_runner_.get());
  61. CHECK(service_);
  62. unlink(producer_.c_str());
  63. unlink(consumer_.c_str());
  64. bool succeeded = service_->Start(producer_.c_str(), consumer_.c_str());
  65. CHECK(succeeded);
  66. }
  67. const std::string& MockSystemService::consumer() const {
  68. return consumer_;
  69. }
  70. const std::string& MockSystemService::producer() const {
  71. return producer_;
  72. }
  73. perfetto::TracingService* MockSystemService::GetService() {
  74. return service_->service();
  75. }
  76. MockPosixSystemProducer::MockPosixSystemProducer(
  77. const std::string& socket,
  78. bool check_sdk_level,
  79. uint32_t num_data_sources,
  80. base::OnceClosure data_source_enabled_callback,
  81. base::OnceClosure data_source_disabled_callback,
  82. bool sandbox_forbids_socket_connection)
  83. : PosixSystemProducer(socket.c_str(),
  84. PerfettoTracedProcess::Get()->GetTaskRunner()),
  85. num_data_sources_expected_(num_data_sources),
  86. data_source_enabled_callback_(std::move(data_source_enabled_callback)),
  87. data_source_disabled_callback_(std::move(data_source_disabled_callback)),
  88. sandbox_forbids_socket_connection_(sandbox_forbids_socket_connection) {
  89. // We want to set the SystemProducer to this mock, but that 'requires' passing
  90. // ownership of ourselves to PerfettoTracedProcess. Since someone else manages
  91. // our deletion we need to be careful in the deconstructor to not double free
  92. // ourselves (so we must call release once we get back our pointer.
  93. std::unique_ptr<MockPosixSystemProducer> client;
  94. client.reset(this);
  95. old_producer_ = PerfettoTracedProcess::Get()->SetSystemProducerForTesting(
  96. std::move(client));
  97. SetDisallowPreAndroidPieForTesting(check_sdk_level);
  98. Connect();
  99. }
  100. MockPosixSystemProducer::~MockPosixSystemProducer() {
  101. // See comment in the constructor.
  102. auto client = PerfettoTracedProcess::Get()->SetSystemProducerForTesting(
  103. std::move(old_producer_));
  104. CHECK(client.get() == this);
  105. client.release();
  106. }
  107. void MockPosixSystemProducer::StartDataSource(
  108. perfetto::DataSourceInstanceID id,
  109. const perfetto::DataSourceConfig& data_source_config) {
  110. PosixSystemProducer::StartDataSource(id, data_source_config);
  111. CHECK_LT(num_data_sources_active_, num_data_sources_expected_);
  112. if (++num_data_sources_active_ == num_data_sources_expected_ &&
  113. data_source_enabled_callback_) {
  114. std::move(data_source_enabled_callback_).Run();
  115. }
  116. }
  117. void MockPosixSystemProducer::StopDataSource(
  118. perfetto::DataSourceInstanceID id) {
  119. PosixSystemProducer::StopDataSource(id);
  120. CHECK_GT(num_data_sources_active_, 0u);
  121. if (--num_data_sources_active_ == 0 && data_source_disabled_callback_) {
  122. std::move(data_source_disabled_callback_).Run();
  123. }
  124. }
  125. void MockPosixSystemProducer::SetDataSourceEnabledCallback(
  126. base::OnceClosure data_source_enabled_callback) {
  127. data_source_enabled_callback_ = std::move(data_source_enabled_callback);
  128. }
  129. void MockPosixSystemProducer::SetDataSourceDisabledCallback(
  130. base::OnceClosure data_source_disabled_callback) {
  131. data_source_disabled_callback_ = std::move(data_source_disabled_callback);
  132. }
  133. bool MockPosixSystemProducer::SandboxForbidsSocketConnection() {
  134. return sandbox_forbids_socket_connection_;
  135. }
  136. } // namespace tracing