Home | History | Annotate | Download | only in tests
      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 #include <gtest/gtest.h>
     17 #include "frameworks/base/cmds/statsd/src/stats_log.pb.h"
     18 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
     19 #include "matchers/matcher_util.h"
     20 #include "src/logd/LogEvent.h"
     21 #include "stats_log_util.h"
     22 #include "stats_util.h"
     23 #include "subscriber/SubscriberReporter.h"
     24 
     25 #ifdef __ANDROID__
     26 
     27 namespace android {
     28 namespace os {
     29 namespace statsd {
     30 
     31 TEST(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)0x02010001, matcher12.mMatcher.getField());
     49     EXPECT_EQ((int32_t)0xff7f007f, matcher12.mMask);
     50 }
     51 
     52 TEST(AtomMatcherTest, TestFieldTranslation_ALL) {
     53     FieldMatcher matcher1;
     54     matcher1.set_field(10);
     55     FieldMatcher* child = matcher1.add_child();
     56     child->set_field(1);
     57     child->set_position(Position::ALL);
     58 
     59     child = child->add_child();
     60     child->set_field(1);
     61 
     62     vector<Matcher> output;
     63     translateFieldMatcher(matcher1, &output);
     64 
     65     EXPECT_EQ((size_t)1, output.size());
     66 
     67     const auto& matcher12 = output[0];
     68     EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag());
     69     EXPECT_EQ((int32_t)0x02010001, matcher12.mMatcher.getField());
     70     EXPECT_EQ((int32_t)0xff7f7f7f, matcher12.mMask);
     71 }
     72 
     73 TEST(AtomMatcherTest, TestFilter_ALL) {
     74     FieldMatcher matcher1;
     75     matcher1.set_field(10);
     76     FieldMatcher* child = matcher1.add_child();
     77     child->set_field(1);
     78     child->set_position(Position::ALL);
     79 
     80     child->add_child()->set_field(1);
     81     child->add_child()->set_field(2);
     82 
     83     child = matcher1.add_child();
     84     child->set_field(2);
     85 
     86     vector<Matcher> matchers;
     87     translateFieldMatcher(matcher1, &matchers);
     88 
     89     AttributionNodeInternal attribution_node1;
     90     attribution_node1.set_uid(1111);
     91     attribution_node1.set_tag("location1");
     92 
     93     AttributionNodeInternal attribution_node2;
     94     attribution_node2.set_uid(2222);
     95     attribution_node2.set_tag("location2");
     96 
     97     AttributionNodeInternal attribution_node3;
     98     attribution_node3.set_uid(3333);
     99     attribution_node3.set_tag("location3");
    100     std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
    101                                                               attribution_node3};
    102 
    103     // Set up the event
    104     LogEvent event(10, 12345);
    105     event.write(attribution_nodes);
    106     event.write("some value");
    107     // Convert to a LogEvent
    108     event.init();
    109     HashableDimensionKey output;
    110 
    111     filterValues(matchers, event.getValues(), &output);
    112 
    113     EXPECT_EQ((size_t)7, output.getValues().size());
    114     EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField());
    115     EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value);
    116     EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField());
    117     EXPECT_EQ("location1", output.getValues()[1].mValue.str_value);
    118 
    119     EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField());
    120     EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value);
    121     EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField());
    122     EXPECT_EQ("location2", output.getValues()[3].mValue.str_value);
    123 
    124     EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField());
    125     EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value);
    126     EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField());
    127     EXPECT_EQ("location3", output.getValues()[5].mValue.str_value);
    128 
    129     EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField());
    130     EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
    131 }
    132 
    133 TEST(AtomMatcherTest, TestSubDimension) {
    134     HashableDimensionKey dim;
    135 
    136     int pos1[] = {1, 1, 1};
    137     int pos2[] = {1, 1, 2};
    138     int pos3[] = {1, 1, 3};
    139     int pos4[] = {2, 0, 0};
    140     Field field1(10, pos1, 2);
    141     Field field2(10, pos2, 2);
    142 
    143     Field field3(10, pos3, 2);
    144     Field field4(10, pos4, 0);
    145 
    146     Value value1((int32_t)10025);
    147     Value value2("tag");
    148 
    149     Value value11((int32_t)10026);
    150     Value value22("tag2");
    151 
    152     dim.addValue(FieldValue(field1, value1));
    153     dim.addValue(FieldValue(field2, value2));
    154 
    155     HashableDimensionKey subDim1;
    156     subDim1.addValue(FieldValue(field1, value1));
    157 
    158     HashableDimensionKey subDim2;
    159     subDim1.addValue(FieldValue(field2, value2));
    160 
    161     EXPECT_TRUE(dim.contains(dim));
    162     EXPECT_TRUE(dim.contains(subDim1));
    163     EXPECT_TRUE(dim.contains(subDim2));
    164 
    165     HashableDimensionKey subDim3;
    166     subDim3.addValue(FieldValue(field1, value11));
    167     EXPECT_FALSE(dim.contains(subDim3));
    168 
    169     HashableDimensionKey subDim4;
    170     // Empty dimension is always a sub dimension of other dimensions
    171     EXPECT_TRUE(dim.contains(subDim4));
    172 }
    173 
    174 TEST(AtomMatcherTest, TestMetric2ConditionLink) {
    175     AttributionNodeInternal attribution_node1;
    176     attribution_node1.set_uid(1111);
    177     attribution_node1.set_tag("location1");
    178 
    179     AttributionNodeInternal attribution_node2;
    180     attribution_node2.set_uid(2222);
    181     attribution_node2.set_tag("location2");
    182 
    183     AttributionNodeInternal attribution_node3;
    184     attribution_node3.set_uid(3333);
    185     attribution_node3.set_tag("location3");
    186     std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2,
    187                                                               attribution_node3};
    188 
    189     // Set up the event
    190     LogEvent event(10, 12345);
    191     event.write(attribution_nodes);
    192     event.write("some value");
    193     // Convert to a LogEvent
    194     event.init();
    195 
    196     FieldMatcher whatMatcher;
    197     whatMatcher.set_field(10);
    198     FieldMatcher* child11 = whatMatcher.add_child();
    199     child11->set_field(1);
    200     child11->set_position(Position::ANY);
    201     child11 = child11->add_child();
    202     child11->set_field(1);
    203 
    204     FieldMatcher conditionMatcher;
    205     conditionMatcher.set_field(27);
    206     FieldMatcher* child2 = conditionMatcher.add_child();
    207     child2->set_field(2);
    208     child2->set_position(Position::LAST);
    209 
    210     child2 = child2->add_child();
    211     child2->set_field(2);
    212 
    213     Metric2Condition link;
    214 
    215     translateFieldMatcher(whatMatcher, &link.metricFields);
    216     translateFieldMatcher(conditionMatcher, &link.conditionFields);
    217 
    218     EXPECT_EQ((size_t)1, link.metricFields.size());
    219     EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField());
    220     EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask);
    221     EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag());
    222 
    223     EXPECT_EQ((size_t)1, link.conditionFields.size());
    224     EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField());
    225     EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask);
    226     EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag());
    227 }
    228 
    229 TEST(AtomMatcherTest, TestWriteDimensionPath) {
    230     for (auto position : {Position::ANY, Position::ALL, Position::FIRST, Position::LAST}) {
    231         FieldMatcher matcher1;
    232         matcher1.set_field(10);
    233         FieldMatcher* child = matcher1.add_child();
    234         child->set_field(2);
    235         child->set_position(position);
    236         child->add_child()->set_field(1);
    237         child->add_child()->set_field(3);
    238 
    239         child = matcher1.add_child();
    240         child->set_field(4);
    241 
    242         child = matcher1.add_child();
    243         child->set_field(6);
    244         child->add_child()->set_field(2);
    245 
    246         vector<Matcher> matchers;
    247         translateFieldMatcher(matcher1, &matchers);
    248 
    249         android::util::ProtoOutputStream protoOut;
    250         writeDimensionPathToProto(matchers, &protoOut);
    251 
    252         vector<uint8_t> outData;
    253         outData.resize(protoOut.size());
    254         size_t pos = 0;
    255         auto iter = protoOut.data();
    256         while (iter.readBuffer() != NULL) {
    257             size_t toRead = iter.currentToRead();
    258             std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
    259             pos += toRead;
    260             iter.rp()->move(toRead);
    261         }
    262 
    263         DimensionsValue result;
    264         EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
    265 
    266         EXPECT_EQ(10, result.field());
    267         EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
    268         EXPECT_EQ(3, result.value_tuple().dimensions_value_size());
    269 
    270         const auto& dim1 = result.value_tuple().dimensions_value(0);
    271         EXPECT_EQ(2, dim1.field());
    272         EXPECT_EQ(2, dim1.value_tuple().dimensions_value_size());
    273 
    274         const auto& dim11 = dim1.value_tuple().dimensions_value(0);
    275         EXPECT_EQ(1, dim11.field());
    276 
    277         const auto& dim12 = dim1.value_tuple().dimensions_value(1);
    278         EXPECT_EQ(3, dim12.field());
    279 
    280         const auto& dim2 = result.value_tuple().dimensions_value(1);
    281         EXPECT_EQ(4, dim2.field());
    282 
    283         const auto& dim3 = result.value_tuple().dimensions_value(2);
    284         EXPECT_EQ(6, dim3.field());
    285         EXPECT_EQ(1, dim3.value_tuple().dimensions_value_size());
    286         const auto& dim31 = dim3.value_tuple().dimensions_value(0);
    287         EXPECT_EQ(2, dim31.field());
    288     }
    289 }
    290 
    291 TEST(AtomMatcherTest, TestSubscriberDimensionWrite) {
    292     HashableDimensionKey dim;
    293 
    294     int pos1[] = {1, 1, 1};
    295     int pos2[] = {1, 1, 2};
    296     int pos3[] = {1, 1, 3};
    297     int pos4[] = {2, 0, 0};
    298 
    299     Field field1(10, pos1, 2);
    300     Field field2(10, pos2, 2);
    301     Field field3(10, pos3, 2);
    302     Field field4(10, pos4, 0);
    303 
    304     Value value1((int32_t)10025);
    305     Value value2("tag");
    306     Value value3((int32_t)987654);
    307     Value value4((int32_t)99999);
    308 
    309     dim.addValue(FieldValue(field1, value1));
    310     dim.addValue(FieldValue(field2, value2));
    311     dim.addValue(FieldValue(field3, value3));
    312     dim.addValue(FieldValue(field4, value4));
    313 
    314     SubscriberReporter::getStatsDimensionsValue(dim);
    315     // TODO: can't test anything here because SubscriberReport class doesn't have any read api.
    316 }
    317 
    318 TEST(AtomMatcherTest, TestWriteDimensionToProto) {
    319     HashableDimensionKey dim;
    320     int pos1[] = {1, 1, 1};
    321     int pos2[] = {1, 1, 2};
    322     int pos3[] = {1, 1, 3};
    323     int pos4[] = {2, 0, 0};
    324     Field field1(10, pos1, 2);
    325     Field field2(10, pos2, 2);
    326     Field field3(10, pos3, 2);
    327     Field field4(10, pos4, 0);
    328 
    329     Value value1((int32_t)10025);
    330     Value value2("tag");
    331     Value value3((int32_t)987654);
    332     Value value4((int32_t)99999);
    333 
    334     dim.addValue(FieldValue(field1, value1));
    335     dim.addValue(FieldValue(field2, value2));
    336     dim.addValue(FieldValue(field3, value3));
    337     dim.addValue(FieldValue(field4, value4));
    338 
    339     android::util::ProtoOutputStream protoOut;
    340     writeDimensionToProto(dim, nullptr /* include strings */, &protoOut);
    341 
    342     vector<uint8_t> outData;
    343     outData.resize(protoOut.size());
    344     size_t pos = 0;
    345     auto iter = protoOut.data();
    346     while (iter.readBuffer() != NULL) {
    347         size_t toRead = iter.currentToRead();
    348         std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
    349         pos += toRead;
    350         iter.rp()->move(toRead);
    351     }
    352 
    353     DimensionsValue result;
    354     EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
    355     EXPECT_EQ(10, result.field());
    356     EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case());
    357     EXPECT_EQ(2, result.value_tuple().dimensions_value_size());
    358 
    359     const auto& dim1 = result.value_tuple().dimensions_value(0);
    360     EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case());
    361     EXPECT_EQ(3, dim1.value_tuple().dimensions_value_size());
    362 
    363     const auto& dim11 = dim1.value_tuple().dimensions_value(0);
    364     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case());
    365     EXPECT_EQ(10025, dim11.value_int());
    366 
    367     const auto& dim12 = dim1.value_tuple().dimensions_value(1);
    368     EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim12.value_case());
    369     EXPECT_EQ("tag", dim12.value_str());
    370 
    371     const auto& dim13 = dim1.value_tuple().dimensions_value(2);
    372     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim13.value_case());
    373     EXPECT_EQ(987654, dim13.value_int());
    374 
    375     const auto& dim2 = result.value_tuple().dimensions_value(1);
    376     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim2.value_case());
    377     EXPECT_EQ(99999, dim2.value_int());
    378 }
    379 
    380 TEST(AtomMatcherTest, TestWriteDimensionLeafNodesToProto) {
    381     HashableDimensionKey dim;
    382     int pos1[] = {1, 1, 1};
    383     int pos2[] = {1, 1, 2};
    384     int pos3[] = {1, 1, 3};
    385     int pos4[] = {2, 0, 0};
    386     Field field1(10, pos1, 2);
    387     Field field2(10, pos2, 2);
    388     Field field3(10, pos3, 2);
    389     Field field4(10, pos4, 0);
    390 
    391     Value value1((int32_t)10025);
    392     Value value2("tag");
    393     Value value3((int32_t)987654);
    394     Value value4((int64_t)99999);
    395 
    396     dim.addValue(FieldValue(field1, value1));
    397     dim.addValue(FieldValue(field2, value2));
    398     dim.addValue(FieldValue(field3, value3));
    399     dim.addValue(FieldValue(field4, value4));
    400 
    401     android::util::ProtoOutputStream protoOut;
    402     writeDimensionLeafNodesToProto(dim, 1, nullptr /* include strings */, &protoOut);
    403 
    404     vector<uint8_t> outData;
    405     outData.resize(protoOut.size());
    406     size_t pos = 0;
    407     auto iter = protoOut.data();
    408     while (iter.readBuffer() != NULL) {
    409         size_t toRead = iter.currentToRead();
    410         std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
    411         pos += toRead;
    412         iter.rp()->move(toRead);
    413     }
    414 
    415     DimensionsValueTuple result;
    416     EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
    417     EXPECT_EQ(4, result.dimensions_value_size());
    418 
    419     const auto& dim1 = result.dimensions_value(0);
    420     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim1.value_case());
    421     EXPECT_EQ(10025, dim1.value_int());
    422 
    423     const auto& dim2 = result.dimensions_value(1);
    424     EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim2.value_case());
    425     EXPECT_EQ("tag", dim2.value_str());
    426 
    427     const auto& dim3 = result.dimensions_value(2);
    428     EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim3.value_case());
    429     EXPECT_EQ(987654, dim3.value_int());
    430 
    431     const auto& dim4 = result.dimensions_value(3);
    432     EXPECT_EQ(DimensionsValue::ValueCase::kValueLong, dim4.value_case());
    433     EXPECT_EQ(99999, dim4.value_long());
    434 }
    435 
    436 TEST(AtomMatcherTest, TestWriteAtomToProto) {
    437     AttributionNodeInternal attribution_node1;
    438     attribution_node1.set_uid(1111);
    439     attribution_node1.set_tag("location1");
    440 
    441     AttributionNodeInternal attribution_node2;
    442     attribution_node2.set_uid(2222);
    443     attribution_node2.set_tag("location2");
    444 
    445     std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2};
    446 
    447     // Set up the event
    448     LogEvent event(4, 12345);
    449     event.write(attribution_nodes);
    450     event.write((int32_t)999);
    451     // Convert to a LogEvent
    452     event.init();
    453 
    454     android::util::ProtoOutputStream protoOutput;
    455     writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput);
    456 
    457     vector<uint8_t> outData;
    458     outData.resize(protoOutput.size());
    459     size_t pos = 0;
    460     auto iter = protoOutput.data();
    461     while (iter.readBuffer() != NULL) {
    462         size_t toRead = iter.currentToRead();
    463         std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
    464         pos += toRead;
    465         iter.rp()->move(toRead);
    466     }
    467 
    468     Atom result;
    469     EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
    470     EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case());
    471     const auto& atom = result.ble_scan_result_received();
    472     EXPECT_EQ(2, atom.attribution_node_size());
    473     EXPECT_EQ(1111, atom.attribution_node(0).uid());
    474     EXPECT_EQ("location1", atom.attribution_node(0).tag());
    475     EXPECT_EQ(2222, atom.attribution_node(1).uid());
    476     EXPECT_EQ("location2", atom.attribution_node(1).tag());
    477     EXPECT_EQ(999, atom.num_results());
    478 }
    479 
    480 
    481 }  // namespace statsd
    482 }  // namespace os
    483 }  // namespace android
    484 #else
    485 GTEST_LOG_(INFO) << "This test does nothing.\n";
    486 #endif