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