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 "../metrics/metrics_test_helper.h"
21 
22 #ifdef __ANDROID__
23 
24 namespace android {
25 namespace os {
26 namespace statsd {
27 
28 using namespace testing;
29 using std::make_shared;
30 using std::shared_ptr;
31 using std::vector;
32 using testing::Contains;
33 /*
34  * Test merge isolated and host uid
35  */
36 
37 int uidAtomTagId = android::util::CPU_CLUSTER_TIME;
38 int nonUidAtomTagId = android::util::SYSTEM_UPTIME;
39 int timestamp = 1234;
40 int isolatedUid = 30;
41 int isolatedAdditiveData = 31;
42 int isolatedNonAdditiveData = 32;
43 int hostUid = 20;
44 int hostAdditiveData = 21;
45 int hostNonAdditiveData = 22;
46 
extractIntoVector(vector<shared_ptr<LogEvent>> events,vector<vector<int>> & ret)47 void extractIntoVector(vector<shared_ptr<LogEvent>> events,
48                       vector<vector<int>>& ret) {
49   ret.clear();
50   status_t err;
51   for (const auto& event : events) {
52     vector<int> vec;
53     vec.push_back(event->GetInt(1, &err));
54     vec.push_back(event->GetInt(2, &err));
55     vec.push_back(event->GetInt(3, &err));
56     ret.push_back(vec);
57   }
58 }
59 
TEST(puller_util,MergeNoDimension)60 TEST(puller_util, MergeNoDimension) {
61   vector<shared_ptr<LogEvent>> inputData;
62   shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
63   // 30->22->31
64   event->write(isolatedUid);
65   event->write(hostNonAdditiveData);
66   event->write(isolatedAdditiveData);
67   event->init();
68   inputData.push_back(event);
69 
70   // 20->22->21
71   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
72   event->write(hostUid);
73   event->write(hostNonAdditiveData);
74   event->write(hostAdditiveData);
75   event->init();
76   inputData.push_back(event);
77 
78   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
79   EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
80       .WillRepeatedly(Return(hostUid));
81   EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
82       .WillRepeatedly(ReturnArg<0>());
83   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
84 
85   vector<vector<int>> actual;
86   extractIntoVector(inputData, actual);
87   vector<int> expectedV1 = {20, 22, 52};
88   EXPECT_EQ(1, (int)actual.size());
89   EXPECT_THAT(actual, Contains(expectedV1));
90 }
91 
TEST(puller_util,MergeWithDimension)92 TEST(puller_util, MergeWithDimension) {
93   vector<shared_ptr<LogEvent>> inputData;
94   shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
95   // 30->32->31
96   event->write(isolatedUid);
97   event->write(isolatedNonAdditiveData);
98   event->write(isolatedAdditiveData);
99   event->init();
100   inputData.push_back(event);
101 
102   // 20->32->21
103   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
104   event->write(hostUid);
105   event->write(isolatedNonAdditiveData);
106   event->write(hostAdditiveData);
107   event->init();
108   inputData.push_back(event);
109 
110   // 20->22->21
111   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
112   event->write(hostUid);
113   event->write(hostNonAdditiveData);
114   event->write(hostAdditiveData);
115   event->init();
116   inputData.push_back(event);
117 
118   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
119   EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
120       .WillRepeatedly(Return(hostUid));
121   EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
122       .WillRepeatedly(ReturnArg<0>());
123   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
124 
125   vector<vector<int>> actual;
126   extractIntoVector(inputData, actual);
127   vector<int> expectedV1 = {20, 22, 21};
128   vector<int> expectedV2 = {20, 32, 52};
129   EXPECT_EQ(2, (int)actual.size());
130   EXPECT_THAT(actual, Contains(expectedV1));
131   EXPECT_THAT(actual, Contains(expectedV2));
132 }
133 
TEST(puller_util,NoMergeHostUidOnly)134 TEST(puller_util, NoMergeHostUidOnly) {
135   vector<shared_ptr<LogEvent>> inputData;
136   shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
137   // 20->32->31
138   event->write(hostUid);
139   event->write(isolatedNonAdditiveData);
140   event->write(isolatedAdditiveData);
141   event->init();
142   inputData.push_back(event);
143 
144   // 20->22->21
145   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
146   event->write(hostUid);
147   event->write(hostNonAdditiveData);
148   event->write(hostAdditiveData);
149   event->init();
150   inputData.push_back(event);
151 
152   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
153   EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
154       .WillRepeatedly(Return(hostUid));
155   EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
156       .WillRepeatedly(ReturnArg<0>());
157   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
158 
159   // 20->32->31
160   // 20->22->21
161   vector<vector<int>> actual;
162   extractIntoVector(inputData, actual);
163   vector<int> expectedV1 = {20, 32, 31};
164   vector<int> expectedV2 = {20, 22, 21};
165   EXPECT_EQ(2, (int)actual.size());
166   EXPECT_THAT(actual, Contains(expectedV1));
167   EXPECT_THAT(actual, Contains(expectedV2));
168 }
169 
TEST(puller_util,IsolatedUidOnly)170 TEST(puller_util, IsolatedUidOnly) {
171   vector<shared_ptr<LogEvent>> inputData;
172   shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
173   // 30->32->31
174   event->write(hostUid);
175   event->write(isolatedNonAdditiveData);
176   event->write(isolatedAdditiveData);
177   event->init();
178   inputData.push_back(event);
179 
180   // 30->22->21
181   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
182   event->write(hostUid);
183   event->write(hostNonAdditiveData);
184   event->write(hostAdditiveData);
185   event->init();
186   inputData.push_back(event);
187 
188   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
189   EXPECT_CALL(*uidMap, getHostUidOrSelf(isolatedUid))
190       .WillRepeatedly(Return(hostUid));
191   EXPECT_CALL(*uidMap, getHostUidOrSelf(Ne(isolatedUid)))
192       .WillRepeatedly(ReturnArg<0>());
193   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
194 
195   // 20->32->31
196   // 20->22->21
197   vector<vector<int>> actual;
198   extractIntoVector(inputData, actual);
199   vector<int> expectedV1 = {20, 32, 31};
200   vector<int> expectedV2 = {20, 22, 21};
201   EXPECT_EQ(2, (int)actual.size());
202   EXPECT_THAT(actual, Contains(expectedV1));
203   EXPECT_THAT(actual, Contains(expectedV2));
204 }
205 
TEST(puller_util,MultipleIsolatedUidToOneHostUid)206 TEST(puller_util, MultipleIsolatedUidToOneHostUid) {
207   vector<shared_ptr<LogEvent>> inputData;
208   shared_ptr<LogEvent> event = make_shared<LogEvent>(uidAtomTagId, timestamp);
209   // 30->32->31
210   event->write(isolatedUid);
211   event->write(isolatedNonAdditiveData);
212   event->write(isolatedAdditiveData);
213   event->init();
214   inputData.push_back(event);
215 
216   // 31->32->21
217   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
218   event->write(isolatedUid + 1);
219   event->write(isolatedNonAdditiveData);
220   event->write(hostAdditiveData);
221   event->init();
222   inputData.push_back(event);
223 
224   // 20->32->21
225   event = make_shared<LogEvent>(uidAtomTagId, timestamp);
226   event->write(hostUid);
227   event->write(isolatedNonAdditiveData);
228   event->write(hostAdditiveData);
229   event->init();
230   inputData.push_back(event);
231 
232   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
233   EXPECT_CALL(*uidMap, getHostUidOrSelf(_)).WillRepeatedly(Return(hostUid));
234   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, uidAtomTagId);
235 
236   vector<vector<int>> actual;
237   extractIntoVector(inputData, actual);
238   vector<int> expectedV1 = {20, 32, 73};
239   EXPECT_EQ(1, (int)actual.size());
240   EXPECT_THAT(actual, Contains(expectedV1));
241 }
242 
TEST(puller_util,NoNeedToMerge)243 TEST(puller_util, NoNeedToMerge) {
244   vector<shared_ptr<LogEvent>> inputData;
245   shared_ptr<LogEvent> event =
246       make_shared<LogEvent>(nonUidAtomTagId, timestamp);
247   // 32
248   event->write(isolatedNonAdditiveData);
249   event->init();
250   inputData.push_back(event);
251 
252   event = make_shared<LogEvent>(nonUidAtomTagId, timestamp);
253   // 22
254   event->write(hostNonAdditiveData);
255   event->init();
256   inputData.push_back(event);
257 
258   sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
259   mapAndMergeIsolatedUidsToHostUid(inputData, uidMap, nonUidAtomTagId);
260 
261   EXPECT_EQ(2, (int)inputData.size());
262 }
263 
264 }  // namespace statsd
265 }  // namespace os
266 }  // namespace android
267 #else
268 GTEST_LOG_(INFO) << "This test does nothing.\n";
269 #endif
270