1 // Copyright (C) 2018 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "external/puller_util.h"
16 #include <gmock/gmock.h>
17 #include <gtest/gtest.h>
18 #include <stdio.h>
19 #include <vector>
20 #include "statslog.h"
21 #include "../metrics/metrics_test_helper.h"
22 
23 #ifdef __ANDROID__
24 
25 namespace android {
26 namespace os {
27 namespace statsd {
28 
29 using namespace testing;
30 using std::make_shared;
31 using std::shared_ptr;
32 using std::vector;
33 using testing::Contains;
34 /*
35  * Test merge isolated and host uid
36  */
37 
38 int uidAtomTagId = android::util::CPU_CLUSTER_TIME;
39 int nonUidAtomTagId = android::util::SYSTEM_UPTIME;
40 int timestamp = 1234;
41 int isolatedUid = 30;
42 int isolatedAdditiveData = 31;
43 int isolatedNonAdditiveData = 32;
44 int hostUid = 20;
45 int hostAdditiveData = 21;
46 int hostNonAdditiveData = 22;
47 
extractIntoVector(vector<shared_ptr<LogEvent>> events,vector<vector<int>> & ret)48 void extractIntoVector(vector<shared_ptr<LogEvent>> events,
49                       vector<vector<int>>& ret) {
50   ret.clear();
51   status_t err;
52   for (const auto& event : events) {
53     vector<int> vec;
54     vec.push_back(event->GetInt(1, &err));
55     vec.push_back(event->GetInt(2, &err));
56     vec.push_back(event->GetInt(3, &err));
57     ret.push_back(vec);
58   }
59 }
60 
TEST(puller_util,MergeNoDimension)61 TEST(puller_util, MergeNoDimension) {
62   vector<shared_ptr<LogEvent>> inputData;
63   shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
64   // 30->22->31
65   event->write(isolatedUid);
66   event->write(hostNonAdditiveData);
67   event->write(isolatedAdditiveData);
68   event->init();
69   inputData.push_back(event);
70 
71   // 20->22->21
72   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
73   event->write(hostUid);
74   event->write(hostNonAdditiveData);
75   event->write(hostAdditiveData);
76   event->init();
77   inputData.push_back(event);
78 
79   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
80   EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
81       .WillRepeatedly(Return(hostUid));
82   EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
83       .WillRepeatedly(ReturnArg<0>());
84   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
85 
86   vector<vector<int>> actual;
87   extractIntoVector(inputData, actual);
88   vector<int> expectedV1 = {20, 22, 52};
89   EXPECT_EQ(1, (int)actual.size());
90   EXPECT_THAT(actual, Contains(expectedV1));
91 }
92 
TEST(puller_util,MergeWithDimension)93 TEST(puller_util, MergeWithDimension) {
94   vector<shared_ptr<LogEvent>> inputData;
95   shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
96   // 30->32->31
97   event->write(isolatedUid);
98   event->write(isolatedNonAdditiveData);
99   event->write(isolatedAdditiveData);
100   event->init();
101   inputData.push_back(event);
102 
103   // 20->32->21
104   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
105   event->write(hostUid);
106   event->write(isolatedNonAdditiveData);
107   event->write(hostAdditiveData);
108   event->init();
109   inputData.push_back(event);
110 
111   // 20->22->21
112   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
113   event->write(hostUid);
114   event->write(hostNonAdditiveData);
115   event->write(hostAdditiveData);
116   event->init();
117   inputData.push_back(event);
118 
119   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
120   EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
121       .WillRepeatedly(Return(hostUid));
122   EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
123       .WillRepeatedly(ReturnArg<0>());
124   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
125 
126   vector<vector<int>> actual;
127   extractIntoVector(inputData, actual);
128   vector<int> expectedV1 = {20, 22, 21};
129   vector<int> expectedV2 = {20, 32, 52};
130   EXPECT_EQ(2, (int)actual.size());
131   EXPECT_THAT(actual, Contains(expectedV1));
132   EXPECT_THAT(actual, Contains(expectedV2));
133 }
134 
TEST(puller_util,NoMergeHostUidOnly)135 TEST(puller_util, NoMergeHostUidOnly) {
136   vector<shared_ptr<LogEvent>> inputData;
137   shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
138   // 20->32->31
139   event->write(hostUid);
140   event->write(isolatedNonAdditiveData);
141   event->write(isolatedAdditiveData);
142   event->init();
143   inputData.push_back(event);
144 
145   // 20->22->21
146   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
147   event->write(hostUid);
148   event->write(hostNonAdditiveData);
149   event->write(hostAdditiveData);
150   event->init();
151   inputData.push_back(event);
152 
153   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
154   EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
155       .WillRepeatedly(Return(hostUid));
156   EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
157       .WillRepeatedly(ReturnArg<0>());
158   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
159 
160   // 20->32->31
161   // 20->22->21
162   vector<vector<int>> actual;
163   extractIntoVector(inputData, actual);
164   vector<int> expectedV1 = {20, 32, 31};
165   vector<int> expectedV2 = {20, 22, 21};
166   EXPECT_EQ(2, (int)actual.size());
167   EXPECT_THAT(actual, Contains(expectedV1));
168   EXPECT_THAT(actual, Contains(expectedV2));
169 }
170 
TEST(puller_util,IsolatedUidOnly)171 TEST(puller_util, IsolatedUidOnly) {
172   vector<shared_ptr<LogEvent>> inputData;
173   shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
174   // 30->32->31
175   event->write(hostUid);
176   event->write(isolatedNonAdditiveData);
177   event->write(isolatedAdditiveData);
178   event->init();
179   inputData.push_back(event);
180 
181   // 30->22->21
182   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
183   event->write(hostUid);
184   event->write(hostNonAdditiveData);
185   event->write(hostAdditiveData);
186   event->init();
187   inputData.push_back(event);
188 
189   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
190   EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
191       .WillRepeatedly(Return(hostUid));
192   EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
193       .WillRepeatedly(ReturnArg<0>());
194   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
195 
196   // 20->32->31
197   // 20->22->21
198   vector<vector<int>> actual;
199   extractIntoVector(inputData, actual);
200   vector<int> expectedV1 = {20, 32, 31};
201   vector<int> expectedV2 = {20, 22, 21};
202   EXPECT_EQ(2, (int)actual.size());
203   EXPECT_THAT(actual, Contains(expectedV1));
204   EXPECT_THAT(actual, Contains(expectedV2));
205 }
206 
TEST(puller_util,MultipleIsolatedUidToOneHostUid)207 TEST(puller_util, MultipleIsolatedUidToOneHostUid) {
208   vector<shared_ptr<LogEvent>> inputData;
209   shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
210   // 30->32->31
211   event->write(isolatedUid);
212   event->write(isolatedNonAdditiveData);
213   event->write(isolatedAdditiveData);
214   event->init();
215   inputData.push_back(event);
216 
217   // 31->32->21
218   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
219   event->write(isolatedUid + 1);
220   event->write(isolatedNonAdditiveData);
221   event->write(hostAdditiveData);
222   event->init();
223   inputData.push_back(event);
224 
225   // 20->32->21
226   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
227   event->write(hostUid);
228   event->write(isolatedNonAdditiveData);
229   event->write(hostAdditiveData);
230   event->init();
231   inputData.push_back(event);
232 
233   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
234   EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(Return(hostUid));
235   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
236 
237   vector<vector<int>> actual;
238   extractIntoVector(inputData, actual);
239   vector<int> expectedV1 = {20, 32, 73};
240   EXPECT_EQ(1, (int)actual.size());
241   EXPECT_THAT(actual, Contains(expectedV1));
242 }
243 
TEST(puller_util,NoNeedToMerge)244 TEST(puller_util, NoNeedToMerge) {
245   vector<shared_ptr<LogEvent>> inputData;
246   shared_ptr<LogEvent> event =
247       make_shared<LogEvent>(nonUidAtomTagId, timestamp);
248   // 32
249   event->write(isolatedNonAdditiveData);
250   event->init();
251   inputData.push_back(event);
252 
253   event = make_shared<LogEvent>(nonUidAtomTagId, timestamp);
254   // 22
255   event->write(hostNonAdditiveData);
256   event->init();
257   inputData.push_back(event);
258 
259   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
260   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, nonUidAtomTagId);
261 
262   EXPECT_EQ(2, (int)inputData.size());
263 }
264 
265 }  // namespace statsd
266 }  // namespace os
267 }  // namespace android
268 #else
269 GTEST_LOG_(INFO) << "This test does nothing.\n";
270 #endif
271