blob: a21eb9b9147ff56a2c7842f2d20028dfa194805b [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>
tsaichristinea3d2ed82020-03-19 20:53:36 -070017
Yao Chen9c1debe2018-02-19 14:39:19 -080018#include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
Yao Chen8a8d16c2018-02-08 14:50:40 -080019#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
20#include "matchers/matcher_util.h"
Yao Chen9c1debe2018-02-19 14:39:19 -080021#include "src/logd/LogEvent.h"
tsaichristinea3d2ed82020-03-19 20:53:36 -070022#include "stats_event.h"
Yao Chen8a8d16c2018-02-08 14:50:40 -080023#include "stats_log_util.h"
24#include "stats_util.h"
25#include "subscriber/SubscriberReporter.h"
tsaichristinea3d2ed82020-03-19 20:53:36 -070026#include "tests/statsd_test_util.h"
Yao Chen8a8d16c2018-02-08 14:50:40 -080027
28#ifdef __ANDROID__
29
Joe Onorato99598ee2019-02-11 15:55:13 +000030using android::util::ProtoReader;
31
Yao Chen8a8d16c2018-02-08 14:50:40 -080032namespace android {
33namespace os {
34namespace statsd {
35
Ruchir Rastogi197107c2020-06-14 22:07:38 -070036// These constants must be kept in sync with those in StatsDimensionsValue.java.
37const static int STATS_DIMENSIONS_VALUE_STRING_TYPE = 2;
38const static int STATS_DIMENSIONS_VALUE_INT_TYPE = 3;
39const static int STATS_DIMENSIONS_VALUE_FLOAT_TYPE = 6;
40const static int STATS_DIMENSIONS_VALUE_TUPLE_TYPE = 7;
41
tsaichristinea3d2ed82020-03-19 20:53:36 -070042namespace {
43void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
44 const vector<int>& attributionUids, const vector<string>& attributionTags,
45 const string& name) {
46 AStatsEvent* statsEvent = AStatsEvent_obtain();
47 AStatsEvent_setAtomId(statsEvent, atomId);
48 AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
49
tsaichristine8dca82e2020-04-07 09:40:03 -070050 writeAttribution(statsEvent, attributionUids, attributionTags);
tsaichristinea3d2ed82020-03-19 20:53:36 -070051 AStatsEvent_writeString(statsEvent, name.c_str());
tsaichristinea3d2ed82020-03-19 20:53:36 -070052
tsaichristine8dca82e2020-04-07 09:40:03 -070053 parseStatsEventToLogEvent(statsEvent, logEvent);
tsaichristinea3d2ed82020-03-19 20:53:36 -070054}
55
56void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp,
57 const vector<int>& attributionUids, const vector<string>& attributionTags,
58 const int32_t value) {
59 AStatsEvent* statsEvent = AStatsEvent_obtain();
60 AStatsEvent_setAtomId(statsEvent, atomId);
61 AStatsEvent_overwriteTimestamp(statsEvent, timestamp);
62
tsaichristine8dca82e2020-04-07 09:40:03 -070063 writeAttribution(statsEvent, attributionUids, attributionTags);
tsaichristinea3d2ed82020-03-19 20:53:36 -070064 AStatsEvent_writeInt32(statsEvent, value);
tsaichristinea3d2ed82020-03-19 20:53:36 -070065
tsaichristine8dca82e2020-04-07 09:40:03 -070066 parseStatsEventToLogEvent(statsEvent, logEvent);
tsaichristinea3d2ed82020-03-19 20:53:36 -070067}
68} // anonymous namespace
69
Yao Chen8a8d16c2018-02-08 14:50:40 -080070TEST(AtomMatcherTest, TestFieldTranslation) {
71 FieldMatcher matcher1;
72 matcher1.set_field(10);
73 FieldMatcher* child = matcher1.add_child();
74 child->set_field(1);
75 child->set_position(Position::ANY);
76
77 child = child->add_child();
78 child->set_field(1);
79
80 vector<Matcher> output;
81 translateFieldMatcher(matcher1, &output);
82
Muhammad Qureshidff78d62020-05-11 13:37:43 -070083 ASSERT_EQ((size_t)1, output.size());
Yao Chen8a8d16c2018-02-08 14:50:40 -080084
85 const auto& matcher12 = output[0];
86 EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
Yangster-mace06cfd72018-03-10 23:22:59 -080087 EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
Yao Chen8a8d16c2018-02-08 14:50:40 -080088 EXPECT_EQ((int32_t)0xff7f007f, matcher12.mMask);
89}
90
Yangster-mace06cfd72018-03-10 23:22:59 -080091TEST(AtomMatcherTest, TestFieldTranslation_ALL) {
Yao Chen8a8d16c2018-02-08 14:50:40 -080092 FieldMatcher matcher1;
93 matcher1.set_field(10);
94 FieldMatcher* child = matcher1.add_child();
95 child->set_field(1);
Yangster-mace06cfd72018-03-10 23:22:59 -080096 child->set_position(Position::ALL);
Yao Chen8a8d16c2018-02-08 14:50:40 -080097
98 child = child->add_child();
99 child->set_field(1);
100
Yangster-mace06cfd72018-03-10 23:22:59 -0800101 vector<Matcher> output;
102 translateFieldMatcher(matcher1, &output);
103
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700104 ASSERT_EQ((size_t)1, output.size());
Yangster-mace06cfd72018-03-10 23:22:59 -0800105
106 const auto& matcher12 = output[0];
107 EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
108 EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
109 EXPECT_EQ((int32_t)0xff7f7f7f, matcher12.mMask);
110}
111
tsaichristinea3d2ed82020-03-19 20:53:36 -0700112TEST(AtomMatcherTest, TestFilter_ALL) {
113 FieldMatcher matcher1;
114 matcher1.set_field(10);
115 FieldMatcher* child = matcher1.add_child();
116 child->set_field(1);
117 child->set_position(Position::ALL);
118
119 child->add_child()->set_field(1);
120 child->add_child()->set_field(2);
121
122 child = matcher1.add_child();
123 child->set_field(2);
124
125 vector<Matcher> matchers;
126 translateFieldMatcher(matcher1, &matchers);
127
128 std::vector<int> attributionUids = {1111, 2222, 3333};
129 std::vector<string> attributionTags = {"location1", "location2", "location3"};
130
131 LogEvent event(/*uid=*/0, /*pid=*/0);
132 makeLogEvent(&event, 10 /*atomId*/, 1012345, attributionUids, attributionTags, "some value");
133 HashableDimensionKey output;
134
135 filterValues(matchers, event.getValues(), &output);
136
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700137 ASSERT_EQ((size_t)7, output.getValues().size());
tsaichristinea3d2ed82020-03-19 20:53:36 -0700138 EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
139 EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
140 EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
141 EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
142
143 EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField());
144 EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value);
145 EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField());
146 EXPECT_EQ("location2", output.getValues()[3].mValue.str_value);
147
148 EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField());
149 EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value);
150 EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField());
151 EXPECT_EQ("location3", output.getValues()[5].mValue.str_value);
152
153 EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField());
154 EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
155}
Yao Chen8a8d16c2018-02-08 14:50:40 -0800156
157TEST(AtomMatcherTest, TestSubDimension) {
158 HashableDimensionKey dim;
159
160 int pos1[] = {1, 1, 1};
161 int pos2[] = {1, 1, 2};
162 int pos3[] = {1, 1, 3};
163 int pos4[] = {2, 0, 0};
164 Field field1(10, pos1, 2);
165 Field field2(10, pos2, 2);
166
167 Field field3(10, pos3, 2);
168 Field field4(10, pos4, 0);
169
170 Value value1((int32_t)10025);
171 Value value2("tag");
172
173 Value value11((int32_t)10026);
174 Value value22("tag2");
175
176 dim.addValue(FieldValue(field1, value1));
177 dim.addValue(FieldValue(field2, value2));
178
179 HashableDimensionKey subDim1;
180 subDim1.addValue(FieldValue(field1, value1));
181
182 HashableDimensionKey subDim2;
183 subDim1.addValue(FieldValue(field2, value2));
184
185 EXPECT_TRUE(dim.contains(dim));
186 EXPECT_TRUE(dim.contains(subDim1));
187 EXPECT_TRUE(dim.contains(subDim2));
188
189 HashableDimensionKey subDim3;
190 subDim3.addValue(FieldValue(field1, value11));
191 EXPECT_FALSE(dim.contains(subDim3));
192
193 HashableDimensionKey subDim4;
194 // Empty dimension is always a sub dimension of other dimensions
195 EXPECT_TRUE(dim.contains(subDim4));
196}
197
tsaichristinea3d2ed82020-03-19 20:53:36 -0700198TEST(AtomMatcherTest, TestMetric2ConditionLink) {
199 std::vector<int> attributionUids = {1111, 2222, 3333};
200 std::vector<string> attributionTags = {"location1", "location2", "location3"};
201
202 LogEvent event(/*uid=*/0, /*pid=*/0);
203 makeLogEvent(&event, 10 /*atomId*/, 12345, attributionUids, attributionTags, "some value");
204
205 FieldMatcher whatMatcher;
206 whatMatcher.set_field(10);
207 FieldMatcher* child11 = whatMatcher.add_child();
208 child11->set_field(1);
209 child11->set_position(Position::ANY);
210 child11 = child11->add_child();
211 child11->set_field(1);
212
213 FieldMatcher conditionMatcher;
214 conditionMatcher.set_field(27);
215 FieldMatcher* child2 = conditionMatcher.add_child();
216 child2->set_field(2);
217 child2->set_position(Position::LAST);
218
219 child2 = child2->add_child();
220 child2->set_field(2);
221
222 Metric2Condition link;
223
224 translateFieldMatcher(whatMatcher, &link.metricFields);
225 translateFieldMatcher(conditionMatcher, &link.conditionFields);
226
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700227 ASSERT_EQ((size_t)1, link.metricFields.size());
tsaichristinea3d2ed82020-03-19 20:53:36 -0700228 EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
229 EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
230 EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
231
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700232 ASSERT_EQ((size_t)1, link.conditionFields.size());
tsaichristinea3d2ed82020-03-19 20:53:36 -0700233 EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
234 EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
235 EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
236}
Yao Chen8a8d16c2018-02-08 14:50:40 -0800237
Yangster-mac9def8e32018-04-17 13:55:51 -0700238TEST(AtomMatcherTest, TestWriteDimensionPath) {
239 for (auto position : {Position::ANY, Position::ALL, Position::FIRST, Position::LAST}) {
240 FieldMatcher matcher1;
241 matcher1.set_field(10);
242 FieldMatcher* child = matcher1.add_child();
243 child->set_field(2);
244 child->set_position(position);
245 child->add_child()->set_field(1);
246 child->add_child()->set_field(3);
247
248 child = matcher1.add_child();
249 child->set_field(4);
250
251 child = matcher1.add_child();
252 child->set_field(6);
253 child->add_child()->set_field(2);
254
255 vector<Matcher> matchers;
256 translateFieldMatcher(matcher1, &matchers);
257
258 android::util::ProtoOutputStream protoOut;
259 writeDimensionPathToProto(matchers, &protoOut);
260
261 vector<uint8_t> outData;
262 outData.resize(protoOut.size());
263 size_t pos = 0;
Joe Onorato99598ee2019-02-11 15:55:13 +0000264 sp<ProtoReader> reader = protoOut.data();
265 while (reader->readBuffer() != NULL) {
266 size_t toRead = reader->currentToRead();
267 std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
Yangster-mac9def8e32018-04-17 13:55:51 -0700268 pos += toRead;
Joe Onorato99598ee2019-02-11 15:55:13 +0000269 reader->move(toRead);
Yangster-mac9def8e32018-04-17 13:55:51 -0700270 }
271
272 DimensionsValue result;
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700273 ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
Yangster-mac9def8e32018-04-17 13:55:51 -0700274
275 EXPECT_EQ(10, result.field());
276 EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700277 ASSERT_EQ(3, result.value_tuple().dimensions_value_size());
Yangster-mac9def8e32018-04-17 13:55:51 -0700278
279 const auto& dim1 = result.value_tuple().dimensions_value(0);
280 EXPECT_EQ(2, dim1.field());
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700281 ASSERT_EQ(2, dim1.value_tuple().dimensions_value_size());
Yangster-mac9def8e32018-04-17 13:55:51 -0700282
283 const auto& dim11 = dim1.value_tuple().dimensions_value(0);
284 EXPECT_EQ(1, dim11.field());
285
286 const auto& dim12 = dim1.value_tuple().dimensions_value(1);
287 EXPECT_EQ(3, dim12.field());
288
289 const auto& dim2 = result.value_tuple().dimensions_value(1);
290 EXPECT_EQ(4, dim2.field());
291
292 const auto& dim3 = result.value_tuple().dimensions_value(2);
293 EXPECT_EQ(6, dim3.field());
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700294 ASSERT_EQ(1, dim3.value_tuple().dimensions_value_size());
Yangster-mac9def8e32018-04-17 13:55:51 -0700295 const auto& dim31 = dim3.value_tuple().dimensions_value(0);
296 EXPECT_EQ(2, dim31.field());
297 }
298}
299
Ruchir Rastogi197107c2020-06-14 22:07:38 -0700300void checkAttributionNodeInDimensionsValueParcel(StatsDimensionsValueParcel& attributionNodeParcel,
301 int32_t nodeDepthInAttributionChain,
302 int32_t uid, string tag) {
303 EXPECT_EQ(attributionNodeParcel.field, nodeDepthInAttributionChain /*position at depth 1*/);
304 ASSERT_EQ(attributionNodeParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
305 ASSERT_EQ(attributionNodeParcel.tupleValue.size(), 2);
306
307 StatsDimensionsValueParcel uidParcel = attributionNodeParcel.tupleValue[0];
308 EXPECT_EQ(uidParcel.field, 1 /*position at depth 2*/);
309 EXPECT_EQ(uidParcel.valueType, STATS_DIMENSIONS_VALUE_INT_TYPE);
310 EXPECT_EQ(uidParcel.intValue, uid);
311
312 StatsDimensionsValueParcel tagParcel = attributionNodeParcel.tupleValue[1];
313 EXPECT_EQ(tagParcel.field, 2 /*position at depth 2*/);
314 EXPECT_EQ(tagParcel.valueType, STATS_DIMENSIONS_VALUE_STRING_TYPE);
315 EXPECT_EQ(tagParcel.stringValue, tag);
316}
317
318// Test conversion of a HashableDimensionKey into a StatsDimensionValueParcel
319TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
320 int atomId = 10;
321 // First four fields form an attribution chain
322 int pos1[] = {1, 1, 1};
323 int pos2[] = {1, 1, 2};
324 int pos3[] = {1, 2, 1};
325 int pos4[] = {1, 2, 2};
326 int pos5[] = {2, 1, 1};
327
328 Field field1(atomId, pos1, /*depth=*/2);
329 Field field2(atomId, pos2, /*depth=*/2);
330 Field field3(atomId, pos3, /*depth=*/2);
331 Field field4(atomId, pos4, /*depth=*/2);
332 Field field5(atomId, pos5, /*depth=*/0);
333
334 Value value1((int32_t)1);
335 Value value2("string2");
336 Value value3((int32_t)3);
337 Value value4("string4");
338 Value value5((float)5.0);
339
340 HashableDimensionKey dimensionKey;
341 dimensionKey.addValue(FieldValue(field1, value1));
342 dimensionKey.addValue(FieldValue(field2, value2));
343 dimensionKey.addValue(FieldValue(field3, value3));
344 dimensionKey.addValue(FieldValue(field4, value4));
345 dimensionKey.addValue(FieldValue(field5, value5));
346
347 StatsDimensionsValueParcel rootParcel = dimensionKey.toStatsDimensionsValueParcel();
348 EXPECT_EQ(rootParcel.field, atomId);
349 ASSERT_EQ(rootParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
350 ASSERT_EQ(rootParcel.tupleValue.size(), 2);
351
352 // Check that attribution chain is populated correctly
353 StatsDimensionsValueParcel attributionChainParcel = rootParcel.tupleValue[0];
354 EXPECT_EQ(attributionChainParcel.field, 1 /*position at depth 0*/);
355 ASSERT_EQ(attributionChainParcel.valueType, STATS_DIMENSIONS_VALUE_TUPLE_TYPE);
356 ASSERT_EQ(attributionChainParcel.tupleValue.size(), 2);
357 checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[0],
358 /*nodeDepthInAttributionChain=*/1,
359 value1.int_value, value2.str_value);
360 checkAttributionNodeInDimensionsValueParcel(attributionChainParcel.tupleValue[1],
361 /*nodeDepthInAttributionChain=*/2,
362 value3.int_value, value4.str_value);
363
364 // Check that the float is populated correctly
365 StatsDimensionsValueParcel floatParcel = rootParcel.tupleValue[1];
366 EXPECT_EQ(floatParcel.field, 2 /*position at depth 0*/);
367 EXPECT_EQ(floatParcel.valueType, STATS_DIMENSIONS_VALUE_FLOAT_TYPE);
368 EXPECT_EQ(floatParcel.floatValue, value5.float_value);
369}
Yao Chen8a8d16c2018-02-08 14:50:40 -0800370
371TEST(AtomMatcherTest, TestWriteDimensionToProto) {
372 HashableDimensionKey dim;
373 int pos1[] = {1, 1, 1};
374 int pos2[] = {1, 1, 2};
375 int pos3[] = {1, 1, 3};
376 int pos4[] = {2, 0, 0};
377 Field field1(10, pos1, 2);
378 Field field2(10, pos2, 2);
379 Field field3(10, pos3, 2);
380 Field field4(10, pos4, 0);
381
382 Value value1((int32_t)10025);
383 Value value2("tag");
384 Value value3((int32_t)987654);
385 Value value4((int32_t)99999);
386
387 dim.addValue(FieldValue(field1, value1));
388 dim.addValue(FieldValue(field2, value2));
389 dim.addValue(FieldValue(field3, value3));
390 dim.addValue(FieldValue(field4, value4));
391
392 android::util::ProtoOutputStream protoOut;
Yangster-mac9def8e32018-04-17 13:55:51 -0700393 writeDimensionToProto(dim, nullptr /* include strings */, &protoOut);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800394
395 vector<uint8_t> outData;
396 outData.resize(protoOut.size());
397 size_t pos = 0;
Joe Onorato99598ee2019-02-11 15:55:13 +0000398 sp<ProtoReader> reader = protoOut.data();
399 while (reader->readBuffer() != NULL) {
400 size_t toRead = reader->currentToRead();
401 std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800402 pos += toRead;
Joe Onorato99598ee2019-02-11 15:55:13 +0000403 reader->move(toRead);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800404 }
405
406 DimensionsValue result;
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700407 ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
Yao Chen8a8d16c2018-02-08 14:50:40 -0800408 EXPECT_EQ(10, result.field());
409 EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700410 ASSERT_EQ(2, result.value_tuple().dimensions_value_size());
Yao Chen8a8d16c2018-02-08 14:50:40 -0800411
412 const auto& dim1 = result.value_tuple().dimensions_value(0);
413 EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case());
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700414 ASSERT_EQ(3, dim1.value_tuple().dimensions_value_size());
Yao Chen8a8d16c2018-02-08 14:50:40 -0800415
416 const auto& dim11 = dim1.value_tuple().dimensions_value(0);
417 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case());
418 EXPECT_EQ(10025, dim11.value_int());
419
420 const auto& dim12 = dim1.value_tuple().dimensions_value(1);
421 EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim12.value_case());
422 EXPECT_EQ("tag", dim12.value_str());
423
424 const auto& dim13 = dim1.value_tuple().dimensions_value(2);
425 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim13.value_case());
426 EXPECT_EQ(987654, dim13.value_int());
427
428 const auto& dim2 = result.value_tuple().dimensions_value(1);
429 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim2.value_case());
430 EXPECT_EQ(99999, dim2.value_int());
431}
432
Yangster-mac9def8e32018-04-17 13:55:51 -0700433TEST(AtomMatcherTest, TestWriteDimensionLeafNodesToProto) {
434 HashableDimensionKey dim;
435 int pos1[] = {1, 1, 1};
436 int pos2[] = {1, 1, 2};
437 int pos3[] = {1, 1, 3};
438 int pos4[] = {2, 0, 0};
439 Field field1(10, pos1, 2);
440 Field field2(10, pos2, 2);
441 Field field3(10, pos3, 2);
442 Field field4(10, pos4, 0);
443
444 Value value1((int32_t)10025);
445 Value value2("tag");
446 Value value3((int32_t)987654);
447 Value value4((int64_t)99999);
448
449 dim.addValue(FieldValue(field1, value1));
450 dim.addValue(FieldValue(field2, value2));
451 dim.addValue(FieldValue(field3, value3));
452 dim.addValue(FieldValue(field4, value4));
453
454 android::util::ProtoOutputStream protoOut;
455 writeDimensionLeafNodesToProto(dim, 1, nullptr /* include strings */, &protoOut);
456
457 vector<uint8_t> outData;
458 outData.resize(protoOut.size());
459 size_t pos = 0;
Joe Onorato99598ee2019-02-11 15:55:13 +0000460 sp<ProtoReader> reader = protoOut.data();
461 while (reader->readBuffer() != NULL) {
462 size_t toRead = reader->currentToRead();
463 std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
Yangster-mac9def8e32018-04-17 13:55:51 -0700464 pos += toRead;
Joe Onorato99598ee2019-02-11 15:55:13 +0000465 reader->move(toRead);
Yangster-mac9def8e32018-04-17 13:55:51 -0700466 }
467
468 DimensionsValueTuple result;
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700469 ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
470 ASSERT_EQ(4, result.dimensions_value_size());
Yangster-mac9def8e32018-04-17 13:55:51 -0700471
472 const auto& dim1 = result.dimensions_value(0);
473 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim1.value_case());
474 EXPECT_EQ(10025, dim1.value_int());
475
476 const auto& dim2 = result.dimensions_value(1);
477 EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim2.value_case());
478 EXPECT_EQ("tag", dim2.value_str());
479
480 const auto& dim3 = result.dimensions_value(2);
481 EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim3.value_case());
482 EXPECT_EQ(987654, dim3.value_int());
483
484 const auto& dim4 = result.dimensions_value(3);
485 EXPECT_EQ(DimensionsValue::ValueCase::kValueLong, dim4.value_case());
486 EXPECT_EQ(99999, dim4.value_long());
487}
488
tsaichristinea3d2ed82020-03-19 20:53:36 -0700489TEST(AtomMatcherTest, TestWriteAtomToProto) {
490 std::vector<int> attributionUids = {1111, 2222};
491 std::vector<string> attributionTags = {"location1", "location2"};
492
493 LogEvent event(/*uid=*/0, /*pid=*/0);
494 makeLogEvent(&event, 4 /*atomId*/, 12345, attributionUids, attributionTags, 999);
495
496 android::util::ProtoOutputStream protoOutput;
497 writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
498
499 vector<uint8_t> outData;
500 outData.resize(protoOutput.size());
501 size_t pos = 0;
502 sp<ProtoReader> reader = protoOutput.data();
503 while (reader->readBuffer() != NULL) {
504 size_t toRead = reader->currentToRead();
505 std::memcpy(&(outData[pos]), reader->readBuffer(), toRead);
506 pos += toRead;
507 reader->move(toRead);
508 }
509
510 Atom result;
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700511 ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
tsaichristinea3d2ed82020-03-19 20:53:36 -0700512 EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
513 const auto& atom = result.ble_scan_result_received();
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700514 ASSERT_EQ(2, atom.attribution_node_size());
tsaichristinea3d2ed82020-03-19 20:53:36 -0700515 EXPECT_EQ(1111, atom.attribution_node(0).uid());
516 EXPECT_EQ("location1", atom.attribution_node(0).tag());
517 EXPECT_EQ(2222, atom.attribution_node(1).uid());
518 EXPECT_EQ("location2", atom.attribution_node(1).tag());
519 EXPECT_EQ(999, atom.num_results());
520}
Yao Chen8a8d16c2018-02-08 14:50:40 -0800521
tsaichristine3a83e812019-12-13 16:46:11 -0800522/*
523 * Test two Matchers is not a subset of one Matcher.
524 * Test one Matcher is subset of two Matchers.
525 */
526TEST(AtomMatcherTest, TestSubsetDimensions1) {
527 // Initialize first set of matchers
528 FieldMatcher matcher1;
529 matcher1.set_field(10);
530
531 FieldMatcher* child = matcher1.add_child();
532 child->set_field(1);
533 child->set_position(Position::ALL);
534 child->add_child()->set_field(1);
535 child->add_child()->set_field(2);
536
537 vector<Matcher> matchers1;
538 translateFieldMatcher(matcher1, &matchers1);
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700539 ASSERT_EQ(2, matchers1.size());
tsaichristine3a83e812019-12-13 16:46:11 -0800540
541 // Initialize second set of matchers
542 FieldMatcher matcher2;
543 matcher2.set_field(10);
544
545 child = matcher2.add_child();
546 child->set_field(1);
547 child->set_position(Position::ALL);
548 child->add_child()->set_field(1);
549
550 vector<Matcher> matchers2;
551 translateFieldMatcher(matcher2, &matchers2);
Muhammad Qureshidff78d62020-05-11 13:37:43 -0700552 ASSERT_EQ(1, matchers2.size());
tsaichristine3a83e812019-12-13 16:46:11 -0800553
554 EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
555 EXPECT_TRUE(subsetDimensions(matchers2, matchers1));
556}
557/*
558 * Test not a subset with one matching Matcher, one non-matching Matcher.
559 */
560TEST(AtomMatcherTest, TestSubsetDimensions2) {
561 // Initialize first set of matchers
562 FieldMatcher matcher1;
563 matcher1.set_field(10);
564
565 FieldMatcher* child = matcher1.add_child();
566 child->set_field(1);
567
568 child = matcher1.add_child();
569 child->set_field(2);
570
571 vector<Matcher> matchers1;
572 translateFieldMatcher(matcher1, &matchers1);
573
574 // Initialize second set of matchers
575 FieldMatcher matcher2;
576 matcher2.set_field(10);
577
578 child = matcher2.add_child();
579 child->set_field(1);
580
581 child = matcher2.add_child();
582 child->set_field(3);
583
584 vector<Matcher> matchers2;
585 translateFieldMatcher(matcher2, &matchers2);
586
587 EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
588}
589
590/*
591 * Test not a subset if parent field is not equal.
592 */
593TEST(AtomMatcherTest, TestSubsetDimensions3) {
594 // Initialize first set of matchers
595 FieldMatcher matcher1;
596 matcher1.set_field(10);
597
598 FieldMatcher* child = matcher1.add_child();
599 child->set_field(1);
600
601 vector<Matcher> matchers1;
602 translateFieldMatcher(matcher1, &matchers1);
603
604 // Initialize second set of matchers
605 FieldMatcher matcher2;
606 matcher2.set_field(5);
607
608 child = matcher2.add_child();
609 child->set_field(1);
610
611 vector<Matcher> matchers2;
612 translateFieldMatcher(matcher2, &matchers2);
613
614 EXPECT_FALSE(subsetDimensions(matchers1, matchers2));
615}
616
617/*
618 * Test is subset with two matching Matchers.
619 */
620TEST(AtomMatcherTest, TestSubsetDimensions4) {
621 // Initialize first set of matchers
622 FieldMatcher matcher1;
623 matcher1.set_field(10);
624
625 FieldMatcher* child = matcher1.add_child();
626 child->set_field(1);
627
628 child = matcher1.add_child();
629 child->set_field(2);
630
631 vector<Matcher> matchers1;
632 translateFieldMatcher(matcher1, &matchers1);
633
634 // Initialize second set of matchers
635 FieldMatcher matcher2;
636 matcher2.set_field(10);
637
638 child = matcher2.add_child();
639 child->set_field(1);
640
641 child = matcher2.add_child();
642 child->set_field(2);
643
644 child = matcher2.add_child();
645 child->set_field(3);
646
647 vector<Matcher> matchers2;
648 translateFieldMatcher(matcher2, &matchers2);
649
650 EXPECT_TRUE(subsetDimensions(matchers1, matchers2));
651 EXPECT_FALSE(subsetDimensions(matchers2, matchers1));
652}
Yao Chen8a8d16c2018-02-08 14:50:40 -0800653
654} // namespace statsd
655} // namespace os
656} // namespace android
657#else
658GTEST_LOG_(INFO) << "This test does nothing.\n";
Yao Chen5bfffb52018-06-21 16:58:51 -0700659#endif