• 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/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