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