• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2023 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 
20 #include <ostream>
21 
22 #include "frameworks/proto_logging/stats/atoms.pb.h"
23 #include "frameworks/proto_logging/stats/attribution_node.pb.h"
24 #include "packages/modules/StatsD/statsd/src/guardrail/stats_log_enums.pb.h"
25 #include "packages/modules/StatsD/statsd/src/shell/shell_data.pb.h"
26 #include "packages/modules/StatsD/statsd/src/stats_log.pb.h"
27 
28 namespace android {
29 namespace os {
30 namespace statsd {
31 
32 using PackageInfo = UidMapping_PackageInfoSnapshot_PackageInfo;
33 
34 // clang-format off
35 
36 #define PROPERTY_MATCHER(typename, propname, matcher)                               \
37     testing::Property(#propname, &typename::propname, matcher(expected.propname()))
38 
39 #define REPEATED_PROPERTY_MATCHER(typename, propname, matcher)                      \
40     testing::Property(#propname, &typename::propname,                               \
41             testing::Pointwise(matcher(), expected.propname()))
42 
43 #define PROPERTY_EQ(typename, propname) PROPERTY_MATCHER(typename, propname, testing::Eq)
44 
45 #define REPEATED_PROPERTY_EQ(typename, propname)               \
46     REPEATED_PROPERTY_MATCHER(typename, propname, testing::Eq)
47 
48 /**
49  * Generate a GoogleTest equality matcher for a custom type specified by typename with the given
50  * properties.
51  *
52  * Example: For the protos:
53  *     message Bar {
54  *         optional int32 aa = 1;
55  *     }
56  *     message Foo {
57  *         optional int32 a = 1;
58  *         repeated float b = 2;
59  *         optional Bar bar = 3;
60  *         repeated Bar repeated_bar = 4;
61  *     }
62  * This will generate equality matchers for them called EqBar() and EqFoo():
63  *      EQ_MATCHER(Bar, PROPERTY_EQ(Bar, aa));
64  *      EQ_MATCHER(Foo,
65  *              PROPERTY_EQ(Foo, a),
66  *              PROPERTY_EQ(Foo, b),
67  *              PROPERTY_MATCHER(Foo, bar, EqBar),
68  *              REPEATED_PROPERTY_MATCHER(Foo, repeated_bar, EqBar)
69  *      );
70  */
71 #define EQ_MATCHER(typename, properties...)                                                   \
72     MATCHER(Eq##typename, " ") {                                                              \
73         return testing::Matches(Eq##typename(std::get<1>(arg)))(std::get<0>(arg));            \
74     }                                                                                         \
75     MATCHER_P(Eq##typename, expected, testing::PrintToString(expected)) {                     \
76         return testing::ExplainMatchResult(testing::AllOf(properties), arg, result_listener); \
77     }
78 
79 #define PROPERTY_PRINT(propname)                                                    \
80     if (obj.has_##propname()) {                                                     \
81         *os << #propname << ": " << testing::PrintToString(obj.propname()) << ", "; \
82     }
83 
84 #define REPEATED_PROPERTY_PRINT(propname)                                           \
85     if (obj.propname##_size() > 0) {                                                \
86         *os << #propname << ": " << testing::PrintToString(obj.propname()) << ", "; \
87     }
88 
89 /**
90  * Generates a method that teaches GoogleTest how to print a custom type specified by typename
91  * with the given properties.
92  * The equality matcher generated by EQ_MATCHER for the given typename will use this generated
93  * printer method to print the object when the matcher fails.
94  *
95  * Example: For the protos:
96  *     message Bar {
97  *         optional int32 aa = 1;
98  *     }
99  *     message Foo {
100  *         optional int32 a = 1;
101  *         repeated float b = 2;
102  *         optional Bar bar = 3;
103  *         repeated Bar repeated_bar = 4;
104  *     }
105  * This will generate printer methods for them:
106  *      TYPE_PRINTER(Bar, PROPERTY_PRINT(aa));
107  *      TYPE_PRINTER(Foo,
108  *              PROPERTY_PRINT(a)
109  *              PROPERTY_PRINT(b)
110  *              PROPERTY_PRINT(bar)
111  *              REPEATED_PROPERTY_PRINT(repeated_bar)
112  *      );
113  */
114 #define TYPE_PRINTER(typename, properties)                       \
115     inline void PrintTo(const typename& obj, std::ostream* os) { \
116         *os << #typename << ": { ";                              \
117         properties                                               \
118         *os << "}";                                              \
119     }
120 
121 EQ_MATCHER(PackageInfo,
122         PROPERTY_EQ(PackageInfo, version),
123         PROPERTY_EQ(PackageInfo, uid),
124         PROPERTY_EQ(PackageInfo, deleted),
125         PROPERTY_EQ(PackageInfo, truncated_certificate_hash),
126         PROPERTY_EQ(PackageInfo, name_hash),
127         PROPERTY_EQ(PackageInfo, version_string_hash),
128         PROPERTY_EQ(PackageInfo, name),
129         PROPERTY_EQ(PackageInfo, version_string),
130         PROPERTY_EQ(PackageInfo, installer_index),
131         PROPERTY_EQ(PackageInfo, installer_hash),
132         PROPERTY_EQ(PackageInfo, installer)
133 );
134 TYPE_PRINTER(PackageInfo,
135         PROPERTY_PRINT(version)
136         PROPERTY_PRINT(uid)
137         PROPERTY_PRINT(deleted)
138         PROPERTY_PRINT(truncated_certificate_hash)
139         PROPERTY_PRINT(name_hash)
140         PROPERTY_PRINT(version_string_hash)
141         PROPERTY_PRINT(name)
142         PROPERTY_PRINT(version_string)
143         PROPERTY_PRINT(installer_index)
144         PROPERTY_PRINT(installer_hash)
145         PROPERTY_PRINT(installer)
146 );
147 
148 EQ_MATCHER(AttributionNode,
149         PROPERTY_EQ(AttributionNode, uid),
150         PROPERTY_EQ(AttributionNode, tag)
151 );
152 TYPE_PRINTER(AttributionNode,
153         PROPERTY_PRINT(uid)
154         PROPERTY_PRINT(tag)
155 );
156 
157 EQ_MATCHER(ScreenStateChanged, PROPERTY_EQ(ScreenStateChanged, state));
158 TYPE_PRINTER(ScreenStateChanged, PROPERTY_PRINT(state));
159 
160 EQ_MATCHER(TrainExperimentIds,
161         REPEATED_PROPERTY_EQ(TrainExperimentIds, experiment_id)
162 );
163 TYPE_PRINTER(TrainExperimentIds, REPEATED_PROPERTY_PRINT(experiment_id));
164 
165 EQ_MATCHER(TestAtomReported,
166         REPEATED_PROPERTY_MATCHER(TestAtomReported, attribution_node, EqAttributionNode),
167         PROPERTY_EQ(TestAtomReported, int_field),
168         PROPERTY_EQ(TestAtomReported, long_field),
169         PROPERTY_EQ(TestAtomReported, float_field),
170         PROPERTY_EQ(TestAtomReported, string_field),
171         PROPERTY_EQ(TestAtomReported, boolean_field),
172         PROPERTY_EQ(TestAtomReported, state),
173         PROPERTY_MATCHER(TestAtomReported, bytes_field, EqTrainExperimentIds),
174         REPEATED_PROPERTY_EQ(TestAtomReported, repeated_int_field),
175         REPEATED_PROPERTY_EQ(TestAtomReported, repeated_long_field),
176         REPEATED_PROPERTY_EQ(TestAtomReported, repeated_float_field),
177         REPEATED_PROPERTY_EQ(TestAtomReported, repeated_string_field),
178         REPEATED_PROPERTY_EQ(TestAtomReported, repeated_boolean_field),
179         REPEATED_PROPERTY_EQ(TestAtomReported, repeated_enum_field)
180 );
181 TYPE_PRINTER(TestAtomReported,
182         REPEATED_PROPERTY_PRINT(attribution_node)
183         PROPERTY_PRINT(int_field)
184         PROPERTY_PRINT(long_field)
185         PROPERTY_PRINT(float_field)
186         PROPERTY_PRINT(string_field)
187         PROPERTY_PRINT(boolean_field)
188         PROPERTY_PRINT(state)
189         PROPERTY_PRINT(bytes_field)
190         REPEATED_PROPERTY_PRINT(repeated_int_field)
191         REPEATED_PROPERTY_PRINT(repeated_long_field)
192         REPEATED_PROPERTY_PRINT(repeated_float_field)
193         REPEATED_PROPERTY_PRINT(repeated_string_field)
194         REPEATED_PROPERTY_PRINT(repeated_boolean_field)
195         REPEATED_PROPERTY_PRINT(repeated_enum_field)
196 );
197 
198 EQ_MATCHER(CpuActiveTime,
199         PROPERTY_EQ(CpuActiveTime, uid),
200         PROPERTY_EQ(CpuActiveTime, time_millis)
201 );
202 TYPE_PRINTER(CpuActiveTime,
203         PROPERTY_PRINT(uid)
204         PROPERTY_PRINT(time_millis)
205 );
206 
207 EQ_MATCHER(PluggedStateChanged, PROPERTY_EQ(PluggedStateChanged, state));
208 TYPE_PRINTER(PluggedStateChanged, PROPERTY_PRINT(state));
209 
210 EQ_MATCHER(WakelockStateChanged,
211         REPEATED_PROPERTY_MATCHER(WakelockStateChanged, attribution_node, EqAttributionNode),
212         PROPERTY_EQ(WakelockStateChanged, type),
213         PROPERTY_EQ(WakelockStateChanged, tag),
214         PROPERTY_EQ(WakelockStateChanged, state),
215         PROPERTY_EQ(WakelockStateChanged, process_state)
216 );
217 TYPE_PRINTER(WakelockStateChanged,
218         REPEATED_PROPERTY_PRINT(attribution_node)
219         PROPERTY_PRINT(type)
220         PROPERTY_PRINT(tag)
221         PROPERTY_PRINT(state)
222         PROPERTY_PRINT(process_state)
223 );
224 
225 EQ_MATCHER(Atom,
226         PROPERTY_MATCHER(Atom, screen_state_changed, EqScreenStateChanged),
227         PROPERTY_MATCHER(Atom, test_atom_reported, EqTestAtomReported),
228         PROPERTY_MATCHER(Atom, wakelock_state_changed, EqWakelockStateChanged)
229 );
230 TYPE_PRINTER(Atom,
231         PROPERTY_PRINT(screen_state_changed)
232         PROPERTY_PRINT(test_atom_reported)
233         PROPERTY_PRINT(wakelock_state_changed)
234 );
235 
236 EQ_MATCHER(ShellData,
237         REPEATED_PROPERTY_MATCHER(ShellData, atom, EqAtom),
238         REPEATED_PROPERTY_EQ(ShellData, elapsed_timestamp_nanos),
239         REPEATED_PROPERTY_EQ(ShellData, logging_uid)
240 );
241 TYPE_PRINTER(ShellData,
242         REPEATED_PROPERTY_PRINT(atom)
243         REPEATED_PROPERTY_PRINT(elapsed_timestamp_nanos)
244         REPEATED_PROPERTY_PRINT(logging_uid)
245 );
246 
247 using CounterStats = StatsdStatsReport_CounterStats;
248 
249 EQ_MATCHER(CounterStats,
250         PROPERTY_EQ(CounterStats, counter_type),
251         PROPERTY_EQ(CounterStats, count)
252 );
253 TYPE_PRINTER(CounterStats,
254         PROPERTY_PRINT(counter_type)
255         PROPERTY_PRINT(count)
256 );
257 
258 using AtomStats = StatsdStatsReport_AtomStats;
259 
260 EQ_MATCHER(AtomStats,
261         PROPERTY_EQ(AtomStats, tag),
262         PROPERTY_EQ(AtomStats, count),
263         PROPERTY_EQ(AtomStats, error_count),
264         PROPERTY_EQ(AtomStats, dropped_count),
265         PROPERTY_EQ(AtomStats, skip_count),
266         PROPERTY_EQ(AtomStats, peak_rate)
267 );
268 TYPE_PRINTER(AtomStats,
269         PROPERTY_PRINT(tag)
270         PROPERTY_PRINT(count)
271         PROPERTY_PRINT(error_count)
272         PROPERTY_PRINT(dropped_count)
273         PROPERTY_PRINT(skip_count)
274         PROPERTY_PRINT(peak_rate)
275 );
276 
277 // clang-format on
278 
279 }  // namespace statsd
280 }  // namespace os
281 }  // namespace android
282