blob: e7d4880c267c2f53f24a13371fceff0c0a4dfc89 [file] [log] [blame]
Elliott Hughes5a7788c2016-09-21 16:53:15 -07001/*
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
Elliott Hughes530448e2017-02-10 19:02:51 -080021#include <atomic>
22#include <chrono>
Elliott Hughes5a7788c2016-09-21 16:53:15 -070023#include <string>
Elliott Hughes530448e2017-02-10 19:02:51 -080024#include <thread>
25
Elliott Hughes083c2fe2018-05-24 18:00:39 -070026#if !defined(_WIN32)
27using namespace std::literals;
28#endif
Elliott Hughes5a7788c2016-09-21 16:53:15 -070029
30TEST(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
47TEST(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
56static 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
61TEST(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
69TEST(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
77TEST(properties, GetBoolProperty_default) {
78 CheckGetBoolProperty(true, "burp", true);
79 CheckGetBoolProperty(false, "burp", false);
80}
81
82template <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
104template <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
120TEST(properties, GetIntProperty_int8_t) { CheckGetIntProperty<int8_t>(); }
121TEST(properties, GetIntProperty_int16_t) { CheckGetIntProperty<int16_t>(); }
122TEST(properties, GetIntProperty_int32_t) { CheckGetIntProperty<int32_t>(); }
123TEST(properties, GetIntProperty_int64_t) { CheckGetIntProperty<int64_t>(); }
124
125TEST(properties, GetUintProperty_uint8_t) { CheckGetUintProperty<uint8_t>(); }
126TEST(properties, GetUintProperty_uint16_t) { CheckGetUintProperty<uint16_t>(); }
127TEST(properties, GetUintProperty_uint32_t) { CheckGetUintProperty<uint32_t>(); }
128TEST(properties, GetUintProperty_uint64_t) { CheckGetUintProperty<uint64_t>(); }
Elliott Hughes530448e2017-02-10 19:02:51 -0800129
130TEST(properties, WaitForProperty) {
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700131#if defined(__BIONIC__)
Elliott Hughes530448e2017-02-10 19:02:51 -0800132 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
Elliott Hughes81bcb212017-02-16 17:14:10 -0800140 ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "a", 1s));
Elliott Hughes530448e2017-02-10 19:02:51 -0800141 flag = true;
Elliott Hughes81bcb212017-02-16 17:14:10 -0800142 ASSERT_TRUE(android::base::WaitForProperty("debug.libbase.WaitForProperty_test", "b", 1s));
Elliott Hughes530448e2017-02-10 19:02:51 -0800143 thread.join();
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700144#else
145 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
146#endif
Elliott Hughes530448e2017-02-10 19:02:51 -0800147}
Elliott Hughes81bcb212017-02-16 17:14:10 -0800148
149TEST(properties, WaitForProperty_timeout) {
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700150#if defined(__BIONIC__)
Elliott Hughes81bcb212017-02-16 17:14:10 -0800151 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);
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700159#else
160 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
161#endif
Elliott Hughes81bcb212017-02-16 17:14:10 -0800162}
Keun-young Park16f70512017-02-27 13:23:50 -0800163
Tom Cherryd0516ca2017-03-24 16:52:29 -0700164TEST(properties, WaitForProperty_MaxTimeout) {
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700165#if defined(__BIONIC__)
Tom Cherryd0516ca2017-03-24 16:52:29 -0700166 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();
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700179#else
180 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
181#endif
Tom Cherryd0516ca2017-03-24 16:52:29 -0700182}
183
184TEST(properties, WaitForProperty_NegativeTimeout) {
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700185#if defined(__BIONIC__)
Tom Cherryd0516ca2017-03-24 16:52:29 -0700186 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();
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700199#else
200 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
201#endif
Tom Cherryd0516ca2017-03-24 16:52:29 -0700202}
203
Keun-young Park16f70512017-02-27 13:23:50 -0800204TEST(properties, WaitForPropertyCreation) {
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700205#if defined(__BIONIC__)
Keun-young Park16f70512017-02-27 13:23:50 -0800206 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();
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700214#else
215 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
216#endif
Keun-young Park16f70512017-02-27 13:23:50 -0800217}
218
219TEST(properties, WaitForPropertyCreation_timeout) {
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700220#if defined(__BIONIC__)
Keun-young Park16f70512017-02-27 13:23:50 -0800221 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);
Elliott Hughes083c2fe2018-05-24 18:00:39 -0700229#else
230 GTEST_LOG_(INFO) << "This test does nothing on the host.\n";
231#endif
Keun-young Park16f70512017-02-27 13:23:50 -0800232}