• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 "android-base/properties.h"
18 
19 #include <gtest/gtest.h>
20 
21 #include <atomic>
22 #include <chrono>
23 #include <string>
24 #include <thread>
25 
26 #if !defined(_WIN32)
27 using namespace std::literals;
28 #endif
29 
TEST(properties,smoke)30 TEST(properties, smoke) {
31   android::base::SetProperty("debug.libbase.property_test", "hello");
32 
33   std::string s = android::base::GetProperty("debug.libbase.property_test", "");
34   ASSERT_EQ("hello", s);
35 
36   android::base::SetProperty("debug.libbase.property_test", "world");
37   s = android::base::GetProperty("debug.libbase.property_test", "");
38   ASSERT_EQ("world", s);
39 
40   s = android::base::GetProperty("this.property.does.not.exist", "");
41   ASSERT_EQ("", s);
42 
43   s = android::base::GetProperty("this.property.does.not.exist", "default");
44   ASSERT_EQ("default", s);
45 }
46 
TEST(properties,empty)47 TEST(properties, empty) {
48   // Because you can't delete a property, people "delete" them by
49   // setting them to the empty string. In that case we'd want to
50   // keep the default value (like cutils' property_get did).
51   android::base::SetProperty("debug.libbase.property_test", "");
52   std::string s = android::base::GetProperty("debug.libbase.property_test", "default");
53   ASSERT_EQ("default", s);
54 }
55 
CheckGetBoolProperty(bool expected,const std::string & value,bool default_value)56 static void CheckGetBoolProperty(bool expected, const std::string& value, bool default_value) {
57   android::base::SetProperty("debug.libbase.property_test", value.c_str());
58   ASSERT_EQ(expected, android::base::GetBoolProperty("debug.libbase.property_test", default_value));
59 }
60 
TEST(properties,GetBoolProperty_true)61 TEST(properties, GetBoolProperty_true) {
62   CheckGetBoolProperty(true, "1", false);
63   CheckGetBoolProperty(true, "y", false);
64   CheckGetBoolProperty(true, "yes", false);
65   CheckGetBoolProperty(true, "on", false);
66   CheckGetBoolProperty(true, "true", false);
67 }
68 
TEST(properties,GetBoolProperty_false)69 TEST(properties, GetBoolProperty_false) {
70   CheckGetBoolProperty(false, "0", true);
71   CheckGetBoolProperty(false, "n", true);
72   CheckGetBoolProperty(false, "no", true);
73   CheckGetBoolProperty(false, "off", true);
74   CheckGetBoolProperty(false, "false", true);
75 }
76 
TEST(properties,GetBoolProperty_default)77 TEST(properties, GetBoolProperty_default) {
78   CheckGetBoolProperty(true, "burp", true);
79   CheckGetBoolProperty(false, "burp", false);
80 }
81 
CheckGetIntProperty()82 template <typename T> void CheckGetIntProperty() {
83   // Positive and negative.
84   android::base::SetProperty("debug.libbase.property_test", "-12");
85   EXPECT_EQ(T(-12), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
86   android::base::SetProperty("debug.libbase.property_test", "12");
87   EXPECT_EQ(T(12), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
88 
89   // Default value.
90   android::base::SetProperty("debug.libbase.property_test", "");
91   EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
92 
93   // Bounds checks.
94   android::base::SetProperty("debug.libbase.property_test", "0");
95   EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
96   android::base::SetProperty("debug.libbase.property_test", "1");
97   EXPECT_EQ(T(1), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
98   android::base::SetProperty("debug.libbase.property_test", "2");
99   EXPECT_EQ(T(2), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
100   android::base::SetProperty("debug.libbase.property_test", "3");
101   EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
102 }
103 
CheckGetUintProperty()104 template <typename T> void CheckGetUintProperty() {
105   // Positive.
106   android::base::SetProperty("debug.libbase.property_test", "12");
107   EXPECT_EQ(T(12), android::base::GetUintProperty<T>("debug.libbase.property_test", 45));
108 
109   // Default value.
110   android::base::SetProperty("debug.libbase.property_test", "");
111   EXPECT_EQ(T(45), android::base::GetUintProperty<T>("debug.libbase.property_test", 45));
112 
113   // Bounds checks.
114   android::base::SetProperty("debug.libbase.property_test", "12");
115   EXPECT_EQ(T(12), android::base::GetUintProperty<T>("debug.libbase.property_test", 33, 22));
116   android::base::SetProperty("debug.libbase.property_test", "12");
117   EXPECT_EQ(T(5), android::base::GetUintProperty<T>("debug.libbase.property_test", 5, 10));
118 }
119 
TEST(properties,GetIntProperty_int8_t)120 TEST(properties, GetIntProperty_int8_t) { CheckGetIntProperty<int8_t>(); }
TEST(properties,GetIntProperty_int16_t)121 TEST(properties, GetIntProperty_int16_t) { CheckGetIntProperty<int16_t>(); }
TEST(properties,GetIntProperty_int32_t)122 TEST(properties, GetIntProperty_int32_t) { CheckGetIntProperty<int32_t>(); }
TEST(properties,GetIntProperty_int64_t)123 TEST(properties, GetIntProperty_int64_t) { CheckGetIntProperty<int64_t>(); }
124 
TEST(properties,GetUintProperty_uint8_t)125 TEST(properties, GetUintProperty_uint8_t) { CheckGetUintProperty<uint8_t>(); }
TEST(properties,GetUintProperty_uint16_t)126 TEST(properties, GetUintProperty_uint16_t) { CheckGetUintProperty<uint16_t>(); }
TEST(properties,GetUintProperty_uint32_t)127 TEST(properties, GetUintProperty_uint32_t) { CheckGetUintProperty<uint32_t>(); }
TEST(properties,GetUintProperty_uint64_t)128 TEST(properties, GetUintProperty_uint64_t) { CheckGetUintProperty<uint64_t>(); }
129 
TEST(properties,WaitForProperty)130 TEST(properties, WaitForProperty) {
131 #if defined(__BIONIC__)
132   std::atomic<bool> flag{false};
133   std::thread thread([&]() {
134     std::this_thread::sleep_for(100ms);
135     android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
136     while (!flag) std::this_thread::yield();
137     android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
138   });
139 
140   ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
141   flag = true;
142   ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", 1s));
143   thread.join();
144 #else
145   GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
146 #endif
147 }
148 
TEST(properties,WaitForProperty_timeout)149 TEST(properties, WaitForProperty_timeout) {
150 #if defined(__BIONIC__)
151   auto t0 = std::chrono::steady_clock::now();
152   ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_timeout_test", "a",
153                                               200ms));
154   auto t1 = std::chrono::steady_clock::now();
155 
156   ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms);
157   // Upper bounds on timing are inherently flaky, but let's try...
158   ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms);
159 #else
160   GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
161 #endif
162 }
163 
TEST(properties,WaitForProperty_MaxTimeout)164 TEST(properties, WaitForProperty_MaxTimeout) {
165 #if defined(__BIONIC__)
166   std::atomic<bool> flag{false};
167   std::thread thread([&]() {
168     android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
169     while (!flag) std::this_thread::yield();
170     std::this_thread::sleep_for(500ms);
171     android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
172   });
173 
174   ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
175   flag = true;
176   // Test that this does not immediately return false due to overflow issues with the timeout.
177   ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b"));
178   thread.join();
179 #else
180   GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
181 #endif
182 }
183 
TEST(properties,WaitForProperty_NegativeTimeout)184 TEST(properties, WaitForProperty_NegativeTimeout) {
185 #if defined(__BIONIC__)
186   std::atomic<bool> flag{false};
187   std::thread thread([&]() {
188     android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
189     while (!flag) std::this_thread::yield();
190     std::this_thread::sleep_for(500ms);
191     android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
192   });
193 
194   ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
195   flag = true;
196   // Assert that this immediately returns with a negative timeout
197   ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", -100ms));
198   thread.join();
199 #else
200   GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
201 #endif
202 }
203 
TEST(properties,WaitForPropertyCreation)204 TEST(properties, WaitForPropertyCreation) {
205 #if defined(__BIONIC__)
206   std::thread thread([&]() {
207     std::this_thread::sleep_for(100ms);
208     android::base::SetProperty("debug.libbase.WaitForPropertyCreation_test", "a");
209   });
210 
211   ASSERT_TRUE(android::base::WaitForPropertyCreation(
212           "debug.libbase.WaitForPropertyCreation_test", 1s));
213   thread.join();
214 #else
215   GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
216 #endif
217 }
218 
TEST(properties,WaitForPropertyCreation_timeout)219 TEST(properties, WaitForPropertyCreation_timeout) {
220 #if defined(__BIONIC__)
221   auto t0 = std::chrono::steady_clock::now();
222   ASSERT_FALSE(android::base::WaitForPropertyCreation(
223           "debug.libbase.WaitForPropertyCreation_timeout_test", 200ms));
224   auto t1 = std::chrono::steady_clock::now();
225 
226   ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms);
227   // Upper bounds on timing are inherently flaky, but let's try...
228   ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms);
229 #else
230   GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
231 #endif
232 }
233 
TEST(properties,CachedProperty)234 TEST(properties, CachedProperty) {
235 #if defined(__BIONIC__)
236   android::base::CachedProperty cached_property("debug.libbase.CachedProperty_test");
237   bool changed;
238   cached_property.Get(&changed);
239 
240   android::base::SetProperty("debug.libbase.CachedProperty_test", "foo");
241   ASSERT_STREQ("foo", cached_property.Get(&changed));
242   ASSERT_TRUE(changed);
243 
244   ASSERT_STREQ("foo", cached_property.Get(&changed));
245   ASSERT_FALSE(changed);
246 
247   android::base::SetProperty("debug.libbase.CachedProperty_test", "bar");
248   ASSERT_STREQ("bar", cached_property.Get(&changed));
249   ASSERT_TRUE(changed);
250 
251   ASSERT_STREQ("bar", cached_property.Get(&changed));
252   ASSERT_FALSE(changed);
253 
254 #else
255   GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
256 #endif
257 }
258