xref: /aosp_15_r20/system/server_configurable_flags/aconfigd/aconfigd_test.cpp (revision 207333786ba243bc7d4d69ef6b05487aa7071806)
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