1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "IoOveruseConfigs.h"
18 #include "OveruseConfigurationTestUtils.h"
19 #include "OveruseConfigurationXmlHelper.h"
20 #include "PackageInfoTestUtils.h"
21 
22 #include <android-base/strings.h>
23 #include <gmock/gmock.h>
24 
25 #include <inttypes.h>
26 
27 #include <unordered_map>
28 
29 namespace android {
30 namespace automotive {
31 namespace watchdog {
32 
33 using ::android::sp;
34 using ::android::automotive::watchdog::internal::ApplicationCategoryType;
35 using ::android::automotive::watchdog::internal::ComponentType;
36 using ::android::automotive::watchdog::internal::IoOveruseAlertThreshold;
37 using ::android::automotive::watchdog::internal::IoOveruseConfiguration;
38 using ::android::automotive::watchdog::internal::PackageInfo;
39 using ::android::automotive::watchdog::internal::PackageMetadata;
40 using ::android::automotive::watchdog::internal::ResourceOveruseConfiguration;
41 using ::android::automotive::watchdog::internal::ResourceSpecificConfiguration;
42 using ::android::automotive::watchdog::internal::UidType;
43 using ::android::base::Error;
44 using ::android::base::StringAppendF;
45 using ::android::base::StringPrintf;
46 using ::testing::Eq;
47 using ::testing::IsEmpty;
48 using ::testing::Matcher;
49 using ::testing::UnorderedElementsAre;
50 using ::testing::UnorderedElementsAreArray;
51 using ::testing::UnorderedPointwise;
52 
53 namespace {
54 
55 const PerStateBytes SYSTEM_COMPONENT_LEVEL_THRESHOLDS = toPerStateBytes(200, 100, 500);
56 const PerStateBytes SYSTEM_PACKAGE_A_THRESHOLDS = toPerStateBytes(600, 400, 1000);
57 const PerStateBytes SYSTEM_PACKAGE_B_THRESHOLDS = toPerStateBytes(1200, 800, 1500);
58 const PerStateBytes VENDOR_COMPONENT_LEVEL_THRESHOLDS = toPerStateBytes(100, 50, 900);
59 const PerStateBytes VENDOR_PACKAGE_A_THRESHOLDS = toPerStateBytes(800, 300, 500);
60 const PerStateBytes VENDOR_PKG_B_THRESHOLDS = toPerStateBytes(1600, 600, 1000);
61 const PerStateBytes MAPS_THRESHOLDS = toPerStateBytes(700, 900, 1300);
62 const PerStateBytes MEDIA_THRESHOLDS = toPerStateBytes(1800, 1900, 2100);
63 const PerStateBytes THIRD_PARTY_COMPONENT_LEVEL_THRESHOLDS = toPerStateBytes(300, 150, 1900);
64 const std::vector<IoOveruseAlertThreshold> ALERT_THRESHOLDS = {toIoOveruseAlertThreshold(5, 200),
65                                                                toIoOveruseAlertThreshold(30,
66                                                                                          40000)};
67 
toPackageToAppCategoryMappings(const std::vector<PackageMetadata> & metas)68 std::unordered_map<std::string, ApplicationCategoryType> toPackageToAppCategoryMappings(
69         const std::vector<PackageMetadata>& metas) {
70     std::unordered_map<std::string, ApplicationCategoryType> mappings;
71     for (const auto& meta : metas) {
72         mappings[meta.packageName] = meta.appCategoryType;
73     }
74     return mappings;
75 }
76 
toString(std::vector<ResourceOveruseConfiguration> configs)77 std::string toString(std::vector<ResourceOveruseConfiguration> configs) {
78     std::string buffer;
79     StringAppendF(&buffer, "[");
80     for (const auto& config : configs) {
81         if (buffer.size() > 1) {
82             StringAppendF(&buffer, ",\n");
83         }
84         StringAppendF(&buffer, "%s", config.toString().c_str());
85     }
86     StringAppendF(&buffer, "]\n");
87     return buffer;
88 }
89 
ResourceOveruseConfigurationsMatchers(const std::vector<ResourceOveruseConfiguration> & configs)90 std::vector<Matcher<const ResourceOveruseConfiguration&>> ResourceOveruseConfigurationsMatchers(
91         const std::vector<ResourceOveruseConfiguration>& configs) {
92     std::vector<Matcher<const ResourceOveruseConfiguration&>> matchers;
93     for (const auto config : configs) {
94         matchers.push_back(ResourceOveruseConfigurationMatcher(config));
95     }
96     return matchers;
97 }
98 
toString(const std::unordered_map<std::string,ResourceOveruseConfiguration> & configsByFilePath)99 std::string toString(
100         const std::unordered_map<std::string, ResourceOveruseConfiguration>& configsByFilePath) {
101     std::string buffer;
102     StringAppendF(&buffer, "[");
103     for (const auto& [filepath, config] : configsByFilePath) {
104         if (buffer.size() > 1) {
105             StringAppendF(&buffer, ",\n");
106         }
107         StringAppendF(&buffer, "{Filepath{\"%s\"}, %s}", filepath.c_str(),
108                       config.toString().c_str());
109     }
110     StringAppendF(&buffer, "]\n");
111     return buffer;
112 }
113 
114 MATCHER(ConfigsByFilepathsEq, "") {
115     const auto actual = std::get<0>(arg);
116     const auto expected = std::get<1>(arg);
117     return actual.first == expected.first &&
118             ExplainMatchResult(ResourceOveruseConfigurationMatcher(expected.second), actual.second,
119                                result_listener);
120 }
121 
sampleBuildSystemConfig()122 ResourceOveruseConfiguration sampleBuildSystemConfig() {
123     auto systemIoConfig = constructIoOveruseConfig(
124             /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM,
125                                                             toPerStateBytes(1200, 1100, 1500)),
126             /*packageSpecific=*/
127             {toPerStateIoOveruseThreshold("systemPackageA", SYSTEM_PACKAGE_A_THRESHOLDS)},
128             /*categorySpecific=*/{},
129             /*systemWide=*/ALERT_THRESHOLDS);
130     return constructResourceOveruseConfig(ComponentType::SYSTEM,
131                                           /*safeToKill=*/{"systemPackageA"},
132                                           /*vendorPrefixes=*/{},
133                                           /*packageMetadata*/
134                                           {toPackageMetadata("systemPackageA",
135                                                              ApplicationCategoryType::MEDIA)},
136                                           systemIoConfig);
137 }
138 
sampleBuildVendorConfig()139 ResourceOveruseConfiguration sampleBuildVendorConfig() {
140     auto vendorIoConfig = constructIoOveruseConfig(
141             /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR,
142                                                             toPerStateBytes(1100, 150, 1900)),
143             /*packageSpecific=*/
144             {toPerStateIoOveruseThreshold("vendorPackageA", VENDOR_PACKAGE_A_THRESHOLDS)},
145             /*categorySpecific=*/
146             {toPerStateIoOveruseThreshold("MEDIA", MEDIA_THRESHOLDS)},
147             /*systemWide=*/{});
148     return constructResourceOveruseConfig(ComponentType::VENDOR,
149                                           /*safeToKill=*/{},
150                                           /*vendorPrefixes=*/{"vendorPackage"},
151                                           /*packageMetadata=*/
152                                           {toPackageMetadata("vendorPackageA",
153                                                              ApplicationCategoryType::MEDIA)},
154                                           vendorIoConfig);
155 }
156 
sampleBuildThirdPartyConfig()157 ResourceOveruseConfiguration sampleBuildThirdPartyConfig() {
158     auto thirdPartyIoConfig = constructIoOveruseConfig(
159             /*componentLevel=*/
160             toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY,
161                                          toPerStateBytes(1300, 1150, 2900)),
162             /*packageSpecific=*/{}, /*categorySpecific=*/{}, /*systemWide=*/{});
163     return constructResourceOveruseConfig(ComponentType::THIRD_PARTY, /*safeToKill=*/{},
164                                           /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
165                                           thirdPartyIoConfig);
166 }
167 
sampleUpdateSystemConfig()168 ResourceOveruseConfiguration sampleUpdateSystemConfig() {
169     auto systemIoConfig = constructIoOveruseConfig(
170             /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM,
171                                                             SYSTEM_COMPONENT_LEVEL_THRESHOLDS),
172             /*packageSpecific=*/
173             {toPerStateIoOveruseThreshold("systemPackageA", SYSTEM_PACKAGE_A_THRESHOLDS),
174              toPerStateIoOveruseThreshold("systemPackageB", SYSTEM_PACKAGE_B_THRESHOLDS)},
175             /*categorySpecific=*/{},
176             /*systemWide=*/ALERT_THRESHOLDS);
177     return constructResourceOveruseConfig(ComponentType::SYSTEM, /*safeToKill=*/{"systemPackageA"},
178                                           /*vendorPrefixes=*/{},
179                                           /*packageMetadata=*/
180                                           {toPackageMetadata("systemPackageA",
181                                                              ApplicationCategoryType::MEDIA),
182                                            toPackageMetadata("vendorPkgB",
183                                                              ApplicationCategoryType::MAPS)},
184                                           systemIoConfig);
185 }
186 
sampleUpdateVendorConfig()187 ResourceOveruseConfiguration sampleUpdateVendorConfig() {
188     auto vendorIoConfig = constructIoOveruseConfig(
189             /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR,
190                                                             VENDOR_COMPONENT_LEVEL_THRESHOLDS),
191             /*packageSpecific=*/
192             {toPerStateIoOveruseThreshold("vendorPackageA", VENDOR_PACKAGE_A_THRESHOLDS),
193              toPerStateIoOveruseThreshold("vendorPkgB", VENDOR_PKG_B_THRESHOLDS)},
194             /*categorySpecific=*/
195             {toPerStateIoOveruseThreshold("MAPS", MAPS_THRESHOLDS),
196              toPerStateIoOveruseThreshold("MEDIA", MEDIA_THRESHOLDS)},
197             /*systemWide=*/{});
198     return constructResourceOveruseConfig(ComponentType::VENDOR,
199                                           /*safeToKill=*/{"vendorPackageA"},
200                                           /*vendorPrefixes=*/{"vendorPackage"},
201                                           /*packageMetadata=*/
202                                           {toPackageMetadata("systemPackageA",
203                                                              ApplicationCategoryType::MEDIA),
204                                            toPackageMetadata("vendorPkgB",
205                                                              ApplicationCategoryType::MAPS)},
206                                           vendorIoConfig);
207 }
208 
sampleUpdateThirdPartyConfig()209 ResourceOveruseConfiguration sampleUpdateThirdPartyConfig() {
210     auto thirdPartyIoConfig = constructIoOveruseConfig(
211             /*componentLevel=*/
212             toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY,
213                                          THIRD_PARTY_COMPONENT_LEVEL_THRESHOLDS),
214             /*packageSpecific=*/{}, /*categorySpecific=*/{}, /*systemWide=*/{});
215     return constructResourceOveruseConfig(ComponentType::THIRD_PARTY, /*safeToKill=*/{},
216                                           /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
217                                           thirdPartyIoConfig);
218 }
219 
sampleIoOveruseConfigs()220 sp<IoOveruseConfigs> sampleIoOveruseConfigs() {
221     sp<IoOveruseConfigs> ioOveruseConfigs = new IoOveruseConfigs();
222     EXPECT_RESULT_OK(
223             ioOveruseConfigs->update({sampleUpdateSystemConfig(), sampleUpdateVendorConfig(),
224                                       sampleUpdateThirdPartyConfig()}));
225     return ioOveruseConfigs;
226 }
227 
228 }  // namespace
229 
230 namespace internal {
231 
232 class IoOveruseConfigsPeer : public android::RefBase {
233 public:
IoOveruseConfigsPeer()234     IoOveruseConfigsPeer() {
235         IoOveruseConfigs::sParseXmlFile =
236                 [&](const char* filepath) -> android::base::Result<ResourceOveruseConfiguration> {
237             if (const auto it = configsByFilepaths.find(filepath); it != configsByFilepaths.end()) {
238                 return it->second;
239             }
240             return Error() << "No configs available for the given filepath '" << filepath << "'";
241         };
242         IoOveruseConfigs::sWriteXmlFile =
243                 [&](const android::automotive::watchdog::internal::ResourceOveruseConfiguration&
244                             config,
245                     const char* filepath) -> android::base::Result<void> {
246             configsByFilepaths[filepath] = config;
247             return {};
248         };
249     }
~IoOveruseConfigsPeer()250     ~IoOveruseConfigsPeer() {
251         IoOveruseConfigs::sParseXmlFile = &OveruseConfigurationXmlHelper::parseXmlFile;
252         IoOveruseConfigs::sWriteXmlFile = &OveruseConfigurationXmlHelper::writeXmlFile;
253     }
injectErrorOnWriteXmlFile()254     void injectErrorOnWriteXmlFile() {
255         IoOveruseConfigs::sWriteXmlFile =
256                 [&]([[maybe_unused]] const android::automotive::watchdog::internal::
257                             ResourceOveruseConfiguration& config,
258                     [[maybe_unused]] const char* filepath) -> android::base::Result<void> {
259             return Error() << "Failed to write XML files";
260         };
261     }
262     std::unordered_map<std::string, ResourceOveruseConfiguration> configsByFilepaths;
263 };
264 
265 }  // namespace internal
266 
267 class IoOveruseConfigsTest : public ::testing::Test {
268 public:
SetUp()269     virtual void SetUp() { mPeer = sp<internal::IoOveruseConfigsPeer>::make(); }
TearDown()270     virtual void TearDown() { mPeer.clear(); }
271 
272     sp<internal::IoOveruseConfigsPeer> mPeer;
273 };
274 
TEST_F(IoOveruseConfigsTest,TestConstructWithBuildConfigs)275 TEST_F(IoOveruseConfigsTest, TestConstructWithBuildConfigs) {
276     auto buildSystemResourceConfig = sampleBuildSystemConfig();
277     auto buildVendorResourceConfig = sampleBuildVendorConfig();
278     const auto buildThirdPartyResourceConfig = sampleBuildThirdPartyConfig();
279 
280     mPeer->configsByFilepaths = {{kBuildSystemConfigXmlPath, buildSystemResourceConfig},
281                                  {kBuildVendorConfigXmlPath, buildVendorResourceConfig},
282                                  {kBuildThirdPartyConfigXmlPath, buildThirdPartyResourceConfig}};
283 
284     IoOveruseConfigs ioOveruseConfigs;
285 
286     /* Package to app category mapping should be merged from both vendor and system configs. */
287     buildVendorResourceConfig.packageMetadata
288             .insert(buildVendorResourceConfig.packageMetadata.end(),
289                     buildSystemResourceConfig.packageMetadata.begin(),
290                     buildSystemResourceConfig.packageMetadata.end());
291     buildSystemResourceConfig.packageMetadata = buildVendorResourceConfig.packageMetadata;
292     std::vector<ResourceOveruseConfiguration> expected = {buildSystemResourceConfig,
293                                                           buildVendorResourceConfig,
294                                                           buildThirdPartyResourceConfig};
295 
296     std::vector<ResourceOveruseConfiguration> actual;
297     ioOveruseConfigs.get(&actual);
298 
299     EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
300             << "Expected: " << toString(expected) << "Actual:" << toString(actual);
301 }
302 
TEST_F(IoOveruseConfigsTest,TestConstructWithLatestConfigs)303 TEST_F(IoOveruseConfigsTest, TestConstructWithLatestConfigs) {
304     const auto latestSystemResourceConfig = sampleUpdateSystemConfig();
305     auto latestVendorResourceConfig = sampleUpdateVendorConfig();
306     const auto latestThirdPartyResourceConfig = sampleUpdateThirdPartyConfig();
307 
308     mPeer->configsByFilepaths = {{kBuildSystemConfigXmlPath, sampleBuildSystemConfig()},
309                                  {kBuildVendorConfigXmlPath, sampleBuildVendorConfig()},
310                                  {kBuildThirdPartyConfigXmlPath, sampleBuildThirdPartyConfig()},
311                                  {kLatestSystemConfigXmlPath, latestSystemResourceConfig},
312                                  {kLatestVendorConfigXmlPath, latestVendorResourceConfig},
313                                  {kLatestThirdPartyConfigXmlPath, latestThirdPartyResourceConfig}};
314 
315     IoOveruseConfigs ioOveruseConfigs;
316 
317     latestVendorResourceConfig.vendorPackagePrefixes.push_back("vendorPkgB");
318     std::vector<ResourceOveruseConfiguration> expected = {latestSystemResourceConfig,
319                                                           latestVendorResourceConfig,
320                                                           latestThirdPartyResourceConfig};
321 
322     std::vector<ResourceOveruseConfiguration> actual;
323     ioOveruseConfigs.get(&actual);
324 
325     EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
326             << "Expected: " << toString(expected) << "Actual:" << toString(actual);
327 }
328 
TEST_F(IoOveruseConfigsTest,TestConstructWithOnlyBuildSystemConfig)329 TEST_F(IoOveruseConfigsTest, TestConstructWithOnlyBuildSystemConfig) {
330     const auto buildSystemResourceConfig = sampleBuildSystemConfig();
331 
332     mPeer->configsByFilepaths = {{kBuildSystemConfigXmlPath, buildSystemResourceConfig}};
333 
334     IoOveruseConfigs ioOveruseConfigs;
335 
336     /*
337      * Vendor/Third-party component-level thresholds should be derived from system
338      * component-level thresholds when build configs for Vendor/Third-party components are not
339      * available.
340      */
341     const auto& defaultComponentLevelThresholds =
342             buildSystemResourceConfig.resourceSpecificConfigurations[0]
343                     .get<ResourceSpecificConfiguration::ioOveruseConfiguration>()
344                     .componentLevelThresholds.perStateWriteBytes;
345     const auto vendorResourceConfig = constructResourceOveruseConfig(
346             ComponentType::VENDOR, /*safeToKill=*/{}, /*vendorPrefixes=*/{},
347             /*packageMetadata=*/buildSystemResourceConfig.packageMetadata,
348             constructIoOveruseConfig(
349                     /*componentLevel=*/
350                     toPerStateIoOveruseThreshold(ComponentType::VENDOR,
351                                                  defaultComponentLevelThresholds),
352                     /*packageSpecific=*/{}, /*categorySpecific=*/{}, /*systemWide=*/{}));
353     const auto thirdPartyResourceConfig =
354             constructResourceOveruseConfig(ComponentType::THIRD_PARTY, /*safeToKill=*/{},
355                                            /*vendorPrefixes=*/{},
356                                            /*packageMetadata=*/{},
357                                            constructIoOveruseConfig(
358                                                    /*componentLevel=*/toPerStateIoOveruseThreshold(
359                                                            ComponentType::THIRD_PARTY,
360                                                            defaultComponentLevelThresholds),
361                                                    /*packageSpecific=*/{}, /*categorySpecific=*/{},
362                                                    /*systemWide=*/{}));
363 
364     std::vector<ResourceOveruseConfiguration> expected = {buildSystemResourceConfig,
365                                                           vendorResourceConfig,
366                                                           thirdPartyResourceConfig};
367 
368     std::vector<ResourceOveruseConfiguration> actual;
369     ioOveruseConfigs.get(&actual);
370 
371     EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
372             << "Expected: " << toString(expected) << "Actual:" << toString(actual);
373 }
374 
TEST_F(IoOveruseConfigsTest,TestConstructWithBuildSystemConfigLatestVendorConfig)375 TEST_F(IoOveruseConfigsTest, TestConstructWithBuildSystemConfigLatestVendorConfig) {
376     auto buildSystemResourceConfig = sampleBuildSystemConfig();
377     auto latestVendorResourceConfig = sampleUpdateVendorConfig();
378     const auto buildThirdPartyResourceConfig = sampleBuildThirdPartyConfig();
379 
380     mPeer->configsByFilepaths = {{kBuildSystemConfigXmlPath, buildSystemResourceConfig},
381                                  {kBuildVendorConfigXmlPath, sampleBuildVendorConfig()},
382                                  {kBuildThirdPartyConfigXmlPath, buildThirdPartyResourceConfig},
383                                  {kLatestVendorConfigXmlPath, latestVendorResourceConfig}};
384 
385     IoOveruseConfigs ioOveruseConfigs;
386 
387     // Package to app category mapping from latest vendor configuration should be given priority.
388     buildSystemResourceConfig.packageMetadata = latestVendorResourceConfig.packageMetadata;
389     latestVendorResourceConfig.vendorPackagePrefixes.push_back("vendorPkgB");
390     std::vector<ResourceOveruseConfiguration> expected = {buildSystemResourceConfig,
391                                                           latestVendorResourceConfig,
392                                                           buildThirdPartyResourceConfig};
393 
394     std::vector<ResourceOveruseConfiguration> actual;
395     ioOveruseConfigs.get(&actual);
396 
397     EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
398             << "Expected: " << toString(expected) << "Actual:" << toString(actual);
399 }
400 
TEST_F(IoOveruseConfigsTest,TestConstructWithLatestSystemConfigBuildVendorConfig)401 TEST_F(IoOveruseConfigsTest, TestConstructWithLatestSystemConfigBuildVendorConfig) {
402     const auto latestSystemResourceConfig = sampleUpdateSystemConfig();
403     auto buildVendorResourceConfig = sampleBuildVendorConfig();
404     const auto buildThirdPartyResourceConfig = sampleBuildThirdPartyConfig();
405 
406     mPeer->configsByFilepaths = {{kBuildSystemConfigXmlPath, sampleBuildSystemConfig()},
407                                  {kBuildVendorConfigXmlPath, sampleBuildVendorConfig()},
408                                  {kBuildThirdPartyConfigXmlPath, buildThirdPartyResourceConfig},
409                                  {kLatestSystemConfigXmlPath, latestSystemResourceConfig}};
410 
411     IoOveruseConfigs ioOveruseConfigs;
412 
413     // Package to app category mapping from latest system configuration should be given priority.
414     buildVendorResourceConfig.packageMetadata = latestSystemResourceConfig.packageMetadata;
415     std::vector<ResourceOveruseConfiguration> expected = {latestSystemResourceConfig,
416                                                           buildVendorResourceConfig,
417                                                           buildThirdPartyResourceConfig};
418 
419     std::vector<ResourceOveruseConfiguration> actual;
420     ioOveruseConfigs.get(&actual);
421 
422     EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
423             << "Expected: " << toString(expected) << "Actual:" << toString(actual);
424 }
425 
TEST_F(IoOveruseConfigsTest,TestUpdateWithValidConfigs)426 TEST_F(IoOveruseConfigsTest, TestUpdateWithValidConfigs) {
427     auto systemResourceConfig = sampleUpdateSystemConfig();
428     auto vendorResourceConfig = sampleUpdateVendorConfig();
429     auto thirdPartyResourceConfig = sampleUpdateThirdPartyConfig();
430 
431     IoOveruseConfigs ioOveruseConfigs;
432     ASSERT_RESULT_OK(ioOveruseConfigs.update(
433             {systemResourceConfig, vendorResourceConfig, thirdPartyResourceConfig}));
434 
435     vendorResourceConfig.vendorPackagePrefixes.push_back("vendorPkgB");
436     std::vector<ResourceOveruseConfiguration> expected = {systemResourceConfig,
437                                                           vendorResourceConfig,
438                                                           thirdPartyResourceConfig};
439 
440     std::vector<ResourceOveruseConfiguration> actual;
441     ioOveruseConfigs.get(&actual);
442 
443     EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
444             << "Expected: " << toString(expected) << "Actual:" << toString(actual);
445 
446     // Check whether previous configs are overwritten.
447     auto systemIoConfig = constructIoOveruseConfig(
448             /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 300, 400, 600),
449             /*packageSpecific=*/
450             {toPerStateIoOveruseThreshold("systemPackageC", 700, 100, 200),
451              toPerStateIoOveruseThreshold("systemPackageC", 300, 200, 300)},
452             /*categorySpecific=*/{},
453             /*systemWide=*/
454             {toIoOveruseAlertThreshold(6, 4), toIoOveruseAlertThreshold(6, 10)});
455     systemResourceConfig =
456             constructResourceOveruseConfig(ComponentType::SYSTEM, /*safeToKill=*/{"systemPackageC"},
457                                            /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
458                                            systemIoConfig);
459 
460     /*
461      * Not adding any safe to kill packages list or package specific thresholds should clear
462      * previous entries after update.
463      */
464     auto vendorIoConfig = constructIoOveruseConfig(
465             /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR, 10, 90, 300),
466             /*packageSpecific=*/{},
467             /*categorySpecific=*/
468             {toPerStateIoOveruseThreshold("MAPS", 800, 900, 2000),
469              toPerStateIoOveruseThreshold("MEDIA", 1800, 1900, 2100),
470              toPerStateIoOveruseThreshold("MEDIA", 1400, 1600, 2000)},
471             /*systemWide=*/{});
472     vendorResourceConfig =
473             constructResourceOveruseConfig(ComponentType::VENDOR, /*safeToKill=*/{},
474                                            /*vendorPrefixes=*/{"vendorPackage", "vendorPkg"},
475                                            /*packageMetadata=*/{}, vendorIoConfig);
476 
477     auto thirdPartyIoConfig = constructIoOveruseConfig(
478             /*componentLevel=*/
479             toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 600, 300, 2300),
480             /*packageSpecific=*/{}, /*categorySpecific=*/{}, /*systemWide=*/{});
481     thirdPartyResourceConfig =
482             constructResourceOveruseConfig(ComponentType::THIRD_PARTY, /*safeToKill=*/{},
483                                            /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
484                                            thirdPartyIoConfig);
485 
486     ASSERT_RESULT_OK(ioOveruseConfigs.update(
487             {systemResourceConfig, vendorResourceConfig, thirdPartyResourceConfig}));
488 
489     systemIoConfig.packageSpecificThresholds.erase(
490             systemIoConfig.packageSpecificThresholds.begin());
491     systemIoConfig.systemWideThresholds.erase(systemIoConfig.systemWideThresholds.begin() + 1);
492     systemResourceConfig =
493             constructResourceOveruseConfig(ComponentType::SYSTEM, /*safeToKill=*/{"systemPackageC"},
494                                            /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
495                                            systemIoConfig);
496 
497     vendorIoConfig.categorySpecificThresholds.erase(
498             vendorIoConfig.categorySpecificThresholds.begin() + 1);
499     vendorResourceConfig =
500             constructResourceOveruseConfig(ComponentType::VENDOR, /*safeToKill=*/{},
501                                            /*vendorPrefixes=*/{"vendorPackage", "vendorPkg"},
502                                            /*packageMetadata=*/{}, vendorIoConfig);
503 
504     expected = {systemResourceConfig, vendorResourceConfig, thirdPartyResourceConfig};
505 
506     actual.clear();
507     ioOveruseConfigs.get(&actual);
508 
509     EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
510             << "Expected: " << toString(expected) << "Actual:" << toString(actual);
511 }
512 
TEST_F(IoOveruseConfigsTest,TestDefaultConfigWithoutUpdate)513 TEST_F(IoOveruseConfigsTest, TestDefaultConfigWithoutUpdate) {
514     PerStateBytes defaultPerStateBytes = defaultThreshold().perStateWriteBytes;
515     IoOveruseConfigs ioOveruseConfigs;
516 
517     auto packageInfo = constructAppPackageInfo("systemPackage", ComponentType::SYSTEM);
518     EXPECT_THAT(ioOveruseConfigs.fetchThreshold(packageInfo), defaultPerStateBytes)
519             << "System package should have default threshold";
520     EXPECT_FALSE(ioOveruseConfigs.isSafeToKill(packageInfo))
521             << "System package shouldn't be killed by default";
522 
523     packageInfo = constructAppPackageInfo("vendorPackage", ComponentType::VENDOR,
524                                           ApplicationCategoryType::MEDIA);
525     EXPECT_THAT(ioOveruseConfigs.fetchThreshold(packageInfo), defaultPerStateBytes)
526             << "Vendor package should have default threshold";
527     EXPECT_FALSE(ioOveruseConfigs.isSafeToKill(packageInfo))
528             << "Vendor package shouldn't be killed by default";
529 
530     packageInfo = constructAppPackageInfo("3pPackage", ComponentType::THIRD_PARTY,
531                                           ApplicationCategoryType::MAPS);
532     EXPECT_THAT(ioOveruseConfigs.fetchThreshold(packageInfo), defaultPerStateBytes)
533             << "Third-party package should have default threshold";
534     EXPECT_TRUE(ioOveruseConfigs.isSafeToKill(packageInfo))
535             << "Third-party package should be killed by default";
536 
537     EXPECT_THAT(ioOveruseConfigs.systemWideAlertThresholds(), IsEmpty());
538     EXPECT_THAT(ioOveruseConfigs.vendorPackagePrefixes(), IsEmpty());
539 
540     std::vector<ResourceOveruseConfiguration> actual;
541     ioOveruseConfigs.get(&actual);
542 
543     EXPECT_THAT(actual, IsEmpty());
544 }
545 
TEST_F(IoOveruseConfigsTest,TestFailsUpdateOnInvalidComponentName)546 TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnInvalidComponentName) {
547     IoOveruseConfiguration randomIoConfig;
548     randomIoConfig.componentLevelThresholds =
549             toPerStateIoOveruseThreshold("random name", 200, 100, 500);
550 
551     IoOveruseConfigs ioOveruseConfigs;
552     EXPECT_FALSE(ioOveruseConfigs
553                          .update({constructResourceOveruseConfig(ComponentType::SYSTEM, {}, {}, {},
554                                                                  randomIoConfig)})
555                          .ok());
556 
557     EXPECT_FALSE(ioOveruseConfigs
558                          .update({constructResourceOveruseConfig(ComponentType::VENDOR, {}, {}, {},
559                                                                  randomIoConfig)})
560                          .ok());
561 
562     EXPECT_FALSE(ioOveruseConfigs
563                          .update({constructResourceOveruseConfig(ComponentType::THIRD_PARTY, {}, {},
564                                                                  {}, randomIoConfig)})
565                          .ok());
566 
567     std::vector<ResourceOveruseConfiguration> actual;
568     ioOveruseConfigs.get(&actual);
569 
570     EXPECT_THAT(actual, IsEmpty());
571 }
572 
TEST_F(IoOveruseConfigsTest,TestFailsUpdateOnDuplicatePackageToAppCategoryMappings)573 TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnDuplicatePackageToAppCategoryMappings) {
574     IoOveruseConfiguration ioConfig;
575     ioConfig.componentLevelThresholds =
576             toPerStateIoOveruseThreshold(ComponentType::VENDOR, VENDOR_COMPONENT_LEVEL_THRESHOLDS);
577 
578     IoOveruseConfigs ioOveruseConfigs;
579     EXPECT_FALSE(
580             ioOveruseConfigs
581                     .update({constructResourceOveruseConfig(
582                             ComponentType::VENDOR,
583                             /*safeToKill=*/{},
584                             /*vendorPrefixes=*/{"vendorPackage"},
585                             /*packageMetadata=*/
586                             {toPackageMetadata("vendorPackageA", ApplicationCategoryType::MEDIA),
587                              toPackageMetadata("vendorPackageA", ApplicationCategoryType::MAPS)},
588                             ioConfig)})
589                     .ok())
590             << "Should error on duplicate package to app category mapping";
591 
592     std::vector<ResourceOveruseConfiguration> actual;
593     ioOveruseConfigs.get(&actual);
594 
595     EXPECT_THAT(actual, IsEmpty());
596 }
597 
TEST_F(IoOveruseConfigsTest,TestFailsUpdateOnInvalidComponentLevelThresholds)598 TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnInvalidComponentLevelThresholds) {
599     IoOveruseConfiguration ioConfig;
600     ioConfig.componentLevelThresholds =
601             toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 0, 0, 0);
602 
603     IoOveruseConfigs ioOveruseConfigs;
604     EXPECT_FALSE(ioOveruseConfigs
605                          .update({constructResourceOveruseConfig(ComponentType::THIRD_PARTY, {}, {},
606                                                                  {}, ioConfig)})
607                          .ok())
608             << "Should error on invalid component level thresholds";
609 
610     std::vector<ResourceOveruseConfiguration> actual;
611     ioOveruseConfigs.get(&actual);
612 
613     EXPECT_THAT(actual, IsEmpty());
614 }
615 
TEST_F(IoOveruseConfigsTest,TestFailsUpdateOnInvalidSystemWideAlertThresholds)616 TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnInvalidSystemWideAlertThresholds) {
617     IoOveruseConfiguration ioConfig;
618     ioConfig.componentLevelThresholds =
619             toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 100, 200, 300);
620     ioConfig.systemWideThresholds = {toIoOveruseAlertThreshold(0, 0)};
621 
622     IoOveruseConfigs ioOveruseConfigs;
623     EXPECT_FALSE(ioOveruseConfigs
624                          .update({constructResourceOveruseConfig(ComponentType::SYSTEM, {}, {}, {},
625                                                                  ioConfig)})
626                          .ok())
627             << "Should error on invalid system-wide thresholds";
628 
629     std::vector<ResourceOveruseConfiguration> actual;
630     ioOveruseConfigs.get(&actual);
631 
632     EXPECT_THAT(actual, IsEmpty());
633 }
634 
TEST_F(IoOveruseConfigsTest,TestFailsUpdateOnDuplicateConfigsForSameComponent)635 TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnDuplicateConfigsForSameComponent) {
636     IoOveruseConfigs ioOveruseConfigs;
637     EXPECT_FALSE(ioOveruseConfigs
638                          .update({sampleUpdateThirdPartyConfig(), sampleUpdateThirdPartyConfig()})
639                          .ok())
640             << "Should error on duplicate configs for the same component";
641 
642     std::vector<ResourceOveruseConfiguration> actual;
643     ioOveruseConfigs.get(&actual);
644 
645     EXPECT_THAT(actual, IsEmpty());
646 }
647 
TEST_F(IoOveruseConfigsTest,TestFailsUpdateOnNoIoOveruseConfiguration)648 TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnNoIoOveruseConfiguration) {
649     ResourceOveruseConfiguration resConfig;
650     resConfig.componentType = ComponentType::THIRD_PARTY;
651 
652     IoOveruseConfigs ioOveruseConfigs;
653     EXPECT_FALSE(ioOveruseConfigs.update({resConfig}).ok())
654             << "Should error on no I/O overuse configuration";
655 
656     std::vector<ResourceOveruseConfiguration> actual;
657     ioOveruseConfigs.get(&actual);
658 
659     EXPECT_THAT(actual, IsEmpty());
660 }
661 
TEST_F(IoOveruseConfigsTest,TestFailsUpdateOnMultipleIoOveruseConfigurations)662 TEST_F(IoOveruseConfigsTest, TestFailsUpdateOnMultipleIoOveruseConfigurations) {
663     IoOveruseConfiguration ioConfig;
664     ioConfig.componentLevelThresholds =
665             toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 100, 200, 300);
666 
667     ResourceOveruseConfiguration resConfig;
668     resConfig.componentType = ComponentType::THIRD_PARTY;
669     ResourceSpecificConfiguration resourceSpecificConfig;
670     resourceSpecificConfig.set<ResourceSpecificConfiguration::ioOveruseConfiguration>(ioConfig);
671     resConfig.resourceSpecificConfigurations.push_back(resourceSpecificConfig);
672     resConfig.resourceSpecificConfigurations.push_back(resourceSpecificConfig);
673 
674     IoOveruseConfigs ioOveruseConfigs;
675     EXPECT_FALSE(ioOveruseConfigs.update({resConfig}).ok())
676             << "Should error on multiple I/O overuse configuration";
677 
678     std::vector<ResourceOveruseConfiguration> actual;
679     ioOveruseConfigs.get(&actual);
680 
681     EXPECT_THAT(actual, IsEmpty());
682 }
683 
TEST_F(IoOveruseConfigsTest,TestIgnoresNonUpdatableConfigsBySystemComponent)684 TEST_F(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsBySystemComponent) {
685     auto systemIoConfig = constructIoOveruseConfig(
686             /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM, 200, 100, 500),
687             /*packageSpecific=*/
688             {toPerStateIoOveruseThreshold("systemPackageA", 600, 400, 1000),
689              toPerStateIoOveruseThreshold("systemPackageB", 1200, 800, 1500)},
690             /*categorySpecific=*/
691             {toPerStateIoOveruseThreshold("MAPS", 700, 900, 1300),
692              toPerStateIoOveruseThreshold("MEDIA", 1800, 1900, 2100)},
693             /*systemWide=*/
694             {toIoOveruseAlertThreshold(5, 200), toIoOveruseAlertThreshold(30, 40000)});
695     auto systemResourceConfig =
696             constructResourceOveruseConfig(ComponentType::SYSTEM, /*safeToKill=*/{"systemPackageA"},
697                                            /*vendorPrefixes=*/{"vendorPackage"},
698                                            /*packageMetadata=*/{}, systemIoConfig);
699 
700     IoOveruseConfigs ioOveruseConfigs;
701     ASSERT_RESULT_OK(ioOveruseConfigs.update({systemResourceConfig}));
702 
703     // Drop fields that aren't updatable by system component.
704     systemIoConfig.categorySpecificThresholds.clear();
705     systemResourceConfig =
706             constructResourceOveruseConfig(ComponentType::SYSTEM, /*safeToKill=*/{"systemPackageA"},
707                                            /*vendorPrefixes=*/{}, /*packageMetadata=*/{},
708                                            systemIoConfig);
709 
710     std::vector<ResourceOveruseConfiguration> expected = {systemResourceConfig};
711 
712     std::vector<ResourceOveruseConfiguration> actual;
713     ioOveruseConfigs.get(&actual);
714 
715     EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
716             << "Expected: " << toString(expected) << "Actual:" << toString(actual);
717 }
718 
TEST_F(IoOveruseConfigsTest,TestIgnoresNonUpdatableConfigsByVendorComponent)719 TEST_F(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsByVendorComponent) {
720     auto vendorIoConfig = constructIoOveruseConfig(
721             /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR, 100, 50, 900),
722             /*packageSpecific=*/
723             {toPerStateIoOveruseThreshold("vendorPackageA", 800, 300, 500),
724              toPerStateIoOveruseThreshold("vendorPkgB", 1600, 600, 1000)},
725             /*categorySpecific=*/
726             {toPerStateIoOveruseThreshold("MAPS", 700, 900, 1300),
727              toPerStateIoOveruseThreshold("MEDIA", 1800, 1900, 2100)},
728             /*systemWide=*/
729             {toIoOveruseAlertThreshold(5, 200), toIoOveruseAlertThreshold(30, 40000)});
730     auto vendorResourceConfig =
731             constructResourceOveruseConfig(ComponentType::VENDOR,
732                                            /*safeToKill=*/
733                                            {"vendorPackageA"},
734                                            /*vendorPrefixes=*/{"vendorPackage", "vendorPkg"},
735                                            /*packageMetadata=*/{}, vendorIoConfig);
736 
737     IoOveruseConfigs ioOveruseConfigs;
738     ASSERT_RESULT_OK(ioOveruseConfigs.update({vendorResourceConfig}));
739 
740     // Drop fields that aren't updatable by vendor component.
741     vendorIoConfig.systemWideThresholds.clear();
742     vendorResourceConfig =
743             constructResourceOveruseConfig(ComponentType::VENDOR,
744                                            /*safeToKill=*/
745                                            {"vendorPackageA"},
746                                            /*vendorPrefixes=*/{"vendorPackage", "vendorPkg"},
747                                            /*packageMetadata=*/{}, vendorIoConfig);
748 
749     std::vector<ResourceOveruseConfiguration> expected = {vendorResourceConfig};
750 
751     std::vector<ResourceOveruseConfiguration> actual;
752     ioOveruseConfigs.get(&actual);
753 
754     EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
755             << "Expected: " << toString(expected) << "Actual:" << toString(actual);
756 }
757 
TEST_F(IoOveruseConfigsTest,TestIgnoresNonUpdatableConfigsByThirdPartyComponent)758 TEST_F(IoOveruseConfigsTest, TestIgnoresNonUpdatableConfigsByThirdPartyComponent) {
759     auto thirdPartyIoConfig = constructIoOveruseConfig(
760             /*componentLevel=*/
761             toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY, 300, 150, 1900),
762             /*packageSpecific=*/
763             {toPerStateIoOveruseThreshold("vendorPackageA", 800, 300, 500),
764              toPerStateIoOveruseThreshold("systemPackageB", 1600, 600, 1000)},
765             /*categorySpecific=*/
766             {toPerStateIoOveruseThreshold("MAPS", 700, 900, 1300),
767              toPerStateIoOveruseThreshold("MEDIA", 1800, 1900, 2100)},
768             /*systemWide=*/
769             {toIoOveruseAlertThreshold(5, 200), toIoOveruseAlertThreshold(30, 40000)});
770     auto thirdPartyResourceConfig =
771             constructResourceOveruseConfig(ComponentType::THIRD_PARTY,
772                                            /*safeToKill=*/{"vendorPackageA", "systemPackageB"},
773                                            /*vendorPrefixes=*/{"vendorPackage"},
774                                            /*packageMetadata=*/{}, thirdPartyIoConfig);
775 
776     IoOveruseConfigs ioOveruseConfigs;
777     ASSERT_RESULT_OK(ioOveruseConfigs.update({thirdPartyResourceConfig}));
778 
779     // Drop fields that aren't updatable by third-party component.
780     thirdPartyIoConfig.packageSpecificThresholds.clear();
781     thirdPartyIoConfig.categorySpecificThresholds.clear();
782     thirdPartyIoConfig.systemWideThresholds.clear();
783     thirdPartyResourceConfig =
784             constructResourceOveruseConfig(ComponentType::THIRD_PARTY,
785                                            /*safeToKill=*/{}, /*vendorPrefixes=*/{},
786                                            /*packageMetadata=*/{}, thirdPartyIoConfig);
787 
788     std::vector<ResourceOveruseConfiguration> expected = {thirdPartyResourceConfig};
789 
790     std::vector<ResourceOveruseConfiguration> actual;
791     ioOveruseConfigs.get(&actual);
792 
793     EXPECT_THAT(actual, UnorderedElementsAreArray(ResourceOveruseConfigurationsMatchers(expected)))
794             << "Expected: " << toString(expected) << "Actual:" << toString(actual);
795 }
796 
TEST_F(IoOveruseConfigsTest,TestFetchThresholdForSystemPackages)797 TEST_F(IoOveruseConfigsTest, TestFetchThresholdForSystemPackages) {
798     const auto ioOveruseConfigs = sampleIoOveruseConfigs();
799 
800     auto actual = ioOveruseConfigs->fetchThreshold(
801             constructAppPackageInfo("systemPackageGeneric", ComponentType::SYSTEM));
802 
803     EXPECT_THAT(actual, SYSTEM_COMPONENT_LEVEL_THRESHOLDS);
804 
805     actual = ioOveruseConfigs->fetchThreshold(
806             constructAppPackageInfo("systemPackageA", ComponentType::SYSTEM));
807 
808     EXPECT_THAT(actual, SYSTEM_PACKAGE_A_THRESHOLDS);
809 
810     actual = ioOveruseConfigs->fetchThreshold(
811             constructAppPackageInfo("systemPackageB", ComponentType::SYSTEM,
812                                     ApplicationCategoryType::MEDIA));
813 
814     // Package specific thresholds get priority over media category thresholds.
815     EXPECT_THAT(actual, SYSTEM_PACKAGE_B_THRESHOLDS);
816 
817     actual = ioOveruseConfigs->fetchThreshold(
818             constructAppPackageInfo("systemPackageC", ComponentType::SYSTEM,
819                                     ApplicationCategoryType::MEDIA));
820 
821     // Media category thresholds as there is no package specific thresholds.
822     EXPECT_THAT(actual, MEDIA_THRESHOLDS);
823 }
824 
TEST_F(IoOveruseConfigsTest,TestFetchThresholdForSharedSystemPackages)825 TEST_F(IoOveruseConfigsTest, TestFetchThresholdForSharedSystemPackages) {
826     const auto ioOveruseConfigs = sampleIoOveruseConfigs();
827     auto sampleSystemConfig = sampleUpdateSystemConfig();
828     auto& ioConfig = sampleSystemConfig.resourceSpecificConfigurations[0]
829                              .get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
830     ioConfig.packageSpecificThresholds.push_back(
831             toPerStateIoOveruseThreshold("shared:systemSharedPackage",
832                                          toPerStateBytes(100, 200, 300)));
833 
834     ioOveruseConfigs->update({sampleSystemConfig});
835 
836     auto actual = ioOveruseConfigs->fetchThreshold(
837             constructAppPackageInfo("shared:systemSharedPackage", ComponentType::SYSTEM));
838 
839     EXPECT_THAT(actual, toPerStateBytes(100, 200, 300));
840 
841     actual = ioOveruseConfigs->fetchThreshold(
842             constructAppPackageInfo("systemSharedPackage", ComponentType::SYSTEM));
843 
844     EXPECT_THAT(actual, SYSTEM_COMPONENT_LEVEL_THRESHOLDS);
845 }
846 
TEST_F(IoOveruseConfigsTest,TestFetchThresholdForVendorPackages)847 TEST_F(IoOveruseConfigsTest, TestFetchThresholdForVendorPackages) {
848     const auto ioOveruseConfigs = sampleIoOveruseConfigs();
849 
850     auto actual = ioOveruseConfigs->fetchThreshold(
851             constructAppPackageInfo("vendorPackageGeneric", ComponentType::VENDOR));
852 
853     EXPECT_THAT(actual, VENDOR_COMPONENT_LEVEL_THRESHOLDS);
854 
855     actual = ioOveruseConfigs->fetchThreshold(
856             constructAppPackageInfo("vendorPkgB", ComponentType::VENDOR));
857 
858     EXPECT_THAT(actual, VENDOR_PKG_B_THRESHOLDS);
859 
860     actual = ioOveruseConfigs->fetchThreshold(
861             constructAppPackageInfo("vendorPackageC", ComponentType::VENDOR,
862                                     ApplicationCategoryType::MAPS));
863 
864     // Maps category thresholds as there is no package specific thresholds.
865     EXPECT_THAT(actual, MAPS_THRESHOLDS);
866 }
867 
TEST_F(IoOveruseConfigsTest,TestFetchThresholdForSharedVendorPackages)868 TEST_F(IoOveruseConfigsTest, TestFetchThresholdForSharedVendorPackages) {
869     const auto ioOveruseConfigs = sampleIoOveruseConfigs();
870     auto sampleVendorConfig = sampleUpdateVendorConfig();
871     auto& ioConfig = sampleVendorConfig.resourceSpecificConfigurations[0]
872                              .get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
873     ioConfig.packageSpecificThresholds.push_back(
874             toPerStateIoOveruseThreshold("shared:vendorSharedPackage",
875                                          toPerStateBytes(100, 200, 300)));
876 
877     ioOveruseConfigs->update({sampleVendorConfig});
878 
879     auto actual = ioOveruseConfigs->fetchThreshold(
880             constructAppPackageInfo("shared:vendorSharedPackage", ComponentType::VENDOR));
881 
882     EXPECT_THAT(actual, toPerStateBytes(100, 200, 300));
883 
884     actual = ioOveruseConfigs->fetchThreshold(
885             constructAppPackageInfo("vendorSharedPackage", ComponentType::VENDOR));
886 
887     EXPECT_THAT(actual, VENDOR_COMPONENT_LEVEL_THRESHOLDS);
888 }
889 
TEST_F(IoOveruseConfigsTest,TestFetchThresholdForThirdPartyPackages)890 TEST_F(IoOveruseConfigsTest, TestFetchThresholdForThirdPartyPackages) {
891     const auto ioOveruseConfigs = sampleIoOveruseConfigs();
892 
893     auto actual = ioOveruseConfigs->fetchThreshold(
894             constructAppPackageInfo("vendorPackageGenericImpostor", ComponentType::THIRD_PARTY));
895 
896     EXPECT_THAT(actual, THIRD_PARTY_COMPONENT_LEVEL_THRESHOLDS);
897 
898     actual = ioOveruseConfigs->fetchThreshold(
899             constructAppPackageInfo("3pMapsPackage", ComponentType::THIRD_PARTY,
900                                     ApplicationCategoryType::MAPS));
901 
902     EXPECT_THAT(actual, MAPS_THRESHOLDS);
903 
904     actual = ioOveruseConfigs->fetchThreshold(
905             constructAppPackageInfo("3pMediaPackage", ComponentType::THIRD_PARTY,
906                                     ApplicationCategoryType::MEDIA));
907 
908     EXPECT_THAT(actual, MEDIA_THRESHOLDS);
909 }
910 
TEST_F(IoOveruseConfigsTest,TestIsSafeToKillSystemPackages)911 TEST_F(IoOveruseConfigsTest, TestIsSafeToKillSystemPackages) {
912     const auto ioOveruseConfigs = sampleIoOveruseConfigs();
913     EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(
914             constructAppPackageInfo("systemPackageGeneric", ComponentType::SYSTEM)));
915 
916     EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(
917             constructAppPackageInfo("systemPackageA", ComponentType::SYSTEM)));
918 }
919 
TEST_F(IoOveruseConfigsTest,TestIsSafeToKillSharedSystemPackages)920 TEST_F(IoOveruseConfigsTest, TestIsSafeToKillSharedSystemPackages) {
921     auto sampleSystemConfig = sampleUpdateSystemConfig();
922     sampleSystemConfig.safeToKillPackages.push_back("sharedUidSystemPackageC");
923     sampleSystemConfig.safeToKillPackages.push_back("shared:systemSharedPackageD");
924     sp<IoOveruseConfigs> ioOveruseConfigs = new IoOveruseConfigs();
925 
926     EXPECT_RESULT_OK(ioOveruseConfigs->update({sampleSystemConfig}));
927 
928     PackageInfo packageInfo =
929             constructAppPackageInfo("systemSharedPackage", ComponentType::SYSTEM,
930                                     ApplicationCategoryType::OTHERS,
931                                     {"sharedUidSystemPackageA", "sharedUidSystemPackageB",
932                                      "sharedUidSystemPackageC"});
933 
934     EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(packageInfo))
935             << "Should be safe-to-kill when at least one package under shared UID is safe-to-kill";
936 
937     packageInfo =
938             constructAppPackageInfo("shared:systemSharedPackageD", ComponentType::SYSTEM,
939                                     ApplicationCategoryType::OTHERS, {"sharedUidSystemPackageA"});
940     EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(packageInfo))
941             << "Should be safe-to-kill when shared package is safe-to-kill";
942 
943     packageInfo =
944             constructAppPackageInfo("systemSharedPackageD", ComponentType::SYSTEM,
945                                     ApplicationCategoryType::OTHERS, {"sharedUidSystemPackageA"});
946     EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(packageInfo))
947             << "Shouldn't be safe-to-kill when the 'shared:' prefix is missing";
948 }
949 
TEST_F(IoOveruseConfigsTest,TestIsSafeToKillVendorPackages)950 TEST_F(IoOveruseConfigsTest, TestIsSafeToKillVendorPackages) {
951     const auto ioOveruseConfigs = sampleIoOveruseConfigs();
952     EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(
953             constructAppPackageInfo("vendorPackageGeneric", ComponentType::VENDOR)));
954 
955     EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(
956             constructAppPackageInfo("vendorPackageA", ComponentType::VENDOR)));
957 }
958 
TEST_F(IoOveruseConfigsTest,TestIsSafeToKillSharedVendorPackages)959 TEST_F(IoOveruseConfigsTest, TestIsSafeToKillSharedVendorPackages) {
960     auto sampleVendorConfig = sampleUpdateVendorConfig();
961     sampleVendorConfig.safeToKillPackages.push_back("sharedUidVendorPackageC");
962     sampleVendorConfig.safeToKillPackages.push_back("shared:vendorSharedPackageD");
963 
964     auto sampleSystemConfig = sampleUpdateSystemConfig();
965     sampleSystemConfig.safeToKillPackages.push_back("sharedUidSystemPackageC");
966 
967     sp<IoOveruseConfigs> ioOveruseConfigs = new IoOveruseConfigs();
968 
969     EXPECT_RESULT_OK(ioOveruseConfigs->update({sampleSystemConfig, sampleVendorConfig}));
970 
971     PackageInfo packageInfo =
972             constructAppPackageInfo("vendorSharedPackage", ComponentType::VENDOR,
973                                     ApplicationCategoryType::OTHERS,
974                                     {"sharedUidVendorPackageA", "sharedUidVendorPackageB",
975                                      "sharedUidVendorPackageC"});
976 
977     EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(packageInfo))
978             << "Should be safe-to-kill when at least one package under shared UID is safe-to-kill";
979 
980     packageInfo =
981             constructAppPackageInfo("shared:vendorSharedPackageD", ComponentType::VENDOR,
982                                     ApplicationCategoryType::OTHERS, {"sharedUidVendorPackageA"});
983     EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(packageInfo))
984             << "Should be safe-to-kill when shared package is safe-to-kill";
985 
986     packageInfo =
987             constructAppPackageInfo("shared:vendorSharedPackageE", ComponentType::VENDOR,
988                                     ApplicationCategoryType::OTHERS, {"sharedUidVendorPackageA"});
989     EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(packageInfo))
990             << "Shouldn't be safe-to-kill when the 'shared:' prefix is missing";
991 }
992 
TEST_F(IoOveruseConfigsTest,TestIsSafeToKillThirdPartyPackages)993 TEST_F(IoOveruseConfigsTest, TestIsSafeToKillThirdPartyPackages) {
994     const auto ioOveruseConfigs = sampleIoOveruseConfigs();
995     EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(
996             constructAppPackageInfo("vendorPackageGenericImpostor", ComponentType::THIRD_PARTY)));
997 
998     EXPECT_TRUE(ioOveruseConfigs->isSafeToKill(
999             constructAppPackageInfo("3pMapsPackage", ComponentType::THIRD_PARTY,
1000                                     ApplicationCategoryType::MAPS)));
1001 }
1002 
TEST_F(IoOveruseConfigsTest,TestIsSafeToKillNativePackages)1003 TEST_F(IoOveruseConfigsTest, TestIsSafeToKillNativePackages) {
1004     const auto ioOveruseConfigs = sampleIoOveruseConfigs();
1005 
1006     PackageInfo packageInfo;
1007     packageInfo.packageIdentifier.name = "native package";
1008     packageInfo.uidType = UidType::NATIVE;
1009     packageInfo.componentType = ComponentType::SYSTEM;
1010 
1011     EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(packageInfo));
1012 
1013     packageInfo.componentType = ComponentType::VENDOR;
1014 
1015     EXPECT_FALSE(ioOveruseConfigs->isSafeToKill(packageInfo));
1016 }
1017 
TEST_F(IoOveruseConfigsTest,TestSystemWideAlertThresholds)1018 TEST_F(IoOveruseConfigsTest, TestSystemWideAlertThresholds) {
1019     const auto ioOveruseConfigs = sampleIoOveruseConfigs();
1020 
1021     EXPECT_THAT(ioOveruseConfigs->systemWideAlertThresholds(),
1022                 UnorderedElementsAreArray(ALERT_THRESHOLDS));
1023 }
1024 
TEST_F(IoOveruseConfigsTest,TestVendorPackagePrefixes)1025 TEST_F(IoOveruseConfigsTest, TestVendorPackagePrefixes) {
1026     const auto ioOveruseConfigs = sampleIoOveruseConfigs();
1027 
1028     EXPECT_THAT(ioOveruseConfigs->vendorPackagePrefixes(),
1029                 UnorderedElementsAre("vendorPackage", "vendorPkgB"));
1030 }
1031 
TEST_F(IoOveruseConfigsTest,TestVendorPackagePrefixesWithSharedPackages)1032 TEST_F(IoOveruseConfigsTest, TestVendorPackagePrefixesWithSharedPackages) {
1033     auto sampleVendorConfig = sampleUpdateVendorConfig();
1034     sampleVendorConfig.vendorPackagePrefixes.push_back("shared:vendorSharedPackage");
1035     sampleVendorConfig.safeToKillPackages.push_back("sharedUidVendorPackageD");
1036     sampleVendorConfig.safeToKillPackages.push_back("shared:vendorSharedPackageE");
1037     sampleVendorConfig.safeToKillPackages.push_back("shared:vndrSharedPkgF");
1038 
1039     auto& ioConfig = sampleVendorConfig.resourceSpecificConfigurations[0]
1040                              .get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
1041 
1042     ioConfig.packageSpecificThresholds.push_back(
1043             toPerStateIoOveruseThreshold("shared:vendorSharedPackageG",
1044                                          VENDOR_PACKAGE_A_THRESHOLDS));
1045     ioConfig.packageSpecificThresholds.push_back(
1046             toPerStateIoOveruseThreshold("shared:vndrSharedPkgH", VENDOR_PACKAGE_A_THRESHOLDS));
1047 
1048     sp<IoOveruseConfigs> ioOveruseConfigs = new IoOveruseConfigs();
1049 
1050     EXPECT_RESULT_OK(ioOveruseConfigs->update({sampleVendorConfig}));
1051 
1052     EXPECT_THAT(ioOveruseConfigs->vendorPackagePrefixes(),
1053                 UnorderedElementsAre("vendorPackage", "vendorPkgB", "shared:vendorSharedPackage",
1054                                      "sharedUidVendorPackageD", "shared:vndrSharedPkgF",
1055                                      "shared:vndrSharedPkgH"));
1056 }
1057 
TEST_F(IoOveruseConfigsTest,TestPackagesToAppCategoriesWithSystemConfig)1058 TEST_F(IoOveruseConfigsTest, TestPackagesToAppCategoriesWithSystemConfig) {
1059     IoOveruseConfigs ioOveruseConfigs;
1060     const auto resourceOveruseConfig = sampleUpdateSystemConfig();
1061 
1062     ASSERT_RESULT_OK(ioOveruseConfigs.update({resourceOveruseConfig}));
1063 
1064     EXPECT_THAT(ioOveruseConfigs.packagesToAppCategories(),
1065                 UnorderedElementsAreArray(
1066                         toPackageToAppCategoryMappings(resourceOveruseConfig.packageMetadata)));
1067 }
1068 
TEST_F(IoOveruseConfigsTest,TestPackagesToAppCategoriesWithVendorConfig)1069 TEST_F(IoOveruseConfigsTest, TestPackagesToAppCategoriesWithVendorConfig) {
1070     IoOveruseConfigs ioOveruseConfigs;
1071     const auto resourceOveruseConfig = sampleUpdateVendorConfig();
1072 
1073     ASSERT_RESULT_OK(ioOveruseConfigs.update({resourceOveruseConfig}));
1074 
1075     EXPECT_THAT(ioOveruseConfigs.packagesToAppCategories(),
1076                 UnorderedElementsAreArray(
1077                         toPackageToAppCategoryMappings(resourceOveruseConfig.packageMetadata)));
1078 }
1079 
TEST_F(IoOveruseConfigsTest,TestWriteToDisk)1080 TEST_F(IoOveruseConfigsTest, TestWriteToDisk) {
1081     auto systemResourceConfig = sampleUpdateSystemConfig();
1082     auto vendorResourceConfig = sampleUpdateVendorConfig();
1083     auto thirdPartyResourceConfig = sampleUpdateThirdPartyConfig();
1084 
1085     IoOveruseConfigs ioOveruseConfigs;
1086 
1087     ASSERT_RESULT_OK(ioOveruseConfigs.update(
1088             {systemResourceConfig, vendorResourceConfig, thirdPartyResourceConfig}));
1089 
1090     ASSERT_RESULT_OK(ioOveruseConfigs.writeToDisk());
1091 
1092     ASSERT_EQ(mPeer->configsByFilepaths.size(), 3);
1093 
1094     vendorResourceConfig.vendorPackagePrefixes.push_back("vendorPkgB");
1095     std::unordered_map<std::string, ResourceOveruseConfiguration> expected(
1096             {{kLatestSystemConfigXmlPath, systemResourceConfig},
1097              {kLatestVendorConfigXmlPath, vendorResourceConfig},
1098              {kLatestThirdPartyConfigXmlPath, thirdPartyResourceConfig}});
1099 
1100     EXPECT_THAT(mPeer->configsByFilepaths, UnorderedPointwise(ConfigsByFilepathsEq(), expected))
1101             << "Expected: " << toString(expected)
1102             << "Actual:" << toString(mPeer->configsByFilepaths);
1103 }
1104 
TEST_F(IoOveruseConfigsTest,TestWriteToDiskFailure)1105 TEST_F(IoOveruseConfigsTest, TestWriteToDiskFailure) {
1106     auto systemResourceConfig = sampleUpdateSystemConfig();
1107     auto vendorResourceConfig = sampleUpdateVendorConfig();
1108     auto thirdPartyResourceConfig = sampleUpdateThirdPartyConfig();
1109 
1110     std::vector<ResourceOveruseConfiguration> resourceOvuerseConfigs =
1111             {sampleUpdateSystemConfig(), sampleUpdateVendorConfig(),
1112              sampleUpdateThirdPartyConfig()};
1113 
1114     mPeer->injectErrorOnWriteXmlFile();
1115 
1116     for (const auto config : resourceOvuerseConfigs) {
1117         IoOveruseConfigs ioOveruseConfigs;
1118 
1119         ASSERT_RESULT_OK(ioOveruseConfigs.update({config}));
1120 
1121         ASSERT_FALSE(ioOveruseConfigs.writeToDisk().ok())
1122                 << "Must fail write to disk on XML write error for component "
1123                 << toString(config.componentType);
1124     }
1125 }
1126 
1127 }  // namespace watchdog
1128 }  // namespace automotive
1129 }  // namespace android
1130