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 #include "OveruseConfigurationXmlHelper.h"
19
20 #include <android-base/file.h>
21 #include <android-base/result.h>
22 #include <android/automotive/watchdog/internal/ApplicationCategoryType.h>
23 #include <android/automotive/watchdog/internal/ComponentType.h>
24 #include <gmock/gmock.h>
25
26 namespace android {
27 namespace automotive {
28 namespace watchdog {
29
30 using ::android::automotive::watchdog::internal::ApplicationCategoryType;
31 using ::android::automotive::watchdog::internal::ComponentType;
32 using ::android::automotive::watchdog::internal::ResourceOveruseConfiguration;
33
34 namespace {
35
36 constexpr const char* kTestDataDir = "/tests/data/";
37
38 constexpr const char* kValidSystemConfiguration = "valid_overuse_system_configuration.xml";
39 constexpr const char* kValidVendorConfiguration = "valid_overuse_vendor_configuration.xml";
40 constexpr const char* kValidThirdPartyConfiguration = "valid_overuse_third_party_configuration.xml";
41
42 const std::vector<const char*> kInvalidOveruseConfigurations =
43 {"duplicate_component_io_thresholds_overuse_configuration.xml",
44 "duplicate_component_type_overuse_configuration.xml",
45 "duplicate_io_config_overuse_configuration.xml",
46 "incomplete_app_category_io_thresholds_overuse_configuration.xml",
47 "incomplete_component_io_thresholds_overuse_configuration.xml",
48 "incomplete_pkg_io_thresholds_overuse_configuration.xml",
49 "incomplete_systemwide_io_thresholds_overuse_configuration.xml",
50 "invalid_component_type_overuse_configuration.xml",
51 "invalid_param_systemwide_io_thresholds_overuse_configuration.xml",
52 "invalid_state_app_category_io_thresholds_overuse_configuration.xml",
53 "invalid_state_component_io_thresholds_overuse_configuration.xml",
54 "invalid_state_pkg_io_thresholds_overuse_configuration.xml",
55 "invalid_type_app_category_mapping_overuse_configuration.xml",
56 "missing_component_io_thresholds_overuse_configuration.xml",
57 "missing_io_config_overuse_configuration.xml",
58 "missing_pkg_name_app_category_mapping_overuse_configuration.xml",
59 "missing_pkg_name_pkg_io_thresholds_overuse_configuration.xml",
60 "missing_pkg_name_safe_to_kill_entry_overuse_configuration.xml",
61 "missing_threshold_app_category_io_thresholds_overuse_configuration.xml",
62 "missing_threshold_component_io_thresholds_overuse_configuration.xml",
63 "missing_threshold_pkg_io_thresholds_overuse_configuration.xml",
64 "missing_threshold_systemwide_io_thresholds_overuse_configuration.xml"};
65
getTestFilePath(const char * filename)66 std::string getTestFilePath(const char* filename) {
67 static std::string baseDir = android::base::GetExecutableDirectory();
68 return baseDir + kTestDataDir + filename;
69 }
70
71 } // namespace
72
TEST(OveruseConfigurationXmlHelperTest,TestValidSystemConfiguration)73 TEST(OveruseConfigurationXmlHelperTest, TestValidSystemConfiguration) {
74 auto ioConfig = constructIoOveruseConfig(
75 /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM,
76 300 * kOneMegaByte, 150 * kOneMegaByte,
77 500 * kOneMegaByte),
78 /*packageSpecific=*/
79 {toPerStateIoOveruseThreshold("system.package.C", 400 * kOneMegaByte,
80 100 * kOneMegaByte, 200 * kOneMegaByte),
81 toPerStateIoOveruseThreshold("system.package.D", 1024 * kOneMegaByte,
82 500 * kOneMegaByte, 2048 * kOneMegaByte)},
83 /*categorySpecific=*/{},
84 /*systemWide=*/{toIoOveruseAlertThreshold(10, 200), toIoOveruseAlertThreshold(5, 50)});
85 ResourceOveruseConfiguration expected =
86 constructResourceOveruseConfig(ComponentType::SYSTEM,
87 /*safeToKill=*/{"system.package.A", "system.package.B"},
88 /*vendorPrefixes=*/{},
89 /*packageMetadata=*/
90 {toPackageMetadata("system.package.A",
91 ApplicationCategoryType::MEDIA),
92 toPackageMetadata("system.package.B",
93 ApplicationCategoryType::MAPS)},
94 ioConfig);
95 auto actual = OveruseConfigurationXmlHelper::parseXmlFile(
96 getTestFilePath(kValidSystemConfiguration).c_str());
97 ASSERT_RESULT_OK(actual);
98 EXPECT_THAT(*actual, ResourceOveruseConfigurationMatcher(expected))
99 << "Expected: " << expected.toString() << "\nActual: " << actual->toString();
100 }
101
TEST(OveruseConfigurationXmlHelperTest,TestValidVendorConfiguration)102 TEST(OveruseConfigurationXmlHelperTest, TestValidVendorConfiguration) {
103 auto ioConfig = constructIoOveruseConfig(
104 /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR,
105 1024 * kOneMegaByte, 512 * kOneMegaByte,
106 3072 * kOneMegaByte),
107 /*packageSpecific=*/
108 {toPerStateIoOveruseThreshold("com.vendor.package.C", 400 * kOneMegaByte,
109 100 * kOneMegaByte, 200 * kOneMegaByte),
110 toPerStateIoOveruseThreshold("com.vendor.package.D", 1024 * kOneMegaByte,
111 500 * kOneMegaByte, 2048 * kOneMegaByte)},
112 /*categorySpecific=*/
113 {toPerStateIoOveruseThreshold("MAPS", 800 * kOneMegaByte, 900 * kOneMegaByte,
114 2048 * kOneMegaByte),
115 toPerStateIoOveruseThreshold("MEDIA", 600 * kOneMegaByte, 700 * kOneMegaByte,
116 1024 * kOneMegaByte)},
117 /*systemWide=*/{});
118 ResourceOveruseConfiguration expected =
119 constructResourceOveruseConfig(ComponentType::VENDOR,
120 /*safeToKill=*/
121 {"com.vendor.package.A", "com.vendor.package.B"},
122 /*vendorPrefixes=*/{"com.vendor.package"},
123 /*packageMetadata=*/
124 {toPackageMetadata("com.vendor.package.A",
125 ApplicationCategoryType::MEDIA),
126 toPackageMetadata("com.vendor.package.B",
127 ApplicationCategoryType::MAPS),
128 toPackageMetadata("com.third.party.package.C",
129 ApplicationCategoryType::MEDIA),
130 toPackageMetadata("system.package.D",
131 ApplicationCategoryType::MAPS)},
132 ioConfig);
133 auto actual = OveruseConfigurationXmlHelper::parseXmlFile(
134 getTestFilePath(kValidVendorConfiguration).c_str());
135 ASSERT_RESULT_OK(actual);
136 EXPECT_THAT(*actual, ResourceOveruseConfigurationMatcher(expected))
137 << "Expected: " << expected.toString() << "\nActual: " << actual->toString();
138 }
139
TEST(OveruseConfigurationXmlHelperTest,TestValidThirdPartyConfiguration)140 TEST(OveruseConfigurationXmlHelperTest, TestValidThirdPartyConfiguration) {
141 auto ioConfig = constructIoOveruseConfig(
142 /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY,
143 300 * kOneMegaByte, 150 * kOneMegaByte,
144 500 * kOneMegaByte),
145 /*packageSpecific=*/{},
146 /*categorySpecific=*/{},
147 /*systemWide=*/{});
148 ResourceOveruseConfiguration expected =
149 constructResourceOveruseConfig(ComponentType::THIRD_PARTY,
150 /*safeToKill=*/{},
151 /*vendorPrefixes=*/{},
152 /*packageMetadata=*/{}, ioConfig);
153 auto actual = OveruseConfigurationXmlHelper::parseXmlFile(
154 getTestFilePath(kValidThirdPartyConfiguration).c_str());
155 ASSERT_RESULT_OK(actual);
156 EXPECT_THAT(*actual, ResourceOveruseConfigurationMatcher(expected))
157 << "Expected: " << expected.toString() << "\nActual: " << actual->toString();
158 }
159
TEST(OveruseConfigurationXmlHelperTest,TestInvalidOveruseConfigurations)160 TEST(OveruseConfigurationXmlHelperTest, TestInvalidOveruseConfigurations) {
161 for (const auto& filename : kInvalidOveruseConfigurations) {
162 ASSERT_FALSE(
163 OveruseConfigurationXmlHelper::parseXmlFile(getTestFilePath(filename).c_str()).ok())
164 << "Must return error on parsing '" << filename << "'";
165 }
166 }
167
TEST(OveruseConfigurationXmlHelperTest,TestWriteXmlFileWithSystemConfiguration)168 TEST(OveruseConfigurationXmlHelperTest, TestWriteXmlFileWithSystemConfiguration) {
169 auto ioConfig = constructIoOveruseConfig(
170 /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::SYSTEM,
171 300 * kOneMegaByte, 150 * kOneMegaByte,
172 500 * kOneMegaByte),
173 /*packageSpecific=*/
174 {toPerStateIoOveruseThreshold("system.package.C", 400 * kOneMegaByte,
175 100 * kOneMegaByte, 200 * kOneMegaByte),
176 toPerStateIoOveruseThreshold("system.package.D", 1024 * kOneMegaByte,
177 500 * kOneMegaByte, 2048 * kOneMegaByte)},
178 /*categorySpecific=*/{},
179 /*systemWide=*/{toIoOveruseAlertThreshold(10, 200), toIoOveruseAlertThreshold(5, 50)});
180 ResourceOveruseConfiguration expected =
181 constructResourceOveruseConfig(ComponentType::SYSTEM,
182 /*safeToKill=*/{"system.package.A", "system.package.B"},
183 /*vendorPrefixes=*/{},
184 /*packageMetadata=*/
185 {toPackageMetadata("system.package.A",
186 ApplicationCategoryType::MEDIA),
187 toPackageMetadata("system.package.B",
188 ApplicationCategoryType::MAPS)},
189 ioConfig);
190 TemporaryFile temporaryFile;
191 ASSERT_NE(temporaryFile.fd, -1);
192
193 ASSERT_RESULT_OK(OveruseConfigurationXmlHelper::writeXmlFile(expected, temporaryFile.path));
194
195 ALOGW("Wrote to file: %s", temporaryFile.path);
196
197 auto actual = OveruseConfigurationXmlHelper::parseXmlFile(temporaryFile.path);
198
199 ASSERT_RESULT_OK(actual);
200
201 EXPECT_THAT(*actual, ResourceOveruseConfigurationMatcher(expected))
202 << "Expected: " << expected.toString() << "\nActual: " << actual->toString();
203
204 temporaryFile.release();
205 }
206
TEST(OveruseConfigurationXmlHelperTest,TestWriteXmlFileWithVendorConfiguration)207 TEST(OveruseConfigurationXmlHelperTest, TestWriteXmlFileWithVendorConfiguration) {
208 auto ioConfig = constructIoOveruseConfig(
209 /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::VENDOR,
210 1024 * kOneMegaByte, 512 * kOneMegaByte,
211 3072 * kOneMegaByte),
212 /*packageSpecific=*/
213 {toPerStateIoOveruseThreshold("com.vendor.package.C", 400 * kOneMegaByte,
214 100 * kOneMegaByte, 200 * kOneMegaByte),
215 toPerStateIoOveruseThreshold("com.vendor.package.D", 1024 * kOneMegaByte,
216 500 * kOneMegaByte, 2048 * kOneMegaByte)},
217 /*categorySpecific=*/
218 {toPerStateIoOveruseThreshold("MAPS", 800 * kOneMegaByte, 900 * kOneMegaByte,
219 2048 * kOneMegaByte),
220 toPerStateIoOveruseThreshold("MEDIA", 600 * kOneMegaByte, 700 * kOneMegaByte,
221 1024 * kOneMegaByte)},
222 /*systemWide=*/{});
223 ResourceOveruseConfiguration expected =
224 constructResourceOveruseConfig(ComponentType::VENDOR,
225 /*safeToKill=*/
226 {"com.vendor.package.A", "com.vendor.package.B"},
227 /*vendorPrefixes=*/{"com.vendor.package"},
228 /*packageMetadata=*/
229 {toPackageMetadata("com.vendor.package.A",
230 ApplicationCategoryType::MEDIA),
231 toPackageMetadata("com.vendor.package.B",
232 ApplicationCategoryType::MAPS),
233 toPackageMetadata("com.third.party.package.C",
234 ApplicationCategoryType::MEDIA),
235 toPackageMetadata("system.package.D",
236 ApplicationCategoryType::MAPS)},
237 ioConfig);
238 TemporaryFile temporaryFile;
239 ASSERT_NE(temporaryFile.fd, -1);
240
241 ASSERT_RESULT_OK(OveruseConfigurationXmlHelper::writeXmlFile(expected, temporaryFile.path));
242
243 ALOGW("Wrote to file: %s", temporaryFile.path);
244
245 auto actual = OveruseConfigurationXmlHelper::parseXmlFile(temporaryFile.path);
246
247 ASSERT_RESULT_OK(actual);
248
249 EXPECT_THAT(*actual, ResourceOveruseConfigurationMatcher(expected))
250 << "Expected: " << expected.toString() << "\nActual: " << actual->toString();
251
252 temporaryFile.release();
253 }
254
TEST(OveruseConfigurationXmlHelperTest,TestWriteXmlFileWithThirdPartyConfiguration)255 TEST(OveruseConfigurationXmlHelperTest, TestWriteXmlFileWithThirdPartyConfiguration) {
256 auto ioConfig = constructIoOveruseConfig(
257 /*componentLevel=*/toPerStateIoOveruseThreshold(ComponentType::THIRD_PARTY,
258 300 * kOneMegaByte, 150 * kOneMegaByte,
259 500 * kOneMegaByte),
260 /*packageSpecific=*/{},
261 /*categorySpecific=*/{},
262 /*systemWide=*/{});
263 ResourceOveruseConfiguration expected =
264 constructResourceOveruseConfig(ComponentType::THIRD_PARTY,
265 /*safeToKill=*/{},
266 /*vendorPrefixes=*/{},
267 /*packageMetadata=*/{}, ioConfig);
268 TemporaryFile temporaryFile;
269 ASSERT_NE(temporaryFile.fd, -1);
270
271 ASSERT_RESULT_OK(OveruseConfigurationXmlHelper::writeXmlFile(expected, temporaryFile.path));
272
273 ALOGW("Wrote to file: %s", temporaryFile.path);
274
275 auto actual = OveruseConfigurationXmlHelper::parseXmlFile(temporaryFile.path);
276
277 ASSERT_RESULT_OK(actual);
278
279 EXPECT_THAT(*actual, ResourceOveruseConfigurationMatcher(expected))
280 << "Expected: " << expected.toString() << "\nActual: " << actual->toString();
281
282 temporaryFile.release();
283 }
284
TEST(OveruseConfigurationXmlHelperTest,TestFailsWriteXmlFileWithInvalidConfig)285 TEST(OveruseConfigurationXmlHelperTest, TestFailsWriteXmlFileWithInvalidConfig) {
286 ResourceOveruseConfiguration resourceOveruseConfig;
287 resourceOveruseConfig.componentType = ComponentType::THIRD_PARTY;
288
289 TemporaryFile temporaryFile;
290 ASSERT_NE(temporaryFile.fd, -1);
291
292 ASSERT_FALSE(
293 OveruseConfigurationXmlHelper::writeXmlFile(resourceOveruseConfig, temporaryFile.path)
294 .ok())
295 << "Should fail to write invalid config";
296
297 temporaryFile.release();
298 }
299
300 } // namespace watchdog
301 } // namespace automotive
302 } // namespace android
303