Update IoOveruseMonitor to use UidStatsCollector.
- IoOveruseMonitor process per-UID I/O stats and detects I/O overuse.
Update this class to use UidStatsCollector instead of directly using
process or I/O stats collectors.
- Remove the logic to resolve package/service name from UID because this
is already done by UidStatsCollector.
- Address some minor nits in IoOveruseMonitor.
Test: atest libwatchdog_test
Bug: 199782126
Change-Id: I74dfc03204ebd72b3404da8b9efe3210eb146338
diff --git a/cpp/watchdog/server/src/IoOveruseMonitor.cpp b/cpp/watchdog/server/src/IoOveruseMonitor.cpp
index b97dd98..23e14ee 100644
--- a/cpp/watchdog/server/src/IoOveruseMonitor.cpp
+++ b/cpp/watchdog/server/src/IoOveruseMonitor.cpp
@@ -170,10 +170,11 @@
}
Result<void> IoOveruseMonitor::onPeriodicCollection(
- time_t time, SystemState systemState, const android::wp<UidIoStats>& uidIoStats,
- [[maybe_unused]] const android::wp<ProcStat>& procStat,
- [[maybe_unused]] const android::wp<ProcPidStat>& procPidStat) {
- if (uidIoStats == nullptr) {
+ time_t time, SystemState systemState,
+ const android::wp<UidStatsCollectorInterface>& uidStatsCollector,
+ [[maybe_unused]] const android::wp<ProcStat>& procStat) {
+ android::sp<UidStatsCollectorInterface> uidStatsCollectorSp = uidStatsCollector.promote();
+ if (uidStatsCollectorSp == nullptr) {
return Error() << "Per-UID I/O stats collector must not be null";
}
@@ -191,36 +192,24 @@
mLastUserPackageIoMonitorTime = time;
const auto [startTime, durationInSeconds] = calculateStartAndDuration(curGmt);
- auto perUidIoUsage = uidIoStats.promote()->deltaStats();
- /*
- * TODO(b/185849350): Maybe move the packageInfo fetching logic into UidIoStats module.
- * This will also help avoid fetching package names in IoPerfCollection module.
- */
- std::vector<uid_t> seenUids;
- for (auto it = perUidIoUsage.begin(); it != perUidIoUsage.end();) {
- /*
- * UidIoStats::deltaStats returns entries with zero write bytes because other metrics
- * in these entries are non-zero.
- */
- if (it->second.ios.sumWriteBytes() == 0) {
- it = perUidIoUsage.erase(it);
- continue;
- }
- seenUids.push_back(it->first);
- ++it;
- }
- if (perUidIoUsage.empty()) {
+ auto uidStats = uidStatsCollectorSp->deltaStats();
+ if (uidStats.empty()) {
return {};
}
- const auto packageInfosByUid = mPackageInfoResolver->getPackageInfosForUids(seenUids);
std::unordered_map<uid_t, IoOveruseStats> overusingNativeStats;
bool isGarageModeActive = systemState == SystemState::GARAGE_MODE;
- for (const auto& [uid, uidIoStats] : perUidIoUsage) {
- const auto& packageInfo = packageInfosByUid.find(uid);
- if (packageInfo == packageInfosByUid.end()) {
+ for (const auto& curUidStats : uidStats) {
+ if (curUidStats.ioStats.sumWriteBytes() == 0 || !curUidStats.hasPackageInfo()) {
+ /* 1. Ignore UIDs with zero written bytes since the last collection because they are
+ * either already accounted for or no writes made since system start.
+ *
+ * 2. UID stats without package info is not useful because the stats isn't attributed to
+ * any package/service.
+ */
continue;
}
- UserPackageIoUsage curUsage(packageInfo->second, uidIoStats.ios, isGarageModeActive);
+ UserPackageIoUsage curUsage(curUidStats.packageInfo, curUidStats.ioStats,
+ isGarageModeActive);
UserPackageIoUsage* dailyIoUsage;
if (auto cachedUsage = mUserPackageDailyIoUsageById.find(curUsage.id());
cachedUsage != mUserPackageDailyIoUsageById.end()) {
@@ -235,7 +224,7 @@
const auto threshold = mIoOveruseConfigs->fetchThreshold(dailyIoUsage->packageInfo);
PackageIoOveruseStats stats;
- stats.uid = uid;
+ stats.uid = curUidStats.packageInfo.packageIdentifier.uid;
stats.shouldNotify = false;
stats.ioOveruseStats.startTime = startTime;
stats.ioOveruseStats.durationInSeconds = durationInSeconds;
@@ -272,7 +261,7 @@
*/
stats.shouldNotify = true;
if (dailyIoUsage->packageInfo.uidType == UidType::NATIVE) {
- overusingNativeStats[uid] = stats.ioOveruseStats;
+ overusingNativeStats[stats.uid] = stats.ioOveruseStats;
}
shouldSyncWatchdogService = true;
} else if (dailyIoUsage->packageInfo.uidType != UidType::NATIVE &&
@@ -320,10 +309,10 @@
Result<void> IoOveruseMonitor::onCustomCollection(
time_t time, SystemState systemState,
[[maybe_unused]] const std::unordered_set<std::string>& filterPackages,
- const android::wp<UidIoStats>& uidIoStats, const android::wp<ProcStat>& procStat,
- const android::wp<ProcPidStat>& procPidStat) {
+ const android::wp<UidStatsCollectorInterface>& uidStatsCollector,
+ const android::wp<ProcStat>& procStat) {
// Nothing special for custom collection.
- return onPeriodicCollection(time, systemState, uidIoStats, procStat, procPidStat);
+ return onPeriodicCollection(time, systemState, uidStatsCollector, procStat);
}
Result<void> IoOveruseMonitor::onPeriodicMonitor(
@@ -380,13 +369,13 @@
return {};
}
-Result<void> IoOveruseMonitor::onDump([[maybe_unused]] int fd) {
+Result<void> IoOveruseMonitor::onDump([[maybe_unused]] int fd) const {
// TODO(b/183436216): Dump the list of killed/disabled packages. Dump the list of packages that
// exceed xx% of their threshold.
return {};
}
-bool IoOveruseMonitor::dumpHelpText(int fd) {
+bool IoOveruseMonitor::dumpHelpText(int fd) const {
return WriteStringToFd(StringPrintf(kHelpText, name().c_str(), kResetResourceOveruseStatsFlag),
fd);
}
@@ -438,7 +427,7 @@
}
Result<void> IoOveruseMonitor::getResourceOveruseConfigurations(
- std::vector<ResourceOveruseConfiguration>* configs) {
+ std::vector<ResourceOveruseConfiguration>* configs) const {
std::shared_lock readLock(mRwMutex);
if (!isInitializedLocked()) {
return Error(Status::EX_ILLEGAL_STATE) << name() << " is not initialized";
@@ -496,7 +485,7 @@
return {};
}
-Result<void> IoOveruseMonitor::getIoOveruseStats(IoOveruseStats* ioOveruseStats) {
+Result<void> IoOveruseMonitor::getIoOveruseStats(IoOveruseStats* ioOveruseStats) const {
if (!isInitialized()) {
return Error(Status::EX_ILLEGAL_STATE) << "I/O overuse monitor is not initialized";
}
@@ -580,14 +569,14 @@
}
IoOveruseMonitor::UserPackageIoUsage::UserPackageIoUsage(const PackageInfo& pkgInfo,
- const IoUsage& ioUsage,
+ const UidIoStats& uidIoStats,
const bool isGarageModeActive) {
packageInfo = pkgInfo;
if (isGarageModeActive) {
- writtenBytes.garageModeBytes = ioUsage.sumWriteBytes();
+ writtenBytes.garageModeBytes = uidIoStats.sumWriteBytes();
} else {
- writtenBytes.foregroundBytes = ioUsage.metrics[WRITE_BYTES][FOREGROUND];
- writtenBytes.backgroundBytes = ioUsage.metrics[WRITE_BYTES][BACKGROUND];
+ writtenBytes.foregroundBytes = uidIoStats.metrics[WRITE_BYTES][FOREGROUND];
+ writtenBytes.backgroundBytes = uidIoStats.metrics[WRITE_BYTES][BACKGROUND];
}
}
diff --git a/cpp/watchdog/server/src/IoOveruseMonitor.h b/cpp/watchdog/server/src/IoOveruseMonitor.h
index 27e179f..df7ff60 100644
--- a/cpp/watchdog/server/src/IoOveruseMonitor.h
+++ b/cpp/watchdog/server/src/IoOveruseMonitor.h
@@ -19,9 +19,8 @@
#include "IoOveruseConfigs.h"
#include "PackageInfoResolver.h"
-#include "ProcPidStat.h"
#include "ProcStat.h"
-#include "UidIoStats.h"
+#include "UidStatsCollector.h"
#include "WatchdogPerfService.h"
#include <android-base/result.h>
@@ -62,17 +61,17 @@
// Used only in tests.
std::tuple<int64_t, int64_t> calculateStartAndDuration(const time_t& currentTime);
-/*
+/**
* IIoOveruseMonitor interface defines the methods that the I/O overuse monitoring module
* should implement.
*/
class IIoOveruseMonitor : virtual public IDataProcessorInterface {
public:
// Returns whether or not the monitor is initialized.
- virtual bool isInitialized() = 0;
+ virtual bool isInitialized() const = 0;
// Dumps the help text.
- virtual bool dumpHelpText(int fd) = 0;
+ virtual bool dumpHelpText(int fd) const = 0;
// Below API is from internal/ICarWatchdog.aidl. Please refer to the AIDL for description.
virtual android::base::Result<void> updateResourceOveruseConfigurations(
@@ -81,7 +80,7 @@
configs) = 0;
virtual android::base::Result<void> getResourceOveruseConfigurations(
std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
- configs) = 0;
+ configs) const = 0;
virtual android::base::Result<void> actionTakenOnIoOveruse(
const std::vector<
android::automotive::watchdog::internal::PackageResourceOveruseAction>&
@@ -94,7 +93,7 @@
virtual android::base::Result<void> removeIoOveruseListener(
const sp<IResourceOveruseListener>& listener) = 0;
- virtual android::base::Result<void> getIoOveruseStats(IoOveruseStats* ioOveruseStats) = 0;
+ virtual android::base::Result<void> getIoOveruseStats(IoOveruseStats* ioOveruseStats) const = 0;
virtual android::base::Result<void> resetIoOveruseStats(
const std::vector<std::string>& packageNames) = 0;
@@ -106,42 +105,42 @@
~IoOveruseMonitor() { terminate(); }
- bool isInitialized() {
+ bool isInitialized() const override {
std::shared_lock readLock(mRwMutex);
return isInitializedLocked();
}
// Below methods implement IDataProcessorInterface.
- std::string name() { return "IoOveruseMonitor"; }
+ std::string name() const override { return "IoOveruseMonitor"; }
friend std::ostream& operator<<(std::ostream& os, const IoOveruseMonitor& monitor);
android::base::Result<void> onBoottimeCollection(
- time_t /*time*/, const android::wp<UidIoStats>& /*uidIoStats*/,
- const android::wp<ProcStat>& /*procStat*/,
- const android::wp<ProcPidStat>& /*procPidStat*/) {
+ [[maybe_unused]] time_t time,
+ [[maybe_unused]] const android::wp<UidStatsCollectorInterface>& uidStatsCollector,
+ [[maybe_unused]] const android::wp<ProcStat>& procStat) override {
// No I/O overuse monitoring during boot-time.
return {};
}
- android::base::Result<void> onPeriodicCollection(time_t time, SystemState systemState,
- const android::wp<UidIoStats>& uidIoStats,
- const android::wp<ProcStat>& procStat,
- const android::wp<ProcPidStat>& procPidStat);
+ android::base::Result<void> onPeriodicCollection(
+ time_t time, SystemState systemState,
+ const android::wp<UidStatsCollectorInterface>& uidStatsCollector,
+ const android::wp<ProcStat>& procStat) override;
android::base::Result<void> onCustomCollection(
time_t time, SystemState systemState,
const std::unordered_set<std::string>& filterPackages,
- const android::wp<UidIoStats>& uidIoStats, const android::wp<ProcStat>& procStat,
- const android::wp<ProcPidStat>& procPidStat);
+ const android::wp<UidStatsCollectorInterface>& uidStatsCollector,
+ const android::wp<ProcStat>& procStat) override;
android::base::Result<void> onPeriodicMonitor(
time_t time, const android::wp<IProcDiskStatsInterface>& procDiskStats,
- const std::function<void()>& alertHandler);
+ const std::function<void()>& alertHandler) override;
- android::base::Result<void> onDump(int fd);
+ android::base::Result<void> onDump(int fd) const override;
- bool dumpHelpText(int fd);
+ bool dumpHelpText(int fd) const override;
- android::base::Result<void> onCustomCollectionDump(int /*fd*/) {
+ android::base::Result<void> onCustomCollectionDump([[maybe_unused]] int fd) override {
// No special processing for custom collection. Thus no custom collection dump.
return {};
}
@@ -149,26 +148,28 @@
// Below methods implement AIDL interfaces.
android::base::Result<void> updateResourceOveruseConfigurations(
const std::vector<
- android::automotive::watchdog::internal::ResourceOveruseConfiguration>&
- configs);
+ android::automotive::watchdog::internal::ResourceOveruseConfiguration>& configs)
+ override;
android::base::Result<void> getResourceOveruseConfigurations(
std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*
- configs);
+ configs) const override;
android::base::Result<void> actionTakenOnIoOveruse(
const std::vector<
- android::automotive::watchdog::internal::PackageResourceOveruseAction>&
- actions);
+ android::automotive::watchdog::internal::PackageResourceOveruseAction>& actions)
+ override;
- android::base::Result<void> addIoOveruseListener(const sp<IResourceOveruseListener>& listener);
+ android::base::Result<void> addIoOveruseListener(
+ const sp<IResourceOveruseListener>& listener) override;
android::base::Result<void> removeIoOveruseListener(
- const sp<IResourceOveruseListener>& listener);
+ const sp<IResourceOveruseListener>& listener) override;
- android::base::Result<void> getIoOveruseStats(IoOveruseStats* ioOveruseStats);
+ android::base::Result<void> getIoOveruseStats(IoOveruseStats* ioOveruseStats) const override;
- android::base::Result<void> resetIoOveruseStats(const std::vector<std::string>& packageName);
+ android::base::Result<void> resetIoOveruseStats(
+ const std::vector<std::string>& packageName) override;
protected:
android::base::Result<void> init();
@@ -183,7 +184,7 @@
struct UserPackageIoUsage {
UserPackageIoUsage(const android::automotive::watchdog::internal::PackageInfo& packageInfo,
- const IoUsage& IoUsage, const bool isGarageModeActive);
+ const UidIoStats& uidIoStats, const bool isGarageModeActive);
android::automotive::watchdog::internal::PackageInfo packageInfo = {};
PerStateBytes writtenBytes = {};
PerStateBytes forgivenWriteBytes = {};
@@ -211,7 +212,7 @@
};
private:
- bool isInitializedLocked() { return mIoOveruseConfigs != nullptr; }
+ bool isInitializedLocked() const { return mIoOveruseConfigs != nullptr; }
void notifyNativePackagesLocked(const std::unordered_map<uid_t, IoOveruseStats>& statsByUid);
@@ -221,7 +222,7 @@
using Processor = std::function<void(ListenersByUidMap&, ListenersByUidMap::const_iterator)>;
bool findListenerAndProcessLocked(const sp<IBinder>& binder, const Processor& processor);
- /*
+ /**
* Writes in-memory configs to disk asynchronously if configs are not written after latest
* update.
*/
@@ -239,7 +240,7 @@
// Summary of configs available for all the components and system-wide overuse alert thresholds.
sp<IIoOveruseConfigs> mIoOveruseConfigs GUARDED_BY(mRwMutex);
- /*
+ /**
* Delta of system-wide written kib across all disks from the last |mPeriodicMonitorBufferSize|
* polls along with the polling duration.
*/
diff --git a/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp b/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
index 7dcc2d4..76f3cbb 100644
--- a/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
+++ b/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
@@ -19,14 +19,17 @@
#include "MockPackageInfoResolver.h"
#include "MockProcDiskStats.h"
#include "MockResourceOveruseListener.h"
-#include "MockUidIoStats.h"
+#include "MockUidStatsCollector.h"
#include "MockWatchdogServiceHelper.h"
+#include "PackageInfoTestUtils.h"
#include <binder/IPCThreadState.h>
#include <binder/Status.h>
#include <utils/RefBase.h>
#include <functional>
+#include <tuple>
+#include <unordered_map>
namespace android {
namespace automotive {
@@ -47,6 +50,7 @@
using ::android::binder::Status;
using ::testing::_;
using ::testing::DoAll;
+using ::testing::Eq;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SaveArg;
@@ -68,20 +72,11 @@
return threshold;
}
-PackageIdentifier constructPackageIdentifier(const char* packageName, const int32_t uid) {
- PackageIdentifier packageIdentifier;
- packageIdentifier.name = packageName;
- packageIdentifier.uid = uid;
- return packageIdentifier;
-}
-
-PackageInfo constructPackageInfo(const char* packageName, const int32_t uid,
- const UidType uidType) {
+struct PackageWrittenBytes {
PackageInfo packageInfo;
- packageInfo.packageIdentifier = constructPackageIdentifier(packageName, uid);
- packageInfo.uidType = uidType;
- return packageInfo;
-}
+ int32_t foregroundBytes;
+ int32_t backgroundBytes;
+};
PerStateBytes constructPerStateBytes(const int64_t fgBytes, const int64_t bgBytes,
const int64_t gmBytes) {
@@ -196,42 +191,25 @@
mMockWatchdogServiceHelper = sp<MockWatchdogServiceHelper>::make();
mMockIoOveruseConfigs = sp<MockIoOveruseConfigs>::make();
mMockPackageInfoResolver = sp<MockPackageInfoResolver>::make();
+ mMockUidStatsCollector = sp<MockUidStatsCollector>::make();
mIoOveruseMonitor = sp<IoOveruseMonitor>::make(mMockWatchdogServiceHelper);
mIoOveruseMonitorPeer = sp<internal::IoOveruseMonitorPeer>::make(mIoOveruseMonitor);
mIoOveruseMonitorPeer->init(mMockIoOveruseConfigs, mMockPackageInfoResolver);
+ setUpPackagesAndConfigurations();
}
virtual void TearDown() {
mMockWatchdogServiceHelper.clear();
mMockIoOveruseConfigs.clear();
mMockPackageInfoResolver.clear();
+ mMockUidStatsCollector.clear();
mIoOveruseMonitor.clear();
mIoOveruseMonitorPeer.clear();
}
void setUpPackagesAndConfigurations() {
- std::unordered_map<uid_t, PackageInfo> packageInfoMapping =
- {{1001000,
- constructPackageInfo(
- /*packageName=*/"system.daemon", /*uid=*/1001000, UidType::NATIVE)},
- {1112345,
- constructPackageInfo(
- /*packageName=*/"com.android.google.package", /*uid=*/1112345,
- UidType::APPLICATION)},
- {1113999,
- constructPackageInfo(
- /*packageName=*/"com.android.google.package", /*uid=*/1113999,
- UidType::APPLICATION)},
- {1212345,
- constructPackageInfo(
- /*packageName=*/"com.android.google.package", /*uid=*/1212345,
- UidType::APPLICATION)},
- {1312345,
- constructPackageInfo(
- /*packageName=*/"com.android.google.package", /*uid=*/1312345,
- UidType::APPLICATION)}};
ON_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_))
- .WillByDefault(Return(packageInfoMapping));
+ .WillByDefault(Return(kPackageInfosByUid));
mMockIoOveruseConfigs->injectPackageConfigs({
{"system.daemon",
{constructPerStateBytes(/*fgBytes=*/80'000, /*bgBytes=*/40'000,
@@ -244,6 +222,24 @@
});
}
+ std::vector<UidStats> constructUidStats(
+ std::unordered_map<uid_t, std::tuple<int32_t, int32_t>> writtenBytesByUid) {
+ std::vector<UidStats> uidStats;
+ for (const auto& [uid, writtenBytes] : writtenBytesByUid) {
+ PackageInfo packageInfo;
+ if (kPackageInfosByUid.find(uid) != kPackageInfosByUid.end()) {
+ packageInfo = kPackageInfosByUid.at(uid);
+ }
+ uidStats.push_back(UidStats{.packageInfo = packageInfo,
+ .ioStats = {/*fgRdBytes=*/989'000,
+ /*bgRdBytes=*/678'000,
+ /*fgWrBytes=*/std::get<0>(writtenBytes),
+ /*bgWrBytes=*/std::get<1>(writtenBytes),
+ /*fgFsync=*/10'000, /*bgFsync=*/50'000}});
+ }
+ return uidStats;
+ }
+
void executeAsUid(uid_t uid, std::function<void()> func) {
sp<ScopedChangeCallingUid> scopedChangeCallingUid = sp<ScopedChangeCallingUid>::make(uid);
ASSERT_NO_FATAL_FAILURE(func());
@@ -252,12 +248,36 @@
sp<MockWatchdogServiceHelper> mMockWatchdogServiceHelper;
sp<MockIoOveruseConfigs> mMockIoOveruseConfigs;
sp<MockPackageInfoResolver> mMockPackageInfoResolver;
+ sp<MockUidStatsCollector> mMockUidStatsCollector;
sp<IoOveruseMonitor> mIoOveruseMonitor;
sp<internal::IoOveruseMonitorPeer> mIoOveruseMonitorPeer;
+
+ static const std::unordered_map<uid_t, PackageInfo> kPackageInfosByUid;
};
+const std::unordered_map<uid_t, PackageInfo> IoOveruseMonitorTest::kPackageInfosByUid =
+ {{1001000,
+ constructPackageInfo(
+ /*packageName=*/"system.daemon",
+ /*uid=*/1001000, UidType::NATIVE)},
+ {1112345,
+ constructPackageInfo(
+ /*packageName=*/"com.android.google.package",
+ /*uid=*/1112345, UidType::APPLICATION)},
+ {1113999,
+ constructPackageInfo(
+ /*packageName=*/"com.android.google.package",
+ /*uid=*/1113999, UidType::APPLICATION)},
+ {1212345,
+ constructPackageInfo(
+ /*packageName=*/"com.android.google.package",
+ /*uid=*/1212345, UidType::APPLICATION)},
+ {1312345,
+ constructPackageInfo(
+ /*packageName=*/"com.android.google.package",
+ /*uid=*/1312345, UidType::APPLICATION)}};
+
TEST_F(IoOveruseMonitorTest, TestOnPeriodicCollection) {
- setUpPackagesAndConfigurations();
sp<MockResourceOveruseListener> mockResourceOveruseListener =
sp<MockResourceOveruseListener>::make();
ASSERT_NO_FATAL_FAILURE(executeAsUid(1001000, [&]() {
@@ -268,11 +288,11 @@
* Package "system.daemon" (UID: 1001000) exceeds warn threshold percentage of 80% but no
* warning is issued as it is a native UID.
*/
- sp<MockUidIoStats> mockUidIoStats = sp<MockUidIoStats>::make();
- mockUidIoStats->expectDeltaStats(
- {{1001000, IoUsage(0, 0, /*fgWrBytes=*/70'000, /*bgWrBytes=*/20'000, 0, 0)},
- {1112345, IoUsage(0, 0, /*fgWrBytes=*/35'000, /*bgWrBytes=*/15'000, 0, 0)},
- {1212345, IoUsage(0, 0, /*fgWrBytes=*/70'000, /*bgWrBytes=*/20'000, 0, 0)}});
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(
+ constructUidStats({{1001000, {/*fgWrBytes=*/70'000, /*bgWrBytes=*/20'000}},
+ {1112345, {/*fgWrBytes=*/35'000, /*bgWrBytes=*/15'000}},
+ {1212345, {/*fgWrBytes=*/70'000, /*bgWrBytes=*/20'000}}})));
std::vector<PackageIoOveruseStats> actualIoOveruseStats;
EXPECT_CALL(*mMockWatchdogServiceHelper, latestIoOveruseStats(_))
@@ -282,7 +302,7 @@
const auto [startTime, durationInSeconds] = calculateStartAndDuration(currentTime);
ASSERT_RESULT_OK(mIoOveruseMonitor->onPeriodicCollection(currentTime, SystemState::NORMAL_MODE,
- mockUidIoStats, nullptr, nullptr));
+ mMockUidStatsCollector, nullptr));
std::vector<PackageIoOveruseStats> expectedIoOveruseStats =
{constructPackageIoOveruseStats(/*uid*=*/1001000, /*shouldNotify=*/false,
@@ -308,10 +328,11 @@
ResourceOveruseStats actualOverusingNativeStats;
// Package "com.android.google.package" for user 11 changed uid from 1112345 to 1113999.
- mockUidIoStats->expectDeltaStats(
- {{1001000, IoUsage(0, 0, /*fgWrBytes=*/30'000, /*bgWrBytes=*/0, 0, 0)},
- {1113999, IoUsage(0, 0, /*fgWrBytes=*/25'000, /*bgWrBytes=*/10'000, 0, 0)},
- {1212345, IoUsage(0, 0, /*fgWrBytes=*/20'000, /*bgWrBytes=*/30'000, 0, 0)}});
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(
+ constructUidStats({{1001000, {/*fgWrBytes=*/30'000, /*bgWrBytes=*/0}},
+ {1113999, {/*fgWrBytes=*/25'000, /*bgWrBytes=*/10'000}},
+ {1212345, {/*fgWrBytes=*/20'000, /*bgWrBytes=*/30'000}}})));
actualIoOveruseStats.clear();
EXPECT_CALL(*mockResourceOveruseListener, onOveruse(_))
.WillOnce(DoAll(SaveArg<0>(&actualOverusingNativeStats), Return(Status::ok())));
@@ -319,14 +340,14 @@
.WillOnce(DoAll(SaveArg<0>(&actualIoOveruseStats), Return(Status::ok())));
ASSERT_RESULT_OK(mIoOveruseMonitor->onPeriodicCollection(currentTime, SystemState::NORMAL_MODE,
- mockUidIoStats, nullptr, nullptr));
+ mMockUidStatsCollector, nullptr));
const auto expectedOverusingNativeStats = constructResourceOveruseStats(
constructIoOveruseStats(/*isKillable=*/false,
/*remaining=*/constructPerStateBytes(0, 20'000, 100'000),
/*written=*/constructPerStateBytes(100'000, 20'000, 0),
/*totalOveruses=*/1, startTime, durationInSeconds));
- EXPECT_THAT(actualOverusingNativeStats, expectedOverusingNativeStats)
+ EXPECT_THAT(actualOverusingNativeStats, Eq(expectedOverusingNativeStats))
<< "Expected: " << expectedOverusingNativeStats.toString()
<< "\nActual: " << actualOverusingNativeStats.toString();
@@ -360,17 +381,18 @@
* Current date changed so the daily I/O usage stats should be reset and the latest I/O overuse
* stats should not aggregate with the previous day's stats.
*/
- mockUidIoStats->expectDeltaStats(
- {{1001000, IoUsage(0, 0, /*fgWrBytes=*/78'000, /*bgWrBytes=*/38'000, 0, 0)},
- {1113999, IoUsage(0, 0, /*fgWrBytes=*/55'000, /*bgWrBytes=*/23'000, 0, 0)},
- {1212345, IoUsage(0, 0, /*fgWrBytes=*/55'000, /*bgWrBytes=*/23'000, 0, 0)}});
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(
+ constructUidStats({{1001000, {/*fgWrBytes=*/78'000, /*bgWrBytes=*/38'000}},
+ {1113999, {/*fgWrBytes=*/55'000, /*bgWrBytes=*/23'000}},
+ {1212345, {/*fgWrBytes=*/55'000, /*bgWrBytes=*/23'000}}})));
actualIoOveruseStats.clear();
EXPECT_CALL(*mMockWatchdogServiceHelper, latestIoOveruseStats(_))
.WillOnce(DoAll(SaveArg<0>(&actualIoOveruseStats), Return(Status::ok())));
currentTime += (24 * 60 * 60); // Change collection time to next day.
ASSERT_RESULT_OK(mIoOveruseMonitor->onPeriodicCollection(currentTime, SystemState::NORMAL_MODE,
- mockUidIoStats, nullptr, nullptr));
+ mMockUidStatsCollector, nullptr));
const auto [nextDayStartTime, nextDayDuration] = calculateStartAndDuration(currentTime);
expectedIoOveruseStats =
@@ -397,7 +419,6 @@
}
TEST_F(IoOveruseMonitorTest, TestOnPeriodicCollectionWithGarageMode) {
- setUpPackagesAndConfigurations();
sp<MockResourceOveruseListener> mockResourceOveruseListener =
sp<MockResourceOveruseListener>::make();
ASSERT_NO_FATAL_FAILURE(executeAsUid(1001000, [&]() {
@@ -408,11 +429,11 @@
* Package "system.daemon" (UID: 1001000) exceeds warn threshold percentage of 80% but no
* warning is issued as it is a native UID.
*/
- sp<MockUidIoStats> mockUidIoStats = sp<MockUidIoStats>::make();
- mockUidIoStats->expectDeltaStats(
- {{1001000, IoUsage(0, 0, /*fgWrBytes=*/70'000, /*bgWrBytes=*/60'000, 0, 0)},
- {1112345, IoUsage(0, 0, /*fgWrBytes=*/35'000, /*bgWrBytes=*/15'000, 0, 0)},
- {1212345, IoUsage(0, 0, /*fgWrBytes=*/90'000, /*bgWrBytes=*/20'000, 0, 0)}});
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(
+ constructUidStats({{1001000, {/*fgWrBytes=*/70'000, /*bgWrBytes=*/60'000}},
+ {1112345, {/*fgWrBytes=*/35'000, /*bgWrBytes=*/15'000}},
+ {1212345, {/*fgWrBytes=*/90'000, /*bgWrBytes=*/20'000}}})));
ResourceOveruseStats actualOverusingNativeStats;
EXPECT_CALL(*mockResourceOveruseListener, onOveruse(_))
@@ -425,14 +446,14 @@
const auto [startTime, durationInSeconds] = calculateStartAndDuration(currentTime);
ASSERT_RESULT_OK(mIoOveruseMonitor->onPeriodicCollection(currentTime, SystemState::GARAGE_MODE,
- mockUidIoStats, nullptr, nullptr));
+ mMockUidStatsCollector, nullptr));
const auto expectedOverusingNativeStats = constructResourceOveruseStats(
constructIoOveruseStats(/*isKillable=*/false,
/*remaining=*/constructPerStateBytes(80'000, 40'000, 0),
/*written=*/constructPerStateBytes(0, 0, 130'000),
/*totalOveruses=*/1, startTime, durationInSeconds));
- EXPECT_THAT(actualOverusingNativeStats, expectedOverusingNativeStats)
+ EXPECT_THAT(actualOverusingNativeStats, Eq(expectedOverusingNativeStats))
<< "Expected: " << expectedOverusingNativeStats.toString()
<< "\nActual: " << actualOverusingNativeStats.toString();
@@ -460,11 +481,10 @@
}
TEST_F(IoOveruseMonitorTest, TestOnPeriodicCollectionWithZeroWriteBytes) {
- sp<MockUidIoStats> mockUidIoStats = sp<MockUidIoStats>::make();
- mockUidIoStats->expectDeltaStats(
- {{1001000, IoUsage(10, 0, /*fgWrBytes=*/0, /*bgWrBytes=*/0, 1, 0)},
- {1112345, IoUsage(0, 20, /*fgWrBytes=*/0, /*bgWrBytes=*/0, 0, 0)},
- {1212345, IoUsage(0, 00, /*fgWrBytes=*/0, /*bgWrBytes=*/0, 0, 1)}});
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(constructUidStats({{1001000, {/*fgWrBytes=*/0, /*bgWrBytes=*/0}},
+ {1112345, {/*fgWrBytes=*/0, /*bgWrBytes=*/0}},
+ {1212345, {/*fgWrBytes=*/0, /*bgWrBytes=*/0}}})));
EXPECT_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_)).Times(0);
EXPECT_CALL(*mMockIoOveruseConfigs, fetchThreshold(_)).Times(0);
@@ -474,22 +494,21 @@
ASSERT_RESULT_OK(
mIoOveruseMonitor->onPeriodicCollection(std::chrono::system_clock::to_time_t(
std::chrono::system_clock::now()),
- SystemState::NORMAL_MODE, mockUidIoStats,
- nullptr, nullptr));
+ SystemState::NORMAL_MODE,
+ mMockUidStatsCollector, nullptr));
}
TEST_F(IoOveruseMonitorTest, TestOnPeriodicCollectionWithSmallWrittenBytes) {
- setUpPackagesAndConfigurations();
- sp<MockUidIoStats> mockUidIoStats = sp<MockUidIoStats>::make();
/*
* UID 1212345 current written bytes < |KTestMinSyncWrittenBytes| so the UID's stats are not
* synced.
*/
- mockUidIoStats->expectDeltaStats(
- {{1001000, IoUsage(10, 0, /*fgWrBytes=*/59'200, /*bgWrBytes=*/0, 1, 0)},
- {1112345, IoUsage(0, 20, /*fgWrBytes=*/0, /*bgWrBytes=*/25'200, 0, 0)},
- {1212345, IoUsage(0, 00, /*fgWrBytes=*/300, /*bgWrBytes=*/600, 0, 1)},
- {1312345, IoUsage(0, 00, /*fgWrBytes=*/51'200, /*bgWrBytes=*/0, 0, 1)}});
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(
+ constructUidStats({{1001000, {/*fgWrBytes=*/59'200, /*bgWrBytes=*/0}},
+ {1112345, {/*fgWrBytes=*/0, /*bgWrBytes=*/25'200}},
+ {1212345, {/*fgWrBytes=*/300, /*bgWrBytes=*/600}},
+ {1312345, {/*fgWrBytes=*/51'200, /*bgWrBytes=*/0}}})));
std::vector<PackageIoOveruseStats> actualIoOveruseStats;
EXPECT_CALL(*mMockWatchdogServiceHelper, latestIoOveruseStats(_))
@@ -499,7 +518,7 @@
const auto [startTime, durationInSeconds] = calculateStartAndDuration(currentTime);
ASSERT_RESULT_OK(mIoOveruseMonitor->onPeriodicCollection(currentTime, SystemState::NORMAL_MODE,
- mockUidIoStats, nullptr, nullptr));
+ mMockUidStatsCollector, nullptr));
std::vector<PackageIoOveruseStats> expectedIoOveruseStats =
{constructPackageIoOveruseStats(/*uid*=*/1001000, /*shouldNotify=*/false,
@@ -537,19 +556,15 @@
* UID 1312345 current written bytes is < |kTestMinSyncWrittenBytes| but exceeds warn threshold
* and killable so the UID's stat are synced.
*/
- mockUidIoStats->expectDeltaStats(
- {{1001000,
- IoUsage(10, 0, /*fgWrBytes=*/KTestMinSyncWrittenBytes - 100, /*bgWrBytes=*/0, 1, 0)},
- {1112345,
- IoUsage(0, 20, /*fgWrBytes=*/0, /*bgWrBytes=*/KTestMinSyncWrittenBytes - 100, 0, 0)},
- {1212345,
- IoUsage(0, 00, /*fgWrBytes=*/KTestMinSyncWrittenBytes - 300, /*bgWrBytes=*/0, 0, 1)},
- {1312345,
- IoUsage(0, 00, /*fgWrBytes=*/KTestMinSyncWrittenBytes - 100, /*bgWrBytes=*/0, 0,
- 1)}});
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(constructUidStats(
+ {{1001000, {/*fgWrBytes=*/KTestMinSyncWrittenBytes - 100, /*bgWrBytes=*/0}},
+ {1112345, {/*fgWrBytes=*/0, /*bgWrBytes=*/KTestMinSyncWrittenBytes - 100}},
+ {1212345, {/*fgWrBytes=*/KTestMinSyncWrittenBytes - 300, /*bgWrBytes=*/0}},
+ {1312345, {/*fgWrBytes=*/KTestMinSyncWrittenBytes - 100, /*bgWrBytes=*/0}}})));
ASSERT_RESULT_OK(mIoOveruseMonitor->onPeriodicCollection(currentTime, SystemState::NORMAL_MODE,
- mockUidIoStats, nullptr, nullptr));
+ mMockUidStatsCollector, nullptr));
expectedIoOveruseStats =
{constructPackageIoOveruseStats(/*uid*=*/1112345, /*shouldNotify=*/true,
@@ -573,14 +588,11 @@
}
TEST_F(IoOveruseMonitorTest, TestOnPeriodicCollectionWithNoPackageInfo) {
- sp<MockUidIoStats> mockUidIoStats = sp<MockUidIoStats>::make();
- mockUidIoStats->expectDeltaStats(
- {{1001000, IoUsage(0, 0, /*fgWrBytes=*/70'000, /*bgWrBytes=*/20'000, 0, 0)},
- {1112345, IoUsage(0, 0, /*fgWrBytes=*/35'000, /*bgWrBytes=*/15'000, 0, 0)},
- {1212345, IoUsage(0, 0, /*fgWrBytes=*/70'000, /*bgWrBytes=*/20'000, 0, 0)}});
-
- ON_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_))
- .WillByDefault(Return(std::unordered_map<uid_t, PackageInfo>{}));
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(
+ constructUidStats({{2301000, {/*fgWrBytes=*/70'000, /*bgWrBytes=*/20'000}},
+ {2412345, {/*fgWrBytes=*/35'000, /*bgWrBytes=*/15'000}},
+ {2512345, {/*fgWrBytes=*/70'000, /*bgWrBytes=*/20'000}}})));
EXPECT_CALL(*mMockIoOveruseConfigs, fetchThreshold(_)).Times(0);
EXPECT_CALL(*mMockIoOveruseConfigs, isSafeToKill(_)).Times(0);
@@ -589,8 +601,8 @@
ASSERT_RESULT_OK(
mIoOveruseMonitor->onPeriodicCollection(std::chrono::system_clock::to_time_t(
std::chrono::system_clock::now()),
- SystemState::NORMAL_MODE, mockUidIoStats,
- nullptr, nullptr));
+ SystemState::NORMAL_MODE,
+ mMockUidStatsCollector, nullptr));
}
TEST_F(IoOveruseMonitorTest, TestOnPeriodicMonitor) {
@@ -712,16 +724,15 @@
}
TEST_F(IoOveruseMonitorTest, TestGetIoOveruseStats) {
- setUpPackagesAndConfigurations();
- sp<MockUidIoStats> mockUidIoStats = sp<MockUidIoStats>::make();
- mockUidIoStats->expectDeltaStats(
- {{1001000, IoUsage(0, 0, /*fgWrBytes=*/90'000, /*bgWrBytes=*/20'000, 0, 0)}});
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(
+ constructUidStats({{1001000, {/*fgWrBytes=*/90'000, /*bgWrBytes=*/20'000}}})));
time_t currentTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
const auto [startTime, durationInSeconds] = calculateStartAndDuration(currentTime);
ASSERT_RESULT_OK(mIoOveruseMonitor->onPeriodicCollection(currentTime, SystemState::NORMAL_MODE,
- mockUidIoStats, nullptr, nullptr));
+ mMockUidStatsCollector, nullptr));
const auto expected =
constructIoOveruseStats(/*isKillable=*/false,
@@ -739,16 +750,15 @@
}
TEST_F(IoOveruseMonitorTest, TestResetIoOveruseStats) {
- setUpPackagesAndConfigurations();
- sp<MockUidIoStats> mockUidIoStats = sp<MockUidIoStats>::make();
- mockUidIoStats->expectDeltaStats(
- {{1001000, IoUsage(0, 0, /*fgWrBytes=*/90'000, /*bgWrBytes=*/20'000, 0, 0)}});
+ EXPECT_CALL(*mMockUidStatsCollector, deltaStats())
+ .WillOnce(Return(
+ constructUidStats({{1001000, {/*fgWrBytes=*/90'000, /*bgWrBytes=*/20'000}}})));
ASSERT_RESULT_OK(
mIoOveruseMonitor->onPeriodicCollection(std::chrono::system_clock::to_time_t(
std::chrono::system_clock::now()),
- SystemState::NORMAL_MODE, mockUidIoStats,
- nullptr, nullptr));
+ SystemState::NORMAL_MODE,
+ mMockUidStatsCollector, nullptr));
IoOveruseStats actual;
ASSERT_NO_FATAL_FAILURE(executeAsUid(1001000, [&]() {
diff --git a/cpp/watchdog/server/tests/MockIoOveruseMonitor.h b/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
index 79ba932..a9d677e 100644
--- a/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
+++ b/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
@@ -35,8 +35,8 @@
ON_CALL(*this, name()).WillByDefault(::testing::Return("MockIoOveruseMonitor"));
}
~MockIoOveruseMonitor() {}
- MOCK_METHOD(bool, isInitialized, (), (override));
- MOCK_METHOD(bool, dumpHelpText, (int), (override));
+ MOCK_METHOD(bool, isInitialized, (), (const, override));
+ MOCK_METHOD(bool, dumpHelpText, (int), (const, override));
MOCK_METHOD(android::base::Result<void>, updateResourceOveruseConfigurations,
(const std::vector<
android::automotive::watchdog::internal::ResourceOveruseConfiguration>&),
@@ -44,7 +44,7 @@
MOCK_METHOD(
android::base::Result<void>, getResourceOveruseConfigurations,
(std::vector<android::automotive::watchdog::internal::ResourceOveruseConfiguration>*),
- (override));
+ (const, override));
MOCK_METHOD(android::base::Result<void>, actionTakenOnIoOveruse,
(const std::vector<
android::automotive::watchdog::internal::PackageResourceOveruseAction>&
@@ -54,7 +54,8 @@
(const sp<IResourceOveruseListener>&), (override));
MOCK_METHOD(android::base::Result<void>, removeIoOveruseListener,
(const sp<IResourceOveruseListener>&), (override));
- MOCK_METHOD(android::base::Result<void>, getIoOveruseStats, (IoOveruseStats*), (override));
+ MOCK_METHOD(android::base::Result<void>, getIoOveruseStats, (IoOveruseStats*),
+ (const, override));
MOCK_METHOD(android::base::Result<void>, resetIoOveruseStats, (const std::vector<std::string>&),
(override));
};