xref: /aosp_15_r20/external/perfetto/src/tracing/internal/interceptor_trace_writer_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2022 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 "perfetto/tracing/internal/interceptor_trace_writer.h"
18 
19 #include "perfetto/tracing/interceptor.h"
20 #include "test/gtest_and_gmock.h"
21 
22 namespace perfetto {
23 namespace internal {
24 namespace {
25 
26 using ::testing::AllOf;
27 using ::testing::Field;
28 using ::testing::HasSubstr;
29 using ::testing::InSequence;
30 using ::testing::Invoke;
31 using ::testing::IsNull;
32 using ::testing::MockFunction;
33 using ::testing::Not;
34 using ::testing::NotNull;
35 
36 constexpr uint32_t kInstanceIndex = 42;
37 
38 }  // namespace
39 
40 class InterceptorTraceWriterTest : public testing::Test {
41  protected:
42   using TracePacketCallbackArgs = InterceptorBase::TracePacketCallbackArgs;
43   using ThreadLocalState = InterceptorBase::ThreadLocalState;
44   using MockTracePacketCallback = MockFunction<void(TracePacketCallbackArgs)>;
45 
InterceptorTraceWriterTest()46   InterceptorTraceWriterTest()
47       : tls_ptr_(new ThreadLocalState()),
48         tw_(std::unique_ptr<ThreadLocalState>(tls_ptr_),
49             TracePacketCallback,
50             &dss_,
51             kInstanceIndex) {}
52 
SetUp()53   void SetUp() override {
54     static_trace_packet_callback_ = &trace_packet_callback_;
55   }
56 
TearDown()57   void TearDown() override { static_trace_packet_callback_ = nullptr; }
58 
TracePacketCallback(InterceptorBase::TracePacketCallbackArgs args)59   static void TracePacketCallback(
60       InterceptorBase::TracePacketCallbackArgs args) {
61     ASSERT_THAT(static_trace_packet_callback_, NotNull());
62     static_trace_packet_callback_->Call(args);
63   }
64 
65   MockTracePacketCallback trace_packet_callback_;
66   static MockTracePacketCallback* static_trace_packet_callback_;
67 
68   ThreadLocalState* tls_ptr_;
69   DataSourceStaticState dss_;
70   InterceptorTraceWriter tw_;
71 };
72 
73 InterceptorTraceWriterTest::MockTracePacketCallback*
74     InterceptorTraceWriterTest::static_trace_packet_callback_;
75 
TEST_F(InterceptorTraceWriterTest,TracePacketCallbackParams)76 TEST_F(InterceptorTraceWriterTest, TracePacketCallbackParams) {
77   EXPECT_CALL(trace_packet_callback_,
78               Call(AllOf(Field(&TracePacketCallbackArgs::instance_index,
79                                kInstanceIndex),
80                          Field(&TracePacketCallbackArgs::static_state, &dss_),
81                          Field(&TracePacketCallbackArgs::tls, tls_ptr_))))
82       .Times(1);
83 
84   tw_.NewTracePacket();
85   tw_.Flush();
86 }
87 
TEST_F(InterceptorTraceWriterTest,NewTracePacketAutomaticallyAddedFields)88 TEST_F(InterceptorTraceWriterTest, NewTracePacketAutomaticallyAddedFields) {
89   std::string first_packet;
90   std::string second_packet;
91   EXPECT_CALL(trace_packet_callback_, Call)
92       .WillOnce(Invoke([&](TracePacketCallbackArgs args) {
93         first_packet = args.packet_data.ToStdString();
94       }))
95       .WillOnce(Invoke([&](TracePacketCallbackArgs args) {
96         second_packet = args.packet_data.ToStdString();
97       }));
98 
99   tw_.NewTracePacket();
100   tw_.NewTracePacket();
101   tw_.Flush();
102 
103   protos::pbzero::TracePacket::Decoder first(first_packet);
104   protos::pbzero::TracePacket::Decoder second(second_packet);
105   EXPECT_TRUE(first.has_trusted_packet_sequence_id());
106   EXPECT_TRUE(second.has_trusted_packet_sequence_id());
107   EXPECT_EQ(first.trusted_packet_sequence_id(),
108             second.trusted_packet_sequence_id());
109 }
110 
TEST_F(InterceptorTraceWriterTest,NewTracePacketLargePacket)111 TEST_F(InterceptorTraceWriterTest, NewTracePacketLargePacket) {
112   size_t first_packet_size;
113   size_t second_packet_size;
114   EXPECT_CALL(trace_packet_callback_, Call)
115       .WillOnce(Invoke([&](TracePacketCallbackArgs args) {
116         first_packet_size = args.packet_data.size;
117       }))
118       .WillOnce(Invoke([&](TracePacketCallbackArgs args) {
119         second_packet_size = args.packet_data.size;
120       }));
121 
122   tw_.NewTracePacket();
123   {
124     auto msg = tw_.NewTracePacket();
125     std::vector<uint8_t> large(20000u, 0);
126     msg->AppendRawProtoBytes(large.data(), large.size());
127   }
128   tw_.Flush();
129 
130   EXPECT_EQ(second_packet_size, first_packet_size + 20000u);
131 }
132 
TEST_F(InterceptorTraceWriterTest,NewTracePacketTakeWriterLargePacket)133 TEST_F(InterceptorTraceWriterTest, NewTracePacketTakeWriterLargePacket) {
134   size_t first_packet_size;
135   size_t second_packet_size;
136   EXPECT_CALL(trace_packet_callback_, Call)
137       .WillOnce(Invoke([&](TracePacketCallbackArgs args) {
138         first_packet_size = args.packet_data.size;
139       }))
140       .WillOnce(Invoke([&](TracePacketCallbackArgs args) {
141         second_packet_size = args.packet_data.size;
142       }));
143 
144   tw_.NewTracePacket();
145   tw_.FinishTracePacket();
146 
147   protozero::ScatteredStreamWriter* writer =
148       tw_.NewTracePacket().TakeStreamWriter();
149   std::vector<uint8_t> large(20000u, 0);
150   writer->WriteBytes(large.data(), large.size());
151   tw_.FinishTracePacket();
152   tw_.Flush();
153 
154   EXPECT_EQ(second_packet_size, first_packet_size + 20000u);
155 }
156 
TEST_F(InterceptorTraceWriterTest,MixManualTakeAndMessage)157 TEST_F(InterceptorTraceWriterTest, MixManualTakeAndMessage) {
158   std::string content1 = "AAAAA";
159   std::string content2 = "BBBBB";
160   std::string content3 = "CCCCC";
161   EXPECT_CALL(trace_packet_callback_, Call)
162       .WillOnce(Invoke([&](TracePacketCallbackArgs args) {
163         std::string data = args.packet_data.ToStdString();
164         EXPECT_THAT(data, HasSubstr(content1));
165         EXPECT_THAT(data, Not(HasSubstr(content2)));
166         EXPECT_THAT(data, Not(HasSubstr(content3)));
167       }))
168       .WillOnce(Invoke([&](TracePacketCallbackArgs args) {
169         std::string data = args.packet_data.ToStdString();
170         EXPECT_THAT(data, Not(HasSubstr(content1)));
171         EXPECT_THAT(data, HasSubstr(content2));
172         EXPECT_THAT(data, Not(HasSubstr(content3)));
173       }))
174       .WillOnce(Invoke([&](TracePacketCallbackArgs args) {
175         std::string data = args.packet_data.ToStdString();
176         EXPECT_THAT(data, Not(HasSubstr(content1)));
177         EXPECT_THAT(data, Not(HasSubstr(content2)));
178         EXPECT_THAT(data, HasSubstr(content3));
179       }));
180 
181   protozero::ScatteredStreamWriter* writer =
182       tw_.NewTracePacket().TakeStreamWriter();
183   writer->WriteBytes(reinterpret_cast<const uint8_t*>(content1.data()),
184                      content1.size());
185   tw_.FinishTracePacket();
186   {
187     auto msg = tw_.NewTracePacket();
188     msg->AppendRawProtoBytes(reinterpret_cast<const uint8_t*>(content2.data()),
189                              content2.size());
190   }
191   writer = tw_.NewTracePacket().TakeStreamWriter();
192   writer->WriteBytes(reinterpret_cast<const uint8_t*>(content3.data()),
193                      content3.size());
194   tw_.FinishTracePacket();
195 
196   tw_.Flush();
197 }
198 
TEST_F(InterceptorTraceWriterTest,FlushCallback)199 TEST_F(InterceptorTraceWriterTest, FlushCallback) {
200   MockFunction<void()> flush_cb;
201 
202   InSequence seq;
203   EXPECT_CALL(trace_packet_callback_, Call).Times(1);
204   EXPECT_CALL(flush_cb, Call).Times(1);
205 
206   tw_.NewTracePacket();
207   tw_.Flush(flush_cb.AsStdFunction());
208 }
209 
210 }  // namespace internal
211 }  // namespace perfetto
212