Files
frameworks_base/cmds/statsd/tests/UidMap_test.cpp
Dianne Hackborn 3accca05dd Add major version code to platform.
It turns the version code into almost a 64-bit integer, with the
new major part being the upper 32 bits.

The only tricky part about this is the backup manager, since it
stored 32-bit version codes in its backup data sets.  This is dealt
with by, when the major version code is not 0, writing MIN_INT as
the version code and following that by the full long version code,
which we can detect when reading.  Note that this makes backup sets
containing apps with major version codes incompatible with older
versions of the platform.

Bug: 64459786
Test: Added in Change-Id: Iab8a682b62103babd6c16a56b8dc1e97d7078658
Change-Id: Ibfffe235bbfcf358b3741abd3f7197fdb063d3f3
2017-12-04 13:02:10 -08:00

222 lines
6.7 KiB
C++

// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "packages/UidMap.h"
#include "StatsLogProcessor.h"
#include "config/ConfigKey.h"
#include "guardrail/StatsdStats.h"
#include "logd/LogEvent.h"
#include "statslog.h"
#include <gtest/gtest.h>
#include <stdio.h>
using namespace android;
namespace android {
namespace os {
namespace statsd {
#ifdef __ANDROID__
const string kApp1 = "app1.sharing.1";
const string kApp2 = "app2.sharing.1";
TEST(UidMapTest, TestIsolatedUID) {
sp<UidMap> m = new UidMap();
sp<AnomalyMonitor> anomalyMonitor;
// Construct the processor with a dummy sendBroadcast function that does nothing.
StatsLogProcessor p(m, anomalyMonitor, [](const ConfigKey& key) {});
LogEvent addEvent(android::util::ISOLATED_UID_CHANGED, 1);
addEvent.write(100); // parent UID
addEvent.write(101); // isolated UID
addEvent.write(1); // Indicates creation.
addEvent.init();
EXPECT_EQ(101, m->getParentUidOrSelf(101));
p.OnLogEvent(addEvent);
EXPECT_EQ(100, m->getParentUidOrSelf(101));
LogEvent removeEvent(android::util::ISOLATED_UID_CHANGED, 1);
removeEvent.write(100); // parent UID
removeEvent.write(101); // isolated UID
removeEvent.write(0); // Indicates removal.
removeEvent.init();
p.OnLogEvent(removeEvent);
EXPECT_EQ(101, m->getParentUidOrSelf(101));
}
TEST(UidMapTest, TestMatching) {
UidMap m;
vector<int32_t> uids;
vector<int64_t> versions;
vector<String16> apps;
uids.push_back(1000);
uids.push_back(1000);
apps.push_back(String16(kApp1.c_str()));
apps.push_back(String16(kApp2.c_str()));
versions.push_back(4);
versions.push_back(5);
m.updateMap(uids, versions, apps);
EXPECT_TRUE(m.hasApp(1000, kApp1));
EXPECT_TRUE(m.hasApp(1000, kApp2));
EXPECT_FALSE(m.hasApp(1000, "not.app"));
}
TEST(UidMapTest, TestAddAndRemove) {
UidMap m;
vector<int32_t> uids;
vector<int64_t> versions;
vector<String16> apps;
uids.push_back(1000);
uids.push_back(1000);
apps.push_back(String16(kApp1.c_str()));
apps.push_back(String16(kApp2.c_str()));
versions.push_back(4);
versions.push_back(5);
m.updateMap(uids, versions, apps);
m.updateApp(String16(kApp1.c_str()), 1000, 40);
EXPECT_EQ(40, m.getAppVersion(1000, kApp1));
m.removeApp(String16(kApp1.c_str()), 1000);
EXPECT_FALSE(m.hasApp(1000, kApp1));
EXPECT_TRUE(m.hasApp(1000, kApp2));
}
TEST(UidMapTest, TestClearingOutput) {
UidMap m;
ConfigKey config1(1, "config1");
ConfigKey config2(1, "config2");
m.OnConfigUpdated(config1);
vector<int32_t> uids;
vector<int64_t> versions;
vector<String16> apps;
uids.push_back(1000);
uids.push_back(1000);
apps.push_back(String16(kApp1.c_str()));
apps.push_back(String16(kApp2.c_str()));
versions.push_back(4);
versions.push_back(5);
m.updateMap(1, uids, versions, apps);
EXPECT_EQ(1, m.mOutput.snapshots_size());
UidMapping results = m.getOutput(2, config1);
EXPECT_EQ(1, results.snapshots_size());
// It should be cleared now
EXPECT_EQ(0, m.mOutput.snapshots_size());
results = m.getOutput(3, config1);
EXPECT_EQ(0, results.snapshots_size());
// Now add another configuration.
m.OnConfigUpdated(config2);
m.updateApp(5, String16(kApp1.c_str()), 1000, 40);
EXPECT_EQ(1, m.mOutput.changes_size());
results = m.getOutput(6, config1);
EXPECT_EQ(0, results.snapshots_size());
EXPECT_EQ(1, results.changes_size());
EXPECT_EQ(1, m.mOutput.changes_size());
// Add another delta update.
m.updateApp(7, String16(kApp2.c_str()), 1001, 41);
EXPECT_EQ(2, m.mOutput.changes_size());
// We still can't remove anything.
results = m.getOutput(8, config1);
EXPECT_EQ(0, results.snapshots_size());
EXPECT_EQ(2, results.changes_size());
EXPECT_EQ(2, m.mOutput.changes_size());
results = m.getOutput(9, config2);
EXPECT_EQ(0, results.snapshots_size());
EXPECT_EQ(2, results.changes_size());
// At this point both should be cleared.
EXPECT_EQ(0, m.mOutput.snapshots_size());
EXPECT_EQ(0, m.mOutput.changes_size());
}
TEST(UidMapTest, TestMemoryComputed) {
UidMap m;
ConfigKey config1(1, "config1");
m.OnConfigUpdated(config1);
size_t startBytes = m.mBytesUsed;
vector<int32_t> uids;
vector<int64_t> versions;
vector<String16> apps;
uids.push_back(1000);
apps.push_back(String16(kApp1.c_str()));
versions.push_back(1);
m.updateMap(1, uids, versions, apps);
size_t snapshot_bytes = m.mBytesUsed;
EXPECT_TRUE(snapshot_bytes > startBytes);
m.updateApp(3, String16(kApp1.c_str()), 1000, 40);
EXPECT_TRUE(m.mBytesUsed > snapshot_bytes);
size_t bytesWithSnapshotChange = m.mBytesUsed;
m.getOutput(2, config1);
EXPECT_TRUE(m.mBytesUsed < bytesWithSnapshotChange);
size_t prevBytes = m.mBytesUsed;
m.getOutput(4, config1);
EXPECT_TRUE(m.mBytesUsed < prevBytes);
}
TEST(UidMapTest, TestMemoryGuardrail) {
UidMap m;
string buf;
ConfigKey config1(1, "config1");
m.OnConfigUpdated(config1);
size_t startBytes = m.mBytesUsed;
vector<int32_t> uids;
vector<int64_t> versions;
vector<String16> apps;
for (int i = 0; i < 100; i++) {
uids.push_back(1);
buf = "EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY." + to_string(i);
apps.push_back(String16(buf.c_str()));
versions.push_back(1);
}
m.updateMap(1, uids, versions, apps);
EXPECT_EQ(1, m.mOutput.snapshots_size());
m.updateApp(3, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 2);
EXPECT_EQ(1, m.mOutput.snapshots_size());
EXPECT_EQ(1, m.mOutput.changes_size());
// Now force deletion by limiting the memory to hold one delta change.
m.maxBytesOverride = 80; // Since the app string alone requires >45 characters.
m.updateApp(5, String16("EXTREMELY_LONG_STRING_FOR_APP_TO_WASTE_MEMORY.0"), 1000, 4);
EXPECT_EQ(0, m.mOutput.snapshots_size());
EXPECT_EQ(1, m.mOutput.changes_size());
}
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
} // namespace statsd
} // namespace os
} // namespace android