• 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 using namespace std::chrono_literals;
27 
TEST(properties,smoke)28 TEST(properties, smoke) {
29   android::base::SetProperty("debug.libbase.property_test", "hello");
30 
31   std::string s = android::base::GetProperty("debug.libbase.property_test", "");
32   ASSERT_EQ("hello", s);
33 
34   android::base::SetProperty("debug.libbase.property_test", "world");
35   s = android::base::GetProperty("debug.libbase.property_test", "");
36   ASSERT_EQ("world", s);
37 
38   s = android::base::GetProperty("this.property.does.not.exist", "");
39   ASSERT_EQ("", s);
40 
41   s = android::base::GetProperty("this.property.does.not.exist", "default");
42   ASSERT_EQ("default", s);
43 }
44 
TEST(properties,empty)45 TEST(properties, empty) {
46   // Because you can't delete a property, people "delete" them by
47   // setting them to the empty string. In that case we'd want to
48   // keep the default value (like cutils' property_get did).
49   android::base::SetProperty("debug.libbase.property_test", "");
50   std::string s = android::base::GetProperty("debug.libbase.property_test", "default");
51   ASSERT_EQ("default", s);
52 }
53 
CheckGetBoolProperty(bool expected,const std::string & value,bool default_value)54 static void CheckGetBoolProperty(bool expected, const std::string& value, bool default_value) {
55   android::base::SetProperty("debug.libbase.property_test", value.c_str());
56   ASSERT_EQ(expected, android::base::GetBoolProperty("debug.libbase.property_test", default_value));
57 }
58 
TEST(properties,GetBoolProperty_true)59 TEST(properties, GetBoolProperty_true) {
60   CheckGetBoolProperty(true, "1", false);
61   CheckGetBoolProperty(true, "y", false);
62   CheckGetBoolProperty(true, "yes", false);
63   CheckGetBoolProperty(true, "on", false);
64   CheckGetBoolProperty(true, "true", false);
65 }
66 
TEST(properties,GetBoolProperty_false)67 TEST(properties, GetBoolProperty_false) {
68   CheckGetBoolProperty(false, "0", true);
69   CheckGetBoolProperty(false, "n", true);
70   CheckGetBoolProperty(false, "no", true);
71   CheckGetBoolProperty(false, "off", true);
72   CheckGetBoolProperty(false, "false", true);
73 }
74 
TEST(properties,GetBoolProperty_default)75 TEST(properties, GetBoolProperty_default) {
76   CheckGetBoolProperty(true, "burp", true);
77   CheckGetBoolProperty(false, "burp", false);
78 }
79 
CheckGetIntProperty()80 template <typename T> void CheckGetIntProperty() {
81   // Positive and negative.
82   android::base::SetProperty("debug.libbase.property_test", "-12");
83   EXPECT_EQ(T(-12), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
84   android::base::SetProperty("debug.libbase.property_test", "12");
85   EXPECT_EQ(T(12), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
86 
87   // Default value.
88   android::base::SetProperty("debug.libbase.property_test", "");
89   EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45));
90 
91   // Bounds checks.
92   android::base::SetProperty("debug.libbase.property_test", "0");
93   EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
94   android::base::SetProperty("debug.libbase.property_test", "1");
95   EXPECT_EQ(T(1), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
96   android::base::SetProperty("debug.libbase.property_test", "2");
97   EXPECT_EQ(T(2), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
98   android::base::SetProperty("debug.libbase.property_test", "3");
99   EXPECT_EQ(T(45), android::base::GetIntProperty<T>("debug.libbase.property_test", 45, 1, 2));
100 }
101 
CheckGetUintProperty()102 template <typename T> void CheckGetUintProperty() {
103   // Positive.
104   android::base::SetProperty("debug.libbase.property_test", "12");
105   EXPECT_EQ(T(12), android::base::GetUintProperty<T>("debug.libbase.property_test", 45));
106 
107   // Default value.
108   android::base::SetProperty("debug.libbase.property_test", "");
109   EXPECT_EQ(T(45), android::base::GetUintProperty<T>("debug.libbase.property_test", 45));
110 
111   // Bounds checks.
112   android::base::SetProperty("debug.libbase.property_test", "12");
113   EXPECT_EQ(T(12), android::base::GetUintProperty<T>("debug.libbase.property_test", 33, 22));
114   android::base::SetProperty("debug.libbase.property_test", "12");
115   EXPECT_EQ(T(5), android::base::GetUintProperty<T>("debug.libbase.property_test", 5, 10));
116 }
117 
TEST(properties,GetIntProperty_int8_t)118 TEST(properties, GetIntProperty_int8_t) { CheckGetIntProperty<int8_t>(); }
TEST(properties,GetIntProperty_int16_t)119 TEST(properties, GetIntProperty_int16_t) { CheckGetIntProperty<int16_t>(); }
TEST(properties,GetIntProperty_int32_t)120 TEST(properties, GetIntProperty_int32_t) { CheckGetIntProperty<int32_t>(); }
TEST(properties,GetIntProperty_int64_t)121 TEST(properties, GetIntProperty_int64_t) { CheckGetIntProperty<int64_t>(); }
122 
TEST(properties,GetUintProperty_uint8_t)123 TEST(properties, GetUintProperty_uint8_t) { CheckGetUintProperty<uint8_t>(); }
TEST(properties,GetUintProperty_uint16_t)124 TEST(properties, GetUintProperty_uint16_t) { CheckGetUintProperty<uint16_t>(); }
TEST(properties,GetUintProperty_uint32_t)125 TEST(properties, GetUintProperty_uint32_t) { CheckGetUintProperty<uint32_t>(); }
TEST(properties,GetUintProperty_uint64_t)126 TEST(properties, GetUintProperty_uint64_t) { CheckGetUintProperty<uint64_t>(); }
127 
TEST(properties,WaitForProperty)128 TEST(properties, WaitForProperty) {
129   std::atomic<bool> flag{false};
130   std::thread thread([&]() {
131     std::this_thread::sleep_for(100ms);
132     android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
133     while (!flag) std::this_thread::yield();
134     android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
135   });
136 
137   ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
138   flag = true;
139   ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", 1s));
140   thread.join();
141 }
142 
TEST(properties,WaitForProperty_timeout)143 TEST(properties, WaitForProperty_timeout) {
144   auto t0 = std::chrono::steady_clock::now();
145   ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_timeout_test", "a",
146                                               200ms));
147   auto t1 = std::chrono::steady_clock::now();
148 
149   ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms);
150   // Upper bounds on timing are inherently flaky, but let's try...
151   ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms);
152 }
153 
TEST(properties,WaitForProperty_MaxTimeout)154 TEST(properties, WaitForProperty_MaxTimeout) {
155   std::atomic<bool> flag{false};
156   std::thread thread([&]() {
157     android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
158     while (!flag) std::this_thread::yield();
159     std::this_thread::sleep_for(500ms);
160     android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
161   });
162 
163   ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
164   flag = true;
165   // Test that this does not immediately return false due to overflow issues with the timeout.
166   ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b"));
167   thread.join();
168 }
169 
TEST(properties,WaitForProperty_NegativeTimeout)170 TEST(properties, WaitForProperty_NegativeTimeout) {
171   std::atomic<bool> flag{false};
172   std::thread thread([&]() {
173     android::base::SetProperty("debug.libbase.WaitForProperty_test", "a");
174     while (!flag) std::this_thread::yield();
175     std::this_thread::sleep_for(500ms);
176     android::base::SetProperty("debug.libbase.WaitForProperty_test", "b");
177   });
178 
179   ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
180   flag = true;
181   // Assert that this immediately returns with a negative timeout
182   ASSERT_FALSE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", -100ms));
183   thread.join();
184 }
185 
TEST(properties,WaitForPropertyCreation)186 TEST(properties, WaitForPropertyCreation) {
187   std::thread thread([&]() {
188     std::this_thread::sleep_for(100ms);
189     android::base::SetProperty("debug.libbase.WaitForPropertyCreation_test", "a");
190   });
191 
192   ASSERT_TRUE(android::base::WaitForPropertyCreation(
193           "debug.libbase.WaitForPropertyCreation_test", 1s));
194   thread.join();
195 }
196 
TEST(properties,WaitForPropertyCreation_timeout)197 TEST(properties, WaitForPropertyCreation_timeout) {
198   auto t0 = std::chrono::steady_clock::now();
199   ASSERT_FALSE(android::base::WaitForPropertyCreation(
200           "debug.libbase.WaitForPropertyCreation_timeout_test", 200ms));
201   auto t1 = std::chrono::steady_clock::now();
202 
203   ASSERT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 200ms);
204   // Upper bounds on timing are inherently flaky, but let's try...
205   ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>(t1 - t0), 600ms);
206 }
207