1 /*
2  * Copyright 2021 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 "OveruseConfigurationTestUtils.h"
18 
19 namespace android {
20 namespace automotive {
21 namespace watchdog {
22 
23 using ::android::automotive::watchdog::internal::ApplicationCategoryType;
24 using ::android::automotive::watchdog::internal::ComponentType;
25 using ::android::automotive::watchdog::internal::IoOveruseAlertThreshold;
26 using ::android::automotive::watchdog::internal::IoOveruseConfiguration;
27 using ::android::automotive::watchdog::internal::PackageMetadata;
28 using ::android::automotive::watchdog::internal::PerStateIoOveruseThreshold;
29 using ::android::automotive::watchdog::internal::ResourceOveruseConfiguration;
30 using ::android::automotive::watchdog::internal::ResourceSpecificConfiguration;
31 using ::testing::AllOf;
32 using ::testing::ExplainMatchResult;
33 using ::testing::Field;
34 using ::testing::Matcher;
35 using ::testing::UnorderedElementsAreArray;
36 
37 namespace {
38 
39 MATCHER_P(IsIoOveruseConfiguration, config, "") {
40     return arg.componentLevelThresholds == config.componentLevelThresholds &&
41             ExplainMatchResult(UnorderedElementsAreArray(config.packageSpecificThresholds),
42                                arg.packageSpecificThresholds, result_listener) &&
43             ExplainMatchResult(UnorderedElementsAreArray(config.categorySpecificThresholds),
44                                arg.categorySpecificThresholds, result_listener) &&
45             ExplainMatchResult(UnorderedElementsAreArray(config.systemWideThresholds),
46                                arg.systemWideThresholds, result_listener);
47 }
48 
49 MATCHER_P(IsResourceSpecificConfiguration, config, "") {
50     if (arg.getTag() != config.getTag()) {
51         return false;
52     }
53     // Reference with the actual datatype so the templated get method can be called.
54     const ResourceSpecificConfiguration& expected = config;
55     const ResourceSpecificConfiguration& actual = arg;
56     switch (arg.getTag()) {
57         case ResourceSpecificConfiguration::ioOveruseConfiguration: {
58             const auto& expectedIoConfig =
59                     expected.get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
60             const auto& actualIoConfig =
61                     actual.get<ResourceSpecificConfiguration::ioOveruseConfiguration>();
62             return ExplainMatchResult(IsIoOveruseConfiguration(expectedIoConfig), actualIoConfig,
63                                       result_listener);
64         }
65         default:
66             return true;
67     }
68 }
69 
70 MATCHER_P(IsPackageMetadata, expected, "") {
71     return arg.packageName == expected.packageName &&
72             arg.appCategoryType == expected.appCategoryType;
73 }
74 
75 }  // namespace
76 
constructResourceOveruseConfig(const ComponentType type,const std::vector<std::string> && safeToKill,const std::vector<std::string> && vendorPrefixes,const std::vector<PackageMetadata> packageMetadata,const IoOveruseConfiguration & ioOveruseConfiguration)77 ResourceOveruseConfiguration constructResourceOveruseConfig(
78         const ComponentType type, const std::vector<std::string>&& safeToKill,
79         const std::vector<std::string>&& vendorPrefixes,
80         const std::vector<PackageMetadata> packageMetadata,
81         const IoOveruseConfiguration& ioOveruseConfiguration) {
82     ResourceOveruseConfiguration resourceOveruseConfig;
83     resourceOveruseConfig.componentType = type;
84     resourceOveruseConfig.safeToKillPackages = safeToKill;
85     resourceOveruseConfig.vendorPackagePrefixes = vendorPrefixes;
86     resourceOveruseConfig.packageMetadata = packageMetadata;
87     ResourceSpecificConfiguration config;
88     config.set<ResourceSpecificConfiguration::ioOveruseConfiguration>(ioOveruseConfiguration);
89     resourceOveruseConfig.resourceSpecificConfigurations.push_back(config);
90     return resourceOveruseConfig;
91 }
92 
constructIoOveruseConfig(PerStateIoOveruseThreshold componentLevel,const std::vector<PerStateIoOveruseThreshold> & packageSpecific,const std::vector<PerStateIoOveruseThreshold> & categorySpecific,const std::vector<IoOveruseAlertThreshold> & systemWide)93 IoOveruseConfiguration constructIoOveruseConfig(
94         PerStateIoOveruseThreshold componentLevel,
95         const std::vector<PerStateIoOveruseThreshold>& packageSpecific,
96         const std::vector<PerStateIoOveruseThreshold>& categorySpecific,
97         const std::vector<IoOveruseAlertThreshold>& systemWide) {
98     IoOveruseConfiguration config;
99     config.componentLevelThresholds = componentLevel;
100     config.packageSpecificThresholds = packageSpecific;
101     config.categorySpecificThresholds = categorySpecific;
102     config.systemWideThresholds = systemWide;
103     return config;
104 }
105 
toPerStateBytes(const int64_t fgBytes,const int64_t bgBytes,const int64_t garageModeBytes)106 PerStateBytes toPerStateBytes(const int64_t fgBytes, const int64_t bgBytes,
107                               const int64_t garageModeBytes) {
108     PerStateBytes perStateBytes;
109     perStateBytes.foregroundBytes = fgBytes;
110     perStateBytes.backgroundBytes = bgBytes;
111     perStateBytes.garageModeBytes = garageModeBytes;
112     return perStateBytes;
113 }
114 
toPerStateIoOveruseThreshold(const std::string & name,const PerStateBytes & perStateBytes)115 PerStateIoOveruseThreshold toPerStateIoOveruseThreshold(const std::string& name,
116                                                         const PerStateBytes& perStateBytes) {
117     PerStateIoOveruseThreshold threshold;
118     threshold.name = name;
119     threshold.perStateWriteBytes = perStateBytes;
120     return threshold;
121 }
122 
toPerStateIoOveruseThreshold(const std::string & name,const int64_t fgBytes,const int64_t bgBytes,const int64_t garageModeBytes)123 PerStateIoOveruseThreshold toPerStateIoOveruseThreshold(const std::string& name,
124                                                         const int64_t fgBytes,
125                                                         const int64_t bgBytes,
126                                                         const int64_t garageModeBytes) {
127     return toPerStateIoOveruseThreshold(name, toPerStateBytes(fgBytes, bgBytes, garageModeBytes));
128 }
129 
toPerStateIoOveruseThreshold(const ComponentType type,const PerStateBytes & perStateBytes)130 PerStateIoOveruseThreshold toPerStateIoOveruseThreshold(const ComponentType type,
131                                                         const PerStateBytes& perStateBytes) {
132     return toPerStateIoOveruseThreshold(toString(type), perStateBytes);
133 }
134 
toPerStateIoOveruseThreshold(const ComponentType type,const int64_t fgBytes,const int64_t bgBytes,const int64_t garageModeBytes)135 PerStateIoOveruseThreshold toPerStateIoOveruseThreshold(const ComponentType type,
136                                                         const int64_t fgBytes,
137                                                         const int64_t bgBytes,
138                                                         const int64_t garageModeBytes) {
139     return toPerStateIoOveruseThreshold(type, toPerStateBytes(fgBytes, bgBytes, garageModeBytes));
140 }
141 
toPackageMetadata(std::string packageName,ApplicationCategoryType type)142 PackageMetadata toPackageMetadata(std::string packageName, ApplicationCategoryType type) {
143     PackageMetadata meta;
144     meta.packageName = packageName;
145     meta.appCategoryType = type;
146     return meta;
147 }
148 
toIoOveruseAlertThreshold(const int64_t durationInSeconds,const int64_t writtenBytesPerSecond)149 IoOveruseAlertThreshold toIoOveruseAlertThreshold(const int64_t durationInSeconds,
150                                                   const int64_t writtenBytesPerSecond) {
151     IoOveruseAlertThreshold threshold;
152     threshold.durationInSeconds = durationInSeconds;
153     threshold.writtenBytesPerSecond = writtenBytesPerSecond;
154     return threshold;
155 }
156 
ResourceOveruseConfigurationMatcher(const ResourceOveruseConfiguration & config)157 Matcher<const ResourceOveruseConfiguration&> ResourceOveruseConfigurationMatcher(
158         const ResourceOveruseConfiguration& config) {
159     std::vector<Matcher<const ResourceSpecificConfiguration&>> resourceSpecificConfigMatchers;
160     for (const auto& resourceSpecificConfig : config.resourceSpecificConfigurations) {
161         resourceSpecificConfigMatchers.push_back(
162                 IsResourceSpecificConfiguration(resourceSpecificConfig));
163     }
164 
165     std::vector<Matcher<const PackageMetadata&>> metadataMatchers;
166     for (const auto& metadata : config.packageMetadata) {
167         metadataMatchers.push_back(IsPackageMetadata(metadata));
168     }
169 
170     return AllOf(Field(&ResourceOveruseConfiguration::componentType, config.componentType),
171                  Field(&ResourceOveruseConfiguration::safeToKillPackages,
172                        UnorderedElementsAreArray(config.safeToKillPackages)),
173                  Field(&ResourceOveruseConfiguration::vendorPackagePrefixes,
174                        UnorderedElementsAreArray(config.vendorPackagePrefixes)),
175                  Field(&ResourceOveruseConfiguration::packageMetadata,
176                        UnorderedElementsAreArray(metadataMatchers)),
177                  Field(&ResourceOveruseConfiguration::resourceSpecificConfigurations,
178                        UnorderedElementsAreArray(resourceSpecificConfigMatchers)));
179 }
180 
181 }  // namespace watchdog
182 }  // namespace automotive
183 }  // namespace android
184