• 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(4ul, 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_BOOLEAN,            // bool
100                                   JAVA_TYPE_STRING,             // string
101                                   JAVA_TYPE_INT,                // uint32
102                                   JAVA_TYPE_INT,                // AnEnum
103                                   JAVA_TYPE_FLOAT_ARRAY,        // repeated float
104                                   JAVA_TYPE_LONG_ARRAY,         // repeated int64
105                                   JAVA_TYPE_INT_ARRAY,          // repeated int32
106                                   JAVA_TYPE_BOOLEAN_ARRAY,      // repeated bool
107                                   JAVA_TYPE_STRING_ARRAY        // repeated string
108     );
109 
110     // RepeatedEnumAtom
111     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT_ARRAY);
112 
113     EXPECT_EQ(5ul, atoms.decls.size());
114 
115     AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
116     EXPECT_EQ(1, (*atomIt)->code);
117     EXPECT_EQ("int_atom", (*atomIt)->name);
118     EXPECT_EQ("IntAtom", (*atomIt)->message);
119     EXPECT_NO_ENUM_FIELD((*atomIt));
120     atomIt++;
121 
122     EXPECT_EQ(2, (*atomIt)->code);
123     EXPECT_EQ("out_of_order_atom", (*atomIt)->name);
124     EXPECT_EQ("OutOfOrderAtom", (*atomIt)->message);
125     EXPECT_NO_ENUM_FIELD((*atomIt));
126     atomIt++;
127 
128     EXPECT_EQ(3, (*atomIt)->code);
129     EXPECT_EQ("another_int_atom", (*atomIt)->name);
130     EXPECT_EQ("AnotherIntAtom", (*atomIt)->message);
131     EXPECT_NO_ENUM_FIELD((*atomIt));
132     atomIt++;
133 
134     EXPECT_EQ(4, (*atomIt)->code);
135     EXPECT_EQ("all_types_atom", (*atomIt)->name);
136     EXPECT_EQ("AllTypesAtom", (*atomIt)->message);
137     map<int, string> enumValues;
138     enumValues[0] = "VALUE0";
139     enumValues[1] = "VALUE1";
140     EXPECT_HAS_ENUM_FIELD((*atomIt), "enum_field", enumValues);
141     atomIt++;
142 
143     EXPECT_EQ(5, (*atomIt)->code);
144     EXPECT_EQ("repeated_enum_atom", (*atomIt)->name);
145     EXPECT_EQ("RepeatedEnumAtom", (*atomIt)->message);
146     enumValues[0] = "VALUE0";
147     enumValues[1] = "VALUE1";
148     EXPECT_HAS_ENUM_FIELD((*atomIt), "repeated_enum_field", enumValues);
149     atomIt++;
150 
151     EXPECT_EQ(atoms.decls.end(), atomIt);
152 }
153 
154 /**
155  * Test that event class that contains stuff other than the atoms is rejected.
156  */
TEST(CollationTest,NonMessageTypeFails)157 TEST(CollationTest, NonMessageTypeFails) {
158     Atoms atoms;
159     int errorCount = collate_atoms(IntAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
160 
161     EXPECT_EQ(1, errorCount);
162 }
163 
164 /**
165  * Test that atoms that have unsupported field types are rejected.
166  */
TEST(CollationTest,FailOnBadTypes)167 TEST(CollationTest, FailOnBadTypes) {
168     Atoms atoms;
169     int errorCount = collate_atoms(BadTypesEvent::descriptor(), DEFAULT_MODULE_NAME, &atoms);
170 
171     EXPECT_EQ(20, errorCount);
172 }
173 
174 /**
175  * Test that atoms that skip field numbers (in the first position) are rejected.
176  */
TEST(CollationTest,FailOnSkippedFieldsSingle)177 TEST(CollationTest, FailOnSkippedFieldsSingle) {
178     Atoms atoms;
179     int errorCount =
180             collate_atoms(BadSkippedFieldSingle::descriptor(), DEFAULT_MODULE_NAME, &atoms);
181 
182     EXPECT_EQ(1, errorCount);
183 }
184 
185 /**
186  * Test that atoms that skip field numbers (not in the first position, and
187  * multiple times) are rejected.
188  */
TEST(CollationTest,FailOnSkippedFieldsMultiple)189 TEST(CollationTest, FailOnSkippedFieldsMultiple) {
190     Atoms atoms;
191     int errorCount =
192             collate_atoms(BadSkippedFieldMultiple::descriptor(), DEFAULT_MODULE_NAME, &atoms);
193 
194     EXPECT_EQ(2, errorCount);
195 }
196 
197 /**
198  * Test that atoms that have an attribution chain not in the first position are
199  * rejected.
200  */
TEST(CollationTest,FailBadAttributionNodePosition)201 TEST(CollationTest, FailBadAttributionNodePosition) {
202     Atoms atoms;
203     int errorCount =
204             collate_atoms(BadAttributionNodePosition::descriptor(), DEFAULT_MODULE_NAME, &atoms);
205 
206     EXPECT_EQ(1, errorCount);
207 }
208 
TEST(CollationTest,FailOnBadStateAtomOptions)209 TEST(CollationTest, FailOnBadStateAtomOptions) {
210     Atoms atoms;
211     int errorCount = collate_atoms(BadStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
212 
213     EXPECT_EQ(4, errorCount);
214 }
215 
TEST(CollationTest,PassOnGoodStateAtomOptions)216 TEST(CollationTest, PassOnGoodStateAtomOptions) {
217     Atoms atoms;
218     int errorCount = collate_atoms(GoodStateAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
219     EXPECT_EQ(0, errorCount);
220 }
221 
TEST(CollationTest,FailOnBadUidAtomOptions)222 TEST(CollationTest, FailOnBadUidAtomOptions) {
223     Atoms atoms;
224     int errorCount = collate_atoms(BadUidAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
225 
226     EXPECT_EQ(2, errorCount);
227 }
228 
TEST(CollationTest,PassOnGoodUidAtomOptions)229 TEST(CollationTest, PassOnGoodUidAtomOptions) {
230     Atoms atoms;
231     int errorCount = collate_atoms(GoodUidAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
232     EXPECT_EQ(0, errorCount);
233 }
234 
TEST(CollationTest,PassOnGoodBinaryFieldAtom)235 TEST(CollationTest, PassOnGoodBinaryFieldAtom) {
236     Atoms atoms;
237     int errorCount =
238             collate_atoms(GoodEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
239     EXPECT_EQ(0, errorCount);
240 }
241 
TEST(CollationTest,FailOnBadBinaryFieldAtom)242 TEST(CollationTest, FailOnBadBinaryFieldAtom) {
243     Atoms atoms;
244     int errorCount =
245             collate_atoms(BadEventWithBinaryFieldAtom::descriptor(), DEFAULT_MODULE_NAME, &atoms);
246     EXPECT_GT(errorCount, 0);
247 }
248 
TEST(CollationTest,PassOnLogFromModuleAtom)249 TEST(CollationTest, PassOnLogFromModuleAtom) {
250     Atoms atoms;
251     int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
252     EXPECT_EQ(errorCount, 0);
253     EXPECT_EQ(atoms.decls.size(), 4ul);
254 }
255 
TEST(CollationTest,RecognizeModuleAtom)256 TEST(CollationTest, RecognizeModuleAtom) {
257     Atoms atoms;
258     int errorCount = collate_atoms(ModuleAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
259     EXPECT_EQ(errorCount, 0);
260     EXPECT_EQ(atoms.decls.size(), 4ul);
261     EXPECT_EQ(atoms.signatureInfoMap.size(), 2u);
262     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
263     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_STRING);
264 
265     SignatureInfoMap::const_iterator signatureInfoMapIt;
266     const vector<java_type_t>* signature;
267     const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet;
268     FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt;
269     const AtomDeclSet* atomDeclSet;
270     AtomDeclSet::const_iterator atomDeclSetIt;
271     AtomDecl* atomDecl;
272     FieldNumberToAnnotations* fieldNumberToAnnotations;
273     FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt;
274     const AnnotationSet* annotationSet;
275     AnnotationSet::const_iterator annotationSetIt;
276     Annotation* annotation;
277 
278     signatureInfoMapIt = atoms.signatureInfoMap.begin();
279     signature = &(signatureInfoMapIt->first);
280     fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
281     EXPECT_EQ(1ul, signature->size());
282     EXPECT_EQ(JAVA_TYPE_INT, signature->at(0));
283     EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size());
284     fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin();
285     EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first);
286     atomDeclSet = &fieldNumberToAtomDeclSetIt->second;
287     EXPECT_EQ(2ul, atomDeclSet->size());
288     atomDeclSetIt = atomDeclSet->begin();
289     atomDecl = atomDeclSetIt->get();
290     EXPECT_EQ(1, atomDecl->code);
291     fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
292     fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
293     EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
294     annotationSet = &fieldNumberToAnnotationsIt->second;
295     EXPECT_EQ(1ul, annotationSet->size());
296     annotationSetIt = annotationSet->begin();
297     annotation = annotationSetIt->get();
298     EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
299     EXPECT_EQ(1, annotation->atomId);
300     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
301     EXPECT_TRUE(annotation->value.boolValue);
302 
303     atomDeclSetIt++;
304     atomDecl = atomDeclSetIt->get();
305     EXPECT_EQ(3, atomDecl->code);
306     fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
307     fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
308     EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
309     annotationSet = &fieldNumberToAnnotationsIt->second;
310     EXPECT_EQ(1ul, annotationSet->size());
311     annotationSetIt = annotationSet->begin();
312     annotation = annotationSetIt->get();
313     EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId);
314     EXPECT_EQ(3, annotation->atomId);
315     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
316     EXPECT_TRUE(annotation->value.boolValue);
317 
318     signatureInfoMapIt++;
319     signature = &signatureInfoMapIt->first;
320     fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
321     EXPECT_EQ(1ul, signature->size());
322     EXPECT_EQ(JAVA_TYPE_STRING, signature->at(0));
323     EXPECT_EQ(0ul, fieldNumberToAtomDeclSet->size());
324 }
325 
TEST(CollationTest,RecognizeModule1Atom)326 TEST(CollationTest, RecognizeModule1Atom) {
327     Atoms atoms;
328     const string moduleName = "module1";
329     int errorCount = collate_atoms(ModuleAtoms::descriptor(), moduleName, &atoms);
330     EXPECT_EQ(errorCount, 0);
331     EXPECT_EQ(atoms.decls.size(), 2ul);
332     EXPECT_EQ(atoms.signatureInfoMap.size(), 1u);
333     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
334 
335     SignatureInfoMap::const_iterator signatureInfoMapIt;
336     const vector<java_type_t>* signature;
337     const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet;
338     FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt;
339     const AtomDeclSet* atomDeclSet;
340     AtomDeclSet::const_iterator atomDeclSetIt;
341     AtomDecl* atomDecl;
342     FieldNumberToAnnotations* fieldNumberToAnnotations;
343     FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt;
344     const AnnotationSet* annotationSet;
345     AnnotationSet::const_iterator annotationSetIt;
346     Annotation* annotation;
347 
348     signatureInfoMapIt = atoms.signatureInfoMap.begin();
349     signature = &(signatureInfoMapIt->first);
350     fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
351     EXPECT_EQ(1ul, signature->size());
352     EXPECT_EQ(JAVA_TYPE_INT, signature->at(0));
353     EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size());
354     fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin();
355     EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first);
356     atomDeclSet = &fieldNumberToAtomDeclSetIt->second;
357     EXPECT_EQ(2ul, atomDeclSet->size());
358     atomDeclSetIt = atomDeclSet->begin();
359     atomDecl = atomDeclSetIt->get();
360     EXPECT_EQ(1, atomDecl->code);
361     fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
362     fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
363     EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
364     annotationSet = &fieldNumberToAnnotationsIt->second;
365     EXPECT_EQ(1ul, annotationSet->size());
366     annotationSetIt = annotationSet->begin();
367     annotation = annotationSetIt->get();
368     EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
369     EXPECT_EQ(1, annotation->atomId);
370     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
371     EXPECT_TRUE(annotation->value.boolValue);
372 
373     atomDeclSetIt++;
374     atomDecl = atomDeclSetIt->get();
375     EXPECT_EQ(3, atomDecl->code);
376     fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
377     fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
378     EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
379     annotationSet = &fieldNumberToAnnotationsIt->second;
380     EXPECT_EQ(1ul, annotationSet->size());
381     annotationSetIt = annotationSet->begin();
382     annotation = annotationSetIt->get();
383     EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId);
384     EXPECT_EQ(3, annotation->atomId);
385     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
386     EXPECT_TRUE(annotation->value.boolValue);
387 }
388 
389 /**
390  * Test a correct collation with pushed and pulled atoms.
391  */
TEST(CollationTest,CollatePushedAndPulledAtoms)392 TEST(CollationTest, CollatePushedAndPulledAtoms) {
393     Atoms atoms;
394     int errorCount = collate_atoms(PushedAndPulledAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
395 
396     EXPECT_EQ(0, errorCount);
397     EXPECT_EQ(1ul, atoms.signatureInfoMap.size());
398     EXPECT_EQ(2ul, atoms.pulledAtomsSignatureInfoMap.size());
399 
400     // IntAtom
401     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
402 
403     // AnotherIntAtom
404     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_INT);
405 
406     // OutOfOrderAtom
407     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_INT);
408 
409     EXPECT_EQ(3ul, atoms.decls.size());
410 
411     AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
412     EXPECT_EQ(1, (*atomIt)->code);
413     EXPECT_EQ("int_atom_1", (*atomIt)->name);
414     EXPECT_EQ("IntAtom", (*atomIt)->message);
415     EXPECT_NO_ENUM_FIELD((*atomIt));
416     atomIt++;
417 
418     EXPECT_EQ(10000, (*atomIt)->code);
419     EXPECT_EQ("another_int_atom", (*atomIt)->name);
420     EXPECT_EQ("AnotherIntAtom", (*atomIt)->message);
421     EXPECT_NO_ENUM_FIELD((*atomIt));
422     atomIt++;
423 
424     EXPECT_EQ(99999, (*atomIt)->code);
425     EXPECT_EQ("out_of_order_atom", (*atomIt)->name);
426     EXPECT_EQ("OutOfOrderAtom", (*atomIt)->message);
427     EXPECT_NO_ENUM_FIELD((*atomIt));
428     atomIt++;
429 
430     EXPECT_EQ(atoms.decls.end(), atomIt);
431 }
432 
TEST(CollationTest,CollateVendorAtoms)433 TEST(CollationTest, CollateVendorAtoms) {
434     Atoms atoms;
435     int errorCount = collate_atoms(VendorAtoms::descriptor(), DEFAULT_MODULE_NAME, &atoms);
436 
437     EXPECT_EQ(0, errorCount);
438     EXPECT_EQ(1ul, atoms.signatureInfoMap.size());
439     EXPECT_EQ(1ul, atoms.pulledAtomsSignatureInfoMap.size());
440 
441     // IntAtom
442     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
443 
444     // AnotherIntAtom
445     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_INT);
446 
447     EXPECT_EQ(2ul, atoms.decls.size());
448 
449     AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
450     EXPECT_EQ(100000, (*atomIt)->code);
451     EXPECT_EQ("pushed_atom_100000", (*atomIt)->name);
452     EXPECT_EQ("IntAtom", (*atomIt)->message);
453     EXPECT_NO_ENUM_FIELD((*atomIt));
454     atomIt++;
455 
456     EXPECT_EQ(199999, (*atomIt)->code);
457     EXPECT_EQ("pulled_atom_199999", (*atomIt)->name);
458     EXPECT_EQ("AnotherIntAtom", (*atomIt)->message);
459     EXPECT_NO_ENUM_FIELD((*atomIt));
460     atomIt++;
461 
462     EXPECT_EQ(atoms.decls.end(), atomIt);
463 }
464 
TEST(CollationTest,CollateExtensionAtoms)465 TEST(CollationTest, CollateExtensionAtoms) {
466     Atoms atoms;
467     int errorCount = collate_atoms(ExtensionAtoms::descriptor(), "test_feature", &atoms);
468 
469     EXPECT_EQ(0, errorCount);
470     EXPECT_EQ(1ul, atoms.signatureInfoMap.size());
471     EXPECT_EQ(1ul, atoms.pulledAtomsSignatureInfoMap.size());
472 
473     // ExtensionAtomPushed
474     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_LONG);
475 
476     // ExtensionAtomPulled
477     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_LONG);
478 
479     EXPECT_EQ(2ul, atoms.decls.size());
480 
481     AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
482     EXPECT_EQ(9999, (*atomIt)->code);
483     EXPECT_EQ("extension_atom_pushed", (*atomIt)->name);
484     EXPECT_EQ("ExtensionAtomPushed", (*atomIt)->message);
485     EXPECT_NO_ENUM_FIELD((*atomIt));
486     FieldNumberToAnnotations* fieldNumberToAnnotations = &(*atomIt)->fieldNumberToAnnotations;
487     FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt =
488         fieldNumberToAnnotations->find(1);
489     EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
490     const AnnotationSet* annotationSet = &fieldNumberToAnnotationsIt->second;
491     EXPECT_EQ(1ul, annotationSet->size());
492     Annotation* annotation = annotationSet->begin()->get();
493     EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
494     EXPECT_EQ(9999, annotation->atomId);
495     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
496     EXPECT_TRUE(annotation->value.boolValue);
497     atomIt++;
498 
499     EXPECT_EQ(99999, (*atomIt)->code);
500     EXPECT_EQ("extension_atom_pulled", (*atomIt)->name);
501     EXPECT_EQ("ExtensionAtomPulled", (*atomIt)->message);
502     EXPECT_NO_ENUM_FIELD((*atomIt));
503     atomIt++;
504 
505     EXPECT_EQ(atoms.decls.end(), atomIt);
506 }
507 
508 }  // namespace stats_log_api_gen
509 }  // namespace android
510