| /* |
| * Copyright (C) 2017, The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include <google/protobuf/compiler/importer.h> |
| #include <gtest/gtest.h> |
| #include <stdio.h> |
| |
| #include <filesystem> |
| |
| #include "Collation.h" |
| #include "frameworks/proto_logging/stats/stats_log_api_gen/test.pb.h" |
| |
| namespace android { |
| namespace stats_log_api_gen { |
| |
| using std::map; |
| using std::vector; |
| |
| namespace fs = std::filesystem; |
| |
| /** |
| * Return whether the map contains a vector of the elements provided. |
| */ |
| static bool map_contains_vector(const SignatureInfoMap& s, int count, ...) { |
| va_list args; |
| vector<java_type_t> v(count); |
| |
| va_start(args, count); |
| for (int i = 0; i < count; i++) { |
| v[i] = static_cast<java_type_t>(va_arg(args, int)); |
| } |
| va_end(args); |
| |
| return s.find(v) != s.end(); |
| } |
| |
| /** |
| * Expect that the provided map contains the elements provided. |
| */ |
| #define EXPECT_MAP_CONTAINS_SIGNATURE(s, ...) \ |
| do { \ |
| int count = sizeof((int[]){__VA_ARGS__}) / sizeof(int); \ |
| EXPECT_TRUE(map_contains_vector(s, count, __VA_ARGS__)); \ |
| } while (0) |
| |
| /** Expects that the provided atom has no enum values for any field. */ |
| #define EXPECT_NO_ENUM_FIELD(atom) \ |
| do { \ |
| for (vector<AtomField>::const_iterator field = atom->fields.begin(); \ |
| field != atom->fields.end(); field++) { \ |
| EXPECT_TRUE(field->enumValues.empty()); \ |
| } \ |
| } while (0) |
| |
| /** Expects that exactly one specific field has expected enum values. */ |
| #define EXPECT_HAS_ENUM_FIELD(atom, field_name, values) \ |
| do { \ |
| for (vector<AtomField>::const_iterator field = atom->fields.begin(); \ |
| field != atom->fields.end(); field++) { \ |
| if (field->name == field_name) { \ |
| EXPECT_EQ(field->enumValues, values); \ |
| } else { \ |
| EXPECT_TRUE(field->enumValues.empty()); \ |
| } \ |
| } \ |
| } while (0) |
| |
| // Setup for test fixture. |
| class CollationTest : public testing::TestWithParam<bool> { |
| class MFErrorCollector : public google::protobuf::compiler::MultiFileErrorCollector { |
| public: |
| void AddError(const std::string& filename, int line, int column, |
| const std::string& message) override { |
| fprintf(stdout, "[Error] %s:%d:%d - %s", filename.c_str(), line, column, |
| message.c_str()); |
| } |
| }; |
| |
| public: |
| CollationTest() : mImporter(&mSourceTree, &mErrorCollector) { |
| mSourceTree.MapPath("", fs::current_path().c_str()); |
| mFileDescriptor = mImporter.Import("test_external.proto"); |
| } |
| |
| protected: |
| void SetUp() override { |
| if (GetParam()) { |
| mEvent = Event::descriptor(); |
| mIntAtom = IntAtom::descriptor(); |
| mBadTypesEvent = BadTypesEvent::descriptor(); |
| mBadSkippedFieldSingle = BadSkippedFieldSingle::descriptor(); |
| mBadSkippedFieldMultiple = BadSkippedFieldMultiple::descriptor(); |
| mBadAttributionNodePosition = BadAttributionNodePosition::descriptor(); |
| mBadStateAtoms = BadStateAtoms::descriptor(); |
| mGoodStateAtoms = GoodStateAtoms::descriptor(); |
| mBadUidAtoms = BadUidAtoms::descriptor(); |
| mGoodUidAtoms = GoodUidAtoms::descriptor(); |
| mGoodEventWithBinaryFieldAtom = GoodEventWithBinaryFieldAtom::descriptor(); |
| mBadEventWithBinaryFieldAtom = BadEventWithBinaryFieldAtom::descriptor(); |
| mModuleAtoms = ModuleAtoms::descriptor(); |
| |
| mPushedAndPulledAtoms = PushedAndPulledAtoms::descriptor(); |
| mVendorAtoms = VendorAtoms::descriptor(); |
| mGoodRestrictedAtoms = GoodRestrictedAtoms::descriptor(); |
| mBadRestrictedAtoms1 = BadRestrictedAtoms1::descriptor(); |
| mBadRestrictedAtoms2 = BadRestrictedAtoms2::descriptor(); |
| mBadRestrictedAtoms3 = BadRestrictedAtoms3::descriptor(); |
| mBadRestrictedAtoms4 = BadRestrictedAtoms4::descriptor(); |
| mBadRestrictedAtoms5 = BadRestrictedAtoms5::descriptor(); |
| mGoodUintAtoms = GoodUintAtoms::descriptor(); |
| } else { |
| mEvent = mFileDescriptor->FindMessageTypeByName("Event"); |
| mIntAtom = mFileDescriptor->FindMessageTypeByName("IntAtom"); |
| mBadTypesEvent = mFileDescriptor->FindMessageTypeByName("BadTypesEvent"); |
| mBadSkippedFieldSingle = |
| mFileDescriptor->FindMessageTypeByName("BadSkippedFieldSingle"); |
| mBadSkippedFieldMultiple = |
| mFileDescriptor->FindMessageTypeByName("BadSkippedFieldMultiple"); |
| mBadAttributionNodePosition = |
| mFileDescriptor->FindMessageTypeByName("BadAttributionNodePosition"); |
| mBadStateAtoms = mFileDescriptor->FindMessageTypeByName("BadStateAtoms"); |
| mGoodStateAtoms = mFileDescriptor->FindMessageTypeByName("GoodStateAtoms"); |
| mBadUidAtoms = mFileDescriptor->FindMessageTypeByName("BadUidAtoms"); |
| mGoodUidAtoms = mFileDescriptor->FindMessageTypeByName("GoodUidAtoms"); |
| mGoodEventWithBinaryFieldAtom = |
| mFileDescriptor->FindMessageTypeByName("GoodEventWithBinaryFieldAtom"); |
| mBadEventWithBinaryFieldAtom = |
| mFileDescriptor->FindMessageTypeByName("BadEventWithBinaryFieldAtom"); |
| mModuleAtoms = mFileDescriptor->FindMessageTypeByName("ModuleAtoms"); |
| mPushedAndPulledAtoms = mFileDescriptor->FindMessageTypeByName("PushedAndPulledAtoms"); |
| mVendorAtoms = mFileDescriptor->FindMessageTypeByName("VendorAtoms"); |
| mGoodRestrictedAtoms = mFileDescriptor->FindMessageTypeByName("GoodRestrictedAtoms"); |
| mBadRestrictedAtoms1 = mFileDescriptor->FindMessageTypeByName("BadRestrictedAtoms1"); |
| mBadRestrictedAtoms2 = mFileDescriptor->FindMessageTypeByName("BadRestrictedAtoms2"); |
| mBadRestrictedAtoms3 = mFileDescriptor->FindMessageTypeByName("BadRestrictedAtoms3"); |
| mBadRestrictedAtoms4 = mFileDescriptor->FindMessageTypeByName("BadRestrictedAtoms4"); |
| mBadRestrictedAtoms5 = mFileDescriptor->FindMessageTypeByName("BadRestrictedAtoms5"); |
| mGoodUintAtoms = mFileDescriptor->FindMessageTypeByName("GoodUintAtoms"); |
| } |
| } |
| |
| MFErrorCollector mErrorCollector; |
| google::protobuf::compiler::DiskSourceTree mSourceTree; |
| google::protobuf::compiler::Importer mImporter; |
| const google::protobuf::FileDescriptor* mFileDescriptor; |
| |
| const Descriptor* mEvent; |
| const Descriptor* mIntAtom; |
| const Descriptor* mBadTypesEvent; |
| const Descriptor* mBadSkippedFieldSingle; |
| const Descriptor* mBadSkippedFieldMultiple; |
| const Descriptor* mBadAttributionNodePosition; |
| const Descriptor* mBadStateAtoms; |
| const Descriptor* mGoodStateAtoms; |
| const Descriptor* mBadUidAtoms; |
| const Descriptor* mGoodUidAtoms; |
| const Descriptor* mGoodEventWithBinaryFieldAtom; |
| const Descriptor* mBadEventWithBinaryFieldAtom; |
| const Descriptor* mModuleAtoms; |
| const Descriptor* mPushedAndPulledAtoms; |
| const Descriptor* mVendorAtoms; |
| const Descriptor* mGoodRestrictedAtoms; |
| const Descriptor* mBadRestrictedAtoms1; |
| const Descriptor* mBadRestrictedAtoms2; |
| const Descriptor* mBadRestrictedAtoms3; |
| const Descriptor* mBadRestrictedAtoms4; |
| const Descriptor* mBadRestrictedAtoms5; |
| const Descriptor* mGoodUintAtoms; |
| }; |
| |
| INSTANTIATE_TEST_SUITE_P(ProtoProvider, CollationTest, testing::Values(true, false)); |
| |
| /** |
| * Test a correct collation, with all the types. |
| */ |
| TEST_P(CollationTest, CollateStats) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mEvent, DEFAULT_MODULE_NAME, atoms); |
| |
| EXPECT_EQ(0, errorCount); |
| EXPECT_EQ(4ul, atoms.signatureInfoMap.size()); |
| |
| // IntAtom, AnotherIntAtom |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT); |
| |
| // OutOfOrderAtom |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_INT); |
| |
| // AllTypesAtom |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, |
| JAVA_TYPE_ATTRIBUTION_CHAIN, // AttributionChain |
| JAVA_TYPE_FLOAT, // float |
| JAVA_TYPE_LONG, // int64 |
| JAVA_TYPE_INT, // int32 |
| JAVA_TYPE_BOOLEAN, // bool |
| JAVA_TYPE_STRING, // string |
| JAVA_TYPE_INT, // AnEnum |
| JAVA_TYPE_FLOAT_ARRAY, // repeated float |
| JAVA_TYPE_LONG_ARRAY, // repeated int64 |
| JAVA_TYPE_INT_ARRAY, // repeated int32 |
| JAVA_TYPE_BOOLEAN_ARRAY, // repeated bool |
| JAVA_TYPE_STRING_ARRAY, // repeated string |
| JAVA_TYPE_BYTE_ARRAY // SubMessageWithUint (mode bytes) |
| ); |
| |
| // RepeatedEnumAtom |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT_ARRAY); |
| |
| EXPECT_EQ(5ul, atoms.decls.size()); |
| |
| AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); |
| EXPECT_EQ(1, (*atomIt)->code); |
| EXPECT_EQ("int_atom", (*atomIt)->name); |
| EXPECT_EQ("IntAtom", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| atomIt++; |
| |
| EXPECT_EQ(2, (*atomIt)->code); |
| EXPECT_EQ("out_of_order_atom", (*atomIt)->name); |
| EXPECT_EQ("OutOfOrderAtom", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| atomIt++; |
| |
| EXPECT_EQ(3, (*atomIt)->code); |
| EXPECT_EQ("another_int_atom", (*atomIt)->name); |
| EXPECT_EQ("AnotherIntAtom", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| atomIt++; |
| |
| EXPECT_EQ(4, (*atomIt)->code); |
| EXPECT_EQ("all_types_atom", (*atomIt)->name); |
| EXPECT_EQ("AllTypesAtom", (*atomIt)->message); |
| map<int, string> enumValues; |
| enumValues[0] = "VALUE0"; |
| enumValues[1] = "VALUE1"; |
| EXPECT_HAS_ENUM_FIELD((*atomIt), "enum_field", enumValues); |
| atomIt++; |
| |
| EXPECT_EQ(5, (*atomIt)->code); |
| EXPECT_EQ("repeated_enum_atom", (*atomIt)->name); |
| EXPECT_EQ("RepeatedEnumAtom", (*atomIt)->message); |
| enumValues[0] = "VALUE0"; |
| enumValues[1] = "VALUE1"; |
| EXPECT_HAS_ENUM_FIELD((*atomIt), "repeated_enum_field", enumValues); |
| atomIt++; |
| |
| EXPECT_EQ(atoms.decls.end(), atomIt); |
| } |
| |
| /** |
| * Test that event class that contains stuff other than the atoms is rejected. |
| */ |
| TEST_P(CollationTest, NonMessageTypeFails) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mIntAtom, DEFAULT_MODULE_NAME, atoms); |
| |
| EXPECT_EQ(1, errorCount); |
| } |
| |
| /** |
| * Test that atoms that have unsupported field types are rejected. |
| */ |
| TEST_P(CollationTest, FailOnBadTypes) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mBadTypesEvent, DEFAULT_MODULE_NAME, atoms); |
| |
| EXPECT_EQ(22, errorCount); |
| } |
| |
| /** |
| * Test that atoms that skip field numbers (in the first position) are rejected. |
| */ |
| TEST_P(CollationTest, FailOnSkippedFieldsSingle) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mBadSkippedFieldSingle, DEFAULT_MODULE_NAME, atoms); |
| |
| EXPECT_EQ(1, errorCount); |
| } |
| |
| /** |
| * Test that atoms that skip field numbers (not in the first position, and |
| * multiple times) are rejected. |
| */ |
| TEST_P(CollationTest, FailOnSkippedFieldsMultiple) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mBadSkippedFieldMultiple, DEFAULT_MODULE_NAME, atoms); |
| |
| EXPECT_EQ(2, errorCount); |
| } |
| |
| /** |
| * Test that atoms that have an attribution chain not in the first position are |
| * rejected. |
| */ |
| TEST_P(CollationTest, FailBadAttributionNodePosition) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mBadAttributionNodePosition, DEFAULT_MODULE_NAME, atoms); |
| |
| EXPECT_EQ(1, errorCount); |
| } |
| |
| TEST_P(CollationTest, FailOnBadStateAtomOptions) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mBadStateAtoms, DEFAULT_MODULE_NAME, atoms); |
| |
| EXPECT_EQ(4, errorCount); |
| } |
| |
| TEST_P(CollationTest, PassOnGoodStateAtomOptions) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mGoodStateAtoms, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_EQ(0, errorCount); |
| } |
| |
| TEST_P(CollationTest, FailOnBadUidAtomOptions) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mBadUidAtoms, DEFAULT_MODULE_NAME, atoms); |
| |
| EXPECT_EQ(2, errorCount); |
| } |
| |
| TEST_P(CollationTest, PassOnGoodUidAtomOptions) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mGoodUidAtoms, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_EQ(0, errorCount); |
| } |
| |
| TEST_P(CollationTest, PassOnGoodBinaryFieldAtom) { |
| Atoms atoms; |
| const int errorCount = |
| collate_atoms(*mGoodEventWithBinaryFieldAtom, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_EQ(0, errorCount); |
| } |
| |
| TEST_P(CollationTest, FailOnBadBinaryFieldAtom) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mBadEventWithBinaryFieldAtom, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_GT(errorCount, 0); |
| } |
| |
| TEST_P(CollationTest, PassOnLogFromModuleAtom) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mModuleAtoms, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_EQ(errorCount, 0); |
| EXPECT_EQ(atoms.decls.size(), 4ul); |
| } |
| |
| TEST_P(CollationTest, RecognizeModuleAtom) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mModuleAtoms, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_EQ(errorCount, 0); |
| EXPECT_EQ(atoms.decls.size(), 4ul); |
| EXPECT_EQ(atoms.signatureInfoMap.size(), 2u); |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT); |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_STRING); |
| |
| SignatureInfoMap::const_iterator signatureInfoMapIt; |
| const vector<java_type_t>* signature; |
| const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet; |
| FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt; |
| const AtomDeclSet* atomDeclSet; |
| AtomDeclSet::const_iterator atomDeclSetIt; |
| AtomDecl* atomDecl; |
| FieldNumberToAnnotations* fieldNumberToAnnotations; |
| FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt; |
| const AnnotationSet* annotationSet; |
| AnnotationSet::const_iterator annotationSetIt; |
| Annotation* annotation; |
| |
| signatureInfoMapIt = atoms.signatureInfoMap.begin(); |
| signature = &(signatureInfoMapIt->first); |
| fieldNumberToAtomDeclSet = &signatureInfoMapIt->second; |
| EXPECT_EQ(1ul, signature->size()); |
| EXPECT_EQ(JAVA_TYPE_INT, signature->at(0)); |
| EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size()); |
| fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin(); |
| EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first); |
| atomDeclSet = &fieldNumberToAtomDeclSetIt->second; |
| EXPECT_EQ(2ul, atomDeclSet->size()); |
| atomDeclSetIt = atomDeclSet->begin(); |
| atomDecl = atomDeclSetIt->get(); |
| EXPECT_EQ(1, atomDecl->code); |
| fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations; |
| fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1); |
| EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt); |
| annotationSet = &fieldNumberToAnnotationsIt->second; |
| EXPECT_EQ(1ul, annotationSet->size()); |
| annotationSetIt = annotationSet->begin(); |
| annotation = annotationSetIt->get(); |
| EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId); |
| EXPECT_EQ(1, annotation->atomId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| |
| atomDeclSetIt++; |
| atomDecl = atomDeclSetIt->get(); |
| EXPECT_EQ(3, atomDecl->code); |
| fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations; |
| fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1); |
| EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt); |
| annotationSet = &fieldNumberToAnnotationsIt->second; |
| EXPECT_EQ(1ul, annotationSet->size()); |
| annotationSetIt = annotationSet->begin(); |
| annotation = annotationSetIt->get(); |
| EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId); |
| EXPECT_EQ(3, annotation->atomId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| |
| signatureInfoMapIt++; |
| signature = &signatureInfoMapIt->first; |
| fieldNumberToAtomDeclSet = &signatureInfoMapIt->second; |
| EXPECT_EQ(1ul, signature->size()); |
| EXPECT_EQ(JAVA_TYPE_STRING, signature->at(0)); |
| EXPECT_EQ(0ul, fieldNumberToAtomDeclSet->size()); |
| } |
| |
| TEST_P(CollationTest, RecognizeModule1Atom) { |
| Atoms atoms; |
| const string moduleName = "module1"; |
| const int errorCount = collate_atoms(*mModuleAtoms, moduleName, atoms); |
| EXPECT_EQ(errorCount, 0); |
| EXPECT_EQ(atoms.decls.size(), 2ul); |
| EXPECT_EQ(atoms.signatureInfoMap.size(), 1u); |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT); |
| |
| SignatureInfoMap::const_iterator signatureInfoMapIt; |
| const vector<java_type_t>* signature; |
| const FieldNumberToAtomDeclSet* fieldNumberToAtomDeclSet; |
| FieldNumberToAtomDeclSet::const_iterator fieldNumberToAtomDeclSetIt; |
| const AtomDeclSet* atomDeclSet; |
| AtomDeclSet::const_iterator atomDeclSetIt; |
| AtomDecl* atomDecl; |
| FieldNumberToAnnotations* fieldNumberToAnnotations; |
| FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt; |
| const AnnotationSet* annotationSet; |
| AnnotationSet::const_iterator annotationSetIt; |
| Annotation* annotation; |
| |
| signatureInfoMapIt = atoms.signatureInfoMap.begin(); |
| signature = &(signatureInfoMapIt->first); |
| fieldNumberToAtomDeclSet = &signatureInfoMapIt->second; |
| EXPECT_EQ(1ul, signature->size()); |
| EXPECT_EQ(JAVA_TYPE_INT, signature->at(0)); |
| EXPECT_EQ(1ul, fieldNumberToAtomDeclSet->size()); |
| fieldNumberToAtomDeclSetIt = fieldNumberToAtomDeclSet->begin(); |
| EXPECT_EQ(1, fieldNumberToAtomDeclSetIt->first); |
| atomDeclSet = &fieldNumberToAtomDeclSetIt->second; |
| EXPECT_EQ(2ul, atomDeclSet->size()); |
| atomDeclSetIt = atomDeclSet->begin(); |
| atomDecl = atomDeclSetIt->get(); |
| EXPECT_EQ(1, atomDecl->code); |
| fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations; |
| fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1); |
| EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt); |
| annotationSet = &fieldNumberToAnnotationsIt->second; |
| EXPECT_EQ(1ul, annotationSet->size()); |
| annotationSetIt = annotationSet->begin(); |
| annotation = annotationSetIt->get(); |
| EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId); |
| EXPECT_EQ(1, annotation->atomId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| |
| atomDeclSetIt++; |
| atomDecl = atomDeclSetIt->get(); |
| EXPECT_EQ(3, atomDecl->code); |
| fieldNumberToAnnotations = &atomDecl->fieldNumberToAnnotations; |
| fieldNumberToAnnotationsIt = fieldNumberToAnnotations->find(1); |
| EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt); |
| annotationSet = &fieldNumberToAnnotationsIt->second; |
| EXPECT_EQ(1ul, annotationSet->size()); |
| annotationSetIt = annotationSet->begin(); |
| annotation = annotationSetIt->get(); |
| EXPECT_EQ(ANNOTATION_ID_EXCLUSIVE_STATE, annotation->annotationId); |
| EXPECT_EQ(3, annotation->atomId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| } |
| |
| /** |
| * Test a correct collation with pushed and pulled atoms. |
| */ |
| TEST_P(CollationTest, CollatePushedAndPulledAtoms) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mPushedAndPulledAtoms, DEFAULT_MODULE_NAME, atoms); |
| |
| EXPECT_EQ(0, errorCount); |
| EXPECT_EQ(1ul, atoms.signatureInfoMap.size()); |
| EXPECT_EQ(2ul, atoms.pulledAtomsSignatureInfoMap.size()); |
| |
| // IntAtom |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT); |
| |
| // AnotherIntAtom |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_INT); |
| |
| // OutOfOrderAtom |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_INT); |
| |
| EXPECT_EQ(3ul, atoms.decls.size()); |
| |
| AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); |
| EXPECT_EQ(1, (*atomIt)->code); |
| EXPECT_EQ("int_atom_1", (*atomIt)->name); |
| EXPECT_EQ("IntAtom", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| atomIt++; |
| |
| EXPECT_EQ(10000, (*atomIt)->code); |
| EXPECT_EQ("another_int_atom", (*atomIt)->name); |
| EXPECT_EQ("AnotherIntAtom", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| atomIt++; |
| |
| EXPECT_EQ(99999, (*atomIt)->code); |
| EXPECT_EQ("out_of_order_atom", (*atomIt)->name); |
| EXPECT_EQ("OutOfOrderAtom", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| atomIt++; |
| |
| EXPECT_EQ(atoms.decls.end(), atomIt); |
| } |
| |
| TEST_P(CollationTest, CollateVendorAtoms) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mVendorAtoms, DEFAULT_MODULE_NAME, atoms); |
| |
| EXPECT_EQ(0, errorCount); |
| EXPECT_EQ(1ul, atoms.signatureInfoMap.size()); |
| EXPECT_EQ(1ul, atoms.pulledAtomsSignatureInfoMap.size()); |
| |
| // IntAtom |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT); |
| |
| // AnotherIntAtom |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_INT); |
| |
| EXPECT_EQ(2ul, atoms.decls.size()); |
| |
| AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); |
| EXPECT_EQ(100000, (*atomIt)->code); |
| EXPECT_EQ("pushed_atom_100000", (*atomIt)->name); |
| EXPECT_EQ("IntAtom", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| atomIt++; |
| |
| EXPECT_EQ(199999, (*atomIt)->code); |
| EXPECT_EQ("pulled_atom_199999", (*atomIt)->name); |
| EXPECT_EQ("AnotherIntAtom", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| atomIt++; |
| |
| EXPECT_EQ(atoms.decls.end(), atomIt); |
| } |
| |
| TEST(CollationTest, CollateExtensionAtoms) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*ExtensionAtoms::descriptor(), "test_feature", atoms); |
| |
| EXPECT_EQ(0, errorCount); |
| EXPECT_EQ(1ul, atoms.signatureInfoMap.size()); |
| EXPECT_EQ(1ul, atoms.pulledAtomsSignatureInfoMap.size()); |
| |
| // ExtensionAtomPushed |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT, JAVA_TYPE_LONG); |
| |
| // ExtensionAtomPulled |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.pulledAtomsSignatureInfoMap, JAVA_TYPE_LONG); |
| |
| EXPECT_EQ(2ul, atoms.decls.size()); |
| |
| AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); |
| EXPECT_EQ(9999, (*atomIt)->code); |
| EXPECT_EQ("extension_atom_pushed", (*atomIt)->name); |
| EXPECT_EQ("ExtensionAtomPushed", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| FieldNumberToAnnotations* fieldNumberToAnnotations = &(*atomIt)->fieldNumberToAnnotations; |
| FieldNumberToAnnotations::const_iterator fieldNumberToAnnotationsIt = |
| fieldNumberToAnnotations->find(1); |
| EXPECT_NE(fieldNumberToAnnotations->end(), fieldNumberToAnnotationsIt); |
| const AnnotationSet* annotationSet = &fieldNumberToAnnotationsIt->second; |
| EXPECT_EQ(1ul, annotationSet->size()); |
| Annotation* annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_IS_UID, annotation->annotationId); |
| EXPECT_EQ(9999, annotation->atomId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| atomIt++; |
| |
| EXPECT_EQ(99999, (*atomIt)->code); |
| EXPECT_EQ("extension_atom_pulled", (*atomIt)->name); |
| EXPECT_EQ("ExtensionAtomPulled", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| atomIt++; |
| |
| EXPECT_EQ(atoms.decls.end(), atomIt); |
| } |
| |
| TEST_P(CollationTest, CollateGoodRestrictedAtoms) { |
| Atoms atoms; |
| const int errorCount = collate_atoms(*mGoodRestrictedAtoms, DEFAULT_MODULE_NAME, atoms); |
| |
| EXPECT_EQ(0, errorCount); |
| ASSERT_EQ(1ul, atoms.signatureInfoMap.size()); |
| ASSERT_EQ(0ul, atoms.pulledAtomsSignatureInfoMap.size()); |
| |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_LONG, JAVA_TYPE_INT, |
| JAVA_TYPE_BOOLEAN, JAVA_TYPE_STRING, JAVA_TYPE_INT, |
| JAVA_TYPE_FLOAT, JAVA_TYPE_INT); |
| |
| // Validate signatureInfoMap |
| FieldNumberToAtomDeclSet fieldNumberToAtomDeclSet = atoms.signatureInfoMap.begin()->second; |
| ASSERT_EQ(8ul, fieldNumberToAtomDeclSet.size()); |
| const AtomDeclSet* atomDeclSet = &fieldNumberToAtomDeclSet[ATOM_ID_FIELD_NUMBER]; |
| ASSERT_EQ(2ul, atomDeclSet->size()); |
| AtomDeclSet::const_iterator atomDeclSetIt = atomDeclSet->begin(); |
| |
| const AtomDecl* atomDecl = atomDeclSetIt->get(); |
| EXPECT_EQ(1, atomDecl->code); |
| EXPECT_EQ("pushed_atom_1", atomDecl->name); |
| EXPECT_EQ("GoodRestrictedAtom", atomDecl->message); |
| FieldNumberToAnnotations fieldNumberToAnnotations = atomDecl->fieldNumberToAnnotations; |
| ASSERT_EQ(8ul, fieldNumberToAnnotations.size()); |
| |
| const AnnotationSet* annotationSet = &fieldNumberToAnnotations[ATOM_ID_FIELD_NUMBER]; |
| ASSERT_EQ(1ul, annotationSet->size()); |
| Annotation* annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_RESTRICTION_CATEGORY, annotation->annotationId); |
| EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type); |
| EXPECT_EQ(os::statsd::RESTRICTION_DIAGNOSTIC, annotation->value.intValue); |
| |
| annotationSet = &fieldNumberToAnnotations[1]; |
| ASSERT_EQ(1ul, annotationSet->size()); |
| annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_APP_USAGE, annotation->annotationId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| |
| annotationSet = &fieldNumberToAnnotations[2]; |
| ASSERT_EQ(1ul, annotationSet->size()); |
| annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_HEALTH_CONNECT, annotation->annotationId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| |
| annotationSet = &fieldNumberToAnnotations[3]; |
| ASSERT_EQ(1ul, annotationSet->size()); |
| annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_ACCESSIBILITY, annotation->annotationId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| |
| annotationSet = &fieldNumberToAnnotations[4]; |
| ASSERT_EQ(1ul, annotationSet->size()); |
| annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_SYSTEM_SEARCH, annotation->annotationId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| |
| annotationSet = &fieldNumberToAnnotations[5]; |
| ASSERT_EQ(1ul, annotationSet->size()); |
| annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_AMBIENT_SENSING, annotation->annotationId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| |
| annotationSet = &fieldNumberToAnnotations[6]; |
| ASSERT_EQ(1ul, annotationSet->size()); |
| annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_PERIPHERAL_DEVICE_INFO, annotation->annotationId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| |
| annotationSet = &fieldNumberToAnnotations[7]; |
| ASSERT_EQ(1ul, annotationSet->size()); |
| annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_FIELD_RESTRICTION_DEMOGRAPHIC_CLASSIFICATION, annotation->annotationId); |
| EXPECT_EQ(ANNOTATION_TYPE_BOOL, annotation->type); |
| EXPECT_TRUE(annotation->value.boolValue); |
| atomDeclSetIt++; |
| |
| atomDecl = atomDeclSetIt->get(); |
| EXPECT_EQ(2, atomDecl->code); |
| EXPECT_EQ("pushed_atom_2", atomDecl->name); |
| EXPECT_EQ("GoodRestrictedAtom", atomDecl->message); |
| fieldNumberToAnnotations = atomDecl->fieldNumberToAnnotations; |
| ASSERT_EQ(8ul, fieldNumberToAnnotations.size()); |
| annotationSet = &fieldNumberToAnnotations[ATOM_ID_FIELD_NUMBER]; |
| ASSERT_EQ(1ul, annotationSet->size()); |
| annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_RESTRICTION_CATEGORY, annotation->annotationId); |
| EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type); |
| EXPECT_EQ(os::statsd::RESTRICTION_SYSTEM_INTELLIGENCE, annotation->value.intValue); |
| atomDeclSetIt++; |
| EXPECT_EQ(atomDeclSet->end(), atomDeclSetIt); |
| |
| // Validate decls |
| ASSERT_EQ(2ul, atoms.decls.size()); |
| AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); |
| |
| EXPECT_EQ(1, (*atomIt)->code); |
| EXPECT_EQ("pushed_atom_1", (*atomIt)->name); |
| EXPECT_EQ("GoodRestrictedAtom", (*atomIt)->message); |
| fieldNumberToAnnotations = (*atomIt)->fieldNumberToAnnotations; |
| ASSERT_EQ(8ul, fieldNumberToAnnotations.size()); |
| |
| annotationSet = &fieldNumberToAnnotations[ATOM_ID_FIELD_NUMBER]; |
| ASSERT_EQ(1ul, annotationSet->size()); |
| annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_RESTRICTION_CATEGORY, annotation->annotationId); |
| EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type); |
| EXPECT_EQ(os::statsd::RESTRICTION_DIAGNOSTIC, annotation->value.intValue); |
| atomIt++; |
| |
| EXPECT_EQ(2, (*atomIt)->code); |
| EXPECT_EQ("pushed_atom_2", (*atomIt)->name); |
| EXPECT_EQ("GoodRestrictedAtom", (*atomIt)->message); |
| fieldNumberToAnnotations = (*atomIt)->fieldNumberToAnnotations; |
| ASSERT_EQ(8ul, fieldNumberToAnnotations.size()); |
| annotationSet = &fieldNumberToAnnotations[ATOM_ID_FIELD_NUMBER]; |
| ASSERT_EQ(1ul, annotationSet->size()); |
| annotation = annotationSet->begin()->get(); |
| EXPECT_EQ(ANNOTATION_ID_RESTRICTION_CATEGORY, annotation->annotationId); |
| EXPECT_EQ(ANNOTATION_TYPE_INT, annotation->type); |
| EXPECT_EQ(os::statsd::RESTRICTION_SYSTEM_INTELLIGENCE, annotation->value.intValue); |
| atomIt++; |
| EXPECT_EQ(atoms.decls.end(), atomIt); |
| |
| // Validate non_chained_decls |
| ASSERT_EQ(0ul, atoms.non_chained_decls.size()); |
| |
| // Validate nonChainedSignatureInfoMap |
| ASSERT_EQ(0ul, atoms.nonChainedSignatureInfoMap.size()); |
| } |
| |
| TEST_P(CollationTest, CollateBadRestrictedAtoms) { |
| Atoms atoms; |
| // Nonprimitive fields |
| int errorCount = collate_atoms(*mBadRestrictedAtoms1, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_EQ(6, errorCount); |
| |
| // Restriction category on atom field |
| errorCount = collate_atoms(*mBadRestrictedAtoms2, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_EQ(1, errorCount); |
| |
| // Field restriction without restriction category |
| errorCount = collate_atoms(*mBadRestrictedAtoms3, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_EQ(7, errorCount); |
| |
| // Field restriction option on top level atom field |
| errorCount = collate_atoms(*mBadRestrictedAtoms4, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_EQ(1, errorCount); |
| |
| // Pulled restricted atoms |
| errorCount = collate_atoms(*mBadRestrictedAtoms5, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_EQ(2, errorCount); |
| } |
| |
| TEST_P(CollationTest, CollateGoodUintAtoms) { |
| Atoms atoms; |
| int errorCount = collate_atoms(*mGoodUintAtoms, DEFAULT_MODULE_NAME, atoms); |
| EXPECT_EQ(0, errorCount); |
| |
| EXPECT_EQ(2ul, atoms.signatureInfoMap.size()); |
| |
| // AppDied |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_INT); |
| |
| // SystemUptime |
| EXPECT_MAP_CONTAINS_SIGNATURE(atoms.signatureInfoMap, JAVA_TYPE_LONG); |
| |
| EXPECT_EQ(2ul, atoms.decls.size()); |
| |
| AtomDeclSet::const_iterator atomIt = atoms.decls.begin(); |
| EXPECT_EQ(1, (*atomIt)->code); |
| EXPECT_EQ("app_died", (*atomIt)->name); |
| EXPECT_EQ("AppDied", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| atomIt++; |
| |
| EXPECT_EQ(2, (*atomIt)->code); |
| EXPECT_EQ("system_uptime", (*atomIt)->name); |
| EXPECT_EQ("SystemUptime", (*atomIt)->message); |
| EXPECT_NO_ENUM_FIELD((*atomIt)); |
| atomIt++; |
| |
| EXPECT_EQ(atoms.decls.end(), atomIt); |
| } |
| |
| } // namespace stats_log_api_gen |
| } // namespace android |