blob: f59bb6f49ce11173cc9d2d2fd466b05e2da2ba49 [file] [log] [blame]
Yao Chend54f9dd2017-10-17 17:37:48 +00001/*
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
Stefan Lafon9478f352017-10-30 21:20:20 -070027using std::map;
Yao Chend54f9dd2017-10-17 17:37:48 +000028using std::set;
29using std::vector;
30
31/**
32 * Return whether the set contains a vector of the elements provided.
33 */
34static bool
Tej Singh1f431f32019-03-07 19:08:52 -080035set_contains_vector(const map<vector<java_type_t>, set<string>>& s, int count, ...)
Yao Chend54f9dd2017-10-17 17:37:48 +000036{
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
Stefan Lafon9478f352017-10-30 21:20:20 -070058/** 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
Yangster-mac7604aea2017-12-11 22:55:49 -080067/** Expects that exactly one specific field has expected enum values. */
Stefan Lafon9478f352017-10-30 21:20:20 -070068#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
Yao Chend54f9dd2017-10-17 17:37:48 +000081/**
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);
Tej Singh1f431f32019-03-07 19:08:52 -080089 EXPECT_EQ(3ul, atoms.signatures_to_modules.size());
Yao Chend54f9dd2017-10-17 17:37:48 +000090
91 // IntAtom, AnotherIntAtom
Tej Singh1f431f32019-03-07 19:08:52 -080092 EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT);
Yao Chend54f9dd2017-10-17 17:37:48 +000093
94 // OutOfOrderAtom
Tej Singh1f431f32019-03-07 19:08:52 -080095 EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT, JAVA_TYPE_INT);
Yao Chend54f9dd2017-10-17 17:37:48 +000096
97 // AllTypesAtom
Yangster-mac7604aea2017-12-11 22:55:49 -080098 EXPECT_SET_CONTAINS_SIGNATURE(
Tej Singh1f431f32019-03-07 19:08:52 -080099 atoms.signatures_to_modules,
Yangster-mac7604aea2017-12-11 22:55:49 -0800100 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 );
Yao Chend54f9dd2017-10-17 17:37:48 +0000117
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);
Stefan Lafon9478f352017-10-30 21:20:20 -0700122 EXPECT_NO_ENUM_FIELD(atom);
Yao Chend54f9dd2017-10-17 17:37:48 +0000123 atom++;
124
125 EXPECT_EQ(2, atom->code);
126 EXPECT_EQ("out_of_order_atom", atom->name);
127 EXPECT_EQ("OutOfOrderAtom", atom->message);
Stefan Lafon9478f352017-10-30 21:20:20 -0700128 EXPECT_NO_ENUM_FIELD(atom);
Yao Chend54f9dd2017-10-17 17:37:48 +0000129 atom++;
130
131 EXPECT_EQ(3, atom->code);
132 EXPECT_EQ("another_int_atom", atom->name);
133 EXPECT_EQ("AnotherIntAtom", atom->message);
Stefan Lafon9478f352017-10-30 21:20:20 -0700134 EXPECT_NO_ENUM_FIELD(atom);
Yao Chend54f9dd2017-10-17 17:37:48 +0000135 atom++;
136
137 EXPECT_EQ(4, atom->code);
138 EXPECT_EQ("all_types_atom", atom->name);
139 EXPECT_EQ("AllTypesAtom", atom->message);
Stefan Lafon9478f352017-10-30 21:20:20 -0700140 map<int, string> enumValues;
141 enumValues[0] = "VALUE0";
142 enumValues[1] = "VALUE1";
143 EXPECT_HAS_ENUM_FIELD(atom, "enum_field", enumValues);
Yao Chend54f9dd2017-10-17 17:37:48 +0000144 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/**
Stefan Lafon9478f352017-10-30 21:20:20 -0700160 * Test that atoms that have non-primitive types are rejected.
Yao Chend54f9dd2017-10-17 17:37:48 +0000161 */
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/**
Yangster-mac7604aea2017-12-11 22:55:49 -0800191 * Test that atoms that have an attribution chain not in the first position are
192 * rejected.
Yao Chend54f9dd2017-10-17 17:37:48 +0000193 */
Yangster-mac20877162017-12-22 17:19:39 -0800194TEST(CollationTest, FailBadAttributionNodePosition) {
Yangster-mac7604aea2017-12-11 22:55:49 -0800195 Atoms atoms;
196 int errorCount =
Yangster-mac20877162017-12-22 17:19:39 -0800197 collate_atoms(BadAttributionNodePosition::descriptor(), &atoms);
Yao Chend54f9dd2017-10-17 17:37:48 +0000198
Yangster-mac7604aea2017-12-11 22:55:49 -0800199 EXPECT_EQ(1, errorCount);
Yao Chend54f9dd2017-10-17 17:37:48 +0000200}
201
Yao Chen9c1debe2018-02-19 14:39:19 -0800202TEST(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
Yao Chen8b71c742018-10-24 12:15:56 -0700215TEST(CollationTest, PassOnGoodBinaryFieldAtom) {
216 Atoms atoms;
217 int errorCount =
218 collate_atoms(GoodEventWithBinaryFieldAtom::descriptor(), &atoms);
219 EXPECT_EQ(0, errorCount);
220}
221
222TEST(CollationTest, FailOnBadBinaryFieldAtom) {
223 Atoms atoms;
224 int errorCount =
225 collate_atoms(BadEventWithBinaryFieldAtom::descriptor(), &atoms);
226 EXPECT_TRUE(errorCount > 0);
227}
228
Tej Singh1f431f32019-03-07 19:08:52 -0800229TEST(CollationTest, PassOnLogFromModuleAtom) {
230 Atoms atoms;
231 int errorCount = collate_atoms(ModuleAtoms::descriptor(), &atoms);
232 EXPECT_EQ(errorCount, 0);
233 EXPECT_EQ(atoms.decls.size(), 3ul);
234}
235
236TEST(CollationTest, RecognizeModuleAtom) {
237 Atoms atoms;
238 int errorCount = collate_atoms(ModuleAtoms::descriptor(), &atoms);
239 EXPECT_EQ(errorCount, 0);
240 EXPECT_EQ(atoms.decls.size(), 3ul);
241 for (const auto& atomDecl: atoms.decls) {
242 if (atomDecl.code == 1) {
243 EXPECT_TRUE(atomDecl.hasModule);
244 EXPECT_EQ(atomDecl.moduleName, "module1");
245 } else if (atomDecl.code == 2) {
246 EXPECT_TRUE(atomDecl.hasModule);
247 EXPECT_EQ(atomDecl.moduleName, "module2");
248 } else {
249 EXPECT_FALSE(atomDecl.hasModule);
250 }
251 }
252
253 EXPECT_EQ(atoms.signatures_to_modules.size(), 2u);
254 EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT);
255 EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_STRING);
256 for (auto signature_to_modules_it : atoms.signatures_to_modules) {
257 vector<java_type_t> signature = signature_to_modules_it.first;
258 if (signature[0] == JAVA_TYPE_STRING) {
259 EXPECT_EQ(signature_to_modules_it.second.size(), 0u);
260 } else if (signature[0] == JAVA_TYPE_INT) {
261 set<string> modules = signature_to_modules_it.second;
262 EXPECT_EQ(modules.size(), 2u);
263 // Assert that the set contains "module1" and "module2".
264 EXPECT_NE(modules.find("module1"), modules.end());
265 EXPECT_NE(modules.find("module2"), modules.end());
266 }
267 }
268}
269
Yao Chend54f9dd2017-10-17 17:37:48 +0000270} // namespace stats_log_api_gen
Tej Singh1f431f32019-03-07 19:08:52 -0800271} // namespace android