1*8f0ba417SAndroid Build Coastguard Worker /*
2*8f0ba417SAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project
3*8f0ba417SAndroid Build Coastguard Worker *
4*8f0ba417SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8f0ba417SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8f0ba417SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8f0ba417SAndroid Build Coastguard Worker *
8*8f0ba417SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8f0ba417SAndroid Build Coastguard Worker *
10*8f0ba417SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8f0ba417SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8f0ba417SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8f0ba417SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8f0ba417SAndroid Build Coastguard Worker * limitations under the License.
15*8f0ba417SAndroid Build Coastguard Worker */
16*8f0ba417SAndroid Build Coastguard Worker
17*8f0ba417SAndroid Build Coastguard Worker #include "android-base/properties.h"
18*8f0ba417SAndroid Build Coastguard Worker
19*8f0ba417SAndroid Build Coastguard Worker #include <unistd.h>
20*8f0ba417SAndroid Build Coastguard Worker
21*8f0ba417SAndroid Build Coastguard Worker #include <gtest/gtest.h>
22*8f0ba417SAndroid Build Coastguard Worker
23*8f0ba417SAndroid Build Coastguard Worker #include <atomic>
24*8f0ba417SAndroid Build Coastguard Worker #include <chrono>
25*8f0ba417SAndroid Build Coastguard Worker #include <string>
26*8f0ba417SAndroid Build Coastguard Worker #include <thread>
27*8f0ba417SAndroid Build Coastguard Worker
28*8f0ba417SAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
29*8f0ba417SAndroid Build Coastguard Worker
30*8f0ba417SAndroid Build Coastguard Worker #if !defined(_WIN32)
31*8f0ba417SAndroid Build Coastguard Worker using namespace std::literals;
32*8f0ba417SAndroid Build Coastguard Worker #endif
33*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,smoke)34*8f0ba417SAndroid Build Coastguard Worker TEST(properties, smoke) {
35*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "hello");
36*8f0ba417SAndroid Build Coastguard Worker
37*8f0ba417SAndroid Build Coastguard Worker std::string s = android::base::GetProperty("debug.libbase.property_test", "");
38*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ("hello", s);
39*8f0ba417SAndroid Build Coastguard Worker
40*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "world");
41*8f0ba417SAndroid Build Coastguard Worker s = android::base::GetProperty("debug.libbase.property_test", "");
42*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ("world", s);
43*8f0ba417SAndroid Build Coastguard Worker
44*8f0ba417SAndroid Build Coastguard Worker s = android::base::GetProperty("this.property.does.not.exist", "");
45*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ("", s);
46*8f0ba417SAndroid Build Coastguard Worker
47*8f0ba417SAndroid Build Coastguard Worker s = android::base::GetProperty("this.property.does.not.exist", "default");
48*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ("default", s);
49*8f0ba417SAndroid Build Coastguard Worker }
50*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,too_long)51*8f0ba417SAndroid Build Coastguard Worker TEST(properties, too_long) {
52*8f0ba417SAndroid Build Coastguard Worker #if !defined(_WIN32)
53*8f0ba417SAndroid Build Coastguard Worker if (getuid() != 0) {
54*8f0ba417SAndroid Build Coastguard Worker GTEST_SKIP() << "Skipping test, must be run as root.";
55*8f0ba417SAndroid Build Coastguard Worker }
56*8f0ba417SAndroid Build Coastguard Worker #endif
57*8f0ba417SAndroid Build Coastguard Worker // Properties have a fixed limit on the size of their value.
58*8f0ba417SAndroid Build Coastguard Worker std::string key("debug.libbase.property_too_long");
59*8f0ba417SAndroid Build Coastguard Worker std::string value(92, 'a');
60*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::SetProperty(key, value));
61*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ("missing", android::base::GetProperty(key, "missing"));
62*8f0ba417SAndroid Build Coastguard Worker
63*8f0ba417SAndroid Build Coastguard Worker // Except for "ro." properties, which can have arbitrarily-long values.
64*8f0ba417SAndroid Build Coastguard Worker key = "ro." + key + std::to_string(time(nullptr));
65*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::SetProperty(key, value));
66*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(value, android::base::GetProperty(key, "missing"));
67*8f0ba417SAndroid Build Coastguard Worker // ...because you can't change them.
68*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::SetProperty(key, "hello"));
69*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(value, android::base::GetProperty(key, "missing"));
70*8f0ba417SAndroid Build Coastguard Worker }
71*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,empty_key)72*8f0ba417SAndroid Build Coastguard Worker TEST(properties, empty_key) {
73*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::SetProperty("", "hello"));
74*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ("default", android::base::GetProperty("", "default"));
75*8f0ba417SAndroid Build Coastguard Worker }
76*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,empty_value)77*8f0ba417SAndroid Build Coastguard Worker TEST(properties, empty_value) {
78*8f0ba417SAndroid Build Coastguard Worker // Because you can't delete a property, people "delete" them by
79*8f0ba417SAndroid Build Coastguard Worker // setting them to the empty string. In that case we'd want to
80*8f0ba417SAndroid Build Coastguard Worker // keep the default value (like cutils' property_get did).
81*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::SetProperty("debug.libbase.property_empty_value", ""));
82*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ("default", android::base::GetProperty("debug.libbase.property_empty_value", "default"));
83*8f0ba417SAndroid Build Coastguard Worker }
84*8f0ba417SAndroid Build Coastguard Worker
CheckGetBoolProperty(bool expected,const std::string & value,bool default_value)85*8f0ba417SAndroid Build Coastguard Worker static void CheckGetBoolProperty(bool expected, const std::string& value, bool default_value) {
86*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", value.c_str());
87*8f0ba417SAndroid Build Coastguard Worker ASSERT_EQ(expected, android::base::GetBoolProperty("debug.libbase.property_test", default_value));
88*8f0ba417SAndroid Build Coastguard Worker }
89*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,GetBoolProperty_true)90*8f0ba417SAndroid Build Coastguard Worker TEST(properties, GetBoolProperty_true) {
91*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(true, "1", false);
92*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(true, "y", false);
93*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(true, "yes", false);
94*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(true, "on", false);
95*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(true, "true", false);
96*8f0ba417SAndroid Build Coastguard Worker }
97*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,GetBoolProperty_false)98*8f0ba417SAndroid Build Coastguard Worker TEST(properties, GetBoolProperty_false) {
99*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(false, "0", true);
100*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(false, "n", true);
101*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(false, "no", true);
102*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(false, "off", true);
103*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(false, "false", true);
104*8f0ba417SAndroid Build Coastguard Worker }
105*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,GetBoolProperty_default)106*8f0ba417SAndroid Build Coastguard Worker TEST(properties, GetBoolProperty_default) {
107*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(true, "burp", true);
108*8f0ba417SAndroid Build Coastguard Worker CheckGetBoolProperty(false, "burp", false);
109*8f0ba417SAndroid Build Coastguard Worker }
110*8f0ba417SAndroid Build Coastguard Worker
CheckGetIntProperty()111*8f0ba417SAndroid Build Coastguard Worker template <typename T> void CheckGetIntProperty() {
112*8f0ba417SAndroid Build Coastguard Worker // Positive and negative.
113*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "-12");
114*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(-12), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
115*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "12");
116*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(12), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
117*8f0ba417SAndroid Build Coastguard Worker
118*8f0ba417SAndroid Build Coastguard Worker // Default value.
119*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "");
120*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
121*8f0ba417SAndroid Build Coastguard Worker
122*8f0ba417SAndroid Build Coastguard Worker // Bounds checks.
123*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "0");
124*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
125*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "1");
126*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(1), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
127*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "2");
128*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(2), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
129*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "3");
130*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
131*8f0ba417SAndroid Build Coastguard Worker }
132*8f0ba417SAndroid Build Coastguard Worker
CheckGetUintProperty()133*8f0ba417SAndroid Build Coastguard Worker template <typename T> void CheckGetUintProperty() {
134*8f0ba417SAndroid Build Coastguard Worker // Positive.
135*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "12");
136*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(12), android::base::GetUintProperty<T>("debug.libbase.property_test", 45));
137*8f0ba417SAndroid Build Coastguard Worker
138*8f0ba417SAndroid Build Coastguard Worker // Default value.
139*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "");
140*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(45), android::base::GetUintProperty<T>("debug.libbase.property_test", 45));
141*8f0ba417SAndroid Build Coastguard Worker
142*8f0ba417SAndroid Build Coastguard Worker // Bounds checks.
143*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "12");
144*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(12), android::base::GetUintProperty<T>("debug.libbase.property_test", 33, 22));
145*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.property_test", "12");
146*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(T(5), android::base::GetUintProperty<T>("debug.libbase.property_test", 5, 10));
147*8f0ba417SAndroid Build Coastguard Worker }
148*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,GetIntProperty_int8_t)149*8f0ba417SAndroid Build Coastguard Worker TEST(properties, GetIntProperty_int8_t) { CheckGetIntProperty<int8_t>(); }
TEST(properties,GetIntProperty_int16_t)150*8f0ba417SAndroid Build Coastguard Worker TEST(properties, GetIntProperty_int16_t) { CheckGetIntProperty<int16_t>(); }
TEST(properties,GetIntProperty_int32_t)151*8f0ba417SAndroid Build Coastguard Worker TEST(properties, GetIntProperty_int32_t) { CheckGetIntProperty<int32_t>(); }
TEST(properties,GetIntProperty_int64_t)152*8f0ba417SAndroid Build Coastguard Worker TEST(properties, GetIntProperty_int64_t) { CheckGetIntProperty<int64_t>(); }
153*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,GetUintProperty_uint8_t)154*8f0ba417SAndroid Build Coastguard Worker TEST(properties, GetUintProperty_uint8_t) { CheckGetUintProperty<uint8_t>(); }
TEST(properties,GetUintProperty_uint16_t)155*8f0ba417SAndroid Build Coastguard Worker TEST(properties, GetUintProperty_uint16_t) { CheckGetUintProperty<uint16_t>(); }
TEST(properties,GetUintProperty_uint32_t)156*8f0ba417SAndroid Build Coastguard Worker TEST(properties, GetUintProperty_uint32_t) { CheckGetUintProperty<uint32_t>(); }
TEST(properties,GetUintProperty_uint64_t)157*8f0ba417SAndroid Build Coastguard Worker TEST(properties, GetUintProperty_uint64_t) { CheckGetUintProperty<uint64_t>(); }
158*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,WaitForProperty)159*8f0ba417SAndroid Build Coastguard Worker TEST(properties, WaitForProperty) {
160*8f0ba417SAndroid Build Coastguard Worker #if defined(__BIONIC__)
161*8f0ba417SAndroid Build Coastguard Worker std::atomic<bool> flag{false};
162*8f0ba417SAndroid Build Coastguard Worker std::thread thread([&]() {
163*8f0ba417SAndroid Build Coastguard Worker std::this_thread::sleep_for(100ms);
164*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
165*8f0ba417SAndroid Build Coastguard Worker while (!flag) std::this_thread::yield();
166*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
167*8f0ba417SAndroid Build Coastguard Worker });
168*8f0ba417SAndroid Build Coastguard Worker
169*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
170*8f0ba417SAndroid Build Coastguard Worker flag = true;
171*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", 1s));
172*8f0ba417SAndroid Build Coastguard Worker thread.join();
173*8f0ba417SAndroid Build Coastguard Worker #else
174*8f0ba417SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
175*8f0ba417SAndroid Build Coastguard Worker #endif
176*8f0ba417SAndroid Build Coastguard Worker }
177*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,WaitForProperty_timeout)178*8f0ba417SAndroid Build Coastguard Worker TEST(properties, WaitForProperty_timeout) {
179*8f0ba417SAndroid Build Coastguard Worker #if defined(__BIONIC__)
180*8f0ba417SAndroid Build Coastguard Worker auto t0 = std::chrono::steady_clock::now();
181*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_timeout_test", "a",
182*8f0ba417SAndroid Build Coastguard Worker 200ms));
183*8f0ba417SAndroid Build Coastguard Worker auto t1 = std::chrono::steady_clock::now();
184*8f0ba417SAndroid Build Coastguard Worker
185*8f0ba417SAndroid Build Coastguard Worker ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms);
186*8f0ba417SAndroid Build Coastguard Worker // Upper bounds on timing are inherently flaky, but let's try...
187*8f0ba417SAndroid Build Coastguard Worker ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms);
188*8f0ba417SAndroid Build Coastguard Worker #else
189*8f0ba417SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
190*8f0ba417SAndroid Build Coastguard Worker #endif
191*8f0ba417SAndroid Build Coastguard Worker }
192*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,WaitForProperty_MaxTimeout)193*8f0ba417SAndroid Build Coastguard Worker TEST(properties, WaitForProperty_MaxTimeout) {
194*8f0ba417SAndroid Build Coastguard Worker #if defined(__BIONIC__)
195*8f0ba417SAndroid Build Coastguard Worker std::atomic<bool> flag{false};
196*8f0ba417SAndroid Build Coastguard Worker std::thread thread([&]() {
197*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
198*8f0ba417SAndroid Build Coastguard Worker while (!flag) std::this_thread::yield();
199*8f0ba417SAndroid Build Coastguard Worker std::this_thread::sleep_for(500ms);
200*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
201*8f0ba417SAndroid Build Coastguard Worker });
202*8f0ba417SAndroid Build Coastguard Worker
203*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
204*8f0ba417SAndroid Build Coastguard Worker flag = true;
205*8f0ba417SAndroid Build Coastguard Worker // Test that this does not immediately return false due to overflow issues with the timeout.
206*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b"));
207*8f0ba417SAndroid Build Coastguard Worker thread.join();
208*8f0ba417SAndroid Build Coastguard Worker #else
209*8f0ba417SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
210*8f0ba417SAndroid Build Coastguard Worker #endif
211*8f0ba417SAndroid Build Coastguard Worker }
212*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,WaitForProperty_NegativeTimeout)213*8f0ba417SAndroid Build Coastguard Worker TEST(properties, WaitForProperty_NegativeTimeout) {
214*8f0ba417SAndroid Build Coastguard Worker #if defined(__BIONIC__)
215*8f0ba417SAndroid Build Coastguard Worker std::atomic<bool> flag{false};
216*8f0ba417SAndroid Build Coastguard Worker std::thread thread([&]() {
217*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
218*8f0ba417SAndroid Build Coastguard Worker while (!flag) std::this_thread::yield();
219*8f0ba417SAndroid Build Coastguard Worker std::this_thread::sleep_for(500ms);
220*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
221*8f0ba417SAndroid Build Coastguard Worker });
222*8f0ba417SAndroid Build Coastguard Worker
223*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
224*8f0ba417SAndroid Build Coastguard Worker flag = true;
225*8f0ba417SAndroid Build Coastguard Worker // Assert that this immediately returns with a negative timeout
226*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", -100ms));
227*8f0ba417SAndroid Build Coastguard Worker thread.join();
228*8f0ba417SAndroid Build Coastguard Worker #else
229*8f0ba417SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
230*8f0ba417SAndroid Build Coastguard Worker #endif
231*8f0ba417SAndroid Build Coastguard Worker }
232*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,WaitForPropertyCreation)233*8f0ba417SAndroid Build Coastguard Worker TEST(properties, WaitForPropertyCreation) {
234*8f0ba417SAndroid Build Coastguard Worker #if defined(__BIONIC__)
235*8f0ba417SAndroid Build Coastguard Worker std::thread thread([&]() {
236*8f0ba417SAndroid Build Coastguard Worker std::this_thread::sleep_for(100ms);
237*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.WaitForPropertyCreation_test", "a");
238*8f0ba417SAndroid Build Coastguard Worker });
239*8f0ba417SAndroid Build Coastguard Worker
240*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(android::base::WaitForPropertyCreation(
241*8f0ba417SAndroid Build Coastguard Worker "debug.libbase.WaitForPropertyCreation_test", 1s));
242*8f0ba417SAndroid Build Coastguard Worker thread.join();
243*8f0ba417SAndroid Build Coastguard Worker #else
244*8f0ba417SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
245*8f0ba417SAndroid Build Coastguard Worker #endif
246*8f0ba417SAndroid Build Coastguard Worker }
247*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,WaitForPropertyCreation_timeout)248*8f0ba417SAndroid Build Coastguard Worker TEST(properties, WaitForPropertyCreation_timeout) {
249*8f0ba417SAndroid Build Coastguard Worker #if defined(__BIONIC__)
250*8f0ba417SAndroid Build Coastguard Worker auto t0 = std::chrono::steady_clock::now();
251*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(android::base::WaitForPropertyCreation(
252*8f0ba417SAndroid Build Coastguard Worker "debug.libbase.WaitForPropertyCreation_timeout_test", 200ms));
253*8f0ba417SAndroid Build Coastguard Worker auto t1 = std::chrono::steady_clock::now();
254*8f0ba417SAndroid Build Coastguard Worker
255*8f0ba417SAndroid Build Coastguard Worker ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms);
256*8f0ba417SAndroid Build Coastguard Worker // Upper bounds on timing are inherently flaky, but let's try...
257*8f0ba417SAndroid Build Coastguard Worker ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms);
258*8f0ba417SAndroid Build Coastguard Worker #else
259*8f0ba417SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
260*8f0ba417SAndroid Build Coastguard Worker #endif
261*8f0ba417SAndroid Build Coastguard Worker }
262*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,CachedProperty)263*8f0ba417SAndroid Build Coastguard Worker TEST(properties, CachedProperty) {
264*8f0ba417SAndroid Build Coastguard Worker #if defined(__BIONIC__)
265*8f0ba417SAndroid Build Coastguard Worker android::base::CachedProperty cached_property("debug.libbase.CachedProperty_test");
266*8f0ba417SAndroid Build Coastguard Worker bool changed;
267*8f0ba417SAndroid Build Coastguard Worker cached_property.Get(&changed);
268*8f0ba417SAndroid Build Coastguard Worker
269*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.CachedProperty_test", "foo");
270*8f0ba417SAndroid Build Coastguard Worker ASSERT_STREQ("foo", cached_property.Get(&changed));
271*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(changed);
272*8f0ba417SAndroid Build Coastguard Worker
273*8f0ba417SAndroid Build Coastguard Worker ASSERT_STREQ("foo", cached_property.Get(&changed));
274*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(changed);
275*8f0ba417SAndroid Build Coastguard Worker
276*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty("debug.libbase.CachedProperty_test", "bar");
277*8f0ba417SAndroid Build Coastguard Worker ASSERT_STREQ("bar", cached_property.Get(&changed));
278*8f0ba417SAndroid Build Coastguard Worker ASSERT_TRUE(changed);
279*8f0ba417SAndroid Build Coastguard Worker
280*8f0ba417SAndroid Build Coastguard Worker ASSERT_STREQ("bar", cached_property.Get(&changed));
281*8f0ba417SAndroid Build Coastguard Worker ASSERT_FALSE(changed);
282*8f0ba417SAndroid Build Coastguard Worker
283*8f0ba417SAndroid Build Coastguard Worker #else
284*8f0ba417SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
285*8f0ba417SAndroid Build Coastguard Worker #endif
286*8f0ba417SAndroid Build Coastguard Worker }
287*8f0ba417SAndroid Build Coastguard Worker
SetAfter(const std::string & key,const std::string & value,std::chrono::milliseconds delay)288*8f0ba417SAndroid Build Coastguard Worker void SetAfter(const std::string& key, const std::string& value, std::chrono::milliseconds delay) {
289*8f0ba417SAndroid Build Coastguard Worker std::thread([key, value, delay]() {
290*8f0ba417SAndroid Build Coastguard Worker std::this_thread::sleep_for(delay);
291*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty(key, value);
292*8f0ba417SAndroid Build Coastguard Worker }).detach();
293*8f0ba417SAndroid Build Coastguard Worker }
294*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,CachedProperty_WaitForChange)295*8f0ba417SAndroid Build Coastguard Worker TEST(properties, CachedProperty_WaitForChange) {
296*8f0ba417SAndroid Build Coastguard Worker #if defined(__BIONIC__)
297*8f0ba417SAndroid Build Coastguard Worker unsigned long now =
298*8f0ba417SAndroid Build Coastguard Worker std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
299*8f0ba417SAndroid Build Coastguard Worker std::string key = android::base::StringPrintf("debug.libbase.CachedProperty_test_%lu", now);
300*8f0ba417SAndroid Build Coastguard Worker android::base::CachedProperty cached_property(key);
301*8f0ba417SAndroid Build Coastguard Worker
302*8f0ba417SAndroid Build Coastguard Worker // If the property doesn't exist yet, Get returns the empty string.
303*8f0ba417SAndroid Build Coastguard Worker EXPECT_STREQ("", cached_property.Get());
304*8f0ba417SAndroid Build Coastguard Worker
305*8f0ba417SAndroid Build Coastguard Worker // Property doesn't exist yet, timeout.
306*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, cached_property.WaitForChange(0ms));
307*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, cached_property.WaitForChange(100ms));
308*8f0ba417SAndroid Build Coastguard Worker
309*8f0ba417SAndroid Build Coastguard Worker // Property doesn't exist yet, success.
310*8f0ba417SAndroid Build Coastguard Worker SetAfter(key, "foo", 100ms);
311*8f0ba417SAndroid Build Coastguard Worker EXPECT_STREQ("foo", cached_property.WaitForChange());
312*8f0ba417SAndroid Build Coastguard Worker
313*8f0ba417SAndroid Build Coastguard Worker // Property exists, timeout.
314*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, cached_property.WaitForChange(0ms));
315*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, cached_property.WaitForChange(100ms));
316*8f0ba417SAndroid Build Coastguard Worker
317*8f0ba417SAndroid Build Coastguard Worker // Property exists, success.
318*8f0ba417SAndroid Build Coastguard Worker SetAfter(key, "bar", 100ms);
319*8f0ba417SAndroid Build Coastguard Worker EXPECT_STREQ("bar", cached_property.WaitForChange());
320*8f0ba417SAndroid Build Coastguard Worker #else
321*8f0ba417SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
322*8f0ba417SAndroid Build Coastguard Worker #endif
323*8f0ba417SAndroid Build Coastguard Worker }
324*8f0ba417SAndroid Build Coastguard Worker
TEST(properties,CachedBoolProperty)325*8f0ba417SAndroid Build Coastguard Worker TEST(properties, CachedBoolProperty) {
326*8f0ba417SAndroid Build Coastguard Worker #if defined(__BIONIC__)
327*8f0ba417SAndroid Build Coastguard Worker unsigned long now =
328*8f0ba417SAndroid Build Coastguard Worker std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
329*8f0ba417SAndroid Build Coastguard Worker std::string key = android::base::StringPrintf("debug.libbase.CachedBoolProperty_test_%lu", now);
330*8f0ba417SAndroid Build Coastguard Worker android::base::CachedBoolProperty cached_bool_property(key);
331*8f0ba417SAndroid Build Coastguard Worker
332*8f0ba417SAndroid Build Coastguard Worker // Not set yet.
333*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(std::nullopt, cached_bool_property.GetOptional());
334*8f0ba417SAndroid Build Coastguard Worker
335*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty(key, "foo");
336*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(std::nullopt, cached_bool_property.GetOptional());
337*8f0ba417SAndroid Build Coastguard Worker
338*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty(key, "1");
339*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(std::optional(true), cached_bool_property.GetOptional());
340*8f0ba417SAndroid Build Coastguard Worker
341*8f0ba417SAndroid Build Coastguard Worker android::base::SetProperty(key, "0");
342*8f0ba417SAndroid Build Coastguard Worker EXPECT_EQ(std::optional(false), cached_bool_property.GetOptional());
343*8f0ba417SAndroid Build Coastguard Worker #else
344*8f0ba417SAndroid Build Coastguard Worker GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
345*8f0ba417SAndroid Build Coastguard Worker #endif
346*8f0ba417SAndroid Build Coastguard Worker }
347