blob: 8a394f75a0d04f9ec06619e8d8c76c7c78c27161 [file] [log] [blame]
David Chende701692017-10-05 13:16:02 -07001// Copyright (C) 2017 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
Joe Onorato9fc9edf2017-10-15 20:08:52 -070015#include "packages/UidMap.h"
David Chen21582962017-11-01 17:32:46 -070016#include "StatsLogProcessor.h"
David Chend6896892017-10-25 11:49:03 -070017#include "config/ConfigKey.h"
David Chenc136f452017-11-27 11:52:26 -080018#include "guardrail/StatsdStats.h"
David Chen21582962017-11-01 17:32:46 -070019#include "logd/LogEvent.h"
20#include "statslog.h"
David Chende701692017-10-05 13:16:02 -070021
22#include <gtest/gtest.h>
Joe Onorato9fc9edf2017-10-15 20:08:52 -070023
David Chende701692017-10-05 13:16:02 -070024#include <stdio.h>
25
26using namespace android;
David Chend6896892017-10-25 11:49:03 -070027
28namespace android {
29namespace os {
30namespace statsd {
David Chende701692017-10-05 13:16:02 -070031
32#ifdef __ANDROID__
33const string kApp1 = "app1.sharing.1";
34const string kApp2 = "app2.sharing.1";
35
David Chen21582962017-11-01 17:32:46 -070036TEST(UidMapTest, TestIsolatedUID) {
37 sp<UidMap> m = new UidMap();
Yangster-mace2cd6d52017-11-09 20:38:30 -080038 sp<AnomalyMonitor> anomalyMonitor;
David Chenc136f452017-11-27 11:52:26 -080039 // Construct the processor with a dummy sendBroadcast function that does nothing.
Yangster-mac20877162017-12-22 17:19:39 -080040 StatsLogProcessor p(m, anomalyMonitor, 0, [](const ConfigKey& key) {});
David Chen21582962017-11-01 17:32:46 -070041 LogEvent addEvent(android::util::ISOLATED_UID_CHANGED, 1);
Yao Chen80235402017-11-13 20:42:25 -080042 addEvent.write(100); // parent UID
43 addEvent.write(101); // isolated UID
44 addEvent.write(1); // Indicates creation.
David Chen21582962017-11-01 17:32:46 -070045 addEvent.init();
46
47 EXPECT_EQ(101, m->getParentUidOrSelf(101));
48
49 p.OnLogEvent(addEvent);
50 EXPECT_EQ(100, m->getParentUidOrSelf(101));
51
52 LogEvent removeEvent(android::util::ISOLATED_UID_CHANGED, 1);
Yao Chen80235402017-11-13 20:42:25 -080053 removeEvent.write(100); // parent UID
54 removeEvent.write(101); // isolated UID
55 removeEvent.write(0); // Indicates removal.
David Chen21582962017-11-01 17:32:46 -070056 removeEvent.init();
57 p.OnLogEvent(removeEvent);
58 EXPECT_EQ(101, m->getParentUidOrSelf(101));
59}
60
David Chende701692017-10-05 13:16:02 -070061TEST(UidMapTest, TestMatching) {
62 UidMap m;
63 vector<int32_t> uids;
Dianne Hackborn3accca02013-09-20 09:32:11 -070064 vector<int64_t> versions;
David Chende701692017-10-05 13:16:02 -070065 vector<String16> apps;
66
67 uids.push_back(1000);
68 uids.push_back(1000);
69 apps.push_back(String16(kApp1.c_str()));
70 apps.push_back(String16(kApp2.c_str()));
71 versions.push_back(4);
72 versions.push_back(5);
73 m.updateMap(uids, versions, apps);
74 EXPECT_TRUE(m.hasApp(1000, kApp1));
75 EXPECT_TRUE(m.hasApp(1000, kApp2));
76 EXPECT_FALSE(m.hasApp(1000, "not.app"));
Yangster9df9a7f2017-12-18 13:33:05 -080077
78 std::set<string> name_set = m.getAppNamesFromUid(1000u, true /* returnNormalized */);
79 EXPECT_EQ(name_set.size(), 2u);
80 EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
81 EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
82
83 name_set = m.getAppNamesFromUid(12345, true /* returnNormalized */);
84 EXPECT_TRUE(name_set.empty());
David Chende701692017-10-05 13:16:02 -070085}
86
87TEST(UidMapTest, TestAddAndRemove) {
88 UidMap m;
89 vector<int32_t> uids;
Dianne Hackborn3accca02013-09-20 09:32:11 -070090 vector<int64_t> versions;
David Chende701692017-10-05 13:16:02 -070091 vector<String16> apps;
92
93 uids.push_back(1000);
94 uids.push_back(1000);
95 apps.push_back(String16(kApp1.c_str()));
96 apps.push_back(String16(kApp2.c_str()));
97 versions.push_back(4);
98 versions.push_back(5);
99 m.updateMap(uids, versions, apps);
100
Yangster9df9a7f2017-12-18 13:33:05 -0800101 std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
102 EXPECT_EQ(name_set.size(), 2u);
103 EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
104 EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
105
106 // Update the app1 version.
David Chende701692017-10-05 13:16:02 -0700107 m.updateApp(String16(kApp1.c_str()), 1000, 40);
108 EXPECT_EQ(40, m.getAppVersion(1000, kApp1));
109
Yangster9df9a7f2017-12-18 13:33:05 -0800110 name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
111 EXPECT_EQ(name_set.size(), 2u);
112 EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
113 EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
114
David Chende701692017-10-05 13:16:02 -0700115 m.removeApp(String16(kApp1.c_str()), 1000);
116 EXPECT_FALSE(m.hasApp(1000, kApp1));
117 EXPECT_TRUE(m.hasApp(1000, kApp2));
Yangster9df9a7f2017-12-18 13:33:05 -0800118 name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
119 EXPECT_EQ(name_set.size(), 1u);
120 EXPECT_TRUE(name_set.find(kApp1) == name_set.end());
121 EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
122
123 // Remove app2.
124 m.removeApp(String16(kApp2.c_str()), 1000);
125 EXPECT_FALSE(m.hasApp(1000, kApp1));
126 EXPECT_FALSE(m.hasApp(1000, kApp2));
127 name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
128 EXPECT_TRUE(name_set.empty());
129}
130
131TEST(UidMapTest, TestUpdateApp) {
132 UidMap m;
133 m.updateMap({1000, 1000}, {4, 5}, {String16(kApp1.c_str()), String16(kApp2.c_str())});
134 std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
135 EXPECT_EQ(name_set.size(), 2u);
136 EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
137 EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
138
139 // Adds a new name for uid 1000.
140 m.updateApp(String16("NeW_aPP1_NAmE"), 1000, 40);
141 name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
142 EXPECT_EQ(name_set.size(), 3u);
143 EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
144 EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
145 EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
146 EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end());
147
148 // This name is also reused by another uid 2000.
149 m.updateApp(String16("NeW_aPP1_NAmE"), 2000, 1);
150 name_set = m.getAppNamesFromUid(2000, true /* returnNormalized */);
151 EXPECT_EQ(name_set.size(), 1u);
152 EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
153 EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end());
David Chende701692017-10-05 13:16:02 -0700154}
David Chend6896892017-10-25 11:49:03 -0700155
156TEST(UidMapTest, TestClearingOutput) {
157 UidMap m;
158
159 ConfigKey config1(1, "config1");
160 ConfigKey config2(1, "config2");
161
162 m.OnConfigUpdated(config1);
163
164 vector<int32_t> uids;
Dianne Hackborn3accca02013-09-20 09:32:11 -0700165 vector<int64_t> versions;
David Chend6896892017-10-25 11:49:03 -0700166 vector<String16> apps;
167 uids.push_back(1000);
168 uids.push_back(1000);
169 apps.push_back(String16(kApp1.c_str()));
170 apps.push_back(String16(kApp2.c_str()));
171 versions.push_back(4);
172 versions.push_back(5);
173 m.updateMap(1, uids, versions, apps);
David Chenc136f452017-11-27 11:52:26 -0800174 EXPECT_EQ(1, m.mOutput.snapshots_size());
David Chend6896892017-10-25 11:49:03 -0700175
176 UidMapping results = m.getOutput(2, config1);
177 EXPECT_EQ(1, results.snapshots_size());
178
179 // It should be cleared now
David Chenc136f452017-11-27 11:52:26 -0800180 EXPECT_EQ(0, m.mOutput.snapshots_size());
David Chend6896892017-10-25 11:49:03 -0700181 results = m.getOutput(3, config1);
182 EXPECT_EQ(0, results.snapshots_size());
183
184 // Now add another configuration.
185 m.OnConfigUpdated(config2);
186 m.updateApp(5, String16(kApp1.c_str()), 1000, 40);
David Chenc136f452017-11-27 11:52:26 -0800187 EXPECT_EQ(1, m.mOutput.changes_size());
David Chend6896892017-10-25 11:49:03 -0700188 results = m.getOutput(6, config1);
189 EXPECT_EQ(0, results.snapshots_size());
190 EXPECT_EQ(1, results.changes_size());
David Chenc136f452017-11-27 11:52:26 -0800191 EXPECT_EQ(1, m.mOutput.changes_size());
David Chend6896892017-10-25 11:49:03 -0700192
David Chenc136f452017-11-27 11:52:26 -0800193 // Add another delta update.
David Chend6896892017-10-25 11:49:03 -0700194 m.updateApp(7, String16(kApp2.c_str()), 1001, 41);
David Chenc136f452017-11-27 11:52:26 -0800195 EXPECT_EQ(2, m.mOutput.changes_size());
196
197 // We still can't remove anything.
David Chend6896892017-10-25 11:49:03 -0700198 results = m.getOutput(8, config1);
199 EXPECT_EQ(0, results.snapshots_size());
200 EXPECT_EQ(2, results.changes_size());
David Chenc136f452017-11-27 11:52:26 -0800201 EXPECT_EQ(2, m.mOutput.changes_size());
David Chend6896892017-10-25 11:49:03 -0700202
203 results = m.getOutput(9, config2);
204 EXPECT_EQ(0, results.snapshots_size());
205 EXPECT_EQ(2, results.changes_size());
206 // At this point both should be cleared.
207 EXPECT_EQ(0, m.mOutput.snapshots_size());
208 EXPECT_EQ(0, m.mOutput.changes_size());
209}
David Chenc136f452017-11-27 11:52:26 -0800210
211TEST(UidMapTest, TestMemoryComputed) {
212 UidMap m;
213
214 ConfigKey config1(1, "config1");
215 m.OnConfigUpdated(config1);
216
217 size_t startBytes = m.mBytesUsed;
218 vector<int32_t> uids;
Dianne Hackborn3accca02013-09-20 09:32:11 -0700219 vector<int64_t> versions;
David Chenc136f452017-11-27 11:52:26 -0800220 vector<String16> apps;
221 uids.push_back(1000);
222 apps.push_back(String16(kApp1.c_str()));
223 versions.push_back(1);
224 m.updateMap(1, uids, versions, apps);
225 size_t snapshot_bytes = m.mBytesUsed;
226 EXPECT_TRUE(snapshot_bytes > startBytes);
227
228 m.updateApp(3, String16(kApp1.c_str()), 1000, 40);
229 EXPECT_TRUE(m.mBytesUsed > snapshot_bytes);
230 size_t bytesWithSnapshotChange = m.mBytesUsed;
231
232 m.getOutput(2, config1);
233 EXPECT_TRUE(m.mBytesUsed < bytesWithSnapshotChange);
234 size_t prevBytes = m.mBytesUsed;
235
236 m.getOutput(4, config1);
237 EXPECT_TRUE(m.mBytesUsed < prevBytes);
238}
239
240TEST(UidMapTest, TestMemoryGuardrail) {
241 UidMap m;
242 string buf;
243
244 ConfigKey config1(1, "config1");
245 m.OnConfigUpdated(config1);
246
247 size_t startBytes = m.mBytesUsed;
248 vector<int32_t> uids;
Dianne Hackborn3accca02013-09-20 09:32:11 -0700249 vector<int64_t> versions;
David Chenc136f452017-11-27 11:52:26 -0800250 vector<String16> apps;
251 for (int i = 0; i < 100; i++) {
252 uids.push_back(1);
253 buf = "EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY." + to_string(i);
254 apps.push_back(String16(buf.c_str()));
255 versions.push_back(1);
256 }
257 m.updateMap(1, uids, versions, apps);
258 EXPECT_EQ(1, m.mOutput.snapshots_size());
259
260 m.updateApp(3, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 2);
261 EXPECT_EQ(1, m.mOutput.snapshots_size());
262 EXPECT_EQ(1, m.mOutput.changes_size());
263
264 // Now force deletion by limiting the memory to hold one delta change.
265 m.maxBytesOverride = 80; // Since the app string alone requires >45 characters.
266 m.updateApp(5, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 4);
267 EXPECT_EQ(0, m.mOutput.snapshots_size());
268 EXPECT_EQ(1, m.mOutput.changes_size());
269}
David Chende701692017-10-05 13:16:02 -0700270#else
271GTEST_LOG_(INFO) << "This test does nothing.\n";
Joe Onorato9fc9edf2017-10-15 20:08:52 -0700272#endif
David Chend6896892017-10-25 11:49:03 -0700273
274} // namespace statsd
275} // namespace os
Yangster-mac20877162017-12-22 17:19:39 -0800276} // namespace android