diff options
Diffstat (limited to 'cmds/statsd/tests/external/puller_util_test.cpp')
-rw-r--r-- | cmds/statsd/tests/external/puller_util_test.cpp | 570 |
1 files changed, 354 insertions, 216 deletions
diff --git a/cmds/statsd/tests/external/puller_util_test.cpp b/cmds/statsd/tests/external/puller_util_test.cpp index 673082834e18..a21dc8717776 100644 --- a/cmds/statsd/tests/external/puller_util_test.cpp +++ b/cmds/statsd/tests/external/puller_util_test.cpp @@ -13,12 +13,18 @@ // limitations under the License. #include "external/puller_util.h" + #include <gmock/gmock.h> #include <gtest/gtest.h> #include <stdio.h> + #include <vector> -#include "statslog.h" + #include "../metrics/metrics_test_helper.h" +#include "FieldValue.h" +#include "annotations.h" +#include "stats_event.h" +#include "tests/statsd_test_util.h" #ifdef __ANDROID__ @@ -27,239 +33,371 @@ namespace os { namespace statsd { using namespace testing; -using std::make_shared; using std::shared_ptr; using std::vector; -using testing::Contains; /* * Test merge isolated and host uid */ +namespace { +const int uidAtomTagId = 100; +const vector<int> additiveFields = {3}; +const int nonUidAtomTagId = 200; +const int timestamp = 1234; +const int isolatedUid1 = 30; +const int isolatedUid2 = 40; +const int isolatedNonAdditiveData = 32; +const int isolatedAdditiveData = 31; +const int hostUid = 20; +const int hostNonAdditiveData = 22; +const int hostAdditiveData = 21; +const int attributionAtomTagId = 300; + +sp<MockUidMap> makeMockUidMap() { + return makeMockUidMapForOneHost(hostUid, {isolatedUid1, isolatedUid2}); +} + +} // anonymous namespace + +TEST(PullerUtilTest, MergeNoDimension) { + vector<shared_ptr<LogEvent>> data = { + // 30->22->31 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData, + isolatedAdditiveData), + + // 20->22->21 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData, + hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields); + + ASSERT_EQ(1, (int)data.size()); + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(2).mValue.int_value); +} + +TEST(PullerUtilTest, MergeWithDimension) { + vector<shared_ptr<LogEvent>> data = { + // 30->32->31 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 20->32->21 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData, + hostAdditiveData), + + // 20->22->21 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData, + hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields); + + ASSERT_EQ(2, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value); + + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value); +} + +TEST(PullerUtilTest, NoMergeHostUidOnly) { + vector<shared_ptr<LogEvent>> data = { + // 20->32->31 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 20->22->21 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData, + hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields); + + ASSERT_EQ(2, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value); + + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value); +} -int uidAtomTagId = android::util::CPU_CLUSTER_TIME; -int nonUidAtomTagId = android::util::SYSTEM_UPTIME; -int timestamp = 1234; -int isolatedUid = 30; -int isolatedAdditiveData = 31; -int isolatedNonAdditiveData = 32; -int hostUid = 20; -int hostAdditiveData = 21; -int hostNonAdditiveData = 22; - -void extractIntoVector(vector<shared_ptr<LogEvent>> events, - vector<vector<int>>& ret) { - ret.clear(); - status_t err; - for (const auto& event : events) { - vector<int> vec; - vec.push_back(event->GetInt(1, &err)); - vec.push_back(event->GetInt(2, &err)); - vec.push_back(event->GetInt(3, &err)); - ret.push_back(vec); - } +TEST(PullerUtilTest, IsolatedUidOnly) { + vector<shared_ptr<LogEvent>> data = { + // 30->32->31 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 30->22->21 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData, + hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields); + + ASSERT_EQ(2, (int)data.size()); + + // 20->32->31 + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value); + + // 20->22->21 + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(2).mValue.int_value); } -TEST(puller_util, MergeNoDimension) { - vector<shared_ptr<LogEvent>> inputData; - shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp); - // 30->22->31 - event->write(isolatedUid); - event->write(hostNonAdditiveData); - event->write(isolatedAdditiveData); - event->init(); - inputData.push_back(event); - - // 20->22->21 - event = make_shared<LogEvent>(uidAtomTagId, timestamp); - event->write(hostUid); - event->write(hostNonAdditiveData); - event->write(hostAdditiveData); - event->init(); - inputData.push_back(event); - - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)) - .WillRepeatedly(Return(hostUid)); - EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))) - .WillRepeatedly(ReturnArg<0>()); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId); - - vector<vector<int>> actual; - extractIntoVector(inputData, actual); - vector<int> expectedV1 = {20, 22, 52}; - EXPECT_EQ(1, (int)actual.size()); - EXPECT_THAT(actual, Contains(expectedV1)); +TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUid) { + vector<shared_ptr<LogEvent>> data = { + // 30->32->31 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 31->32->21 + makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid2, isolatedNonAdditiveData, + hostAdditiveData), + + // 20->32->21 + makeUidLogEvent(uidAtomTagId, timestamp, hostUid, isolatedNonAdditiveData, + hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields); + + ASSERT_EQ(1, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(3, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(1).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData, + actualFieldValues->at(2).mValue.int_value); +} + +TEST(PullerUtilTest, NoNeedToMerge) { + vector<shared_ptr<LogEvent>> data = { + // 32->31 + CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 22->21 + CreateTwoValueLogEvent(nonUidAtomTagId, timestamp, hostNonAdditiveData, + hostAdditiveData), + + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, nonUidAtomTagId, {} /*no additive fields*/); + + ASSERT_EQ(2, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(2, actualFieldValues->size()); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(1).mValue.int_value); + + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(2, actualFieldValues->size()); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(1).mValue.int_value); } -TEST(puller_util, MergeWithDimension) { - vector<shared_ptr<LogEvent>> inputData; - shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp); - // 30->32->31 - event->write(isolatedUid); - event->write(isolatedNonAdditiveData); - event->write(isolatedAdditiveData); - event->init(); - inputData.push_back(event); - - // 20->32->21 - event = make_shared<LogEvent>(uidAtomTagId, timestamp); - event->write(hostUid); - event->write(isolatedNonAdditiveData); - event->write(hostAdditiveData); - event->init(); - inputData.push_back(event); - - // 20->22->21 - event = make_shared<LogEvent>(uidAtomTagId, timestamp); - event->write(hostUid); - event->write(hostNonAdditiveData); - event->write(hostAdditiveData); - event->init(); - inputData.push_back(event); - - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)) - .WillRepeatedly(Return(hostUid)); - EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))) - .WillRepeatedly(ReturnArg<0>()); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId); - - vector<vector<int>> actual; - extractIntoVector(inputData, actual); - vector<int> expectedV1 = {20, 22, 21}; - vector<int> expectedV2 = {20, 32, 52}; - EXPECT_EQ(2, (int)actual.size()); - EXPECT_THAT(actual, Contains(expectedV1)); - EXPECT_THAT(actual, Contains(expectedV2)); +TEST(PullerUtilTest, MergeNoDimensionAttributionChain) { + vector<shared_ptr<LogEvent>> data = { + // 30->tag1->400->tag2->22->31 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400}, + {"tag1", "tag2"}, hostNonAdditiveData, isolatedAdditiveData), + + // 20->tag1->400->tag2->22->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400}, + {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields); + + ASSERT_EQ(1, (int)data.size()); + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData + hostAdditiveData, actualFieldValues->at(5).mValue.int_value); } -TEST(puller_util, NoMergeHostUidOnly) { - vector<shared_ptr<LogEvent>> inputData; - shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp); - // 20->32->31 - event->write(hostUid); - event->write(isolatedNonAdditiveData); - event->write(isolatedAdditiveData); - event->init(); - inputData.push_back(event); - - // 20->22->21 - event = make_shared<LogEvent>(uidAtomTagId, timestamp); - event->write(hostUid); - event->write(hostNonAdditiveData); - event->write(hostAdditiveData); - event->init(); - inputData.push_back(event); - - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)) - .WillRepeatedly(Return(hostUid)); - EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))) - .WillRepeatedly(ReturnArg<0>()); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId); - - // 20->32->31 - // 20->22->21 - vector<vector<int>> actual; - extractIntoVector(inputData, actual); - vector<int> expectedV1 = {20, 32, 31}; - vector<int> expectedV2 = {20, 22, 21}; - EXPECT_EQ(2, (int)actual.size()); - EXPECT_THAT(actual, Contains(expectedV1)); - EXPECT_THAT(actual, Contains(expectedV2)); +TEST(PullerUtilTest, MergeWithDimensionAttributionChain) { + vector<shared_ptr<LogEvent>> data = { + // 200->tag1->30->tag2->32->31 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, isolatedUid1}, + {"tag1", "tag2"}, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 200->tag1->20->tag2->32->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid}, + {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData), + + // 200->tag1->20->tag2->22->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {200, hostUid}, + {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields); + + ASSERT_EQ(2, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value); + + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(200, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value); } -TEST(puller_util, IsolatedUidOnly) { - vector<shared_ptr<LogEvent>> inputData; - shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp); - // 30->32->31 - event->write(hostUid); - event->write(isolatedNonAdditiveData); - event->write(isolatedAdditiveData); - event->init(); - inputData.push_back(event); - - // 30->22->21 - event = make_shared<LogEvent>(uidAtomTagId, timestamp); - event->write(hostUid); - event->write(hostNonAdditiveData); - event->write(hostAdditiveData); - event->init(); - inputData.push_back(event); - - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid)) - .WillRepeatedly(Return(hostUid)); - EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid))) - .WillRepeatedly(ReturnArg<0>()); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId); - - // 20->32->31 - // 20->22->21 - vector<vector<int>> actual; - extractIntoVector(inputData, actual); - vector<int> expectedV1 = {20, 32, 31}; - vector<int> expectedV2 = {20, 22, 21}; - EXPECT_EQ(2, (int)actual.size()); - EXPECT_THAT(actual, Contains(expectedV1)); - EXPECT_THAT(actual, Contains(expectedV2)); +TEST(PullerUtilTest, NoMergeHostUidOnlyAttributionChain) { + vector<shared_ptr<LogEvent>> data = { + // 20->tag1->400->tag2->32->31 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400}, + {"tag1", "tag2"}, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 20->tag1->400->tag2->22->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400}, + {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields); + + ASSERT_EQ(2, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value); + + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value); } -TEST(puller_util, MultipleIsolatedUidToOneHostUid) { - vector<shared_ptr<LogEvent>> inputData; - shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp); - // 30->32->31 - event->write(isolatedUid); - event->write(isolatedNonAdditiveData); - event->write(isolatedAdditiveData); - event->init(); - inputData.push_back(event); - - // 31->32->21 - event = make_shared<LogEvent>(uidAtomTagId, timestamp); - event->write(isolatedUid + 1); - event->write(isolatedNonAdditiveData); - event->write(hostAdditiveData); - event->init(); - inputData.push_back(event); - - // 20->32->21 - event = make_shared<LogEvent>(uidAtomTagId, timestamp); - event->write(hostUid); - event->write(isolatedNonAdditiveData); - event->write(hostAdditiveData); - event->init(); - inputData.push_back(event); - - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(Return(hostUid)); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId); - - vector<vector<int>> actual; - extractIntoVector(inputData, actual); - vector<int> expectedV1 = {20, 32, 73}; - EXPECT_EQ(1, (int)actual.size()); - EXPECT_THAT(actual, Contains(expectedV1)); +TEST(PullerUtilTest, IsolatedUidOnlyAttributionChain) { + vector<shared_ptr<LogEvent>> data = { + // 30->tag1->400->tag2->32->31 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400}, + {"tag1", "tag2"}, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 30->tag1->400->tag2->22->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400}, + {"tag1", "tag2"}, hostNonAdditiveData, hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields); + + ASSERT_EQ(2, (int)data.size()); + + // 20->tag1->400->tag2->32->31 + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(hostAdditiveData, actualFieldValues->at(5).mValue.int_value); + + // 20->tag1->400->tag2->22->21 + actualFieldValues = &data[1]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData, actualFieldValues->at(5).mValue.int_value); } -TEST(puller_util, NoNeedToMerge) { - vector<shared_ptr<LogEvent>> inputData; - shared_ptr<LogEvent> event = - make_shared<LogEvent>(nonUidAtomTagId, timestamp); - // 32 - event->write(isolatedNonAdditiveData); - event->init(); - inputData.push_back(event); - - event = make_shared<LogEvent>(nonUidAtomTagId, timestamp); - // 22 - event->write(hostNonAdditiveData); - event->init(); - inputData.push_back(event); - - sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>(); - mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, nonUidAtomTagId); - - EXPECT_EQ(2, (int)inputData.size()); +TEST(PullerUtilTest, MultipleIsolatedUidToOneHostUidAttributionChain) { + vector<shared_ptr<LogEvent>> data = { + // 30->tag1->400->tag2->32->31 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid1, 400}, + {"tag1", "tag2"}, isolatedNonAdditiveData, + isolatedAdditiveData), + + // 31->tag1->400->tag2->32->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {isolatedUid2, 400}, + {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData), + + // 20->tag1->400->tag2->32->21 + makeAttributionLogEvent(attributionAtomTagId, timestamp, {hostUid, 400}, + {"tag1", "tag2"}, isolatedNonAdditiveData, hostAdditiveData), + }; + + sp<MockUidMap> uidMap = makeMockUidMap(); + mapAndMergeIsolatedUidsToHostUid(data, uidMap, attributionAtomTagId, additiveFields); + + ASSERT_EQ(1, (int)data.size()); + + const vector<FieldValue>* actualFieldValues = &data[0]->getValues(); + ASSERT_EQ(6, actualFieldValues->size()); + EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value); + EXPECT_EQ("tag1", actualFieldValues->at(1).mValue.str_value); + EXPECT_EQ(400, actualFieldValues->at(2).mValue.int_value); + EXPECT_EQ("tag2", actualFieldValues->at(3).mValue.str_value); + EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(4).mValue.int_value); + EXPECT_EQ(isolatedAdditiveData + hostAdditiveData + hostAdditiveData, + actualFieldValues->at(5).mValue.int_value); } } // namespace statsd |