diff options
Diffstat (limited to 'cmds/statsd/tests/FieldValue_test.cpp')
-rw-r--r-- | cmds/statsd/tests/FieldValue_test.cpp | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp new file mode 100644 index 000000000000..f1ad0c88b242 --- /dev/null +++ b/cmds/statsd/tests/FieldValue_test.cpp @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <gtest/gtest.h> +#include "src/logd/LogEvent.h" +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" +#include "matchers/matcher_util.h" +#include "stats_log_util.h" +#include "stats_util.h" +#include "subscriber/SubscriberReporter.h" + +#ifdef __ANDROID__ + +namespace android { +namespace os { +namespace statsd { + +TEST(AtomMatcherTest, TestFieldTranslation) { + FieldMatcher matcher1; + matcher1.set_field(10); + FieldMatcher* child = matcher1.add_child(); + child->set_field(1); + child->set_position(Position::ANY); + + child = child->add_child(); + child->set_field(1); + + vector<Matcher> output; + translateFieldMatcher(matcher1, &output); + + EXPECT_EQ((size_t)1, output.size()); + + const auto& matcher12 = output[0]; + EXPECT_EQ((int32_t)10, matcher12.mMatcher.getTag()); + EXPECT_EQ((int32_t)0x2010001, matcher12.mMatcher.getField()); + EXPECT_EQ((int32_t)0xff7f007f, matcher12.mMask); +} + +TEST(AtomMatcherTest, TestFilter) { + FieldMatcher matcher1; + matcher1.set_field(10); + FieldMatcher* child = matcher1.add_child(); + child->set_field(1); + child->set_position(Position::ANY); + + child = child->add_child(); + child->set_field(1); + + child = matcher1.add_child(); + child->set_field(2); + + vector<Matcher> matchers; + translateFieldMatcher(matcher1, &matchers); + + AttributionNode attribution_node1; + attribution_node1.set_uid(1111); + attribution_node1.set_tag("location1"); + + AttributionNode attribution_node2; + attribution_node2.set_uid(2222); + attribution_node2.set_tag("location2"); + + AttributionNode attribution_node3; + attribution_node3.set_uid(3333); + attribution_node3.set_tag("location3"); + std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2, + attribution_node3}; + + // Set up the event + LogEvent event(10, 12345); + event.write(attribution_nodes); + event.write("some value"); + // Convert to a LogEvent + event.init(); + vector<HashableDimensionKey> output; + + filterValues(matchers, event.getValues(), &output); + + EXPECT_EQ((size_t)(3), output.size()); + + const auto& key1 = output[0]; + EXPECT_EQ((size_t)2, key1.getValues().size()); + EXPECT_EQ((int32_t)0x02010001, key1.getValues()[0].mField.getField()); + EXPECT_EQ((int32_t)1111, key1.getValues()[0].mValue.int_value); + EXPECT_EQ((int32_t)0x00020000, key1.getValues()[1].mField.getField()); + EXPECT_EQ("some value", key1.getValues()[1].mValue.str_value); + + const auto& key2 = output[1]; + EXPECT_EQ((size_t)2, key2.getValues().size()); + EXPECT_EQ((int32_t)0x02010001, key2.getValues()[0].mField.getField()); + EXPECT_EQ((int32_t)2222, key2.getValues()[0].mValue.int_value); + EXPECT_EQ((int32_t)0x00020000, key2.getValues()[1].mField.getField()); + EXPECT_EQ("some value", key2.getValues()[1].mValue.str_value); + + const auto& key3 = output[2]; + EXPECT_EQ((size_t)2, key3.getValues().size()); + EXPECT_EQ((int32_t)0x02010001, key3.getValues()[0].mField.getField()); + EXPECT_EQ((int32_t)3333, key3.getValues()[0].mValue.int_value); + EXPECT_EQ((int32_t)0x00020000, key3.getValues()[1].mField.getField()); + EXPECT_EQ("some value", key3.getValues()[1].mValue.str_value); +} + +TEST(AtomMatcherTest, TestSubDimension) { + HashableDimensionKey dim; + + int pos1[] = {1, 1, 1}; + int pos2[] = {1, 1, 2}; + int pos3[] = {1, 1, 3}; + int pos4[] = {2, 0, 0}; + Field field1(10, pos1, 2); + Field field2(10, pos2, 2); + + Field field3(10, pos3, 2); + Field field4(10, pos4, 0); + + Value value1((int32_t)10025); + Value value2("tag"); + + Value value11((int32_t)10026); + Value value22("tag2"); + + dim.addValue(FieldValue(field1, value1)); + dim.addValue(FieldValue(field2, value2)); + + HashableDimensionKey subDim1; + subDim1.addValue(FieldValue(field1, value1)); + + HashableDimensionKey subDim2; + subDim1.addValue(FieldValue(field2, value2)); + + EXPECT_TRUE(dim.contains(dim)); + EXPECT_TRUE(dim.contains(subDim1)); + EXPECT_TRUE(dim.contains(subDim2)); + + HashableDimensionKey subDim3; + subDim3.addValue(FieldValue(field1, value11)); + EXPECT_FALSE(dim.contains(subDim3)); + + HashableDimensionKey subDim4; + // Empty dimension is always a sub dimension of other dimensions + EXPECT_TRUE(dim.contains(subDim4)); +} + +TEST(AtomMatcherTest, TestMetric2ConditionLink) { + AttributionNode attribution_node1; + attribution_node1.set_uid(1111); + attribution_node1.set_tag("location1"); + + AttributionNode attribution_node2; + attribution_node2.set_uid(2222); + attribution_node2.set_tag("location2"); + + AttributionNode attribution_node3; + attribution_node3.set_uid(3333); + attribution_node3.set_tag("location3"); + std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2, + attribution_node3}; + + // Set up the event + LogEvent event(10, 12345); + event.write(attribution_nodes); + event.write("some value"); + // Convert to a LogEvent + event.init(); + + FieldMatcher whatMatcher; + whatMatcher.set_field(10); + FieldMatcher* child11 = whatMatcher.add_child(); + child11->set_field(1); + child11->set_position(Position::ANY); + child11 = child11->add_child(); + child11->set_field(1); + + FieldMatcher conditionMatcher; + conditionMatcher.set_field(27); + FieldMatcher* child2 = conditionMatcher.add_child(); + child2->set_field(2); + child2->set_position(Position::LAST); + + child2 = child2->add_child(); + child2->set_field(2); + + Metric2Condition link; + + translateFieldMatcher(whatMatcher, &link.metricFields); + translateFieldMatcher(conditionMatcher, &link.conditionFields); + + EXPECT_EQ((size_t)1, link.metricFields.size()); + EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField()); + EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask); + EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag()); + + EXPECT_EQ((size_t)1, link.conditionFields.size()); + EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField()); + EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask); + EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag()); +} + +TEST(AtomMatcherTest, TestSubscriberDimensionWrite) { + HashableDimensionKey dim; + + int pos1[] = {1, 1, 1}; + int pos2[] = {1, 1, 2}; + int pos3[] = {1, 1, 3}; + int pos4[] = {2, 0, 0}; + + Field field1(10, pos1, 2); + Field field2(10, pos2, 2); + Field field3(10, pos3, 2); + Field field4(10, pos4, 0); + + Value value1((int32_t)10025); + Value value2("tag"); + Value value3((int32_t)987654); + Value value4((int32_t)99999); + + dim.addValue(FieldValue(field1, value1)); + dim.addValue(FieldValue(field2, value2)); + dim.addValue(FieldValue(field3, value3)); + dim.addValue(FieldValue(field4, value4)); + + SubscriberReporter::getStatsDimensionsValue(dim); + // TODO: can't test anything here because SubscriberReport class doesn't have any read api. +} + +TEST(AtomMatcherTest, TestWriteDimensionToProto) { + HashableDimensionKey dim; + int pos1[] = {1, 1, 1}; + int pos2[] = {1, 1, 2}; + int pos3[] = {1, 1, 3}; + int pos4[] = {2, 0, 0}; + Field field1(10, pos1, 2); + Field field2(10, pos2, 2); + Field field3(10, pos3, 2); + Field field4(10, pos4, 0); + + Value value1((int32_t)10025); + Value value2("tag"); + Value value3((int32_t)987654); + Value value4((int32_t)99999); + + dim.addValue(FieldValue(field1, value1)); + dim.addValue(FieldValue(field2, value2)); + dim.addValue(FieldValue(field3, value3)); + dim.addValue(FieldValue(field4, value4)); + + android::util::ProtoOutputStream protoOut; + writeDimensionToProto(dim, &protoOut); + + vector<uint8_t> outData; + outData.resize(protoOut.size()); + size_t pos = 0; + auto iter = protoOut.data(); + while (iter.readBuffer() != NULL) { + size_t toRead = iter.currentToRead(); + std::memcpy(&(outData[pos]), iter.readBuffer(), toRead); + pos += toRead; + iter.rp()->move(toRead); + } + + DimensionsValue result; + EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size())); + EXPECT_EQ(10, result.field()); + EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, result.value_case()); + EXPECT_EQ(2, result.value_tuple().dimensions_value_size()); + + const auto& dim1 = result.value_tuple().dimensions_value(0); + EXPECT_EQ(DimensionsValue::ValueCase::kValueTuple, dim1.value_case()); + EXPECT_EQ(3, dim1.value_tuple().dimensions_value_size()); + + const auto& dim11 = dim1.value_tuple().dimensions_value(0); + EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim11.value_case()); + EXPECT_EQ(10025, dim11.value_int()); + + const auto& dim12 = dim1.value_tuple().dimensions_value(1); + EXPECT_EQ(DimensionsValue::ValueCase::kValueStr, dim12.value_case()); + EXPECT_EQ("tag", dim12.value_str()); + + const auto& dim13 = dim1.value_tuple().dimensions_value(2); + EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim13.value_case()); + EXPECT_EQ(987654, dim13.value_int()); + + const auto& dim2 = result.value_tuple().dimensions_value(1); + EXPECT_EQ(DimensionsValue::ValueCase::kValueInt, dim2.value_case()); + EXPECT_EQ(99999, dim2.value_int()); +} + +TEST(AtomMatcherTest, TestWriteAtomToProto) { + AttributionNode attribution_node1; + attribution_node1.set_uid(1111); + attribution_node1.set_tag("location1"); + + AttributionNode attribution_node2; + attribution_node2.set_uid(2222); + attribution_node2.set_tag("location2"); + + std::vector<AttributionNode> attribution_nodes = {attribution_node1, attribution_node2}; + + // Set up the event + LogEvent event(4, 12345); + event.write(attribution_nodes); + event.write((int32_t)999); + // Convert to a LogEvent + event.init(); + + android::util::ProtoOutputStream protoOutput; + writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput); + + vector<uint8_t> outData; + outData.resize(protoOutput.size()); + size_t pos = 0; + auto iter = protoOutput.data(); + while (iter.readBuffer() != NULL) { + size_t toRead = iter.currentToRead(); + std::memcpy(&(outData[pos]), iter.readBuffer(), toRead); + pos += toRead; + iter.rp()->move(toRead); + } + + Atom result; + EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size())); + EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case()); + const auto& atom = result.ble_scan_result_received(); + EXPECT_EQ(2, atom.attribution_node_size()); + EXPECT_EQ(1111, atom.attribution_node(0).uid()); + EXPECT_EQ("location1", atom.attribution_node(0).tag()); + EXPECT_EQ(2222, atom.attribution_node(1).uid()); + EXPECT_EQ("location2", atom.attribution_node(1).tag()); + EXPECT_EQ(999, atom.num_of_results()); +} + + +} // namespace statsd +} // namespace os +} // namespace android +#else +GTEST_LOG_(INFO) << "This test does nothing.\n"; +#endif
\ No newline at end of file |