1/* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "src/tracing/test/mock_producer.h" 18 19#include "perfetto/tracing/core/data_source_config.h" 20#include "perfetto/tracing/core/data_source_descriptor.h" 21#include "perfetto/tracing/core/trace_writer.h" 22#include "src/base/test/test_task_runner.h" 23 24using ::testing::_; 25using ::testing::Eq; 26using ::testing::Invoke; 27using ::testing::InvokeWithoutArgs; 28using ::testing::Property; 29 30namespace perfetto { 31 32MockProducer::MockProducer(base::TestTaskRunner* task_runner) 33 : task_runner_(task_runner) {} 34 35MockProducer::~MockProducer() { 36 if (!service_endpoint_) 37 return; 38 static int i = 0; 39 auto checkpoint_name = "on_producer_disconnect_" + std::to_string(i++); 40 auto on_disconnect = task_runner_->CreateCheckpoint(checkpoint_name); 41 EXPECT_CALL(*this, OnDisconnect()).WillOnce(Invoke(on_disconnect)); 42 service_endpoint_.reset(); 43 task_runner_->RunUntilCheckpoint(checkpoint_name); 44} 45 46void MockProducer::Connect(Service* svc, 47 const std::string& producer_name, 48 uid_t uid, 49 size_t shared_memory_size_hint_bytes) { 50 producer_name_ = producer_name; 51 service_endpoint_ = svc->ConnectProducer(this, uid, producer_name, 52 shared_memory_size_hint_bytes); 53 auto checkpoint_name = "on_producer_connect_" + producer_name; 54 auto on_connect = task_runner_->CreateCheckpoint(checkpoint_name); 55 EXPECT_CALL(*this, OnConnect()).WillOnce(Invoke(on_connect)); 56 task_runner_->RunUntilCheckpoint(checkpoint_name); 57} 58 59void MockProducer::RegisterDataSource(const std::string& name) { 60 DataSourceDescriptor ds_desc; 61 ds_desc.set_name(name); 62 service_endpoint_->RegisterDataSource(ds_desc); 63} 64 65void MockProducer::UnregisterDataSource(const std::string& name) { 66 service_endpoint_->UnregisterDataSource(name); 67} 68 69void MockProducer::WaitForTracingSetup() { 70 static int i = 0; 71 auto checkpoint_name = 72 "on_shmem_initialized_" + producer_name_ + "_" + std::to_string(i++); 73 auto on_tracing_enabled = task_runner_->CreateCheckpoint(checkpoint_name); 74 EXPECT_CALL(*this, OnTracingSetup()).WillOnce(Invoke(on_tracing_enabled)); 75 task_runner_->RunUntilCheckpoint(checkpoint_name); 76} 77 78void MockProducer::WaitForDataSourceStart(const std::string& name) { 79 static int i = 0; 80 auto checkpoint_name = "on_ds_start_" + name + "_" + std::to_string(i++); 81 auto on_ds_start = task_runner_->CreateCheckpoint(checkpoint_name); 82 EXPECT_CALL(*this, CreateDataSourceInstance( 83 _, Property(&DataSourceConfig::name, Eq(name)))) 84 .WillOnce(Invoke([on_ds_start, this](DataSourceInstanceID ds_id, 85 const DataSourceConfig& cfg) { 86 EXPECT_FALSE(data_source_instances_.count(cfg.name())); 87 auto target_buffer = static_cast<BufferID>(cfg.target_buffer()); 88 data_source_instances_.emplace(cfg.name(), 89 EnabledDataSource{ds_id, target_buffer}); 90 on_ds_start(); 91 })); 92 task_runner_->RunUntilCheckpoint(checkpoint_name); 93} 94 95void MockProducer::WaitForDataSourceStop(const std::string& name) { 96 static int i = 0; 97 auto checkpoint_name = "on_ds_stop_" + name + "_" + std::to_string(i++); 98 auto on_ds_stop = task_runner_->CreateCheckpoint(checkpoint_name); 99 ASSERT_EQ(1u, data_source_instances_.count(name)); 100 DataSourceInstanceID ds_id = data_source_instances_[name].id; 101 EXPECT_CALL(*this, TearDownDataSourceInstance(ds_id)) 102 .WillOnce(InvokeWithoutArgs(on_ds_stop)); 103 task_runner_->RunUntilCheckpoint(checkpoint_name); 104 data_source_instances_.erase(name); 105} 106 107std::unique_ptr<TraceWriter> MockProducer::CreateTraceWriter( 108 const std::string& data_source_name) { 109 PERFETTO_DCHECK(data_source_instances_.count(data_source_name)); 110 BufferID buf_id = data_source_instances_[data_source_name].target_buffer; 111 return service_endpoint_->CreateTraceWriter(buf_id); 112} 113 114void MockProducer::WaitForFlush(TraceWriter* writer_to_flush) { 115 auto& expected_call = EXPECT_CALL(*this, Flush(_, _, _)); 116 if (!writer_to_flush) 117 return; 118 expected_call.WillOnce( 119 Invoke([this, writer_to_flush](FlushRequestID flush_req_id, 120 const DataSourceInstanceID*, size_t) { 121 writer_to_flush->Flush(); 122 service_endpoint_->NotifyFlushComplete(flush_req_id); 123 })); 124} 125 126} // namespace perfetto 127