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