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