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