1 /*
2  * Copyright (C) 2018 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 "server_configurable_flags/disaster_recovery.h"
18 #include "server_configurable_flags/get_flags.h"
19 
20 #include <gtest/gtest.h>
21 
22 #include <algorithm>
23 #include <string>
24 #include <vector>
25 
26 #include "android-base/file.h"
27 #include "android-base/properties.h"
28 #include "android-base/strings.h"
29 
30 using namespace server_configurable_flags;
31 using namespace android::base;
32 
contains(std::vector<std::string> & vec,std::string & str)33 static bool contains(std::vector<std::string>& vec, std::string& str) {
34   return std::find(vec.begin(), vec.end(), str) != vec.end();
35 }
36 
TEST(server_configurable_flags,empty_flag_returns_default)37 TEST(server_configurable_flags, empty_flag_returns_default) {
38   std::string result =
39       server_configurable_flags::GetServerConfigurableFlag("category", "flag", "default");
40   ASSERT_EQ("default", result);
41 }
42 
TEST(server_configurable_flags,set_flag_returns_value)43 TEST(server_configurable_flags, set_flag_returns_value) {
44   android::base::SetProperty("persist.device_config.category.flag", "hello");
45   std::string result =
46       server_configurable_flags::GetServerConfigurableFlag("category", "flag", "default");
47   ASSERT_EQ("hello", result);
48 
49   // clean up
50   android::base::SetProperty("persist.device_config.category.flag", "");
51 }
52 
TEST(server_configurable_flags,invalid_flag_returns_default)53 TEST(server_configurable_flags, invalid_flag_returns_default) {
54   std::string result =
55       server_configurable_flags::GetServerConfigurableFlag("category.", "flag", "default");
56   ASSERT_EQ("default", result);
57 
58   result = server_configurable_flags::GetServerConfigurableFlag("category", "!flag", "default");
59   ASSERT_EQ("default", result);
60 
61   result = server_configurable_flags::GetServerConfigurableFlag("category", ".flag", "default");
62   ASSERT_EQ("default", result);
63 }
64 
TEST(server_configurable_flags,flags_reset_skip_under_threshold)65 TEST(server_configurable_flags, flags_reset_skip_under_threshold) {
66 #if defined(__BIONIC__)
67   android::base::SetProperty("persist.device_config.attempted_boot_count", "1");
68   android::base::SetProperty("persist.device_config.category1.prop1", "val1");
69   android::base::SetProperty("persist.device_config.category1.prop2", "val2");
70   android::base::SetProperty("persist.device_config.category2.prop3", "val3");
71   android::base::SetProperty("sys.category3.test", "val4");
72   android::base::SetProperty("device_config.reset_performed", "");
73 
74   server_configurable_flags::ServerConfigurableFlagsReset(server_configurable_flags::BOOT_FAILURE);
75 
76   ASSERT_EQ("2", android::base::GetProperty("persist.device_config.attempted_boot_count", ""));
77   ASSERT_EQ("val1", android::base::GetProperty("persist.device_config.category1.prop1", ""));
78   ASSERT_EQ("val2", android::base::GetProperty("persist.device_config.category1.prop2", ""));
79   ASSERT_EQ("val3", android::base::GetProperty("persist.device_config.category2.prop3", ""));
80   ASSERT_EQ("val4", android::base::GetProperty("sys.category3.test", ""));
81   ASSERT_EQ("", android::base::GetProperty("device_config.reset_performed", ""));
82 #else   // __BIONIC__
83   GTEST_LOG_(INFO) << "This test does nothing.\n";
84 #endif  // __BIONIC__
85 }
86 
TEST(server_configurable_flags,flags_reset_performed_over_threshold)87 TEST(server_configurable_flags, flags_reset_performed_over_threshold) {
88 #if defined(__BIONIC__)
89   android::base::SetProperty("persist.device_config.attempted_boot_count", "5");
90   android::base::SetProperty("persist.device_config.category1.prop1", "val1");
91   android::base::SetProperty("persist.device_config.category1.prop2", "val2");
92   android::base::SetProperty("persist.device_config.category2.prop3", "val3");
93   android::base::SetProperty("sys.category3.test", "val4");
94 
95   server_configurable_flags::ServerConfigurableFlagsReset(server_configurable_flags::BOOT_FAILURE);
96 
97   ASSERT_EQ("true", android::base::GetProperty("device_config.reset_performed", ""));
98   ASSERT_EQ("5", android::base::GetProperty("persist.device_config.attempted_boot_count", ""));
99   ASSERT_EQ("", android::base::GetProperty("persist.device_config.category1.prop1", ""));
100   ASSERT_EQ("", android::base::GetProperty("persist.device_config.category1.prop2", ""));
101   ASSERT_EQ("", android::base::GetProperty("persist.device_config.category2.prop3", ""));
102   ASSERT_EQ("val4", android::base::GetProperty("sys.category3.test", ""));
103 
104   std::string content;
105   ASSERT_EQ(true, ReadFileToString("/data/server_configurable_flags/reset_flags", &content));
106   std::vector<std::string> properties = Split(content, ";");
107   ASSERT_EQ((unsigned long)3, properties.size());
108   std::string prop1("persist.device_config.category1.prop1"),
109       prop2("persist.device_config.category1.prop2"),
110       prop3("persist.device_config.category2.prop3");
111   ASSERT_EQ(true, contains(properties, prop1));
112   ASSERT_EQ(true, contains(properties, prop2));
113   ASSERT_EQ(true, contains(properties, prop3));
114 #else   // __BIONIC__
115   GTEST_LOG_(INFO) << "This test does nothing.\n";
116 #endif  // __BIONIC__
117 }
118 
TEST(server_configurable_flags,flags_reset_performed_on_updatable_crashing)119 TEST(server_configurable_flags, flags_reset_performed_on_updatable_crashing) {
120 #if defined(__BIONIC__)
121   android::base::SetProperty("persist.device_config.attempted_boot_count", "1");
122   android::base::SetProperty("persist.device_config.category1.prop1", "val1");
123   android::base::SetProperty("persist.device_config.category1.prop2", "val2");
124   android::base::SetProperty("persist.device_config.category2.prop3", "val3");
125   android::base::SetProperty("sys.category3.test", "val4");
126 
127   server_configurable_flags::ServerConfigurableFlagsReset(
128       server_configurable_flags::UPDATABLE_CRASHING);
129 
130   ASSERT_EQ("true", android::base::GetProperty("device_config.reset_performed", ""));
131   ASSERT_EQ("1", android::base::GetProperty("persist.device_config.attempted_boot_count", ""));
132   ASSERT_EQ("", android::base::GetProperty("persist.device_config.category1.prop1", ""));
133   ASSERT_EQ("", android::base::GetProperty("persist.device_config.category1.prop2", ""));
134   ASSERT_EQ("", android::base::GetProperty("persist.device_config.category2.prop3", ""));
135   ASSERT_EQ("val4", android::base::GetProperty("sys.category3.test", ""));
136 
137   std::string content;
138   ASSERT_EQ(true, ReadFileToString("/data/server_configurable_flags/reset_flags", &content));
139   std::vector<std::string> properties = Split(content, ";");
140   ASSERT_EQ((unsigned long)3, properties.size());
141   std::string prop1("persist.device_config.category1.prop1"),
142       prop2("persist.device_config.category1.prop2"),
143       prop3("persist.device_config.category2.prop3");
144   ASSERT_EQ(true, contains(properties, prop1));
145   ASSERT_EQ(true, contains(properties, prop2));
146   ASSERT_EQ(true, contains(properties, prop3));
147 #else   // __BIONIC__
148   GTEST_LOG_(INFO) << "This test does nothing.\n";
149 #endif  // __BIONIC__
150 }
151