summaryrefslogtreecommitdiff
path: root/cmds/statsd/tests/FieldValue_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/statsd/tests/FieldValue_test.cpp')
-rw-r--r--cmds/statsd/tests/FieldValue_test.cpp350
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