1/* 2 * Copyright (C) 2017, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <gtest/gtest.h> 18 19#include "frameworks/base/tools/stats_log_api_gen/test.pb.h" 20#include "Collation.h" 21 22#include <stdio.h> 23 24namespace android { 25namespace stats_log_api_gen { 26 27using std::map; 28using std::set; 29using std::vector; 30 31/** 32 * Return whether the set contains a vector of the elements provided. 33 */ 34static bool 35set_contains_vector(const set<vector<java_type_t>>& s, int count, ...) 36{ 37 va_list args; 38 vector<java_type_t> v; 39 40 va_start(args, count); 41 for (int i=0; i<count; i++) { 42 v.push_back((java_type_t)va_arg(args, int)); 43 } 44 va_end(args); 45 46 return s.find(v) != s.end(); 47} 48 49/** 50 * Expect that the provided set contains the elements provided. 51 */ 52#define EXPECT_SET_CONTAINS_SIGNATURE(s, ...) \ 53 do { \ 54 int count = sizeof((int[]){__VA_ARGS__})/sizeof(int); \ 55 EXPECT_TRUE(set_contains_vector(s, count, __VA_ARGS__)); \ 56 } while(0) 57 58/** Expects that the provided atom has no enum values for any field. */ 59#define EXPECT_NO_ENUM_FIELD(atom) \ 60 do { \ 61 for (vector<AtomField>::const_iterator field = atom->fields.begin(); \ 62 field != atom->fields.end(); field++) { \ 63 EXPECT_TRUE(field->enumValues.empty()); \ 64 } \ 65 } while(0) 66 67/** Expects that exactly one specific field has expected enum values. */ 68#define EXPECT_HAS_ENUM_FIELD(atom, field_name, values) \ 69 do { \ 70 for (vector<AtomField>::const_iterator field = atom->fields.begin(); \ 71 field != atom->fields.end(); field++) { \ 72 if (field->name == field_name) { \ 73 EXPECT_EQ(field->enumValues, values); \ 74 } else { \ 75 EXPECT_TRUE(field->enumValues.empty()); \ 76 } \ 77 } \ 78 } while(0) 79 80 81/** 82 * Test a correct collation, with all the types. 83 */ 84TEST(CollationTest, CollateStats) { 85 Atoms atoms; 86 int errorCount = collate_atoms(Event::descriptor(), &atoms); 87 88 EXPECT_EQ(0, errorCount); 89 EXPECT_EQ(3ul, atoms.signatures.size()); 90 91 // IntAtom, AnotherIntAtom 92 EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures, JAVA_TYPE_INT); 93 94 // OutOfOrderAtom 95 EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures, JAVA_TYPE_INT, JAVA_TYPE_INT); 96 97 // AllTypesAtom 98 EXPECT_SET_CONTAINS_SIGNATURE( 99 atoms.signatures, 100 JAVA_TYPE_ATTRIBUTION_CHAIN, // AttributionChain 101 JAVA_TYPE_DOUBLE, // double 102 JAVA_TYPE_FLOAT, // float 103 JAVA_TYPE_LONG, // int64 104 JAVA_TYPE_LONG, // uint64 105 JAVA_TYPE_INT, // int32 106 JAVA_TYPE_LONG, // fixed64 107 JAVA_TYPE_INT, // fixed32 108 JAVA_TYPE_BOOLEAN, // bool 109 JAVA_TYPE_STRING, // string 110 JAVA_TYPE_INT, // uint32 111 JAVA_TYPE_INT, // AnEnum 112 JAVA_TYPE_INT, // sfixed32 113 JAVA_TYPE_LONG, // sfixed64 114 JAVA_TYPE_INT, // sint32 115 JAVA_TYPE_LONG // sint64 116 ); 117 118 set<AtomDecl>::const_iterator atom = atoms.decls.begin(); 119 EXPECT_EQ(1, atom->code); 120 EXPECT_EQ("int_atom", atom->name); 121 EXPECT_EQ("IntAtom", atom->message); 122 EXPECT_NO_ENUM_FIELD(atom); 123 atom++; 124 125 EXPECT_EQ(2, atom->code); 126 EXPECT_EQ("out_of_order_atom", atom->name); 127 EXPECT_EQ("OutOfOrderAtom", atom->message); 128 EXPECT_NO_ENUM_FIELD(atom); 129 atom++; 130 131 EXPECT_EQ(3, atom->code); 132 EXPECT_EQ("another_int_atom", atom->name); 133 EXPECT_EQ("AnotherIntAtom", atom->message); 134 EXPECT_NO_ENUM_FIELD(atom); 135 atom++; 136 137 EXPECT_EQ(4, atom->code); 138 EXPECT_EQ("all_types_atom", atom->name); 139 EXPECT_EQ("AllTypesAtom", atom->message); 140 map<int, string> enumValues; 141 enumValues[0] = "VALUE0"; 142 enumValues[1] = "VALUE1"; 143 EXPECT_HAS_ENUM_FIELD(atom, "enum_field", enumValues); 144 atom++; 145 146 EXPECT_TRUE(atom == atoms.decls.end()); 147} 148 149/** 150 * Test that event class that contains stuff other than the atoms is rejected. 151 */ 152TEST(CollationTest, NonMessageTypeFails) { 153 Atoms atoms; 154 int errorCount = collate_atoms(IntAtom::descriptor(), &atoms); 155 156 EXPECT_EQ(1, errorCount); 157} 158 159/** 160 * Test that atoms that have non-primitive types are rejected. 161 */ 162TEST(CollationTest, FailOnBadTypes) { 163 Atoms atoms; 164 int errorCount = collate_atoms(BadTypesEvent::descriptor(), &atoms); 165 166 EXPECT_EQ(2, errorCount); 167} 168 169/** 170 * Test that atoms that skip field numbers (in the first position) are rejected. 171 */ 172TEST(CollationTest, FailOnSkippedFieldsSingle) { 173 Atoms atoms; 174 int errorCount = collate_atoms(BadSkippedFieldSingle::descriptor(), &atoms); 175 176 EXPECT_EQ(1, errorCount); 177} 178 179/** 180 * Test that atoms that skip field numbers (not in the first position, and multiple 181 * times) are rejected. 182 */ 183TEST(CollationTest, FailOnSkippedFieldsMultiple) { 184 Atoms atoms; 185 int errorCount = collate_atoms(BadSkippedFieldMultiple::descriptor(), &atoms); 186 187 EXPECT_EQ(2, errorCount); 188} 189 190/** 191 * Test that atoms that have an attribution chain not in the first position are 192 * rejected. 193 */ 194TEST(CollationTest, FailBadAttributionNodePosition) { 195 Atoms atoms; 196 int errorCount = 197 collate_atoms(BadAttributionNodePosition::descriptor(), &atoms); 198 199 EXPECT_EQ(1, errorCount); 200} 201 202TEST(CollationTest, FailOnBadStateAtomOptions) { 203 Atoms atoms; 204 int errorCount = collate_atoms(BadStateAtoms::descriptor(), &atoms); 205 206 EXPECT_EQ(3, errorCount); 207} 208 209TEST(CollationTest, PassOnGoodStateAtomOptions) { 210 Atoms atoms; 211 int errorCount = collate_atoms(GoodStateAtoms::descriptor(), &atoms); 212 EXPECT_EQ(0, errorCount); 213} 214 215} // namespace stats_log_api_gen 216} // namespace android