1 /*
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>
18 #include <stdio.h>
19
20 #include "Collation.h"
21 #include "frameworks/base/tools/stats_log_api_gen/test.pb.h"
22
23 namespace android {
24 namespace stats_log_api_gen {
25
26 using std::map;
27 using std::set;
28 using std::vector;
29
30 /**
31 * Return whether the map contains a vector of the elements provided.
32 */
map_contains_vector(const SignatureInfoMap & s,int count,...)33 static bool map_contains_vector(const SignatureInfoMap& s, int count, ...) {
34 va_list args;
35 vector<java_type_t> v;
36
37 va_start(args, count);
38 for (int i = 0; i < count; i++) {
39 v.push_back((java_type_t)va_arg(args, int));
40 }
41 va_end(args);
42
43 return s.find(v) != s.end();
44 }
45
46 /**
47 * Expect that the provided map contains the elements provided.
48 */
49 #define EXPECT_MAP_CONTAINS_SIGNATURE(s, ...) \
50 do { \
51 int count = sizeof((int[]){__VA_ARGS__}) / sizeof(int); \
52 EXPECT_TRUE(map_contains_vector(s, count, __VA_ARGS__)); \
53 } while (0)
54
55 /** Expects that the provided atom has no enum values for any field. */
56 #define EXPECT_NO_ENUM_FIELD(atom) \
57 do { \
58 for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
59 field != atom->fields.end(); field++) { \
60 EXPECT_TRUE(field->enumValues.empty()); \
61 } \
62 } while (0)
63
64 /** Expects that exactly one specific field has expected enum values. */
65 #define EXPECT_HAS_ENUM_FIELD(atom, field_name, values) \
66 do { \
67 for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
68 field != atom->fields.end(); field++) { \
69 if (field->name == field_name) { \
70 EXPECT_EQ(field->enumValues, values); \
71 } else { \
72 EXPECT_TRUE(field->enumValues.empty()); \
73 } \
74 } \
75 } while (0)
76
77 /**
78 * Test a correct collation, with all the types.
79 */
TEST(CollationTest,CollateStats)80 TEST(CollationTest, CollateStats) {
81 Atoms atoms;
82 int errorCount = collate_atoms(Event::descriptor(), DEFAULT_MODULE_NAME, &atoms);
83
84 EXPECT_EQ(0, errorCount);
85 EXPECT_EQ(3ul, atoms.signatureInfoMap.size());
86
87 // IntAtom, AnotherIntAtom
88 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
89
90 // OutOfOrderAtom
91 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_INT);
92
93 // AllTypesAtom
94 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap,
95 JAVA_TYPE_ATTRIBUTION_CHAIN, // AttributionChain
96 JAVA_TYPE_FLOAT, // float
97 JAVA_TYPE_LONG, // int64
98 JAVA_TYPE_LONG, // uint64
99 JAVA_TYPE_INT, // int32
100 JAVA_TYPE_LONG, // fixed64
101 JAVA_TYPE_INT, // fixed32
102 JAVA_TYPE_BOOLEAN, // bool
103 JAVA_TYPE_STRING, // string
104 JAVA_TYPE_INT, // uint32
105 JAVA_TYPE_INT, // AnEnum
106 JAVA_TYPE_INT, // sfixed32
107 JAVA_TYPE_LONG, // sfixed64
108 JAVA_TYPE_INT, // sint32
109 JAVA_TYPE_LONG // sint64
110 );
111
112 EXPECT_EQ(4ul, atoms.decls.size());
113
114 AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
115 EXPECT_EQ(1, (*atomIt)->code);
116 EXPECT_EQ("int_atom", (*atomIt)->name);
117 EXPECT_EQ("IntAtom", (*atomIt)->message);
118 EXPECT_NO_ENUM_FIELD((*atomIt));
119 atomIt++;
120
121 EXPECT_EQ(2, (*atomIt)->code);
122 EXPECT_EQ("out_of_order_atom", (*atomIt)->name);
123 EXPECT_EQ("OutOfOrderAtom", (*atomIt)->message);
124 EXPECT_NO_ENUM_FIELD((*atomIt));
125 atomIt++;
126
127 EXPECT_EQ(3, (*atomIt)->code);
128 EXPECT_EQ("another_int_atom", (*atomIt)->name);
129 EXPECT_EQ("AnotherIntAtom", (*atomIt)->message);
130 EXPECT_NO_ENUM_FIELD((*atomIt));
131 atomIt++;
132
133 EXPECT_EQ(4, (*atomIt)->code);
134 EXPECT_EQ("all_types_atom", (*atomIt)->name);
135 EXPECT_EQ("AllTypesAtom", (*atomIt)->message);
136 map<int, string> enumValues;
137 enumValues[0] = "VALUE0";
138 enumValues[1] = "VALUE1";
139 EXPECT_HAS_ENUM_FIELD((*atomIt), "enum_field", enumValues);
140 atomIt++;
141
142 EXPECT_EQ(atoms.decls.end(), atomIt);
143 }
144
145 /**
146 * Test that event class that contains stuff other than the atoms is rejected.
147 */
TEST(CollationTest,NonMessageTypeFails)148 TEST(CollationTest, NonMessageTypeFails) {
149 Atoms atoms;
150 int errorCount = collate_atoms(IntAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
151
152 EXPECT_EQ(1, errorCount);
153 }
154
155 /**
156 * Test that atoms that have non-primitive types or repeated fields are
157 * rejected.
158 */
TEST(CollationTest,FailOnBadTypes)159 TEST(CollationTest, FailOnBadTypes) {
160 Atoms atoms;
161 int errorCount = collate_atoms(BadTypesEvent::descriptor(), DEFAULT_MODULE_NAME, &atoms);
162
163 EXPECT_EQ(4, errorCount);
164 }
165
166 /**
167 * Test that atoms that skip field numbers (in the first position) are rejected.
168 */
TEST(CollationTest,FailOnSkippedFieldsSingle)169 TEST(CollationTest, FailOnSkippedFieldsSingle) {
170 Atoms atoms;
171 int errorCount =
172 collate_atoms(BadSkippedFieldSingle::descriptor(), DEFAULT_MODULE_NAME, &atoms);
173
174 EXPECT_EQ(1, errorCount);
175 }
176
177 /**
178 * Test that atoms that skip field numbers (not in the first position, and
179 * multiple times) are rejected.
180 */
TEST(CollationTest,FailOnSkippedFieldsMultiple)181 TEST(CollationTest, FailOnSkippedFieldsMultiple) {
182 Atoms atoms;
183 int errorCount =
184 collate_atoms(BadSkippedFieldMultiple::descriptor(), DEFAULT_MODULE_NAME, &atoms);
185
186 EXPECT_EQ(2, errorCount);
187 }
188
189 /**
190 * Test that atoms that have an attribution chain not in the first position are
191 * rejected.
192 */
TEST(CollationTest,FailBadAttributionNodePosition)193 TEST(CollationTest, FailBadAttributionNodePosition) {
194 Atoms atoms;
195 int errorCount =
196 collate_atoms(BadAttributionNodePosition::descriptor(), DEFAULT_MODULE_NAME, &atoms);
197
198 EXPECT_EQ(1, errorCount);
199 }
200
TEST(CollationTest,FailOnBadStateAtomOptions)201 TEST(CollationTest, FailOnBadStateAtomOptions) {
202 Atoms atoms;
203 int errorCount = collate_atoms(BadStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
204
205 EXPECT_EQ(3, errorCount);
206 }
207
TEST(CollationTest,PassOnGoodStateAtomOptions)208 TEST(CollationTest, PassOnGoodStateAtomOptions) {
209 Atoms atoms;
210 int errorCount = collate_atoms(GoodStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
211 EXPECT_EQ(0, errorCount);
212 }
213
TEST(CollationTest,PassOnGoodBinaryFieldAtom)214 TEST(CollationTest, PassOnGoodBinaryFieldAtom) {
215 Atoms atoms;
216 int errorCount =
217 collate_atoms(GoodEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
218 EXPECT_EQ(0, errorCount);
219 }
220
TEST(CollationTest,FailOnBadBinaryFieldAtom)221 TEST(CollationTest, FailOnBadBinaryFieldAtom) {
222 Atoms atoms;
223 int errorCount =
224 collate_atoms(BadEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
225 EXPECT_TRUE(errorCount > 0);
226 }
227
TEST(CollationTest,PassOnLogFromModuleAtom)228 TEST(CollationTest, PassOnLogFromModuleAtom) {
229 Atoms atoms;
230 int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
231 EXPECT_EQ(errorCount, 0);
232 EXPECT_EQ(atoms.decls.size(), 4ul);
233 }
234
TEST(CollationTest,RecognizeModuleAtom)235 TEST(CollationTest, RecognizeModuleAtom) {
236 Atoms atoms;
237 int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
238 EXPECT_EQ(errorCount, 0);
239 EXPECT_EQ(atoms.decls.size(), 4ul);
240 EXPECT_EQ(atoms.signatureInfoMap.size(), 2u);
241 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
242 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_STRING);
243
244 SignatureInfoMap::const_iterator signatureInfoMapIt;
245 const vector<java_type_t>* signature;
246 const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet;
247 FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt;
248 const AtomDeclSet* atomDeclSet;
249 AtomDeclSet::const_iterator atomDeclSetIt;
250 AtomDecl* atomDecl;
251 FieldNumberToAnnotations* fieldNumberToAnnotations;
252 FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt;
253 const AnnotationSet* annotationSet;
254 AnnotationSet::const_iterator annotationSetIt;
255 Annotation* annotation;
256
257 signatureInfoMapIt = atoms.signatureInfoMap.begin();
258 signature = &(signatureInfoMapIt->first);
259 fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
260 EXPECT_EQ(1ul, signature->size());
261 EXPECT_EQ(JAVA_TYPE_INT, signature->at(0));
262 EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size());
263 fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin();
264 EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first);
265 atomDeclSet = &fieldNumberToAtomDeclSetIt->second;
266 EXPECT_EQ(2ul, atomDeclSet->size());
267 atomDeclSetIt = atomDeclSet->begin();
268 atomDecl = atomDeclSetIt->get();
269 EXPECT_EQ(1, atomDecl->code);
270 fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
271 fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
272 EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
273 annotationSet = &fieldNumberToAnnotationsIt->second;
274 EXPECT_EQ(1ul, annotationSet->size());
275 annotationSetIt = annotationSet->begin();
276 annotation = annotationSetIt->get();
277 EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
278 EXPECT_EQ(1, annotation->atomId);
279 EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
280 EXPECT_TRUE(annotation->value.boolValue);
281
282 atomDeclSetIt++;
283 atomDecl = atomDeclSetIt->get();
284 EXPECT_EQ(3, atomDecl->code);
285 fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
286 fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
287 EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
288 annotationSet = &fieldNumberToAnnotationsIt->second;
289 EXPECT_EQ(1ul, annotationSet->size());
290 annotationSetIt = annotationSet->begin();
291 annotation = annotationSetIt->get();
292 EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId);
293 EXPECT_EQ(3, annotation->atomId);
294 EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
295 EXPECT_TRUE(annotation->value.boolValue);
296
297 signatureInfoMapIt++;
298 signature = &signatureInfoMapIt->first;
299 fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
300 EXPECT_EQ(1ul, signature->size());
301 EXPECT_EQ(JAVA_TYPE_STRING, signature->at(0));
302 EXPECT_EQ(0ul, fieldNumberToAtomDeclSet->size());
303 }
304
TEST(CollationTest,RecognizeModule1Atom)305 TEST(CollationTest, RecognizeModule1Atom) {
306 Atoms atoms;
307 const string moduleName = "module1";
308 int errorCount = collate_atoms(ModuleAtoms::descriptor(), moduleName, &atoms);
309 EXPECT_EQ(errorCount, 0);
310 EXPECT_EQ(atoms.decls.size(), 2ul);
311 EXPECT_EQ(atoms.signatureInfoMap.size(), 1u);
312 EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
313
314 SignatureInfoMap::const_iterator signatureInfoMapIt;
315 const vector<java_type_t>* signature;
316 const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet;
317 FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt;
318 const AtomDeclSet* atomDeclSet;
319 AtomDeclSet::const_iterator atomDeclSetIt;
320 AtomDecl* atomDecl;
321 FieldNumberToAnnotations* fieldNumberToAnnotations;
322 FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt;
323 const AnnotationSet* annotationSet;
324 AnnotationSet::const_iterator annotationSetIt;
325 Annotation* annotation;
326
327 signatureInfoMapIt = atoms.signatureInfoMap.begin();
328 signature = &(signatureInfoMapIt->first);
329 fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
330 EXPECT_EQ(1ul, signature->size());
331 EXPECT_EQ(JAVA_TYPE_INT, signature->at(0));
332 EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size());
333 fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin();
334 EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first);
335 atomDeclSet = &fieldNumberToAtomDeclSetIt->second;
336 EXPECT_EQ(2ul, atomDeclSet->size());
337 atomDeclSetIt = atomDeclSet->begin();
338 atomDecl = atomDeclSetIt->get();
339 EXPECT_EQ(1, atomDecl->code);
340 fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
341 fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
342 EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
343 annotationSet = &fieldNumberToAnnotationsIt->second;
344 EXPECT_EQ(1ul, annotationSet->size());
345 annotationSetIt = annotationSet->begin();
346 annotation = annotationSetIt->get();
347 EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
348 EXPECT_EQ(1, annotation->atomId);
349 EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
350 EXPECT_TRUE(annotation->value.boolValue);
351
352 atomDeclSetIt++;
353 atomDecl = atomDeclSetIt->get();
354 EXPECT_EQ(3, atomDecl->code);
355 fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
356 fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
357 EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
358 annotationSet = &fieldNumberToAnnotationsIt->second;
359 EXPECT_EQ(1ul, annotationSet->size());
360 annotationSetIt = annotationSet->begin();
361 annotation = annotationSetIt->get();
362 EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId);
363 EXPECT_EQ(3, annotation->atomId);
364 EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
365 EXPECT_TRUE(annotation->value.boolValue);
366 }
367
368 } // namespace stats_log_api_gen
369 } // namespace android
370