blob: 9878926bb04524882134cc326220125880fe2616 [file] [log] [blame]
Yao Chend54f9dd2017-10-17 17:37:48 +00001/*
2 * Copyright (C) 2017, 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 <gtest/gtest.h>
Yao Chend54f9dd2017-10-17 17:37:48 +000018#include <stdio.h>
19
Muhammad Qureshia345af92020-03-24 17:05:14 -070020#include "Collation.h"
21#include "frameworks/base/tools/stats_log_api_gen/test.pb.h"
22
Yao Chend54f9dd2017-10-17 17:37:48 +000023namespace android {
24namespace stats_log_api_gen {
25
Stefan Lafon9478f352017-10-30 21:20:20 -070026using std::map;
Yao Chend54f9dd2017-10-17 17:37:48 +000027using std::set;
28using std::vector;
29
30/**
Muhammad Qureshib13a3212020-03-12 07:37:13 -070031 * Return whether the map contains a vector of the elements provided.
Yao Chend54f9dd2017-10-17 17:37:48 +000032 */
Muhammad Qureshia345af92020-03-24 17:05:14 -070033static bool map_contains_vector(const map<vector<java_type_t>, FieldNumberToAnnotations>& s,
34 int count, ...) {
Yao Chend54f9dd2017-10-17 17:37:48 +000035 va_list args;
36 vector<java_type_t> v;
37
38 va_start(args, count);
Muhammad Qureshia345af92020-03-24 17:05:14 -070039 for (int i = 0; i < count; i++) {
Yao Chend54f9dd2017-10-17 17:37:48 +000040 v.push_back((java_type_t)va_arg(args, int));
41 }
42 va_end(args);
43
44 return s.find(v) != s.end();
45}
46
47/**
Muhammad Qureshib13a3212020-03-12 07:37:13 -070048 * Expect that the provided map contains the elements provided.
Yao Chend54f9dd2017-10-17 17:37:48 +000049 */
Muhammad Qureshia345af92020-03-24 17:05:14 -070050#define EXPECT_MAP_CONTAINS_SIGNATURE(s, ...) \
51 do { \
52 int count = sizeof((int[]){__VA_ARGS__}) / sizeof(int); \
Muhammad Qureshib13a3212020-03-12 07:37:13 -070053 EXPECT_TRUE(map_contains_vector(s, count, __VA_ARGS__)); \
Muhammad Qureshia345af92020-03-24 17:05:14 -070054 } while (0)
Yao Chend54f9dd2017-10-17 17:37:48 +000055
Stefan Lafon9478f352017-10-30 21:20:20 -070056/** Expects that the provided atom has no enum values for any field. */
Muhammad Qureshia345af92020-03-24 17:05:14 -070057#define EXPECT_NO_ENUM_FIELD(atom) \
58 do { \
Stefan Lafon9478f352017-10-30 21:20:20 -070059 for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
Muhammad Qureshia345af92020-03-24 17:05:14 -070060 field != atom->fields.end(); field++) { \
61 EXPECT_TRUE(field->enumValues.empty()); \
62 } \
63 } while (0)
Stefan Lafon9478f352017-10-30 21:20:20 -070064
Yangster-mac7604aea2017-12-11 22:55:49 -080065/** Expects that exactly one specific field has expected enum values. */
Muhammad Qureshia345af92020-03-24 17:05:14 -070066#define EXPECT_HAS_ENUM_FIELD(atom, field_name, values) \
67 do { \
Stefan Lafon9478f352017-10-30 21:20:20 -070068 for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
Muhammad Qureshia345af92020-03-24 17:05:14 -070069 field != atom->fields.end(); field++) { \
70 if (field->name == field_name) { \
71 EXPECT_EQ(field->enumValues, values); \
72 } else { \
73 EXPECT_TRUE(field->enumValues.empty()); \
74 } \
75 } \
76 } while (0)
Stefan Lafon9478f352017-10-30 21:20:20 -070077
Yao Chend54f9dd2017-10-17 17:37:48 +000078/**
79 * Test a correct collation, with all the types.
80 */
81TEST(CollationTest, CollateStats) {
82 Atoms atoms;
Muhammad Qureshib13a3212020-03-12 07:37:13 -070083 int errorCount = collate_atoms(Event::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Yao Chend54f9dd2017-10-17 17:37:48 +000084
85 EXPECT_EQ(0, errorCount);
Muhammad Qureshib13a3212020-03-12 07:37:13 -070086 EXPECT_EQ(3ul, atoms.signatureInfoMap.size());
Yao Chend54f9dd2017-10-17 17:37:48 +000087
88 // IntAtom, AnotherIntAtom
Muhammad Qureshib13a3212020-03-12 07:37:13 -070089 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
Yao Chend54f9dd2017-10-17 17:37:48 +000090
91 // OutOfOrderAtom
Muhammad Qureshib13a3212020-03-12 07:37:13 -070092 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_INT);
Yao Chend54f9dd2017-10-17 17:37:48 +000093
94 // AllTypesAtom
Muhammad Qureshia345af92020-03-24 17:05:14 -070095 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap,
96 JAVA_TYPE_ATTRIBUTION_CHAIN, // AttributionChain
97 JAVA_TYPE_FLOAT, // float
98 JAVA_TYPE_LONG, // int64
99 JAVA_TYPE_LONG, // uint64
100 JAVA_TYPE_INT, // int32
101 JAVA_TYPE_LONG, // fixed64
102 JAVA_TYPE_INT, // fixed32
103 JAVA_TYPE_BOOLEAN, // bool
104 JAVA_TYPE_STRING, // string
105 JAVA_TYPE_INT, // uint32
106 JAVA_TYPE_INT, // AnEnum
107 JAVA_TYPE_INT, // sfixed32
108 JAVA_TYPE_LONG, // sfixed64
109 JAVA_TYPE_INT, // sint32
110 JAVA_TYPE_LONG // sint64
Yangster-mac7604aea2017-12-11 22:55:49 -0800111 );
Yao Chend54f9dd2017-10-17 17:37:48 +0000112
113 set<AtomDecl>::const_iterator atom = atoms.decls.begin();
114 EXPECT_EQ(1, atom->code);
115 EXPECT_EQ("int_atom", atom->name);
116 EXPECT_EQ("IntAtom", atom->message);
Stefan Lafon9478f352017-10-30 21:20:20 -0700117 EXPECT_NO_ENUM_FIELD(atom);
Yao Chend54f9dd2017-10-17 17:37:48 +0000118 atom++;
119
120 EXPECT_EQ(2, atom->code);
121 EXPECT_EQ("out_of_order_atom", atom->name);
122 EXPECT_EQ("OutOfOrderAtom", atom->message);
Stefan Lafon9478f352017-10-30 21:20:20 -0700123 EXPECT_NO_ENUM_FIELD(atom);
Yao Chend54f9dd2017-10-17 17:37:48 +0000124 atom++;
125
126 EXPECT_EQ(3, atom->code);
127 EXPECT_EQ("another_int_atom", atom->name);
128 EXPECT_EQ("AnotherIntAtom", atom->message);
Stefan Lafon9478f352017-10-30 21:20:20 -0700129 EXPECT_NO_ENUM_FIELD(atom);
Yao Chend54f9dd2017-10-17 17:37:48 +0000130 atom++;
131
132 EXPECT_EQ(4, atom->code);
133 EXPECT_EQ("all_types_atom", atom->name);
134 EXPECT_EQ("AllTypesAtom", atom->message);
Stefan Lafon9478f352017-10-30 21:20:20 -0700135 map<int, string> enumValues;
136 enumValues[0] = "VALUE0";
137 enumValues[1] = "VALUE1";
138 EXPECT_HAS_ENUM_FIELD(atom, "enum_field", enumValues);
Yao Chend54f9dd2017-10-17 17:37:48 +0000139 atom++;
140
141 EXPECT_TRUE(atom == atoms.decls.end());
142}
143
144/**
145 * Test that event class that contains stuff other than the atoms is rejected.
146 */
147TEST(CollationTest, NonMessageTypeFails) {
148 Atoms atoms;
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700149 int errorCount = collate_atoms(IntAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Yao Chend54f9dd2017-10-17 17:37:48 +0000150
151 EXPECT_EQ(1, errorCount);
152}
153
154/**
Muhammad Qureshia345af92020-03-24 17:05:14 -0700155 * Test that atoms that have non-primitive types or repeated fields are
156 * rejected.
Yao Chend54f9dd2017-10-17 17:37:48 +0000157 */
158TEST(CollationTest, FailOnBadTypes) {
159 Atoms atoms;
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700160 int errorCount = collate_atoms(BadTypesEvent::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Yao Chend54f9dd2017-10-17 17:37:48 +0000161
Tej Singhc88fbf12020-02-20 18:14:50 -0800162 EXPECT_EQ(4, errorCount);
Yao Chend54f9dd2017-10-17 17:37:48 +0000163}
164
165/**
166 * Test that atoms that skip field numbers (in the first position) are rejected.
167 */
168TEST(CollationTest, FailOnSkippedFieldsSingle) {
169 Atoms atoms;
Muhammad Qureshia345af92020-03-24 17:05:14 -0700170 int errorCount =
171 collate_atoms(BadSkippedFieldSingle::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Yao Chend54f9dd2017-10-17 17:37:48 +0000172
173 EXPECT_EQ(1, errorCount);
174}
175
176/**
Muhammad Qureshia345af92020-03-24 17:05:14 -0700177 * Test that atoms that skip field numbers (not in the first position, and
178 * multiple times) are rejected.
Yao Chend54f9dd2017-10-17 17:37:48 +0000179 */
180TEST(CollationTest, FailOnSkippedFieldsMultiple) {
181 Atoms atoms;
Muhammad Qureshia345af92020-03-24 17:05:14 -0700182 int errorCount =
183 collate_atoms(BadSkippedFieldMultiple::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Yao Chend54f9dd2017-10-17 17:37:48 +0000184
185 EXPECT_EQ(2, errorCount);
186}
187
188/**
Yangster-mac7604aea2017-12-11 22:55:49 -0800189 * Test that atoms that have an attribution chain not in the first position are
190 * rejected.
Yao Chend54f9dd2017-10-17 17:37:48 +0000191 */
Yangster-mac20877162017-12-22 17:19:39 -0800192TEST(CollationTest, FailBadAttributionNodePosition) {
Muhammad Qureshia345af92020-03-24 17:05:14 -0700193 Atoms atoms;
194 int errorCount =
195 collate_atoms(BadAttributionNodePosition::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Yao Chend54f9dd2017-10-17 17:37:48 +0000196
Muhammad Qureshia345af92020-03-24 17:05:14 -0700197 EXPECT_EQ(1, errorCount);
Yao Chend54f9dd2017-10-17 17:37:48 +0000198}
199
Yao Chen9c1debe2018-02-19 14:39:19 -0800200TEST(CollationTest, FailOnBadStateAtomOptions) {
201 Atoms atoms;
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700202 int errorCount = collate_atoms(BadStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Yao Chen9c1debe2018-02-19 14:39:19 -0800203
204 EXPECT_EQ(3, errorCount);
205}
206
207TEST(CollationTest, PassOnGoodStateAtomOptions) {
208 Atoms atoms;
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700209 int errorCount = collate_atoms(GoodStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Yao Chen9c1debe2018-02-19 14:39:19 -0800210 EXPECT_EQ(0, errorCount);
211}
212
Yao Chenbbdd67d2018-10-24 12:15:56 -0700213TEST(CollationTest, PassOnGoodBinaryFieldAtom) {
214 Atoms atoms;
215 int errorCount =
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700216 collate_atoms(GoodEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Yao Chenbbdd67d2018-10-24 12:15:56 -0700217 EXPECT_EQ(0, errorCount);
218}
219
220TEST(CollationTest, FailOnBadBinaryFieldAtom) {
221 Atoms atoms;
222 int errorCount =
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700223 collate_atoms(BadEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Yao Chenbbdd67d2018-10-24 12:15:56 -0700224 EXPECT_TRUE(errorCount > 0);
225}
226
Andrei Oneada01ea52019-01-30 15:28:36 +0000227TEST(CollationTest, PassOnWhitelistedAtom) {
228 Atoms atoms;
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700229 int errorCount = collate_atoms(ListedAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Andrei Oneada01ea52019-01-30 15:28:36 +0000230 EXPECT_EQ(errorCount, 0);
231 EXPECT_EQ(atoms.decls.size(), 2ul);
232}
233
234TEST(CollationTest, RecogniseWhitelistedAtom) {
235 Atoms atoms;
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700236 collate_atoms(ListedAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Andrei Oneada01ea52019-01-30 15:28:36 +0000237 for (const auto& atomDecl : atoms.decls) {
238 if (atomDecl.code == 1) {
239 EXPECT_TRUE(atomDecl.whitelisted);
240 } else {
241 EXPECT_FALSE(atomDecl.whitelisted);
242 }
243 }
244}
245
Tej Singh810eeb32019-03-07 19:08:52 -0800246TEST(CollationTest, PassOnLogFromModuleAtom) {
247 Atoms atoms;
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700248 int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Tej Singh810eeb32019-03-07 19:08:52 -0800249 EXPECT_EQ(errorCount, 0);
Muhammad Qureshif8460f72020-03-05 09:48:48 -0800250 EXPECT_EQ(atoms.decls.size(), 4ul);
Tej Singh810eeb32019-03-07 19:08:52 -0800251}
252
253TEST(CollationTest, RecognizeModuleAtom) {
254 Atoms atoms;
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700255 int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
Tej Singh810eeb32019-03-07 19:08:52 -0800256 EXPECT_EQ(errorCount, 0);
Muhammad Qureshif8460f72020-03-05 09:48:48 -0800257 EXPECT_EQ(atoms.decls.size(), 4ul);
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700258 EXPECT_EQ(atoms.signatureInfoMap.size(), 2u);
259 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
260 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_STRING);
261 for (auto signatureInfoMapIt : atoms.signatureInfoMap) {
262 vector<java_type_t> signature = signatureInfoMapIt.first;
263 const FieldNumberToAnnotations& fieldNumberToAnnotations = signatureInfoMapIt.second;
264 if (signature[0] == JAVA_TYPE_STRING) {
265 EXPECT_EQ(0u, fieldNumberToAnnotations.size());
266 } else if (signature[0] == JAVA_TYPE_INT) {
267 EXPECT_EQ(1u, fieldNumberToAnnotations.size());
268 EXPECT_NE(fieldNumberToAnnotations.end(), fieldNumberToAnnotations.find(1));
269 const set<shared_ptr<Annotation>>& annotations = fieldNumberToAnnotations.at(1);
270 EXPECT_EQ(2u, annotations.size());
271 for (const shared_ptr<Annotation> annotation : annotations) {
Muhammad Qureshia345af92020-03-24 17:05:14 -0700272 EXPECT_TRUE(annotation->annotationId == ANNOTATION_ID_IS_UID ||
273 annotation->annotationId == ANNOTATION_ID_STATE_OPTION);
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700274 if (ANNOTATION_ID_IS_UID == annotation->annotationId) {
275 EXPECT_EQ(1, annotation->atomId);
276 EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
277 EXPECT_TRUE(annotation->value.boolValue);
278 }
279
280 if (ANNOTATION_ID_STATE_OPTION == annotation->annotationId) {
281 EXPECT_EQ(3, annotation->atomId);
282 EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type);
283 EXPECT_EQ(os::statsd::StateField::EXCLUSIVE_STATE, annotation->value.intValue);
284 }
285 }
Tej Singh810eeb32019-03-07 19:08:52 -0800286 }
287 }
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700288}
Tej Singh810eeb32019-03-07 19:08:52 -0800289
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700290TEST(CollationTest, RecognizeModule1Atom) {
291 Atoms atoms;
292 const string moduleName = "module1";
293 int errorCount = collate_atoms(ModuleAtoms::descriptor(), moduleName, &atoms);
294 EXPECT_EQ(errorCount, 0);
295 EXPECT_EQ(atoms.decls.size(), 2ul);
296 EXPECT_EQ(atoms.signatureInfoMap.size(), 1u);
297 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
298 for (auto signatureInfoMapIt : atoms.signatureInfoMap) {
299 vector<java_type_t> signature = signatureInfoMapIt.first;
300 const FieldNumberToAnnotations& fieldNumberToAnnotations = signatureInfoMapIt.second;
301 EXPECT_EQ(JAVA_TYPE_INT, signature[0]);
302 EXPECT_EQ(1u, fieldNumberToAnnotations.size());
303 int fieldNumber = 1;
304 EXPECT_NE(fieldNumberToAnnotations.end(), fieldNumberToAnnotations.find(fieldNumber));
Muhammad Qureshia345af92020-03-24 17:05:14 -0700305 const set<shared_ptr<Annotation>>& annotations = fieldNumberToAnnotations.at(fieldNumber);
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700306 EXPECT_EQ(2u, annotations.size());
307 for (const shared_ptr<Annotation> annotation : annotations) {
Muhammad Qureshia345af92020-03-24 17:05:14 -0700308 EXPECT_TRUE(annotation->annotationId == ANNOTATION_ID_IS_UID ||
309 annotation->annotationId == ANNOTATION_ID_STATE_OPTION);
Muhammad Qureshib13a3212020-03-12 07:37:13 -0700310 if (ANNOTATION_ID_IS_UID == annotation->annotationId) {
311 EXPECT_EQ(1, annotation->atomId);
312 EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
313 EXPECT_TRUE(annotation->value.boolValue);
314 }
315
316 if (ANNOTATION_ID_STATE_OPTION == annotation->annotationId) {
317 EXPECT_EQ(3, annotation->atomId);
318 EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type);
319 EXPECT_EQ(os::statsd::StateField::EXCLUSIVE_STATE, annotation->value.intValue);
320 }
Tej Singh810eeb32019-03-07 19:08:52 -0800321 }
322 }
323}
324
Yao Chend54f9dd2017-10-17 17:37:48 +0000325} // namespace stats_log_api_gen
Muhammad Qureshif8460f72020-03-05 09:48:48 -0800326} // namespace android