123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157 |
- // Copyright 2019 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "services/tracing/perfetto/system_test_utils.h"
- #include <cstdio>
- #include "base/files/scoped_temp_dir.h"
- #include "services/tracing/perfetto/test_utils.h"
- #include "services/tracing/public/cpp/perfetto/perfetto_traced_process.h"
- #include "third_party/perfetto/include/perfetto/ext/tracing/core/commit_data_request.h"
- #include "third_party/perfetto/include/perfetto/ext/tracing/ipc/service_ipc_host.h"
- #include "third_party/perfetto/protos/perfetto/common/commit_data_request.pb.h"
- namespace tracing {
- MockSystemService::MockSystemService(const std::string& consumer_socket,
- const std::string& producer_socket)
- : used_tmpdir_(false),
- consumer_(consumer_socket),
- producer_(producer_socket),
- task_runner_(std::make_unique<base::tracing::PerfettoTaskRunner>(
- base::SequencedTaskRunnerHandle::Get())) {
- StartService();
- }
- MockSystemService::MockSystemService(const base::ScopedTempDir& tmp_dir)
- : MockSystemService(tmp_dir,
- std::make_unique<base::tracing::PerfettoTaskRunner>(
- base::SequencedTaskRunnerHandle::Get())) {}
- MockSystemService::MockSystemService(
- const base::ScopedTempDir& tmp_dir,
- std::unique_ptr<perfetto::base::TaskRunner> task_runner)
- : used_tmpdir_(true), task_runner_(std::move(task_runner)) {
- // We need to set TMPDIR environment variable because when a new producer
- // connects to the perfetto service it needs to create a memmap'd file for
- // the shared memory buffer. Setting TMPDIR allows the service to know
- // where this should be.
- //
- // Finally since environment variables are leaked into other tests if
- // multiple tests run we need to restore the value so each test is
- // hermetic.
- old_tmpdir_ = getenv("TMPDIR");
- setenv("TMPDIR", tmp_dir.GetPath().value().c_str(), true);
- // Set up the system socket locations in a valid tmp directory.
- producer_ = tmp_dir.GetPath().Append(FILE_PATH_LITERAL("producer")).value();
- consumer_ = tmp_dir.GetPath().Append(FILE_PATH_LITERAL("consumer")).value();
- StartService();
- }
- MockSystemService::~MockSystemService() {
- service_.reset();
- remove(producer().c_str());
- remove(consumer().c_str());
- if (used_tmpdir_) {
- if (old_tmpdir_) {
- // Restore the old value back to its initial value.
- setenv("TMPDIR", old_tmpdir_, true);
- } else {
- // TMPDIR wasn't set originally so unset it.
- unsetenv("TMPDIR");
- }
- }
- }
- void MockSystemService::StartService() {
- service_ = perfetto::ServiceIPCHost::CreateInstance(task_runner_.get());
- CHECK(service_);
- unlink(producer_.c_str());
- unlink(consumer_.c_str());
- bool succeeded = service_->Start(producer_.c_str(), consumer_.c_str());
- CHECK(succeeded);
- }
- const std::string& MockSystemService::consumer() const {
- return consumer_;
- }
- const std::string& MockSystemService::producer() const {
- return producer_;
- }
- perfetto::TracingService* MockSystemService::GetService() {
- return service_->service();
- }
- MockPosixSystemProducer::MockPosixSystemProducer(
- const std::string& socket,
- bool check_sdk_level,
- uint32_t num_data_sources,
- base::OnceClosure data_source_enabled_callback,
- base::OnceClosure data_source_disabled_callback,
- bool sandbox_forbids_socket_connection)
- : PosixSystemProducer(socket.c_str(),
- PerfettoTracedProcess::Get()->GetTaskRunner()),
- num_data_sources_expected_(num_data_sources),
- data_source_enabled_callback_(std::move(data_source_enabled_callback)),
- data_source_disabled_callback_(std::move(data_source_disabled_callback)),
- sandbox_forbids_socket_connection_(sandbox_forbids_socket_connection) {
- // We want to set the SystemProducer to this mock, but that 'requires' passing
- // ownership of ourselves to PerfettoTracedProcess. Since someone else manages
- // our deletion we need to be careful in the deconstructor to not double free
- // ourselves (so we must call release once we get back our pointer.
- std::unique_ptr<MockPosixSystemProducer> client;
- client.reset(this);
- old_producer_ = PerfettoTracedProcess::Get()->SetSystemProducerForTesting(
- std::move(client));
- SetDisallowPreAndroidPieForTesting(check_sdk_level);
- Connect();
- }
- MockPosixSystemProducer::~MockPosixSystemProducer() {
- // See comment in the constructor.
- auto client = PerfettoTracedProcess::Get()->SetSystemProducerForTesting(
- std::move(old_producer_));
- CHECK(client.get() == this);
- client.release();
- }
- void MockPosixSystemProducer::StartDataSource(
- perfetto::DataSourceInstanceID id,
- const perfetto::DataSourceConfig& data_source_config) {
- PosixSystemProducer::StartDataSource(id, data_source_config);
- CHECK_LT(num_data_sources_active_, num_data_sources_expected_);
- if (++num_data_sources_active_ == num_data_sources_expected_ &&
- data_source_enabled_callback_) {
- std::move(data_source_enabled_callback_).Run();
- }
- }
- void MockPosixSystemProducer::StopDataSource(
- perfetto::DataSourceInstanceID id) {
- PosixSystemProducer::StopDataSource(id);
- CHECK_GT(num_data_sources_active_, 0u);
- if (--num_data_sources_active_ == 0 && data_source_disabled_callback_) {
- std::move(data_source_disabled_callback_).Run();
- }
- }
- void MockPosixSystemProducer::SetDataSourceEnabledCallback(
- base::OnceClosure data_source_enabled_callback) {
- data_source_enabled_callback_ = std::move(data_source_enabled_callback);
- }
- void MockPosixSystemProducer::SetDataSourceDisabledCallback(
- base::OnceClosure data_source_disabled_callback) {
- data_source_disabled_callback_ = std::move(data_source_disabled_callback);
- }
- bool MockPosixSystemProducer::SandboxForbidsSocketConnection() {
- return sandbox_forbids_socket_connection_;
- }
- } // namespace tracing
|