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 <google/protobuf/compiler/importer.h>
18 #include <gtest/gtest.h>
19 #include <stdio.h>
20 
21 #include <filesystem>
22 
23 #include "Collation.h"
24 #include "frameworks/proto_logging/stats/stats_log_api_gen/test.pb.h"
25 
26 namespace android {
27 namespace stats_log_api_gen {
28 
29 using std::map;
30 using std::vector;
31 
32 namespace fs = std::filesystem;
33 
34 /**
35  * Return whether the map contains a vector of the elements provided.
36  */
map_contains_vector(const SignatureInfoMap & s,int count,...)37 static bool map_contains_vector(const SignatureInfoMap& s, int count, ...) {
38     va_list args;
39     vector<java_type_t> v(count);
40 
41     va_start(args, count);
42     for (int i = 0; i < count; i++) {
43         v[i] = static_cast<java_type_t>(va_arg(args, int));
44     }
45     va_end(args);
46 
47     return s.find(v) != s.end();
48 }
49 
50 /**
51  * Expect that the provided map contains the elements provided.
52  */
53 #define EXPECT_MAP_CONTAINS_SIGNATURE(s, ...)                    \
54     do {                                                         \
55         int count = sizeof((int[]){__VA_ARGS__}) / sizeof(int);  \
56         EXPECT_TRUE(map_contains_vector(s, count, __VA_ARGS__)); \
57     } while (0)
58 
59 /** Expects that the provided atom has no enum values for any field. */
60 #define EXPECT_NO_ENUM_FIELD(atom)                                           \
61     do {                                                                     \
62         for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
63              field != atom->fields.end(); field++) {                         \
64             EXPECT_TRUE(field->enumValues.empty());                          \
65         }                                                                    \
66     } while (0)
67 
68 /** Expects that exactly one specific field has expected enum values. */
69 #define EXPECT_HAS_ENUM_FIELD(atom, field_name, values)                      \
70     do {                                                                     \
71         for (vector<AtomField>::const_iterator field = atom->fields.begin(); \
72              field != atom->fields.end(); field++) {                         \
73             if (field->name == field_name) {                                 \
74                 EXPECT_EQ(field->enumValues, values);                        \
75             } else {                                                         \
76                 EXPECT_TRUE(field->enumValues.empty());                      \
77             }                                                                \
78         }                                                                    \
79     } while (0)
80 
81 // Setup for test fixture.
82 class CollationTest : public testing::TestWithParam<bool> {
83     class MFErrorCollector : public google::protobuf::compiler::MultiFileErrorCollector {
84     public:
AddError(const std::string & filename,int line,int column,const std::string & message)85         void AddError(const std::string& filename, int line, int column,
86                       const std::string& message) override {
87             fprintf(stdout, "[Error] %s:%d:%d - %s", filename.c_str(), line, column,
88                     message.c_str());
89         }
90     };
91 
92 public:
CollationTest()93     CollationTest() : mImporter(&mSourceTree, &mErrorCollector) {
94         mSourceTree.MapPath("", fs::current_path().c_str());
95         mFileDescriptor = mImporter.Import("test_external.proto");
96     }
97 
98 protected:
SetUp()99     void SetUp() override {
100         if (GetParam()) {
101             mEvent = Event::descriptor();
102             mIntAtom = IntAtom::descriptor();
103             mBadTypesEvent = BadTypesEvent::descriptor();
104             mBadSkippedFieldSingle = BadSkippedFieldSingle::descriptor();
105             mBadSkippedFieldMultiple = BadSkippedFieldMultiple::descriptor();
106             mBadAttributionNodePosition = BadAttributionNodePosition::descriptor();
107             mBadStateAtoms = BadStateAtoms::descriptor();
108             mGoodStateAtoms = GoodStateAtoms::descriptor();
109             mBadUidAtoms = BadUidAtoms::descriptor();
110             mGoodUidAtoms = GoodUidAtoms::descriptor();
111             mGoodEventWithBinaryFieldAtom = GoodEventWithBinaryFieldAtom::descriptor();
112             mBadEventWithBinaryFieldAtom = BadEventWithBinaryFieldAtom::descriptor();
113             mModuleAtoms = ModuleAtoms::descriptor();
114 
115             mPushedAndPulledAtoms = PushedAndPulledAtoms::descriptor();
116             mVendorAtoms = VendorAtoms::descriptor();
117             mGoodRestrictedAtoms = GoodRestrictedAtoms::descriptor();
118             mBadRestrictedAtoms1 = BadRestrictedAtoms1::descriptor();
119             mBadRestrictedAtoms2 = BadRestrictedAtoms2::descriptor();
120             mBadRestrictedAtoms3 = BadRestrictedAtoms3::descriptor();
121             mBadRestrictedAtoms4 = BadRestrictedAtoms4::descriptor();
122             mBadRestrictedAtoms5 = BadRestrictedAtoms5::descriptor();
123             mGoodUintAtoms = GoodUintAtoms::descriptor();
124         } else {
125             mEvent = mFileDescriptor->FindMessageTypeByName("Event");
126             mIntAtom = mFileDescriptor->FindMessageTypeByName("IntAtom");
127             mBadTypesEvent = mFileDescriptor->FindMessageTypeByName("BadTypesEvent");
128             mBadSkippedFieldSingle =
129                     mFileDescriptor->FindMessageTypeByName("BadSkippedFieldSingle");
130             mBadSkippedFieldMultiple =
131                     mFileDescriptor->FindMessageTypeByName("BadSkippedFieldMultiple");
132             mBadAttributionNodePosition =
133                     mFileDescriptor->FindMessageTypeByName("BadAttributionNodePosition");
134             mBadStateAtoms = mFileDescriptor->FindMessageTypeByName("BadStateAtoms");
135             mGoodStateAtoms = mFileDescriptor->FindMessageTypeByName("GoodStateAtoms");
136             mBadUidAtoms = mFileDescriptor->FindMessageTypeByName("BadUidAtoms");
137             mGoodUidAtoms = mFileDescriptor->FindMessageTypeByName("GoodUidAtoms");
138             mGoodEventWithBinaryFieldAtom =
139                     mFileDescriptor->FindMessageTypeByName("GoodEventWithBinaryFieldAtom");
140             mBadEventWithBinaryFieldAtom =
141                     mFileDescriptor->FindMessageTypeByName("BadEventWithBinaryFieldAtom");
142             mModuleAtoms = mFileDescriptor->FindMessageTypeByName("ModuleAtoms");
143             mPushedAndPulledAtoms = mFileDescriptor->FindMessageTypeByName("PushedAndPulledAtoms");
144             mVendorAtoms = mFileDescriptor->FindMessageTypeByName("VendorAtoms");
145             mGoodRestrictedAtoms = mFileDescriptor->FindMessageTypeByName("GoodRestrictedAtoms");
146             mBadRestrictedAtoms1 = mFileDescriptor->FindMessageTypeByName("BadRestrictedAtoms1");
147             mBadRestrictedAtoms2 = mFileDescriptor->FindMessageTypeByName("BadRestrictedAtoms2");
148             mBadRestrictedAtoms3 = mFileDescriptor->FindMessageTypeByName("BadRestrictedAtoms3");
149             mBadRestrictedAtoms4 = mFileDescriptor->FindMessageTypeByName("BadRestrictedAtoms4");
150             mBadRestrictedAtoms5 = mFileDescriptor->FindMessageTypeByName("BadRestrictedAtoms5");
151             mGoodUintAtoms = mFileDescriptor->FindMessageTypeByName("GoodUintAtoms");
152         }
153     }
154 
155     MFErrorCollector mErrorCollector;
156     google::protobuf::compiler::DiskSourceTree mSourceTree;
157     google::protobuf::compiler::Importer mImporter;
158     const google::protobuf::FileDescriptor* mFileDescriptor;
159 
160     const Descriptor* mEvent;
161     const Descriptor* mIntAtom;
162     const Descriptor* mBadTypesEvent;
163     const Descriptor* mBadSkippedFieldSingle;
164     const Descriptor* mBadSkippedFieldMultiple;
165     const Descriptor* mBadAttributionNodePosition;
166     const Descriptor* mBadStateAtoms;
167     const Descriptor* mGoodStateAtoms;
168     const Descriptor* mBadUidAtoms;
169     const Descriptor* mGoodUidAtoms;
170     const Descriptor* mGoodEventWithBinaryFieldAtom;
171     const Descriptor* mBadEventWithBinaryFieldAtom;
172     const Descriptor* mModuleAtoms;
173     const Descriptor* mPushedAndPulledAtoms;
174     const Descriptor* mVendorAtoms;
175     const Descriptor* mGoodRestrictedAtoms;
176     const Descriptor* mBadRestrictedAtoms1;
177     const Descriptor* mBadRestrictedAtoms2;
178     const Descriptor* mBadRestrictedAtoms3;
179     const Descriptor* mBadRestrictedAtoms4;
180     const Descriptor* mBadRestrictedAtoms5;
181     const Descriptor* mGoodUintAtoms;
182 };
183 
184 INSTANTIATE_TEST_SUITE_P(ProtoProvider, CollationTest, testing::Values(true, false));
185 
186 /**
187  * Test a correct collation, with all the types.
188  */
TEST_P(CollationTest,CollateStats)189 TEST_P(CollationTest, CollateStats) {
190     Atoms atoms;
191     const int errorCount = collate_atoms(*mEvent, DEFAULT_MODULE_NAME, atoms);
192 
193     EXPECT_EQ(0, errorCount);
194     EXPECT_EQ(4ul, atoms.signatureInfoMap.size());
195 
196     // IntAtom, AnotherIntAtom
197     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
198 
199     // OutOfOrderAtom
200     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_INT);
201 
202     // AllTypesAtom
203     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap,
204                                   JAVA_TYPE_ATTRIBUTION_CHAIN,  // AttributionChain
205                                   JAVA_TYPE_FLOAT,              // float
206                                   JAVA_TYPE_LONG,               // int64
207                                   JAVA_TYPE_INT,                // int32
208                                   JAVA_TYPE_BOOLEAN,            // bool
209                                   JAVA_TYPE_STRING,             // string
210                                   JAVA_TYPE_INT,                // AnEnum
211                                   JAVA_TYPE_FLOAT_ARRAY,        // repeated float
212                                   JAVA_TYPE_LONG_ARRAY,         // repeated int64
213                                   JAVA_TYPE_INT_ARRAY,          // repeated int32
214                                   JAVA_TYPE_BOOLEAN_ARRAY,      // repeated bool
215                                   JAVA_TYPE_STRING_ARRAY,       // repeated string
216                                   JAVA_TYPE_BYTE_ARRAY          // SubMessageWithUint (mode bytes)
217     );
218 
219     // RepeatedEnumAtom
220     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT_ARRAY);
221 
222     EXPECT_EQ(5ul, atoms.decls.size());
223 
224     AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
225     EXPECT_EQ(1, (*atomIt)->code);
226     EXPECT_EQ("int_atom", (*atomIt)->name);
227     EXPECT_EQ("IntAtom", (*atomIt)->message);
228     EXPECT_NO_ENUM_FIELD((*atomIt));
229     atomIt++;
230 
231     EXPECT_EQ(2, (*atomIt)->code);
232     EXPECT_EQ("out_of_order_atom", (*atomIt)->name);
233     EXPECT_EQ("OutOfOrderAtom", (*atomIt)->message);
234     EXPECT_NO_ENUM_FIELD((*atomIt));
235     atomIt++;
236 
237     EXPECT_EQ(3, (*atomIt)->code);
238     EXPECT_EQ("another_int_atom", (*atomIt)->name);
239     EXPECT_EQ("AnotherIntAtom", (*atomIt)->message);
240     EXPECT_NO_ENUM_FIELD((*atomIt));
241     atomIt++;
242 
243     EXPECT_EQ(4, (*atomIt)->code);
244     EXPECT_EQ("all_types_atom", (*atomIt)->name);
245     EXPECT_EQ("AllTypesAtom", (*atomIt)->message);
246     map<int, string> enumValues;
247     enumValues[0] = "VALUE0";
248     enumValues[1] = "VALUE1";
249     EXPECT_HAS_ENUM_FIELD((*atomIt), "enum_field", enumValues);
250     atomIt++;
251 
252     EXPECT_EQ(5, (*atomIt)->code);
253     EXPECT_EQ("repeated_enum_atom", (*atomIt)->name);
254     EXPECT_EQ("RepeatedEnumAtom", (*atomIt)->message);
255     enumValues[0] = "VALUE0";
256     enumValues[1] = "VALUE1";
257     EXPECT_HAS_ENUM_FIELD((*atomIt), "repeated_enum_field", enumValues);
258     atomIt++;
259 
260     EXPECT_EQ(atoms.decls.end(), atomIt);
261 }
262 
263 /**
264  * Test that event class that contains stuff other than the atoms is rejected.
265  */
TEST_P(CollationTest,NonMessageTypeFails)266 TEST_P(CollationTest, NonMessageTypeFails) {
267     Atoms atoms;
268     const int errorCount = collate_atoms(*mIntAtom, DEFAULT_MODULE_NAME, atoms);
269 
270     EXPECT_EQ(1, errorCount);
271 }
272 
273 /**
274  * Test that atoms that have unsupported field types are rejected.
275  */
TEST_P(CollationTest,FailOnBadTypes)276 TEST_P(CollationTest, FailOnBadTypes) {
277     Atoms atoms;
278     const int errorCount = collate_atoms(*mBadTypesEvent, DEFAULT_MODULE_NAME, atoms);
279 
280     EXPECT_EQ(22, errorCount);
281 }
282 
283 /**
284  * Test that atoms that skip field numbers (in the first position) are rejected.
285  */
TEST_P(CollationTest,FailOnSkippedFieldsSingle)286 TEST_P(CollationTest, FailOnSkippedFieldsSingle) {
287     Atoms atoms;
288     const int errorCount = collate_atoms(*mBadSkippedFieldSingle, DEFAULT_MODULE_NAME, atoms);
289 
290     EXPECT_EQ(1, errorCount);
291 }
292 
293 /**
294  * Test that atoms that skip field numbers (not in the first position, and
295  * multiple times) are rejected.
296  */
TEST_P(CollationTest,FailOnSkippedFieldsMultiple)297 TEST_P(CollationTest, FailOnSkippedFieldsMultiple) {
298     Atoms atoms;
299     const int errorCount = collate_atoms(*mBadSkippedFieldMultiple, DEFAULT_MODULE_NAME, atoms);
300 
301     EXPECT_EQ(2, errorCount);
302 }
303 
304 /**
305  * Test that atoms that have an attribution chain not in the first position are
306  * rejected.
307  */
TEST_P(CollationTest,FailBadAttributionNodePosition)308 TEST_P(CollationTest, FailBadAttributionNodePosition) {
309     Atoms atoms;
310     const int errorCount = collate_atoms(*mBadAttributionNodePosition, DEFAULT_MODULE_NAME, atoms);
311 
312     EXPECT_EQ(1, errorCount);
313 }
314 
TEST_P(CollationTest,FailOnBadStateAtomOptions)315 TEST_P(CollationTest, FailOnBadStateAtomOptions) {
316     Atoms atoms;
317     const int errorCount = collate_atoms(*mBadStateAtoms, DEFAULT_MODULE_NAME, atoms);
318 
319     EXPECT_EQ(4, errorCount);
320 }
321 
TEST_P(CollationTest,PassOnGoodStateAtomOptions)322 TEST_P(CollationTest, PassOnGoodStateAtomOptions) {
323     Atoms atoms;
324     const int errorCount = collate_atoms(*mGoodStateAtoms, DEFAULT_MODULE_NAME, atoms);
325     EXPECT_EQ(0, errorCount);
326 }
327 
TEST_P(CollationTest,FailOnBadUidAtomOptions)328 TEST_P(CollationTest, FailOnBadUidAtomOptions) {
329     Atoms atoms;
330     const int errorCount = collate_atoms(*mBadUidAtoms, DEFAULT_MODULE_NAME, atoms);
331 
332     EXPECT_EQ(2, errorCount);
333 }
334 
TEST_P(CollationTest,PassOnGoodUidAtomOptions)335 TEST_P(CollationTest, PassOnGoodUidAtomOptions) {
336     Atoms atoms;
337     const int errorCount = collate_atoms(*mGoodUidAtoms, DEFAULT_MODULE_NAME, atoms);
338     EXPECT_EQ(0, errorCount);
339 }
340 
TEST_P(CollationTest,PassOnGoodBinaryFieldAtom)341 TEST_P(CollationTest, PassOnGoodBinaryFieldAtom) {
342     Atoms atoms;
343     const int errorCount =
344             collate_atoms(*mGoodEventWithBinaryFieldAtom, DEFAULT_MODULE_NAME, atoms);
345     EXPECT_EQ(0, errorCount);
346 }
347 
TEST_P(CollationTest,FailOnBadBinaryFieldAtom)348 TEST_P(CollationTest, FailOnBadBinaryFieldAtom) {
349     Atoms atoms;
350     const int errorCount = collate_atoms(*mBadEventWithBinaryFieldAtom, DEFAULT_MODULE_NAME, atoms);
351     EXPECT_GT(errorCount, 0);
352 }
353 
TEST_P(CollationTest,PassOnLogFromModuleAtom)354 TEST_P(CollationTest, PassOnLogFromModuleAtom) {
355     Atoms atoms;
356     const int errorCount = collate_atoms(*mModuleAtoms, DEFAULT_MODULE_NAME, atoms);
357     EXPECT_EQ(errorCount, 0);
358     EXPECT_EQ(atoms.decls.size(), 4ul);
359 }
360 
TEST_P(CollationTest,RecognizeModuleAtom)361 TEST_P(CollationTest, RecognizeModuleAtom) {
362     Atoms atoms;
363     const int errorCount = collate_atoms(*mModuleAtoms, DEFAULT_MODULE_NAME, atoms);
364     EXPECT_EQ(errorCount, 0);
365     EXPECT_EQ(atoms.decls.size(), 4ul);
366     EXPECT_EQ(atoms.signatureInfoMap.size(), 2u);
367     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
368     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_STRING);
369 
370     SignatureInfoMap::const_iterator signatureInfoMapIt;
371     const vector<java_type_t>* signature;
372     const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet;
373     FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt;
374     const AtomDeclSet* atomDeclSet;
375     AtomDeclSet::const_iterator atomDeclSetIt;
376     AtomDecl* atomDecl;
377     FieldNumberToAnnotations* fieldNumberToAnnotations;
378     FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt;
379     const AnnotationSet* annotationSet;
380     AnnotationSet::const_iterator annotationSetIt;
381     Annotation* annotation;
382 
383     signatureInfoMapIt = atoms.signatureInfoMap.begin();
384     signature = &(signatureInfoMapIt->first);
385     fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
386     EXPECT_EQ(1ul, signature->size());
387     EXPECT_EQ(JAVA_TYPE_INT, signature->at(0));
388     EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size());
389     fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin();
390     EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first);
391     atomDeclSet = &fieldNumberToAtomDeclSetIt->second;
392     EXPECT_EQ(2ul, atomDeclSet->size());
393     atomDeclSetIt = atomDeclSet->begin();
394     atomDecl = atomDeclSetIt->get();
395     EXPECT_EQ(1, atomDecl->code);
396     fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
397     fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
398     EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
399     annotationSet = &fieldNumberToAnnotationsIt->second;
400     EXPECT_EQ(1ul, annotationSet->size());
401     annotationSetIt = annotationSet->begin();
402     annotation = annotationSetIt->get();
403     EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
404     EXPECT_EQ(1, annotation->atomId);
405     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
406     EXPECT_TRUE(annotation->value.boolValue);
407 
408     atomDeclSetIt++;
409     atomDecl = atomDeclSetIt->get();
410     EXPECT_EQ(3, atomDecl->code);
411     fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
412     fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
413     EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
414     annotationSet = &fieldNumberToAnnotationsIt->second;
415     EXPECT_EQ(1ul, annotationSet->size());
416     annotationSetIt = annotationSet->begin();
417     annotation = annotationSetIt->get();
418     EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId);
419     EXPECT_EQ(3, annotation->atomId);
420     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
421     EXPECT_TRUE(annotation->value.boolValue);
422 
423     signatureInfoMapIt++;
424     signature = &signatureInfoMapIt->first;
425     fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
426     EXPECT_EQ(1ul, signature->size());
427     EXPECT_EQ(JAVA_TYPE_STRING, signature->at(0));
428     EXPECT_EQ(0ul, fieldNumberToAtomDeclSet->size());
429 }
430 
TEST_P(CollationTest,RecognizeModule1Atom)431 TEST_P(CollationTest, RecognizeModule1Atom) {
432     Atoms atoms;
433     const string moduleName = "module1";
434     const int errorCount = collate_atoms(*mModuleAtoms, moduleName, atoms);
435     EXPECT_EQ(errorCount, 0);
436     EXPECT_EQ(atoms.decls.size(), 2ul);
437     EXPECT_EQ(atoms.signatureInfoMap.size(), 1u);
438     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
439 
440     SignatureInfoMap::const_iterator signatureInfoMapIt;
441     const vector<java_type_t>* signature;
442     const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet;
443     FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt;
444     const AtomDeclSet* atomDeclSet;
445     AtomDeclSet::const_iterator atomDeclSetIt;
446     AtomDecl* atomDecl;
447     FieldNumberToAnnotations* fieldNumberToAnnotations;
448     FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt;
449     const AnnotationSet* annotationSet;
450     AnnotationSet::const_iterator annotationSetIt;
451     Annotation* annotation;
452 
453     signatureInfoMapIt = atoms.signatureInfoMap.begin();
454     signature = &(signatureInfoMapIt->first);
455     fieldNumberToAtomDeclSet = &signatureInfoMapIt->second;
456     EXPECT_EQ(1ul, signature->size());
457     EXPECT_EQ(JAVA_TYPE_INT, signature->at(0));
458     EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size());
459     fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin();
460     EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first);
461     atomDeclSet = &fieldNumberToAtomDeclSetIt->second;
462     EXPECT_EQ(2ul, atomDeclSet->size());
463     atomDeclSetIt = atomDeclSet->begin();
464     atomDecl = atomDeclSetIt->get();
465     EXPECT_EQ(1, atomDecl->code);
466     fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
467     fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
468     EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
469     annotationSet = &fieldNumberToAnnotationsIt->second;
470     EXPECT_EQ(1ul, annotationSet->size());
471     annotationSetIt = annotationSet->begin();
472     annotation = annotationSetIt->get();
473     EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
474     EXPECT_EQ(1, annotation->atomId);
475     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
476     EXPECT_TRUE(annotation->value.boolValue);
477 
478     atomDeclSetIt++;
479     atomDecl = atomDeclSetIt->get();
480     EXPECT_EQ(3, atomDecl->code);
481     fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations;
482     fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1);
483     EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
484     annotationSet = &fieldNumberToAnnotationsIt->second;
485     EXPECT_EQ(1ul, annotationSet->size());
486     annotationSetIt = annotationSet->begin();
487     annotation = annotationSetIt->get();
488     EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId);
489     EXPECT_EQ(3, annotation->atomId);
490     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
491     EXPECT_TRUE(annotation->value.boolValue);
492 }
493 
494 /**
495  * Test a correct collation with pushed and pulled atoms.
496  */
TEST_P(CollationTest,CollatePushedAndPulledAtoms)497 TEST_P(CollationTest, CollatePushedAndPulledAtoms) {
498     Atoms atoms;
499     const int errorCount = collate_atoms(*mPushedAndPulledAtoms, DEFAULT_MODULE_NAME, atoms);
500 
501     EXPECT_EQ(0, errorCount);
502     EXPECT_EQ(1ul, atoms.signatureInfoMap.size());
503     EXPECT_EQ(2ul, atoms.pulledAtomsSignatureInfoMap.size());
504 
505     // IntAtom
506     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
507 
508     // AnotherIntAtom
509     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_INT);
510 
511     // OutOfOrderAtom
512     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_INT);
513 
514     EXPECT_EQ(3ul, atoms.decls.size());
515 
516     AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
517     EXPECT_EQ(1, (*atomIt)->code);
518     EXPECT_EQ("int_atom_1", (*atomIt)->name);
519     EXPECT_EQ("IntAtom", (*atomIt)->message);
520     EXPECT_NO_ENUM_FIELD((*atomIt));
521     atomIt++;
522 
523     EXPECT_EQ(10000, (*atomIt)->code);
524     EXPECT_EQ("another_int_atom", (*atomIt)->name);
525     EXPECT_EQ("AnotherIntAtom", (*atomIt)->message);
526     EXPECT_NO_ENUM_FIELD((*atomIt));
527     atomIt++;
528 
529     EXPECT_EQ(99999, (*atomIt)->code);
530     EXPECT_EQ("out_of_order_atom", (*atomIt)->name);
531     EXPECT_EQ("OutOfOrderAtom", (*atomIt)->message);
532     EXPECT_NO_ENUM_FIELD((*atomIt));
533     atomIt++;
534 
535     EXPECT_EQ(atoms.decls.end(), atomIt);
536 }
537 
TEST_P(CollationTest,CollateVendorAtoms)538 TEST_P(CollationTest, CollateVendorAtoms) {
539     Atoms atoms;
540     const int errorCount = collate_atoms(*mVendorAtoms, DEFAULT_MODULE_NAME, atoms);
541 
542     EXPECT_EQ(0, errorCount);
543     EXPECT_EQ(1ul, atoms.signatureInfoMap.size());
544     EXPECT_EQ(1ul, atoms.pulledAtomsSignatureInfoMap.size());
545 
546     // IntAtom
547     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
548 
549     // AnotherIntAtom
550     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_INT);
551 
552     EXPECT_EQ(2ul, atoms.decls.size());
553 
554     AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
555     EXPECT_EQ(100000, (*atomIt)->code);
556     EXPECT_EQ("pushed_atom_100000", (*atomIt)->name);
557     EXPECT_EQ("IntAtom", (*atomIt)->message);
558     EXPECT_NO_ENUM_FIELD((*atomIt));
559     atomIt++;
560 
561     EXPECT_EQ(199999, (*atomIt)->code);
562     EXPECT_EQ("pulled_atom_199999", (*atomIt)->name);
563     EXPECT_EQ("AnotherIntAtom", (*atomIt)->message);
564     EXPECT_NO_ENUM_FIELD((*atomIt));
565     atomIt++;
566 
567     EXPECT_EQ(atoms.decls.end(), atomIt);
568 }
569 
TEST(CollationTest,CollateExtensionAtoms)570 TEST(CollationTest, CollateExtensionAtoms) {
571     Atoms atoms;
572     const int errorCount = collate_atoms(*ExtensionAtoms::descriptor(), "test_feature", atoms);
573 
574     EXPECT_EQ(0, errorCount);
575     EXPECT_EQ(1ul, atoms.signatureInfoMap.size());
576     EXPECT_EQ(1ul, atoms.pulledAtomsSignatureInfoMap.size());
577 
578     // ExtensionAtomPushed
579     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_LONG);
580 
581     // ExtensionAtomPulled
582     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_LONG);
583 
584     EXPECT_EQ(2ul, atoms.decls.size());
585 
586     AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
587     EXPECT_EQ(9999, (*atomIt)->code);
588     EXPECT_EQ("extension_atom_pushed", (*atomIt)->name);
589     EXPECT_EQ("ExtensionAtomPushed", (*atomIt)->message);
590     EXPECT_NO_ENUM_FIELD((*atomIt));
591     FieldNumberToAnnotations* fieldNumberToAnnotations = &(*atomIt)->fieldNumberToAnnotations;
592     FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt =
593             fieldNumberToAnnotations->find(1);
594     EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt);
595     const AnnotationSet* annotationSet = &fieldNumberToAnnotationsIt->second;
596     EXPECT_EQ(1ul, annotationSet->size());
597     Annotation* annotation = annotationSet->begin()->get();
598     EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId);
599     EXPECT_EQ(9999, annotation->atomId);
600     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
601     EXPECT_TRUE(annotation->value.boolValue);
602     atomIt++;
603 
604     EXPECT_EQ(99999, (*atomIt)->code);
605     EXPECT_EQ("extension_atom_pulled", (*atomIt)->name);
606     EXPECT_EQ("ExtensionAtomPulled", (*atomIt)->message);
607     EXPECT_NO_ENUM_FIELD((*atomIt));
608     atomIt++;
609 
610     EXPECT_EQ(atoms.decls.end(), atomIt);
611 }
612 
TEST_P(CollationTest,CollateGoodRestrictedAtoms)613 TEST_P(CollationTest, CollateGoodRestrictedAtoms) {
614     Atoms atoms;
615     const int errorCount = collate_atoms(*mGoodRestrictedAtoms, DEFAULT_MODULE_NAME, atoms);
616 
617     EXPECT_EQ(0, errorCount);
618     ASSERT_EQ(1ul, atoms.signatureInfoMap.size());
619     ASSERT_EQ(0ul, atoms.pulledAtomsSignatureInfoMap.size());
620 
621     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_LONG, JAVA_TYPE_INT,
622                                   JAVA_TYPE_BOOLEAN, JAVA_TYPE_STRING, JAVA_TYPE_INT,
623                                   JAVA_TYPE_FLOAT, JAVA_TYPE_INT);
624 
625     // Validate signatureInfoMap
626     FieldNumberToAtomDeclSet fieldNumberToAtomDeclSet = atoms.signatureInfoMap.begin()->second;
627     ASSERT_EQ(8ul, fieldNumberToAtomDeclSet.size());
628     const AtomDeclSet* atomDeclSet = &fieldNumberToAtomDeclSet[ATOM_ID_FIELD_NUMBER];
629     ASSERT_EQ(2ul, atomDeclSet->size());
630     AtomDeclSet::const_iterator atomDeclSetIt = atomDeclSet->begin();
631 
632     const AtomDecl* atomDecl = atomDeclSetIt->get();
633     EXPECT_EQ(1, atomDecl->code);
634     EXPECT_EQ("pushed_atom_1", atomDecl->name);
635     EXPECT_EQ("GoodRestrictedAtom", atomDecl->message);
636     FieldNumberToAnnotations fieldNumberToAnnotations = atomDecl->fieldNumberToAnnotations;
637     ASSERT_EQ(8ul, fieldNumberToAnnotations.size());
638 
639     const AnnotationSet* annotationSet = &fieldNumberToAnnotations[ATOM_ID_FIELD_NUMBER];
640     ASSERT_EQ(1ul, annotationSet->size());
641     Annotation* annotation = annotationSet->begin()->get();
642     EXPECT_EQ(ANNOTATION_ID_RESTRICTION_CATEGORY, annotation->annotationId);
643     EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type);
644     EXPECT_EQ(os::statsd::RESTRICTION_DIAGNOSTIC, annotation->value.intValue);
645 
646     annotationSet = &fieldNumberToAnnotations[1];
647     ASSERT_EQ(1ul, annotationSet->size());
648     annotation = annotationSet->begin()->get();
649     EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_APP_USAGE, annotation->annotationId);
650     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
651     EXPECT_TRUE(annotation->value.boolValue);
652 
653     annotationSet = &fieldNumberToAnnotations[2];
654     ASSERT_EQ(1ul, annotationSet->size());
655     annotation = annotationSet->begin()->get();
656     EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_HEALTH_CONNECT, annotation->annotationId);
657     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
658     EXPECT_TRUE(annotation->value.boolValue);
659 
660     annotationSet = &fieldNumberToAnnotations[3];
661     ASSERT_EQ(1ul, annotationSet->size());
662     annotation = annotationSet->begin()->get();
663     EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_ACCESSIBILITY, annotation->annotationId);
664     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
665     EXPECT_TRUE(annotation->value.boolValue);
666 
667     annotationSet = &fieldNumberToAnnotations[4];
668     ASSERT_EQ(1ul, annotationSet->size());
669     annotation = annotationSet->begin()->get();
670     EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_SYSTEM_SEARCH, annotation->annotationId);
671     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
672     EXPECT_TRUE(annotation->value.boolValue);
673 
674     annotationSet = &fieldNumberToAnnotations[5];
675     ASSERT_EQ(1ul, annotationSet->size());
676     annotation = annotationSet->begin()->get();
677     EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_AMBIENT_SENSING, annotation->annotationId);
678     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
679     EXPECT_TRUE(annotation->value.boolValue);
680 
681     annotationSet = &fieldNumberToAnnotations[6];
682     ASSERT_EQ(1ul, annotationSet->size());
683     annotation = annotationSet->begin()->get();
684     EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_PERIPHERAL_DEVICE_INFO, annotation->annotationId);
685     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
686     EXPECT_TRUE(annotation->value.boolValue);
687 
688     annotationSet = &fieldNumberToAnnotations[7];
689     ASSERT_EQ(1ul, annotationSet->size());
690     annotation = annotationSet->begin()->get();
691     EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_DEMOGRAPHIC_CLASSIFICATION, annotation->annotationId);
692     EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type);
693     EXPECT_TRUE(annotation->value.boolValue);
694     atomDeclSetIt++;
695 
696     atomDecl = atomDeclSetIt->get();
697     EXPECT_EQ(2, atomDecl->code);
698     EXPECT_EQ("pushed_atom_2", atomDecl->name);
699     EXPECT_EQ("GoodRestrictedAtom", atomDecl->message);
700     fieldNumberToAnnotations = atomDecl->fieldNumberToAnnotations;
701     ASSERT_EQ(8ul, fieldNumberToAnnotations.size());
702     annotationSet = &fieldNumberToAnnotations[ATOM_ID_FIELD_NUMBER];
703     ASSERT_EQ(1ul, annotationSet->size());
704     annotation = annotationSet->begin()->get();
705     EXPECT_EQ(ANNOTATION_ID_RESTRICTION_CATEGORY, annotation->annotationId);
706     EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type);
707     EXPECT_EQ(os::statsd::RESTRICTION_SYSTEM_INTELLIGENCE, annotation->value.intValue);
708     atomDeclSetIt++;
709     EXPECT_EQ(atomDeclSet->end(), atomDeclSetIt);
710 
711     // Validate decls
712     ASSERT_EQ(2ul, atoms.decls.size());
713     AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
714 
715     EXPECT_EQ(1, (*atomIt)->code);
716     EXPECT_EQ("pushed_atom_1", (*atomIt)->name);
717     EXPECT_EQ("GoodRestrictedAtom", (*atomIt)->message);
718     fieldNumberToAnnotations = (*atomIt)->fieldNumberToAnnotations;
719     ASSERT_EQ(8ul, fieldNumberToAnnotations.size());
720 
721     annotationSet = &fieldNumberToAnnotations[ATOM_ID_FIELD_NUMBER];
722     ASSERT_EQ(1ul, annotationSet->size());
723     annotation = annotationSet->begin()->get();
724     EXPECT_EQ(ANNOTATION_ID_RESTRICTION_CATEGORY, annotation->annotationId);
725     EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type);
726     EXPECT_EQ(os::statsd::RESTRICTION_DIAGNOSTIC, annotation->value.intValue);
727     atomIt++;
728 
729     EXPECT_EQ(2, (*atomIt)->code);
730     EXPECT_EQ("pushed_atom_2", (*atomIt)->name);
731     EXPECT_EQ("GoodRestrictedAtom", (*atomIt)->message);
732     fieldNumberToAnnotations = (*atomIt)->fieldNumberToAnnotations;
733     ASSERT_EQ(8ul, fieldNumberToAnnotations.size());
734     annotationSet = &fieldNumberToAnnotations[ATOM_ID_FIELD_NUMBER];
735     ASSERT_EQ(1ul, annotationSet->size());
736     annotation = annotationSet->begin()->get();
737     EXPECT_EQ(ANNOTATION_ID_RESTRICTION_CATEGORY, annotation->annotationId);
738     EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type);
739     EXPECT_EQ(os::statsd::RESTRICTION_SYSTEM_INTELLIGENCE, annotation->value.intValue);
740     atomIt++;
741     EXPECT_EQ(atoms.decls.end(), atomIt);
742 
743     // Validate non_chained_decls
744     ASSERT_EQ(0ul, atoms.non_chained_decls.size());
745 
746     // Validate nonChainedSignatureInfoMap
747     ASSERT_EQ(0ul, atoms.nonChainedSignatureInfoMap.size());
748 }
749 
TEST_P(CollationTest,CollateBadRestrictedAtoms)750 TEST_P(CollationTest, CollateBadRestrictedAtoms) {
751     Atoms atoms;
752     // Nonprimitive fields
753     int errorCount = collate_atoms(*mBadRestrictedAtoms1, DEFAULT_MODULE_NAME, atoms);
754     EXPECT_EQ(6, errorCount);
755 
756     // Restriction category on atom field
757     errorCount = collate_atoms(*mBadRestrictedAtoms2, DEFAULT_MODULE_NAME, atoms);
758     EXPECT_EQ(1, errorCount);
759 
760     // Field restriction without restriction category
761     errorCount = collate_atoms(*mBadRestrictedAtoms3, DEFAULT_MODULE_NAME, atoms);
762     EXPECT_EQ(7, errorCount);
763 
764     // Field restriction option on top level atom field
765     errorCount = collate_atoms(*mBadRestrictedAtoms4, DEFAULT_MODULE_NAME, atoms);
766     EXPECT_EQ(1, errorCount);
767 
768     // Pulled restricted atoms
769     errorCount = collate_atoms(*mBadRestrictedAtoms5, DEFAULT_MODULE_NAME, atoms);
770     EXPECT_EQ(2, errorCount);
771 }
772 
TEST_P(CollationTest,CollateGoodUintAtoms)773 TEST_P(CollationTest, CollateGoodUintAtoms) {
774     Atoms atoms;
775     int errorCount = collate_atoms(*mGoodUintAtoms, DEFAULT_MODULE_NAME, atoms);
776     EXPECT_EQ(0, errorCount);
777 
778     EXPECT_EQ(2ul, atoms.signatureInfoMap.size());
779 
780     // AppDied
781     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT);
782 
783     // SystemUptime
784     EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_LONG);
785 
786     EXPECT_EQ(2ul, atoms.decls.size());
787 
788     AtomDeclSet::const_iterator atomIt = atoms.decls.begin();
789     EXPECT_EQ(1, (*atomIt)->code);
790     EXPECT_EQ("app_died", (*atomIt)->name);
791     EXPECT_EQ("AppDied", (*atomIt)->message);
792     EXPECT_NO_ENUM_FIELD((*atomIt));
793     atomIt++;
794 
795     EXPECT_EQ(2, (*atomIt)->code);
796     EXPECT_EQ("system_uptime", (*atomIt)->name);
797     EXPECT_EQ("SystemUptime", (*atomIt)->message);
798     EXPECT_NO_ENUM_FIELD((*atomIt));
799     atomIt++;
800 
801     EXPECT_EQ(atoms.decls.end(), atomIt);
802 }
803 
804 }  // namespace stats_log_api_gen
805 }  // namespace android
806