xref: /aosp_15_r20/external/perfetto/src/trace_redaction/redact_sched_events_integrationtest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2024 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 <cstdint>
18 #include <string>
19 #include <unordered_map>
20 
21 #include "perfetto/base/status.h"
22 #include "src/base/test/status_matchers.h"
23 #include "src/trace_redaction/collect_timeline_events.h"
24 #include "src/trace_redaction/find_package_uid.h"
25 #include "src/trace_redaction/redact_sched_events.h"
26 #include "src/trace_redaction/trace_redaction_framework.h"
27 #include "src/trace_redaction/trace_redaction_integration_fixture.h"
28 #include "src/trace_redaction/trace_redactor.h"
29 #include "test/gtest_and_gmock.h"
30 
31 #include "protos/perfetto/trace/ftrace/ftrace_event.pbzero.h"
32 #include "protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.h"
33 #include "protos/perfetto/trace/ftrace/sched.pbzero.h"
34 #include "protos/perfetto/trace/trace.pbzero.h"
35 #include "protos/perfetto/trace/trace_packet.pbzero.h"
36 
37 namespace perfetto::trace_redaction {
38 
39 // >>> SELECT uid
40 // >>>   FROM package_list
41 // >>>   WHERE package_name='com.Unity.com.unity.multiplayer.samples.coop'
42 //
43 //     +-------+
44 //     |  uid  |
45 //     +-------+
46 //     | 10252 |
47 //     +-------+
48 //
49 // >>> SELECT uid, upid, name
50 // >>>   FROM process
51 // >>>   WHERE uid=10252
52 //
53 //     +-------+------+----------------------------------------------+
54 //     |  uid  | upid | name                                         |
55 //     +-------+------+----------------------------------------------+
56 //     | 10252 | 843  | com.Unity.com.unity.multiplayer.samples.coop |
57 //     +-------+------+----------------------------------------------+
58 //
59 // >>> SELECT tid, name
60 // >>>   FROM thread
61 // >>>   WHERE upid=843 AND name IS NOT NULL
62 //
63 //     +------+-----------------+
64 //     | tid  | name            |
65 //     +------+-----------------+
66 //     | 7120 | Binder:7105_2   |
67 //     | 7127 | UnityMain       |
68 //     | 7142 | Job.worker 0    |
69 //     | 7143 | Job.worker 1    |
70 //     | 7144 | Job.worker 2    |
71 //     | 7145 | Job.worker 3    |
72 //     | 7146 | Job.worker 4    |
73 //     | 7147 | Job.worker 5    |
74 //     | 7148 | Job.worker 6    |
75 //     | 7150 | Background Job. |
76 //     | 7151 | Background Job. |
77 //     | 7167 | UnityGfxDeviceW |
78 //     | 7172 | AudioTrack      |
79 //     | 7174 | FMOD stream thr |
80 //     | 7180 | Binder:7105_3   |
81 //     | 7184 | UnityChoreograp |
82 //     | 7945 | Filter0         |
83 //     | 7946 | Filter1         |
84 //     | 7947 | Thread-7        |
85 //     | 7948 | FMOD mixer thre |
86 //     | 7950 | UnityGfxDeviceW |
87 //     | 7969 | UnityGfxDeviceW |
88 //     +------+-----------------+
89 class RedactSchedSwitchIntegrationTest
90     : public testing::Test,
91       protected TraceRedactionIntegrationFixure {
92  protected:
SetUp()93   void SetUp() override {
94     trace_redactor_.emplace_collect<FindPackageUid>();
95     trace_redactor_.emplace_collect<CollectTimelineEvents>();
96 
97     auto* redact_sched_events =
98         trace_redactor_.emplace_transform<RedactSchedEvents>();
99     redact_sched_events->emplace_modifier<ClearComms>();
100     redact_sched_events->emplace_waking_filter<AllowAll>();
101 
102     context_.package_name = "com.Unity.com.unity.multiplayer.samples.coop";
103   }
104 
105   std::unordered_map<int32_t, std::string> expected_names_ = {
106       {7120, "Binder:7105_2"},   {7127, "UnityMain"},
107       {7142, "Job.worker 0"},    {7143, "Job.worker 1"},
108       {7144, "Job.worker 2"},    {7145, "Job.worker 3"},
109       {7146, "Job.worker 4"},    {7147, "Job.worker 5"},
110       {7148, "Job.worker 6"},    {7150, "Background Job."},
111       {7151, "Background Job."}, {7167, "UnityGfxDeviceW"},
112       {7172, "AudioTrack"},      {7174, "FMOD stream thr"},
113       {7180, "Binder:7105_3"},   {7184, "UnityChoreograp"},
114       {7945, "Filter0"},         {7946, "Filter1"},
115       {7947, "Thread-7"},        {7948, "FMOD mixer thre"},
116       {7950, "UnityGfxDeviceW"}, {7969, "UnityGfxDeviceW"},
117   };
118 
119   Context context_;
120   TraceRedactor trace_redactor_;
121 };
122 
TEST_F(RedactSchedSwitchIntegrationTest,ClearsNonTargetSwitchComms)123 TEST_F(RedactSchedSwitchIntegrationTest, ClearsNonTargetSwitchComms) {
124   auto result = Redact(trace_redactor_, &context_);
125   ASSERT_OK(result) << result.c_message();
126 
127   auto original = LoadOriginal();
128   ASSERT_OK(original) << original.status().c_message();
129 
130   auto redacted = LoadRedacted();
131   ASSERT_OK(redacted) << redacted.status().c_message();
132 
133   auto redacted_trace_data = LoadRedacted();
134   ASSERT_OK(redacted_trace_data) << redacted.status().c_message();
135 
136   protos::pbzero::Trace::Decoder decoder(redacted_trace_data.value());
137 
138   for (auto packet = decoder.packet(); packet; ++packet) {
139     protos::pbzero::TracePacket::Decoder packet_decoder(*packet);
140 
141     if (!packet_decoder.has_ftrace_events()) {
142       continue;
143     }
144 
145     protos::pbzero::FtraceEventBundle::Decoder ftrace_events_decoder(
146         packet_decoder.ftrace_events());
147 
148     for (auto event = ftrace_events_decoder.event(); event; ++event) {
149       protos::pbzero::FtraceEvent::Decoder event_decoder(*event);
150 
151       if (!event_decoder.has_sched_switch()) {
152         continue;
153       }
154 
155       protos::pbzero::SchedSwitchFtraceEvent::Decoder sched_decoder(
156           event_decoder.sched_switch());
157 
158       ASSERT_TRUE(sched_decoder.has_next_pid());
159       ASSERT_TRUE(sched_decoder.has_next_comm());
160 
161       // If the pid is expected, make sure it has the right now. If it is not
162       // expected, it should be missing.
163       auto next_pid = sched_decoder.next_pid();
164       auto next_comm = expected_names_.find(next_pid);
165 
166       if (next_comm == expected_names_.end()) {
167         ASSERT_EQ(sched_decoder.next_comm().size, 0u);
168       } else {
169         ASSERT_EQ(sched_decoder.next_comm().ToStdString(), next_comm->second);
170       }
171 
172       ASSERT_TRUE(sched_decoder.has_prev_pid());
173       ASSERT_TRUE(sched_decoder.has_prev_comm());
174 
175       auto prev_pid = sched_decoder.prev_pid();
176       auto prev_comm = expected_names_.find(prev_pid);
177 
178       if (prev_comm == expected_names_.end()) {
179         ASSERT_EQ(sched_decoder.prev_comm().size, 0u);
180       } else {
181         ASSERT_EQ(sched_decoder.prev_comm().ToStdString(), prev_comm->second);
182       }
183     }
184   }
185 }
186 
187 }  // namespace perfetto::trace_redaction
188