1 /*
2 * Copyright (C) 2024 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 "aconfigd.h"
18
19 #include <android-base/file.h>
20 #include <android-base/logging.h>
21 #include <android-base/properties.h>
22 #include <flag_macros.h>
23 #include <gtest/gtest.h>
24 #include <sys/stat.h>
25
26 #include "aconfigd_test_mock.h"
27 #include "aconfigd_util.h"
28 #include "com_android_aconfig_new_storage.h"
29
30 #define ACONFIGD_NS com::android::aconfig_new_storage
31
32 namespace android {
33 namespace aconfigd {
34
35 class AconfigdTest : public ::testing::Test {
36 protected:
37
new_storage_message(const std::string & container,const std::string & package_map_file,const std::string & flag_map_file,const std::string & flag_value_file,const std::string & flag_info_file)38 StorageRequestMessage new_storage_message(const std::string& container,
39 const std::string& package_map_file,
40 const std::string& flag_map_file,
41 const std::string& flag_value_file,
42 const std::string& flag_info_file) {
43 auto message = StorageRequestMessage();
44 auto* msg = message.mutable_new_storage_message();
45 msg->set_container(container);
46 msg->set_package_map(package_map_file);
47 msg->set_flag_map(flag_map_file);
48 msg->set_flag_value(flag_value_file);
49 msg->set_flag_info(flag_info_file);
50 return message;
51 }
52
new_storage_message(const ContainerMock & mock)53 StorageRequestMessage new_storage_message(const ContainerMock& mock) {
54 return new_storage_message(mock.container, mock.package_map, mock.flag_map,
55 mock.flag_val, mock.flag_info);
56 }
57
flag_override_message(const std::string & package,const std::string & flag,const std::string & value,bool is_local,bool is_immediate)58 StorageRequestMessage flag_override_message(const std::string& package,
59 const std::string& flag,
60 const std::string& value,
61 bool is_local,
62 bool is_immediate) {
63 auto message = StorageRequestMessage();
64 auto* msg = message.mutable_flag_override_message();
65
66 StorageRequestMessage::FlagOverrideType override_type;
67 if (is_local && is_immediate) {
68 override_type = StorageRequestMessage::LOCAL_IMMEDIATE;
69 } else if (is_local && !is_immediate) {
70 override_type = StorageRequestMessage::LOCAL_ON_REBOOT;
71 } else {
72 override_type = StorageRequestMessage::SERVER_ON_REBOOT;
73 }
74
75 msg->set_package_name(package);
76 msg->set_flag_name(flag);
77 msg->set_flag_value(value);
78 msg->set_override_type(override_type);
79 return message;
80 }
81
flag_query_message(const std::string & package,const std::string & flag)82 StorageRequestMessage flag_query_message(const std::string& package,
83 const std::string& flag) {
84 auto message = StorageRequestMessage();
85 auto* msg = message.mutable_flag_query_message();
86 msg->set_package_name(package);
87 msg->set_flag_name(flag);
88 return message;
89 }
90
flag_local_override_remove_message(const std::string & package,const std::string & flag,bool remove_all=false)91 StorageRequestMessage flag_local_override_remove_message(
92 const std::string& package,
93 const std::string& flag,
94 bool remove_all = false) {
95 auto message = StorageRequestMessage();
96 auto* msg = message.mutable_remove_local_override_message();
97 msg->set_package_name(package);
98 msg->set_flag_name(flag);
99 msg->set_remove_all(remove_all);
100 return message;
101 }
102
reset_storage_message()103 StorageRequestMessage reset_storage_message() {
104 auto message = StorageRequestMessage();
105 auto* msg = message.mutable_reset_storage_message();
106 return message;
107 }
108
list_storage_message()109 StorageRequestMessage list_storage_message() {
110 auto message = StorageRequestMessage();
111 auto* msg = message.mutable_list_storage_message();
112 msg->set_all(true);
113 return message;
114 }
115
list_container_storage_message(const std::string & container)116 StorageRequestMessage list_container_storage_message(const std::string& container) {
117 auto message = StorageRequestMessage();
118 auto* msg = message.mutable_list_storage_message();
119 msg->set_container(container);
120 return message;
121 }
122
list_package_storage_message(const std::string & package)123 StorageRequestMessage list_package_storage_message(const std::string& package) {
124 auto message = StorageRequestMessage();
125 auto* msg = message.mutable_list_storage_message();
126 msg->set_package_name(package);
127 return message;
128 }
129
verify_new_storage_return_message(base::Result<StorageReturnMessage> msg_result,bool ensure_updated=false)130 void verify_new_storage_return_message(base::Result<StorageReturnMessage> msg_result,
131 bool ensure_updated = false) {
132 ASSERT_TRUE(msg_result.ok()) << msg_result.error();
133 auto msg = *msg_result;
134 ASSERT_TRUE(msg.has_new_storage_message()) << msg.error_message();
135 if (ensure_updated) {
136 auto message = msg.new_storage_message();
137 ASSERT_TRUE(message.storage_updated());
138 }
139 }
140
verify_flag_override_return_message(base::Result<StorageReturnMessage> msg_result)141 void verify_flag_override_return_message(
142 base::Result<StorageReturnMessage> msg_result) {
143 ASSERT_TRUE(msg_result.ok()) << msg_result.error();
144 auto msg = *msg_result;
145 ASSERT_TRUE(msg.has_flag_override_message()) << msg.error_message();
146 }
147
verify_flag_query_return_message(const StorageReturnMessage::FlagQueryReturnMessage & message,const std::string & package_name,const std::string & flag_name,const std::string & server_value,const std::string & local_value,const std::string & boot_value,const std::string & default_value,bool is_readwrite,bool has_server_override,bool has_local_override)148 void verify_flag_query_return_message(
149 const StorageReturnMessage::FlagQueryReturnMessage& message,
150 const std::string& package_name,
151 const std::string& flag_name,
152 const std::string& server_value,
153 const std::string& local_value,
154 const std::string& boot_value,
155 const std::string& default_value,
156 bool is_readwrite,
157 bool has_server_override,
158 bool has_local_override) {
159 ASSERT_EQ(message.package_name(), package_name);
160 ASSERT_EQ(message.flag_name(), flag_name);
161 ASSERT_EQ(message.server_flag_value(), server_value);
162 ASSERT_EQ(message.local_flag_value(), local_value);
163 ASSERT_EQ(message.boot_flag_value(), boot_value);
164 ASSERT_EQ(message.default_flag_value(), default_value);
165 ASSERT_EQ(message.is_readwrite(), is_readwrite);
166 ASSERT_EQ(message.has_server_override(), has_server_override);
167 ASSERT_EQ(message.has_local_override(), has_local_override);
168 }
169
verify_flag_query_return_message(base::Result<StorageReturnMessage> msg_result,const std::string & package_name,const std::string & flag_name,const std::string & server_value,const std::string & local_value,const std::string & boot_value,const std::string & default_value,bool is_readwrite,bool has_server_override,bool has_local_override)170 void verify_flag_query_return_message(base::Result<StorageReturnMessage> msg_result,
171 const std::string& package_name,
172 const std::string& flag_name,
173 const std::string& server_value,
174 const std::string& local_value,
175 const std::string& boot_value,
176 const std::string& default_value,
177 bool is_readwrite,
178 bool has_server_override,
179 bool has_local_override) {
180 ASSERT_TRUE(msg_result.ok()) << msg_result.error();
181 auto msg = *msg_result;
182 ASSERT_TRUE(msg.has_flag_query_message()) << msg.error_message();
183 auto message = msg.flag_query_message();
184 verify_flag_query_return_message(
185 message, package_name, flag_name, server_value, local_value, boot_value,
186 default_value, is_readwrite, has_server_override, has_local_override);
187 }
188
verify_local_override_remove_return_message(base::Result<StorageReturnMessage> msg_result)189 void verify_local_override_remove_return_message(
190 base::Result<StorageReturnMessage> msg_result) {
191 ASSERT_TRUE(msg_result.ok()) << msg_result.error();
192 auto msg = *msg_result;
193 ASSERT_TRUE(msg.has_remove_local_override_message()) << msg.error_message();
194 }
195
verify_reset_storage_message(base::Result<StorageReturnMessage> msg_result)196 void verify_reset_storage_message(base::Result<StorageReturnMessage> msg_result) {
197 ASSERT_TRUE(msg_result.ok()) << msg_result.error();
198 auto msg = *msg_result;
199 ASSERT_TRUE(msg.has_reset_storage_message()) << msg.error_message();
200 }
201
verify_error_message(base::Result<StorageReturnMessage> msg_result,const std::string & errmsg)202 void verify_error_message(base::Result<StorageReturnMessage> msg_result,
203 const std::string& errmsg) {
204 ASSERT_FALSE(msg_result.ok());
205 ASSERT_TRUE(msg_result.error().message().find(errmsg) != std::string::npos)
206 << msg_result.error().message();
207 }
208
verify_equal_file_content(const std::string & file_one,const std::string & file_two)209 void verify_equal_file_content(const std::string& file_one,
210 const std::string& file_two) {
211 ASSERT_TRUE(FileExists(file_one)) << file_one << " does not exist";
212 ASSERT_TRUE(FileExists(file_two)) << file_one << " does not exist";
213 auto content_one = std::string();
214 auto content_two = std::string();
215 ASSERT_TRUE(base::ReadFileToString(file_one, &content_one)) << strerror(errno);
216 ASSERT_TRUE(base::ReadFileToString(file_two, &content_two)) << strerror(errno);
217 ASSERT_EQ(content_one, content_two) << file_one << " is different from "
218 << file_two;
219 }
220
221 // setup test suites
SetUpTestSuite()222 static void SetUpTestSuite() {
223 auto test_dir = base::GetExecutableDirectory();
224 package_map_ = test_dir + "/tests/data/v1/package.map";
225 flag_map_ = test_dir + "/tests/data/v1/flag.map";
226 flag_val_ = test_dir + "/tests/data/v1/flag.val";
227 flag_info_ = test_dir + "/tests/data/v1/flag.info";
228 updated_package_map_ = test_dir + "/tests/data/v2/package.map";
229 updated_flag_map_ = test_dir + "/tests/data/v2/flag.map";
230 updated_flag_val_ = test_dir + "/tests/data/v2/flag.val";
231 updated_flag_info_ = test_dir + "/tests/data/v2/flag.info";
232 }
233
234 static std::string package_map_;
235 static std::string flag_map_;
236 static std::string flag_val_;
237 static std::string flag_info_;
238 static std::string updated_package_map_;
239 static std::string updated_flag_map_;
240 static std::string updated_flag_val_;
241 static std::string updated_flag_info_;
242 }; // class AconfigdTest
243
244 std::string AconfigdTest::package_map_;
245 std::string AconfigdTest::flag_map_;
246 std::string AconfigdTest::flag_val_;
247 std::string AconfigdTest::flag_info_;
248 std::string AconfigdTest::updated_package_map_;
249 std::string AconfigdTest::updated_flag_map_;
250 std::string AconfigdTest::updated_flag_val_;
251 std::string AconfigdTest::updated_flag_info_;
252
TEST_F(AconfigdTest,init_platform_storage_fresh)253 TEST_F(AconfigdTest, init_platform_storage_fresh) {
254 auto a_mock = AconfigdMock();
255 auto init_result = a_mock.aconfigd.InitializePlatformStorage();
256 ASSERT_TRUE(init_result.ok()) << init_result.error();
257
258 auto partitions = std::vector<std::pair<std::string, std::string>>{
259 {"system", "/system/etc/aconfig"},
260 {"vendor", "/vendor/etc/aconfig"},
261 {"product", "/product/etc/aconfig"}};
262
263 for (auto const& [container, storage_dir] : partitions) {
264 auto package_map = std::string(storage_dir) + "/package.map";
265 auto flag_map = std::string(storage_dir) + "/flag.map";
266 auto flag_val = std::string(storage_dir) + "/flag.val";
267 auto flag_info = std::string(storage_dir) + "/flag.info";
268 if (!FileNonZeroSize(flag_val)) {
269 continue;
270 }
271
272 verify_equal_file_content(a_mock.maps_dir + "/" + container + ".package.map", package_map);
273 verify_equal_file_content(a_mock.maps_dir + "/" + container + ".flag.map", flag_map);
274 verify_equal_file_content(a_mock.flags_dir + "/" + container + ".val", flag_val);
275 verify_equal_file_content(a_mock.boot_dir + "/" + container + ".val", flag_val);
276 verify_equal_file_content(a_mock.flags_dir + "/" + container + ".info", flag_info);
277 verify_equal_file_content(a_mock.boot_dir + "/" + container + ".info", flag_info);
278 }
279 }
280
TEST_F(AconfigdTest,init_platform_storage_reboot)281 TEST_F(AconfigdTest, init_platform_storage_reboot) {
282 auto a_mock = AconfigdMock();
283 auto init_result = a_mock.aconfigd.InitializePlatformStorage();
284 ASSERT_TRUE(init_result.ok()) << init_result.error();
285
286 init_result = a_mock.aconfigd.InitializePlatformStorage();
287 ASSERT_TRUE(init_result.ok()) << init_result.error();
288
289 auto partitions = std::vector<std::pair<std::string, std::string>>{
290 {"system", "/system/etc/aconfig"},
291 {"vendor", "/vendor/etc/aconfig"},
292 {"product", "/product/etc/aconfig"}};
293
294 for (auto const& [container, storage_dir] : partitions) {
295 auto package_map = std::string(storage_dir) + "/package.map";
296 auto flag_map = std::string(storage_dir) + "/flag.map";
297 auto flag_val = std::string(storage_dir) + "/flag.val";
298 auto flag_info = std::string(storage_dir) + "/flag.info";
299 if (!FileNonZeroSize(flag_val)) {
300 continue;
301 }
302
303 verify_equal_file_content(a_mock.maps_dir + "/" + container + ".package.map", package_map);
304 verify_equal_file_content(a_mock.maps_dir + "/" + container + ".flag.map", flag_map);
305 verify_equal_file_content(a_mock.flags_dir + "/" + container + ".val", flag_val);
306 verify_equal_file_content(a_mock.boot_dir + "/" + container + ".val", flag_val);
307 verify_equal_file_content(a_mock.flags_dir + "/" + container + ".info", flag_info);
308 verify_equal_file_content(a_mock.boot_dir + "/" + container + ".info", flag_info);
309 }
310 }
311
TEST_F(AconfigdTest,init_mainline_storage_fresh)312 TEST_F(AconfigdTest, init_mainline_storage_fresh) {
313 auto a_mock = AconfigdMock();
314 auto init_result = a_mock.aconfigd.InitializeMainlineStorage();
315 ASSERT_TRUE(init_result.ok()) << init_result.error();
316 }
317
TEST_F(AconfigdTest,add_new_storage)318 TEST_F(AconfigdTest, add_new_storage) {
319 // create mocks
320 auto a_mock = AconfigdMock();
321 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
322
323 // mock a socket request
324 auto request_msg = new_storage_message(c_mock);
325 auto return_msg = a_mock.SendRequestToSocket(request_msg);
326 verify_new_storage_return_message(return_msg, true);
327
328 auto digest = GetFilesDigest(
329 {c_mock.package_map, c_mock.flag_map, c_mock.flag_val, c_mock.flag_info});
330 ASSERT_TRUE(digest.ok());
331
332 // verify the record exists in persist records pb
333 auto persist_records_pb = PersistStorageRecords();
334 auto content = std::string();
335 ASSERT_TRUE(base::ReadFileToString(a_mock.persist_pb, &content)) << strerror(errno);
336 ASSERT_TRUE(persist_records_pb.ParseFromString(content)) << strerror(errno);
337 bool found = false;
338 for (auto& entry : persist_records_pb.records()) {
339 if (entry.container() == "mockup") {
340 found = true;
341 ASSERT_EQ(entry.version(), 1);
342 ASSERT_EQ(entry.package_map(), c_mock.package_map);
343 ASSERT_EQ(entry.flag_map(), c_mock.flag_map);
344 ASSERT_EQ(entry.flag_val(), c_mock.flag_val);
345 ASSERT_EQ(entry.flag_info(), c_mock.flag_info);
346 ASSERT_EQ(entry.digest(), *digest);
347 break;
348 }
349 }
350 ASSERT_TRUE(found);
351
352 // verify persist and boot files
353 verify_equal_file_content(a_mock.maps_dir + "/mockup.package.map", package_map_);
354 verify_equal_file_content(a_mock.maps_dir + "/mockup.flag.map", flag_map_);
355 verify_equal_file_content(a_mock.flags_dir + "/mockup.val", flag_val_);
356 verify_equal_file_content(a_mock.boot_dir + "/mockup.val", flag_val_);
357 verify_equal_file_content(a_mock.flags_dir + "/mockup.info", flag_info_);
358 verify_equal_file_content(a_mock.boot_dir + "/mockup.info", flag_info_);
359 }
360
TEST_F(AconfigdTest,container_update_in_ota)361 TEST_F(AconfigdTest, container_update_in_ota) {
362 // create mocks
363 auto a_mock = AconfigdMock();
364 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
365
366 // mock a socket request
367 auto request_msg = new_storage_message(c_mock);
368 auto return_msg = a_mock.SendRequestToSocket(request_msg);
369 verify_new_storage_return_message(return_msg, true);
370
371 // mock an ota container update
372 c_mock.UpdateFiles(
373 updated_package_map_, updated_flag_map_, updated_flag_val_, updated_flag_info_);
374
375 // force update
376 request_msg = new_storage_message(c_mock);
377 return_msg = a_mock.SendRequestToSocket(request_msg);
378 verify_new_storage_return_message(return_msg, true);
379
380 auto digest = GetFilesDigest(
381 {c_mock.package_map, c_mock.flag_map, c_mock.flag_val, c_mock.flag_info});
382 ASSERT_TRUE(digest.ok());
383
384 // verify the record exists in persist records pb
385 auto persist_records_pb = PersistStorageRecords();
386 auto content = std::string();
387 ASSERT_TRUE(base::ReadFileToString(a_mock.persist_pb, &content))
388 << strerror(errno);
389 ASSERT_TRUE(persist_records_pb.ParseFromString(content)) << strerror(errno);
390 bool found = false;
391 for (auto& entry : persist_records_pb.records()) {
392 if (entry.container() == "mockup") {
393 found = true;
394 ASSERT_EQ(entry.version(), 1);
395 ASSERT_EQ(entry.package_map(), c_mock.package_map);
396 ASSERT_EQ(entry.flag_map(), c_mock.flag_map);
397 ASSERT_EQ(entry.flag_val(), c_mock.flag_val);
398 ASSERT_EQ(entry.flag_info(), c_mock.flag_info);
399 ASSERT_EQ(entry.digest(), *digest);
400 break;
401 }
402 }
403 ASSERT_TRUE(found);
404
405 // verify persist and boot files
406 verify_equal_file_content(a_mock.maps_dir + "/mockup.package.map", updated_package_map_);
407 verify_equal_file_content(a_mock.maps_dir + "/mockup.flag.map", updated_flag_map_);
408 verify_equal_file_content(a_mock.flags_dir + "/mockup.val", updated_flag_val_);
409 verify_equal_file_content(a_mock.flags_dir + "/mockup.info", updated_flag_info_);
410
411 // the boot copy should never be updated
412 verify_equal_file_content(a_mock.boot_dir + "/mockup.val", flag_val_);
413 verify_equal_file_content(a_mock.boot_dir + "/mockup.info", flag_info_);
414 }
415
TEST_F(AconfigdTest,server_override)416 TEST_F(AconfigdTest, server_override) {
417 auto a_mock = AconfigdMock();
418 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
419
420 auto request_msg = new_storage_message(c_mock);
421 auto return_msg = a_mock.SendRequestToSocket(request_msg);
422 verify_new_storage_return_message(return_msg, true);
423
424 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
425 "enabled_rw", "false", false, false);
426 return_msg = a_mock.SendRequestToSocket(request_msg);
427 verify_flag_override_return_message(return_msg);
428
429 request_msg = flag_query_message(
430 "com.android.aconfig.storage.test_1", "enabled_rw");
431 return_msg = a_mock.SendRequestToSocket(request_msg);
432 verify_flag_query_return_message(
433 return_msg, "com.android.aconfig.storage.test_1", "enabled_rw", "false", "",
434 "true", "true", true, true, false);
435
436 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
437 "enabled_rw", "true", false, false);
438 return_msg = a_mock.SendRequestToSocket(request_msg);
439 verify_flag_override_return_message(return_msg);
440
441 request_msg = flag_query_message(
442 "com.android.aconfig.storage.test_1", "enabled_rw");
443 return_msg = a_mock.SendRequestToSocket(request_msg);
444 verify_flag_query_return_message(
445 return_msg, "com.android.aconfig.storage.test_1", "enabled_rw", "true", "",
446 "true", "true", true, true, false);
447 }
448
TEST_F(AconfigdTest,server_override_survive_update)449 TEST_F(AconfigdTest, server_override_survive_update) {
450 auto a_mock = AconfigdMock();
451 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
452
453 auto request_msg = new_storage_message(c_mock);
454 auto return_msg = a_mock.SendRequestToSocket(request_msg);
455 verify_new_storage_return_message(return_msg, true);
456
457 // create a server override
458 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
459 "enabled_rw", "false", false, false);
460 return_msg = a_mock.SendRequestToSocket(request_msg);
461 verify_flag_override_return_message(return_msg);
462
463 request_msg = flag_query_message(
464 "com.android.aconfig.storage.test_1", "enabled_rw");
465 return_msg = a_mock.SendRequestToSocket(request_msg);
466 verify_flag_query_return_message(
467 return_msg, "com.android.aconfig.storage.test_1", "enabled_rw", "false", "",
468 "true", "true", true, true, false);
469
470 // mock an ota container update
471 c_mock.UpdateFiles(
472 updated_package_map_, updated_flag_map_, updated_flag_val_, updated_flag_info_);
473
474 // force update
475 request_msg = new_storage_message(c_mock);
476 return_msg = a_mock.SendRequestToSocket(request_msg);
477 verify_new_storage_return_message(return_msg, true);
478
479 // server override should persist
480 request_msg = flag_query_message(
481 "com.android.aconfig.storage.test_1", "enabled_rw");
482 return_msg = a_mock.SendRequestToSocket(request_msg);
483 verify_flag_query_return_message(
484 return_msg, "com.android.aconfig.storage.test_1", "enabled_rw", "false", "",
485 "true", "true", true, true, false);
486 }
487
TEST_F_WITH_FLAGS(AconfigdTest,local_override_immediate,REQUIRES_FLAGS_ENABLED (ACONFIG_FLAG (ACONFIGD_NS,support_immediate_local_overrides)))488 TEST_F_WITH_FLAGS(AconfigdTest, local_override_immediate,
489 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(
490 ACONFIGD_NS, support_immediate_local_overrides))) {
491 auto a_mock = AconfigdMock();
492 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
493
494 auto request_msg = new_storage_message(c_mock);
495 auto return_msg = a_mock.SendRequestToSocket(request_msg);
496 verify_new_storage_return_message(return_msg, true);
497
498 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
499 "enabled_rw", "false", true, true);
500 return_msg = a_mock.SendRequestToSocket(request_msg);
501 verify_flag_override_return_message(return_msg);
502
503 request_msg =
504 flag_query_message("com.android.aconfig.storage.test_1", "enabled_rw");
505 return_msg = a_mock.SendRequestToSocket(request_msg);
506 verify_flag_query_return_message(
507 return_msg, "com.android.aconfig.storage.test_1", "enabled_rw", "",
508 "false", "false", "true", true, false, true);
509 }
510
TEST_F(AconfigdTest,local_override)511 TEST_F(AconfigdTest, local_override) {
512 auto a_mock = AconfigdMock();
513 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
514
515 auto request_msg = new_storage_message(c_mock);
516 auto return_msg = a_mock.SendRequestToSocket(request_msg);
517 verify_new_storage_return_message(return_msg, true);
518
519 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
520 "enabled_rw", "false", true, false);
521 return_msg = a_mock.SendRequestToSocket(request_msg);
522 verify_flag_override_return_message(return_msg);
523
524 request_msg = flag_query_message(
525 "com.android.aconfig.storage.test_1", "enabled_rw");
526 return_msg = a_mock.SendRequestToSocket(request_msg);
527 verify_flag_query_return_message(
528 return_msg, "com.android.aconfig.storage.test_1", "enabled_rw", "", "false",
529 "true", "true", true, false, true);
530
531 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
532 "enabled_rw", "true", true, false);
533 return_msg = a_mock.SendRequestToSocket(request_msg);
534 verify_flag_override_return_message(return_msg);
535
536 request_msg = flag_query_message(
537 "com.android.aconfig.storage.test_1", "enabled_rw");
538 return_msg = a_mock.SendRequestToSocket(request_msg);
539 verify_flag_query_return_message(
540 return_msg, "com.android.aconfig.storage.test_1", "enabled_rw", "", "true",
541 "true", "true", true, false, true);
542 }
543
TEST_F(AconfigdTest,local_override_survive_update)544 TEST_F(AconfigdTest, local_override_survive_update) {
545 auto a_mock = AconfigdMock();
546 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
547
548 auto request_msg = new_storage_message(c_mock);
549 auto return_msg = a_mock.SendRequestToSocket(request_msg);
550 verify_new_storage_return_message(return_msg, true);
551
552 // create a local override
553 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
554 "enabled_rw", "false", true, false);
555 return_msg = a_mock.SendRequestToSocket(request_msg);
556 verify_flag_override_return_message(return_msg);
557
558 request_msg = flag_query_message(
559 "com.android.aconfig.storage.test_1", "enabled_rw");
560 return_msg = a_mock.SendRequestToSocket(request_msg);
561 verify_flag_query_return_message(
562 return_msg, "com.android.aconfig.storage.test_1", "enabled_rw", "", "false",
563 "true", "true", true, false, true);
564
565 // mock an ota container update
566 c_mock.UpdateFiles(
567 updated_package_map_, updated_flag_map_, updated_flag_val_, updated_flag_info_);
568
569 // force update
570 request_msg = new_storage_message(c_mock);
571 return_msg = a_mock.SendRequestToSocket(request_msg);
572 verify_new_storage_return_message(return_msg, true);
573
574 // local override should persist
575 request_msg = flag_query_message(
576 "com.android.aconfig.storage.test_1", "enabled_rw");
577 return_msg = a_mock.SendRequestToSocket(request_msg);
578 verify_flag_query_return_message(
579 return_msg, "com.android.aconfig.storage.test_1", "enabled_rw", "", "false",
580 "true", "true", true, false, true);
581 }
582
TEST_F(AconfigdTest,single_local_override_remove)583 TEST_F(AconfigdTest, single_local_override_remove) {
584 auto a_mock = AconfigdMock();
585 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
586
587 auto request_msg = new_storage_message(c_mock);
588 auto return_msg = a_mock.SendRequestToSocket(request_msg);
589 verify_new_storage_return_message(return_msg, true);
590
591 // local override enabled_rw
592 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
593 "enabled_rw", "false", true, false);
594 return_msg = a_mock.SendRequestToSocket(request_msg);
595 verify_flag_override_return_message(return_msg);
596
597 // local override disabled_rw
598 request_msg = flag_override_message("com.android.aconfig.storage.test_2",
599 "disabled_rw", "true", true, false);
600 return_msg = a_mock.SendRequestToSocket(request_msg);
601 verify_flag_override_return_message(return_msg);
602
603 // remove local override enabled_rw
604 request_msg = flag_local_override_remove_message(
605 "com.android.aconfig.storage.test_1", "enabled_rw");
606 return_msg = a_mock.SendRequestToSocket(request_msg);
607 verify_local_override_remove_return_message(return_msg);
608
609 // enabled_rw local override should be gone
610 request_msg = flag_query_message(
611 "com.android.aconfig.storage.test_1", "enabled_rw");
612 return_msg = a_mock.SendRequestToSocket(request_msg);
613 verify_flag_query_return_message(
614 return_msg, "com.android.aconfig.storage.test_1", "enabled_rw", "", "",
615 "true", "true", true, false, false);
616
617 // disabled_rw local override should still exists
618 request_msg = flag_query_message(
619 "com.android.aconfig.storage.test_2", "disabled_rw");
620 return_msg = a_mock.SendRequestToSocket(request_msg);
621 verify_flag_query_return_message(
622 return_msg, "com.android.aconfig.storage.test_2", "disabled_rw", "", "true",
623 "false", "false", true, false, true);
624 }
625
TEST_F(AconfigdTest,readonly_flag_override)626 TEST_F(AconfigdTest, readonly_flag_override) {
627 auto a_mock = AconfigdMock();
628 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
629
630 auto request_msg = new_storage_message(c_mock);
631 auto return_msg = a_mock.SendRequestToSocket(request_msg);
632 verify_new_storage_return_message(return_msg, true);
633
634 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
635 "enabled_ro", "false", false, false);
636 return_msg = a_mock.SendRequestToSocket(request_msg);
637 verify_error_message(return_msg, "Cannot update read only flag");
638
639 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
640 "enabled_ro", "false", true, false);
641 return_msg = a_mock.SendRequestToSocket(request_msg);
642 verify_error_message(return_msg, "Cannot update read only flag");
643 }
644
TEST_F(AconfigdTest,nonexist_flag_override)645 TEST_F(AconfigdTest, nonexist_flag_override) {
646 auto a_mock = AconfigdMock();
647 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
648
649 auto request_msg = new_storage_message(c_mock);
650 auto return_msg = a_mock.SendRequestToSocket(request_msg);
651 verify_new_storage_return_message(return_msg, true);
652
653 request_msg =
654 flag_override_message("unknown", "enabled_rw", "false", false, false);
655 return_msg = a_mock.SendRequestToSocket(request_msg);
656 verify_error_message(return_msg, "Failed to find owning container");
657
658 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
659 "unknown", "false", false, false);
660 return_msg = a_mock.SendRequestToSocket(request_msg);
661 verify_error_message(return_msg, "Flag does not exist");
662 }
663
TEST_F(AconfigdTest,nonexist_flag_query)664 TEST_F(AconfigdTest, nonexist_flag_query) {
665 auto a_mock = AconfigdMock();
666 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
667
668 auto request_msg = new_storage_message(c_mock);
669 auto return_msg = a_mock.SendRequestToSocket(request_msg);
670 verify_new_storage_return_message(return_msg, true);
671
672 request_msg = flag_query_message("unknown", "enabled_rw");
673 return_msg = a_mock.SendRequestToSocket(request_msg);
674 verify_error_message(return_msg, "Failed to find owning container");
675
676 request_msg = flag_query_message("com.android.aconfig.storage.test_1", "unknown");
677 return_msg = a_mock.SendRequestToSocket(request_msg);
678 verify_error_message(return_msg, "unknown does not exist");
679 }
680
TEST_F(AconfigdTest,storage_reset)681 TEST_F(AconfigdTest, storage_reset) {
682 auto a_mock = AconfigdMock();
683 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
684
685 auto request_msg = new_storage_message(c_mock);
686 auto return_msg = a_mock.SendRequestToSocket(request_msg);
687 verify_new_storage_return_message(return_msg, true);
688
689 // server override enabled_rw
690 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
691 "enabled_rw", "false", false, false);
692 return_msg = a_mock.SendRequestToSocket(request_msg);
693 verify_flag_override_return_message(return_msg);
694
695 // local override disabled_rw
696 request_msg = flag_override_message("com.android.aconfig.storage.test_2",
697 "disabled_rw", "true", true, false);
698 return_msg = a_mock.SendRequestToSocket(request_msg);
699 verify_flag_override_return_message(return_msg);
700
701 // storage reset
702 request_msg = reset_storage_message();
703 return_msg = a_mock.SendRequestToSocket(request_msg);
704 verify_reset_storage_message(return_msg);
705
706 // enabled_rw server override should be gone
707 request_msg = flag_query_message(
708 "com.android.aconfig.storage.test_1", "enabled_rw");
709 return_msg = a_mock.SendRequestToSocket(request_msg);
710 verify_flag_query_return_message(
711 return_msg, "com.android.aconfig.storage.test_1", "enabled_rw", "", "",
712 "true", "true", true, false, false);
713
714 // disabled_rw local override should be gone
715 request_msg = flag_query_message(
716 "com.android.aconfig.storage.test_2", "disabled_rw");
717 return_msg = a_mock.SendRequestToSocket(request_msg);
718 verify_flag_query_return_message(
719 return_msg, "com.android.aconfig.storage.test_2", "disabled_rw", "", "",
720 "false", "false", true, false, false);
721 }
722
TEST_F(AconfigdTest,list_package)723 TEST_F(AconfigdTest, list_package) {
724 auto a_mock = AconfigdMock();
725 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
726
727 auto request_msg = new_storage_message(c_mock);
728 auto return_msg = a_mock.SendRequestToSocket(request_msg);
729 verify_new_storage_return_message(return_msg, true);
730
731 // server override disabled_rw
732 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
733 "disabled_rw", "true", false, false);
734 return_msg = a_mock.SendRequestToSocket(request_msg);
735 verify_flag_override_return_message(return_msg);
736
737 // local override enabled_rw
738 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
739 "enabled_rw", "false", true, false);
740 return_msg = a_mock.SendRequestToSocket(request_msg);
741 verify_flag_override_return_message(return_msg);
742
743 // list package
744 request_msg = list_package_storage_message("com.android.aconfig.storage.test_1");
745 return_msg = a_mock.SendRequestToSocket(request_msg);
746 ASSERT_TRUE(return_msg.ok()) << return_msg.error();
747 auto flags_msg = return_msg->list_storage_message();
748 ASSERT_EQ(flags_msg.flags_size(), 3);
749 verify_flag_query_return_message(
750 flags_msg.flags(0), "com.android.aconfig.storage.test_1", "disabled_rw",
751 "true", "", "false", "false", true, true, false);
752 verify_flag_query_return_message(
753 flags_msg.flags(1), "com.android.aconfig.storage.test_1", "enabled_ro",
754 "", "", "true", "true", false, false, false);
755 verify_flag_query_return_message(
756 flags_msg.flags(2), "com.android.aconfig.storage.test_1", "enabled_rw",
757 "", "false", "true", "true", true, false, true);
758 }
759
TEST_F(AconfigdTest,list_container)760 TEST_F(AconfigdTest, list_container) {
761 auto a_mock = AconfigdMock();
762 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
763
764 auto request_msg = new_storage_message(c_mock);
765 auto return_msg = a_mock.SendRequestToSocket(request_msg);
766 verify_new_storage_return_message(return_msg, true);
767
768 // server override test1.disabled_rw
769 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
770 "disabled_rw", "true", false, false);
771 return_msg = a_mock.SendRequestToSocket(request_msg);
772 verify_flag_override_return_message(return_msg);
773
774 // local override test2.disabled_rw
775 request_msg = flag_override_message("com.android.aconfig.storage.test_2",
776 "disabled_rw", "false", true, false);
777 return_msg = a_mock.SendRequestToSocket(request_msg);
778 verify_flag_override_return_message(return_msg);
779
780 // list container
781 request_msg = list_container_storage_message("mockup");
782 return_msg = a_mock.SendRequestToSocket(request_msg);
783 ASSERT_TRUE(return_msg.ok()) << return_msg.error();
784 auto flags_msg = return_msg->list_storage_message();
785 ASSERT_EQ(flags_msg.flags_size(), 8);
786 verify_flag_query_return_message(
787 flags_msg.flags(0), "com.android.aconfig.storage.test_1", "disabled_rw",
788 "true", "", "false", "false", true, true, false);
789 verify_flag_query_return_message(
790 flags_msg.flags(1), "com.android.aconfig.storage.test_1", "enabled_ro",
791 "", "", "true", "true", false, false, false);
792 verify_flag_query_return_message(
793 flags_msg.flags(2), "com.android.aconfig.storage.test_1", "enabled_rw",
794 "", "", "true", "true", true, false, false);
795 verify_flag_query_return_message(
796 flags_msg.flags(3), "com.android.aconfig.storage.test_2", "disabled_rw",
797 "", "false", "false", "false", true, false, true);
798 verify_flag_query_return_message(
799 flags_msg.flags(4), "com.android.aconfig.storage.test_2", "enabled_fixed_ro",
800 "", "", "true", "true", false, false, false);
801 verify_flag_query_return_message(
802 flags_msg.flags(5), "com.android.aconfig.storage.test_2", "enabled_ro",
803 "", "", "true", "true", false, false, false);
804 verify_flag_query_return_message(
805 flags_msg.flags(6), "com.android.aconfig.storage.test_4", "enabled_fixed_ro",
806 "", "", "true", "true", false, false, false);
807 verify_flag_query_return_message(
808 flags_msg.flags(7), "com.android.aconfig.storage.test_4", "enabled_rw",
809 "", "", "true", "true", true, false, false);
810 }
811
TEST_F(AconfigdTest,list_all)812 TEST_F(AconfigdTest, list_all) {
813 auto a_mock = AconfigdMock();
814 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
815
816 auto request_msg = new_storage_message(c_mock);
817 auto return_msg = a_mock.SendRequestToSocket(request_msg);
818 verify_new_storage_return_message(return_msg, true);
819
820 // server override test1.disabled_rw
821 request_msg = flag_override_message("com.android.aconfig.storage.test_1",
822 "disabled_rw", "true", false, false);
823 return_msg = a_mock.SendRequestToSocket(request_msg);
824 verify_flag_override_return_message(return_msg);
825
826 // local override test2.disabled_rw
827 request_msg = flag_override_message("com.android.aconfig.storage.test_2",
828 "disabled_rw", "false", true, false);
829 return_msg = a_mock.SendRequestToSocket(request_msg);
830 verify_flag_override_return_message(return_msg);
831
832 // list all storage
833 request_msg = list_storage_message();
834 return_msg = a_mock.SendRequestToSocket(request_msg);
835 ASSERT_TRUE(return_msg.ok()) << return_msg.error();
836 auto flags_msg = return_msg->list_storage_message();
837 ASSERT_EQ(flags_msg.flags_size(), 8);
838 verify_flag_query_return_message(
839 flags_msg.flags(0), "com.android.aconfig.storage.test_1", "disabled_rw",
840 "true", "", "false", "false", true, true, false);
841 verify_flag_query_return_message(
842 flags_msg.flags(1), "com.android.aconfig.storage.test_1", "enabled_ro",
843 "", "", "true", "true", false, false, false);
844 verify_flag_query_return_message(
845 flags_msg.flags(2), "com.android.aconfig.storage.test_1", "enabled_rw",
846 "", "", "true", "true", true, false, false);
847 verify_flag_query_return_message(
848 flags_msg.flags(3), "com.android.aconfig.storage.test_2", "disabled_rw",
849 "", "false", "false", "false", true, false, true);
850 verify_flag_query_return_message(
851 flags_msg.flags(4), "com.android.aconfig.storage.test_2", "enabled_fixed_ro",
852 "", "", "true", "true", false, false, false);
853 verify_flag_query_return_message(
854 flags_msg.flags(5), "com.android.aconfig.storage.test_2", "enabled_ro",
855 "", "", "true", "true", false, false, false);
856 verify_flag_query_return_message(
857 flags_msg.flags(6), "com.android.aconfig.storage.test_4", "enabled_fixed_ro",
858 "", "", "true", "true", false, false, false);
859 verify_flag_query_return_message(
860 flags_msg.flags(7), "com.android.aconfig.storage.test_4", "enabled_rw",
861 "", "", "true", "true", true, false, false);
862 }
863
TEST_F(AconfigdTest,list_nonexist_package)864 TEST_F(AconfigdTest, list_nonexist_package) {
865 auto a_mock = AconfigdMock();
866 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
867
868 auto request_msg = new_storage_message(c_mock);
869 auto return_msg = a_mock.SendRequestToSocket(request_msg);
870 verify_new_storage_return_message(return_msg, true);
871
872 request_msg = list_package_storage_message("unknown");
873 return_msg = a_mock.SendRequestToSocket(request_msg);
874 verify_error_message(return_msg, "container not found");
875 }
876
TEST_F(AconfigdTest,list_nonexist_container)877 TEST_F(AconfigdTest, list_nonexist_container) {
878 auto a_mock = AconfigdMock();
879 auto c_mock = ContainerMock("mockup", package_map_, flag_map_, flag_val_, flag_info_);
880
881 auto request_msg = new_storage_message(c_mock);
882 auto return_msg = a_mock.SendRequestToSocket(request_msg);
883 verify_new_storage_return_message(return_msg, true);
884
885 request_msg = list_container_storage_message("unknown");
886 return_msg = a_mock.SendRequestToSocket(request_msg);
887 verify_error_message(return_msg, "Missing storage files object");
888 }
889
890 } // namespace aconfigd
891 } // namespace android
892