blob: 5846761cb8e9884de0abc5b8a73d087f400cb6e6 [file] [log] [blame]
Yao Chen8a8d16c2018-02-08 14:50:40 -08001/*
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#include <gtest/gtest.h>
Yao Chen9c1debe2018-02-19 14:39:19 -080017#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
Yao Chen8a8d16c2018-02-08 14:50:40 -080018#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
19#include "matchers/matcher_util.h"
Yao Chen9c1debe2018-02-19 14:39:19 -080020#include "src/logd/LogEvent.h"
Yao Chen8a8d16c2018-02-08 14:50:40 -080021#include "stats_log_util.h"
22#include "stats_util.h"
23#include "subscriber/SubscriberReporter.h"
24
25#ifdef __ANDROID__
26
27namespace android {
28namespace os {
29namespace statsd {
30
31TEST(AtomMatcherTest, TestFieldTranslation) {
32 FieldMatcher matcher1;
33 matcher1.set_field(10);
34 FieldMatcher* child = matcher1.add_child();
35 child->set_field(1);
36 child->set_position(Position::ANY);
37
38 child = child->add_child();
39 child->set_field(1);
40
41 vector<Matcher> output;
42 translateFieldMatcher(matcher1, &output);
43
44 EXPECT_EQ((size_t)1, output.size());
45
46 const auto& matcher12 = output[0];
47 EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
48 EXPECT_EQ((int32_t)0x2010001, matcher12.mMatcher.getField());
49 EXPECT_EQ((int32_t)0xff7f007f, matcher12.mMask);
50}
51
52TEST(AtomMatcherTest, TestFilter) {
53 FieldMatcher matcher1;
54 matcher1.set_field(10);
55 FieldMatcher* child = matcher1.add_child();
56 child->set_field(1);
57 child->set_position(Position::ANY);
58
59 child = child->add_child();
60 child->set_field(1);
61
62 child = matcher1.add_child();
63 child->set_field(2);
64
65 vector<Matcher> matchers;
66 translateFieldMatcher(matcher1, &matchers);
67
Yao Chen9c1debe2018-02-19 14:39:19 -080068 AttributionNodeInternal attribution_node1;
Yao Chen8a8d16c2018-02-08 14:50:40 -080069 attribution_node1.set_uid(1111);
70 attribution_node1.set_tag("location1");
71
Yao Chen9c1debe2018-02-19 14:39:19 -080072 AttributionNodeInternal attribution_node2;
Yao Chen8a8d16c2018-02-08 14:50:40 -080073 attribution_node2.set_uid(2222);
74 attribution_node2.set_tag("location2");
75
Yao Chen9c1debe2018-02-19 14:39:19 -080076 AttributionNodeInternal attribution_node3;
Yao Chen8a8d16c2018-02-08 14:50:40 -080077 attribution_node3.set_uid(3333);
78 attribution_node3.set_tag("location3");
Yao Chen9c1debe2018-02-19 14:39:19 -080079 std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
80 attribution_node3};
Yao Chen8a8d16c2018-02-08 14:50:40 -080081
82 // Set up the event
83 LogEvent event(10, 12345);
84 event.write(attribution_nodes);
85 event.write("some value");
86 // Convert to a LogEvent
87 event.init();
88 vector<HashableDimensionKey> output;
89
90 filterValues(matchers, event.getValues(), &output);
91
92 EXPECT_EQ((size_t)(3), output.size());
93
94 const auto& key1 = output[0];
95 EXPECT_EQ((size_t)2, key1.getValues().size());
96 EXPECT_EQ((int32_t)0x02010001, key1.getValues()[0].mField.getField());
97 EXPECT_EQ((int32_t)1111, key1.getValues()[0].mValue.int_value);
98 EXPECT_EQ((int32_t)0x00020000, key1.getValues()[1].mField.getField());
99 EXPECT_EQ("some value", key1.getValues()[1].mValue.str_value);
100
101 const auto& key2 = output[1];
102 EXPECT_EQ((size_t)2, key2.getValues().size());
103 EXPECT_EQ((int32_t)0x02010001, key2.getValues()[0].mField.getField());
104 EXPECT_EQ((int32_t)2222, key2.getValues()[0].mValue.int_value);
105 EXPECT_EQ((int32_t)0x00020000, key2.getValues()[1].mField.getField());
106 EXPECT_EQ("some value", key2.getValues()[1].mValue.str_value);
107
108 const auto& key3 = output[2];
109 EXPECT_EQ((size_t)2, key3.getValues().size());
110 EXPECT_EQ((int32_t)0x02010001, key3.getValues()[0].mField.getField());
111 EXPECT_EQ((int32_t)3333, key3.getValues()[0].mValue.int_value);
112 EXPECT_EQ((int32_t)0x00020000, key3.getValues()[1].mField.getField());
113 EXPECT_EQ("some value", key3.getValues()[1].mValue.str_value);
114}
115
116TEST(AtomMatcherTest, TestSubDimension) {
117 HashableDimensionKey dim;
118
119 int pos1[] = {1, 1, 1};
120 int pos2[] = {1, 1, 2};
121 int pos3[] = {1, 1, 3};
122 int pos4[] = {2, 0, 0};
123 Field field1(10, pos1, 2);
124 Field field2(10, pos2, 2);
125
126 Field field3(10, pos3, 2);
127 Field field4(10, pos4, 0);
128
129 Value value1((int32_t)10025);
130 Value value2("tag");
131
132 Value value11((int32_t)10026);
133 Value value22("tag2");
134
135 dim.addValue(FieldValue(field1, value1));
136 dim.addValue(FieldValue(field2, value2));
137
138 HashableDimensionKey subDim1;
139 subDim1.addValue(FieldValue(field1, value1));
140
141 HashableDimensionKey subDim2;
142 subDim1.addValue(FieldValue(field2, value2));
143
144 EXPECT_TRUE(dim.contains(dim));
145 EXPECT_TRUE(dim.contains(subDim1));
146 EXPECT_TRUE(dim.contains(subDim2));
147
148 HashableDimensionKey subDim3;
149 subDim3.addValue(FieldValue(field1, value11));
150 EXPECT_FALSE(dim.contains(subDim3));
151
152 HashableDimensionKey subDim4;
153 // Empty dimension is always a sub dimension of other dimensions
154 EXPECT_TRUE(dim.contains(subDim4));
155}
156
157TEST(AtomMatcherTest, TestMetric2ConditionLink) {
Yao Chen9c1debe2018-02-19 14:39:19 -0800158 AttributionNodeInternal attribution_node1;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800159 attribution_node1.set_uid(1111);
160 attribution_node1.set_tag("location1");
161
Yao Chen9c1debe2018-02-19 14:39:19 -0800162 AttributionNodeInternal attribution_node2;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800163 attribution_node2.set_uid(2222);
164 attribution_node2.set_tag("location2");
165
Yao Chen9c1debe2018-02-19 14:39:19 -0800166 AttributionNodeInternal attribution_node3;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800167 attribution_node3.set_uid(3333);
168 attribution_node3.set_tag("location3");
Yao Chen9c1debe2018-02-19 14:39:19 -0800169 std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
170 attribution_node3};
Yao Chen8a8d16c2018-02-08 14:50:40 -0800171
172 // Set up the event
173 LogEvent event(10, 12345);
174 event.write(attribution_nodes);
175 event.write("some value");
176 // Convert to a LogEvent
177 event.init();
178
179 FieldMatcher whatMatcher;
180 whatMatcher.set_field(10);
181 FieldMatcher* child11 = whatMatcher.add_child();
182 child11->set_field(1);
183 child11->set_position(Position::ANY);
184 child11 = child11->add_child();
185 child11->set_field(1);
186
187 FieldMatcher conditionMatcher;
188 conditionMatcher.set_field(27);
189 FieldMatcher* child2 = conditionMatcher.add_child();
190 child2->set_field(2);
191 child2->set_position(Position::LAST);
192
193 child2 = child2->add_child();
194 child2->set_field(2);
195
196 Metric2Condition link;
197
198 translateFieldMatcher(whatMatcher, &link.metricFields);
199 translateFieldMatcher(conditionMatcher, &link.conditionFields);
200
201 EXPECT_EQ((size_t)1, link.metricFields.size());
202 EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
203 EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
204 EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
205
206 EXPECT_EQ((size_t)1, link.conditionFields.size());
207 EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
208 EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
209 EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
210}
211
212TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
213 HashableDimensionKey dim;
214
215 int pos1[] = {1, 1, 1};
216 int pos2[] = {1, 1, 2};
217 int pos3[] = {1, 1, 3};
218 int pos4[] = {2, 0, 0};
219
220 Field field1(10, pos1, 2);
221 Field field2(10, pos2, 2);
222 Field field3(10, pos3, 2);
223 Field field4(10, pos4, 0);
224
225 Value value1((int32_t)10025);
226 Value value2("tag");
227 Value value3((int32_t)987654);
228 Value value4((int32_t)99999);
229
230 dim.addValue(FieldValue(field1, value1));
231 dim.addValue(FieldValue(field2, value2));
232 dim.addValue(FieldValue(field3, value3));
233 dim.addValue(FieldValue(field4, value4));
234
235 SubscriberReporter::getStatsDimensionsValue(dim);
236 // TODO: can't test anything here because SubscriberReport class doesn't have any read api.
237}
238
239TEST(AtomMatcherTest, TestWriteDimensionToProto) {
240 HashableDimensionKey dim;
241 int pos1[] = {1, 1, 1};
242 int pos2[] = {1, 1, 2};
243 int pos3[] = {1, 1, 3};
244 int pos4[] = {2, 0, 0};
245 Field field1(10, pos1, 2);
246 Field field2(10, pos2, 2);
247 Field field3(10, pos3, 2);
248 Field field4(10, pos4, 0);
249
250 Value value1((int32_t)10025);
251 Value value2("tag");
252 Value value3((int32_t)987654);
253 Value value4((int32_t)99999);
254
255 dim.addValue(FieldValue(field1, value1));
256 dim.addValue(FieldValue(field2, value2));
257 dim.addValue(FieldValue(field3, value3));
258 dim.addValue(FieldValue(field4, value4));
259
260 android::util::ProtoOutputStream protoOut;
261 writeDimensionToProto(dim, &protoOut);
262
263 vector<uint8_t> outData;
264 outData.resize(protoOut.size());
265 size_t pos = 0;
266 auto iter = protoOut.data();
267 while (iter.readBuffer() != NULL) {
268 size_t toRead = iter.currentToRead();
269 std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
270 pos += toRead;
271 iter.rp()->move(toRead);
272 }
273
274 DimensionsValue result;
275 EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
276 EXPECT_EQ(10, result.field());
277 EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
278 EXPECT_EQ(2, result.value_tuple().dimensions_value_size());
279
280 const auto& dim1 = result.value_tuple().dimensions_value(0);
281 EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case());
282 EXPECT_EQ(3, dim1.value_tuple().dimensions_value_size());
283
284 const auto& dim11 = dim1.value_tuple().dimensions_value(0);
285 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case());
286 EXPECT_EQ(10025, dim11.value_int());
287
288 const auto& dim12 = dim1.value_tuple().dimensions_value(1);
289 EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim12.value_case());
290 EXPECT_EQ("tag", dim12.value_str());
291
292 const auto& dim13 = dim1.value_tuple().dimensions_value(2);
293 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim13.value_case());
294 EXPECT_EQ(987654, dim13.value_int());
295
296 const auto& dim2 = result.value_tuple().dimensions_value(1);
297 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim2.value_case());
298 EXPECT_EQ(99999, dim2.value_int());
299}
300
301TEST(AtomMatcherTest, TestWriteAtomToProto) {
Yao Chen9c1debe2018-02-19 14:39:19 -0800302 AttributionNodeInternal attribution_node1;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800303 attribution_node1.set_uid(1111);
304 attribution_node1.set_tag("location1");
305
Yao Chen9c1debe2018-02-19 14:39:19 -0800306 AttributionNodeInternal attribution_node2;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800307 attribution_node2.set_uid(2222);
308 attribution_node2.set_tag("location2");
309
Yao Chen9c1debe2018-02-19 14:39:19 -0800310 std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2};
Yao Chen8a8d16c2018-02-08 14:50:40 -0800311
312 // Set up the event
313 LogEvent event(4, 12345);
314 event.write(attribution_nodes);
315 event.write((int32_t)999);
316 // Convert to a LogEvent
317 event.init();
318
319 android::util::ProtoOutputStream protoOutput;
320 writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
321
322 vector<uint8_t> outData;
323 outData.resize(protoOutput.size());
324 size_t pos = 0;
325 auto iter = protoOutput.data();
326 while (iter.readBuffer() != NULL) {
327 size_t toRead = iter.currentToRead();
328 std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
329 pos += toRead;
330 iter.rp()->move(toRead);
331 }
332
333 Atom result;
334 EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
335 EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
336 const auto& atom = result.ble_scan_result_received();
337 EXPECT_EQ(2, atom.attribution_node_size());
338 EXPECT_EQ(1111, atom.attribution_node(0).uid());
339 EXPECT_EQ("location1", atom.attribution_node(0).tag());
340 EXPECT_EQ(2222, atom.attribution_node(1).uid());
341 EXPECT_EQ("location2", atom.attribution_node(1).tag());
342 EXPECT_EQ(999, atom.num_of_results());
343}
344
345
346} // namespace statsd
347} // namespace os
348} // namespace android
349#else
350GTEST_LOG_(INFO) << "This test does nothing.\n";
351#endif