blob: 949019fc0b3d5c0923f0b0b0b0c375d8251293ad [file] [log] [blame]
Colin Crossb27e2002013-01-28 17:19:43 -08001/*
2 * Copyright (C) 2013 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 <gtest/gtest.h>
Yabin Cui9df70402014-11-05 18:01:01 -080018#include "BionicDeathTest.h"
19
Elliott Hughese4375192013-10-21 17:09:52 -070020#include <errno.h>
Yabin Cui9df70402014-11-05 18:01:01 -080021#include <sys/wait.h>
Greg Hackmanncb215a72013-02-13 14:41:48 -080022#include <unistd.h>
Elliott Hughesa0d374d2017-02-10 18:13:46 -080023
Greg Hackmanncb215a72013-02-13 14:41:48 -080024#include <string>
Elliott Hughesa0d374d2017-02-10 18:13:46 -080025#include <thread>
Colin Crossb27e2002013-01-28 17:19:43 -080026
Tom Cherrye275d6d2017-12-11 23:31:33 -080027#include <android-base/test_utils.h>
28
Tom Cherry8a311632017-10-09 13:49:17 -070029using namespace std::literals;
30
Christopher Ferrisf04935c2013-12-20 18:43:21 -080031#if defined(__BIONIC__)
Colin Crossb27e2002013-01-28 17:19:43 -080032
33#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
34#include <sys/_system_properties.h>
35
Tom Cherrye275d6d2017-12-11 23:31:33 -080036#include <system_properties/system_properties.h>
Greg Hackmanncb215a72013-02-13 14:41:48 -080037
Tom Cherrye275d6d2017-12-11 23:31:33 -080038class SystemPropertiesTest : public SystemProperties {
39 public:
40 SystemPropertiesTest() : SystemProperties(false) {
41 valid_ = AreaInit(dir_.path, nullptr);
42 }
43 ~SystemPropertiesTest() {
44 if (valid_) {
Tom Cherryee8e3dd2018-02-21 15:01:22 -080045 contexts_->FreeAndUnmap();
Colin Crossb27e2002013-01-28 17:19:43 -080046 }
Tom Cherrye275d6d2017-12-11 23:31:33 -080047 }
Colin Crossb27e2002013-01-28 17:19:43 -080048
Tom Cherrye275d6d2017-12-11 23:31:33 -080049 bool valid() const {
50 return valid_;
51 }
Greg Hackmanncb215a72013-02-13 14:41:48 -080052
Tom Cherrye275d6d2017-12-11 23:31:33 -080053 private:
54 TemporaryDir dir_;
55 bool valid_;
Colin Crossb27e2002013-01-28 17:19:43 -080056};
57
Christopher Ferrisf04935c2013-12-20 18:43:21 -080058static void foreach_test_callback(const prop_info *pi, void* cookie) {
59 size_t *count = static_cast<size_t *>(cookie);
60
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +000061 ASSERT_TRUE(pi != nullptr);
Christopher Ferrisf04935c2013-12-20 18:43:21 -080062 (*count)++;
63}
64
65static void hierarchical_test_callback(const prop_info *pi, void *cookie) {
66 bool (*ok)[8][8] = static_cast<bool (*)[8][8]>(cookie);
67
68 char name[PROP_NAME_MAX];
69 char value[PROP_VALUE_MAX];
70
71 __system_property_read(pi, name, value);
72
73 int name_i, name_j, name_k;
74 int value_i, value_j, value_k;
75 ASSERT_EQ(3, sscanf(name, "property_%d.%d.%d", &name_i, &name_j, &name_k));
76 ASSERT_EQ(3, sscanf(value, "value_%d.%d.%d", &value_i, &value_j, &value_k));
77 ASSERT_EQ(name_i, value_i);
78 ASSERT_GE(name_i, 0);
79 ASSERT_LT(name_i, 8);
80 ASSERT_EQ(name_j, value_j);
81 ASSERT_GE(name_j, 0);
82 ASSERT_LT(name_j, 8);
83 ASSERT_EQ(name_k, value_k);
84 ASSERT_GE(name_k, 0);
85 ASSERT_LT(name_k, 8);
86
87 ok[name_i][name_j][name_k] = true;
88}
89
Christopher Ferrisf04935c2013-12-20 18:43:21 -080090#endif // __BIONIC__
91
Elliott Hughesa0d374d2017-02-10 18:13:46 -080092TEST(properties, __system_property_add) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -080093#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -080094 SystemPropertiesTest system_properties;
95 ASSERT_TRUE(system_properties.valid());
Colin Crossb27e2002013-01-28 17:19:43 -080096
Tom Cherrye275d6d2017-12-11 23:31:33 -080097 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
98 ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
99 ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
Colin Crossb27e2002013-01-28 17:19:43 -0800100
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000101 // check that there is no limit on property name length
102 char name[PROP_NAME_MAX + 11];
103 name[0] = 'p';
104 for (size_t i = 1; i < sizeof(name); i++) {
105 name[i] = 'x';
106 }
107
108 name[sizeof(name)-1] = '\0';
Tom Cherrye275d6d2017-12-11 23:31:33 -0800109 ASSERT_EQ(0, system_properties.Add(name, strlen(name), "value", 5));
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000110
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800111 char propvalue[PROP_VALUE_MAX];
Tom Cherrye275d6d2017-12-11 23:31:33 -0800112 ASSERT_EQ(6, system_properties.Get("property", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800113 ASSERT_STREQ(propvalue, "value1");
114
Tom Cherrye275d6d2017-12-11 23:31:33 -0800115 ASSERT_EQ(6, system_properties.Get("other_property", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800116 ASSERT_STREQ(propvalue, "value2");
117
Tom Cherrye275d6d2017-12-11 23:31:33 -0800118 ASSERT_EQ(6, system_properties.Get("property_other", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800119 ASSERT_STREQ(propvalue, "value3");
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000120
Tom Cherrye275d6d2017-12-11 23:31:33 -0800121 ASSERT_EQ(5, system_properties.Get(name, propvalue));
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000122 ASSERT_STREQ(propvalue, "value");
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800123#else // __BIONIC__
124 GTEST_LOG_(INFO) << "This test does nothing.\n";
125#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800126}
127
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800128TEST(properties, __system_property_update) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800129#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800130 SystemPropertiesTest system_properties;
131 ASSERT_TRUE(system_properties.valid());
Colin Crossb27e2002013-01-28 17:19:43 -0800132
Tom Cherrye275d6d2017-12-11 23:31:33 -0800133 ASSERT_EQ(0, system_properties.Add("property", 8, "oldvalue1", 9));
134 ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
135 ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
Colin Crossb27e2002013-01-28 17:19:43 -0800136
Tom Cherrye275d6d2017-12-11 23:31:33 -0800137 const prop_info* pi = system_properties.Find("property");
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800138 ASSERT_TRUE(pi != nullptr);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800139 system_properties.Update(const_cast<prop_info*>(pi), "value4", 6);
Colin Crossb27e2002013-01-28 17:19:43 -0800140
Tom Cherrye275d6d2017-12-11 23:31:33 -0800141 pi = system_properties.Find("other_property");
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800142 ASSERT_TRUE(pi != nullptr);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800143 system_properties.Update(const_cast<prop_info*>(pi), "newvalue5", 9);
Colin Crossb27e2002013-01-28 17:19:43 -0800144
Tom Cherrye275d6d2017-12-11 23:31:33 -0800145 pi = system_properties.Find("property_other");
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800146 ASSERT_TRUE(pi != nullptr);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800147 system_properties.Update(const_cast<prop_info*>(pi), "value6", 6);
Colin Crossb27e2002013-01-28 17:19:43 -0800148
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800149 char propvalue[PROP_VALUE_MAX];
Tom Cherrye275d6d2017-12-11 23:31:33 -0800150 ASSERT_EQ(6, system_properties.Get("property", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800151 ASSERT_STREQ(propvalue, "value4");
152
Tom Cherrye275d6d2017-12-11 23:31:33 -0800153 ASSERT_EQ(9, system_properties.Get("other_property", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800154 ASSERT_STREQ(propvalue, "newvalue5");
155
Tom Cherrye275d6d2017-12-11 23:31:33 -0800156 ASSERT_EQ(6, system_properties.Get("property_other", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800157 ASSERT_STREQ(propvalue, "value6");
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800158#else // __BIONIC__
159 GTEST_LOG_(INFO) << "This test does nothing.\n";
160#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800161}
162
Greg Hackmanncb215a72013-02-13 14:41:48 -0800163TEST(properties, fill) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800164#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800165 SystemPropertiesTest system_properties;
166 ASSERT_TRUE(system_properties.valid());
167
Colin Crossb27e2002013-01-28 17:19:43 -0800168 char prop_name[PROP_NAME_MAX];
169 char prop_value[PROP_VALUE_MAX];
170 char prop_value_ret[PROP_VALUE_MAX];
Greg Hackmanncb215a72013-02-13 14:41:48 -0800171 int count = 0;
Colin Crossb27e2002013-01-28 17:19:43 -0800172 int ret;
173
Greg Hackmanncb215a72013-02-13 14:41:48 -0800174 while (true) {
175 ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d", count);
Colin Crossb27e2002013-01-28 17:19:43 -0800176 memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
Greg Hackmanncb215a72013-02-13 14:41:48 -0800177 ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d", count);
Colin Crossb27e2002013-01-28 17:19:43 -0800178 memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
179 prop_name[PROP_NAME_MAX - 1] = 0;
180 prop_value[PROP_VALUE_MAX - 1] = 0;
181
Tom Cherrye275d6d2017-12-11 23:31:33 -0800182 ret = system_properties.Add(prop_name, PROP_NAME_MAX - 1, prop_value, PROP_VALUE_MAX - 1);
Greg Hackmanncb215a72013-02-13 14:41:48 -0800183 if (ret < 0)
184 break;
185
186 count++;
Colin Crossb27e2002013-01-28 17:19:43 -0800187 }
188
Greg Hackmanncb215a72013-02-13 14:41:48 -0800189 // For historical reasons at least 247 properties must be supported
190 ASSERT_GE(count, 247);
191
192 for (int i = 0; i < count; i++) {
Colin Crossb27e2002013-01-28 17:19:43 -0800193 ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d", i);
194 memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
195 ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d", i);
196 memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
197 prop_name[PROP_NAME_MAX - 1] = 0;
198 prop_value[PROP_VALUE_MAX - 1] = 0;
199 memset(prop_value_ret, '\0', PROP_VALUE_MAX);
200
Tom Cherrye275d6d2017-12-11 23:31:33 -0800201 ASSERT_EQ(PROP_VALUE_MAX - 1, system_properties.Get(prop_name, prop_value_ret));
Colin Crossb27e2002013-01-28 17:19:43 -0800202 ASSERT_EQ(0, memcmp(prop_value, prop_value_ret, PROP_VALUE_MAX));
203 }
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800204#else // __BIONIC__
205 GTEST_LOG_(INFO) << "This test does nothing.\n";
206#endif // __BIONIC__
Greg Hackmannc6ff8442013-02-12 16:39:31 -0800207}
208
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800209TEST(properties, __system_property_foreach) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800210#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800211 SystemPropertiesTest system_properties;
212 ASSERT_TRUE(system_properties.valid());
Greg Hackmannc6ff8442013-02-12 16:39:31 -0800213
Tom Cherrye275d6d2017-12-11 23:31:33 -0800214 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
215 ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
216 ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
Greg Hackmannc6ff8442013-02-12 16:39:31 -0800217
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800218 size_t count = 0;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800219 ASSERT_EQ(0, system_properties.Foreach(foreach_test_callback, &count));
Greg Hackmannc6ff8442013-02-12 16:39:31 -0800220 ASSERT_EQ(3U, count);
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800221#else // __BIONIC__
222 GTEST_LOG_(INFO) << "This test does nothing.\n";
223#endif // __BIONIC__
Greg Hackmannc6ff8442013-02-12 16:39:31 -0800224}
225
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800226TEST(properties, __system_property_find_nth) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800227#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800228 SystemPropertiesTest system_properties;
229 ASSERT_TRUE(system_properties.valid());
Colin Crossb27e2002013-01-28 17:19:43 -0800230
Tom Cherrye275d6d2017-12-11 23:31:33 -0800231 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
232 ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
233 ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
Colin Crossb27e2002013-01-28 17:19:43 -0800234
Elliott Hughes438e0192017-04-17 14:53:07 -0700235 char name[PROP_NAME_MAX];
236 char value[PROP_VALUE_MAX];
Tom Cherrye275d6d2017-12-11 23:31:33 -0800237 EXPECT_EQ(6, system_properties.Read(system_properties.FindNth(0), name, value));
Elliott Hughes438e0192017-04-17 14:53:07 -0700238 EXPECT_STREQ("property", name);
239 EXPECT_STREQ("value1", value);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800240 EXPECT_EQ(6, system_properties.Read(system_properties.FindNth(1), name, value));
Elliott Hughes438e0192017-04-17 14:53:07 -0700241 EXPECT_STREQ("other_property", name);
242 EXPECT_STREQ("value2", value);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800243 EXPECT_EQ(6, system_properties.Read(system_properties.FindNth(2), name, value));
Elliott Hughes438e0192017-04-17 14:53:07 -0700244 EXPECT_STREQ("property_other", name);
245 EXPECT_STREQ("value3", value);
246
247 for (unsigned i = 3; i < 1024; ++i) {
Tom Cherrye275d6d2017-12-11 23:31:33 -0800248 ASSERT_TRUE(system_properties.FindNth(i) == nullptr);
Elliott Hughes438e0192017-04-17 14:53:07 -0700249 }
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800250#else // __BIONIC__
251 GTEST_LOG_(INFO) << "This test does nothing.\n";
252#endif // __BIONIC__
Greg Hackmannd5276422013-06-17 12:37:09 -0700253}
254
255TEST(properties, fill_hierarchical) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800256#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800257 SystemPropertiesTest system_properties;
258 ASSERT_TRUE(system_properties.valid());
259
Greg Hackmannd5276422013-06-17 12:37:09 -0700260 char prop_name[PROP_NAME_MAX];
261 char prop_value[PROP_VALUE_MAX];
262 char prop_value_ret[PROP_VALUE_MAX];
263 int ret;
264
265 for (int i = 0; i < 8; i++) {
266 for (int j = 0; j < 8; j++) {
267 for (int k = 0; k < 8; k++) {
268 ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d.%d.%d", i, j, k);
269 memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
270 ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d.%d.%d", i, j, k);
271 memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
272 prop_name[PROP_NAME_MAX - 1] = 0;
273 prop_value[PROP_VALUE_MAX - 1] = 0;
274
Tom Cherrye275d6d2017-12-11 23:31:33 -0800275 ASSERT_EQ(0, system_properties.Add(
276 prop_name, PROP_NAME_MAX - 1, prop_value, PROP_VALUE_MAX - 1));
Greg Hackmannd5276422013-06-17 12:37:09 -0700277 }
278 }
279 }
280
281 for (int i = 0; i < 8; i++) {
282 for (int j = 0; j < 8; j++) {
283 for (int k = 0; k < 8; k++) {
284 ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d.%d.%d", i, j, k);
285 memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
286 ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d.%d.%d", i, j, k);
287 memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
288 prop_name[PROP_NAME_MAX - 1] = 0;
289 prop_value[PROP_VALUE_MAX - 1] = 0;
290 memset(prop_value_ret, '\0', PROP_VALUE_MAX);
291
Tom Cherrye275d6d2017-12-11 23:31:33 -0800292 ASSERT_EQ(PROP_VALUE_MAX - 1, system_properties.Get(prop_name, prop_value_ret));
Greg Hackmannd5276422013-06-17 12:37:09 -0700293 ASSERT_EQ(0, memcmp(prop_value, prop_value_ret, PROP_VALUE_MAX));
294 }
295 }
296 }
297
298 bool ok[8][8][8];
299 memset(ok, 0, sizeof(ok));
Tom Cherrye275d6d2017-12-11 23:31:33 -0800300 system_properties.Foreach(hierarchical_test_callback, ok);
Greg Hackmannd5276422013-06-17 12:37:09 -0700301
302 for (int i = 0; i < 8; i++) {
303 for (int j = 0; j < 8; j++) {
304 for (int k = 0; k < 8; k++) {
305 ASSERT_TRUE(ok[i][j][k]);
306 }
307 }
308 }
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800309#else // __BIONIC__
310 GTEST_LOG_(INFO) << "This test does nothing.\n";
311#endif // __BIONIC__
Greg Hackmannd5276422013-06-17 12:37:09 -0700312}
313
Colin Crossb27e2002013-01-28 17:19:43 -0800314TEST(properties, errors) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800315#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800316 SystemPropertiesTest system_properties;
317 ASSERT_TRUE(system_properties.valid());
318
Colin Crossb27e2002013-01-28 17:19:43 -0800319 char prop_value[PROP_NAME_MAX];
320
Tom Cherrye275d6d2017-12-11 23:31:33 -0800321 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
322 ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
323 ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
Colin Crossb27e2002013-01-28 17:19:43 -0800324
Tom Cherrye275d6d2017-12-11 23:31:33 -0800325 ASSERT_EQ(0, system_properties.Find("property1"));
326 ASSERT_EQ(0, system_properties.Get("property1", prop_value));
Colin Crossb27e2002013-01-28 17:19:43 -0800327
Tom Cherrye275d6d2017-12-11 23:31:33 -0800328 ASSERT_EQ(-1, system_properties.Add("name", 4, "value", PROP_VALUE_MAX));
329 ASSERT_EQ(-1, system_properties.Update(NULL, "value", PROP_VALUE_MAX));
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800330#else // __BIONIC__
331 GTEST_LOG_(INFO) << "This test does nothing.\n";
332#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800333}
334
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800335TEST(properties, __system_property_serial) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800336#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800337 SystemPropertiesTest system_properties;
338 ASSERT_TRUE(system_properties.valid());
Colin Crossb27e2002013-01-28 17:19:43 -0800339
Tom Cherrye275d6d2017-12-11 23:31:33 -0800340 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
341 const prop_info* pi = system_properties.Find("property");
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800342 ASSERT_TRUE(pi != nullptr);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800343 unsigned serial = system_properties.Serial(pi);
344 ASSERT_EQ(0, system_properties.Update(const_cast<prop_info*>(pi), "value2", 6));
345 ASSERT_NE(serial, system_properties.Serial(pi));
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800346#else // __BIONIC__
347 GTEST_LOG_(INFO) << "This test does nothing.\n";
348#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800349}
350
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800351TEST(properties, __system_property_wait_any) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800352#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800353 SystemPropertiesTest system_properties;
354 ASSERT_TRUE(system_properties.valid());
Colin Crossb27e2002013-01-28 17:19:43 -0800355
Tom Cherrye275d6d2017-12-11 23:31:33 -0800356 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
357 unsigned serial = system_properties.WaitAny(0);
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000358
Tom Cherrye275d6d2017-12-11 23:31:33 -0800359 prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000360 ASSERT_TRUE(pi != nullptr);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800361 system_properties.Update(pi, "value2", 6);
362 serial = system_properties.WaitAny(serial);
Colin Crossb27e2002013-01-28 17:19:43 -0800363
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800364 int flag = 0;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800365 std::thread thread([&system_properties, &flag]() {
366 prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
367 usleep(100000);
368
369 flag = 1;
370 system_properties.Update(pi, "value3", 6);
371 });
Colin Crossb27e2002013-01-28 17:19:43 -0800372 ASSERT_EQ(flag, 0);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800373 serial = system_properties.WaitAny(serial);
Colin Crossb27e2002013-01-28 17:19:43 -0800374 ASSERT_EQ(flag, 1);
375
Tom Cherrye275d6d2017-12-11 23:31:33 -0800376 thread.join();
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800377#else // __BIONIC__
378 GTEST_LOG_(INFO) << "This test does nothing.\n";
379#endif // __BIONIC__
380}
381
382TEST(properties, __system_property_wait) {
383#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800384 SystemPropertiesTest system_properties;
385 ASSERT_TRUE(system_properties.valid());
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800386
Tom Cherrye275d6d2017-12-11 23:31:33 -0800387 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800388
Tom Cherrye275d6d2017-12-11 23:31:33 -0800389 prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800390 ASSERT_TRUE(pi != nullptr);
391
Tom Cherrye275d6d2017-12-11 23:31:33 -0800392 unsigned serial = system_properties.Serial(pi);
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800393
Tom Cherrye275d6d2017-12-11 23:31:33 -0800394 std::thread thread([&system_properties]() {
395 prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800396 ASSERT_TRUE(pi != nullptr);
397
Tom Cherrye275d6d2017-12-11 23:31:33 -0800398 system_properties.Update(pi, "value2", 6);
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800399 });
400
Elliott Hughes40c885a2017-02-16 17:13:04 -0800401 uint32_t new_serial;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800402 system_properties.Wait(pi, serial, &new_serial, nullptr);
Elliott Hughes40c885a2017-02-16 17:13:04 -0800403 ASSERT_GT(new_serial, serial);
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800404
405 char value[PROP_VALUE_MAX];
Tom Cherrye275d6d2017-12-11 23:31:33 -0800406 ASSERT_EQ(6, system_properties.Get("property", value));
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800407 ASSERT_STREQ("value2", value);
408
409 thread.join();
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800410#else // __BIONIC__
411 GTEST_LOG_(INFO) << "This test does nothing.\n";
412#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800413}
414
415class KilledByFault {
416 public:
417 explicit KilledByFault() {};
418 bool operator()(int exit_status) const;
419};
420
421bool KilledByFault::operator()(int exit_status) const {
422 return WIFSIGNALED(exit_status) &&
423 (WTERMSIG(exit_status) == SIGSEGV ||
424 WTERMSIG(exit_status) == SIGBUS ||
425 WTERMSIG(exit_status) == SIGABRT);
426}
427
Yabin Cui9df70402014-11-05 18:01:01 -0800428class properties_DeathTest : public BionicDeathTest {};
429
430TEST_F(properties_DeathTest, read_only) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800431#if defined(__BIONIC__)
Elliott Hughese4375192013-10-21 17:09:52 -0700432
433 // This test only makes sense if we're talking to the real system property service.
434 struct stat sb;
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000435 ASSERT_FALSE(stat(PROP_FILENAME, &sb) == -1 && errno == ENOENT);
Elliott Hughese4375192013-10-21 17:09:52 -0700436
437 ASSERT_EXIT(__system_property_add("property", 8, "value", 5), KilledByFault(), "");
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800438#else // __BIONIC__
439 GTEST_LOG_(INFO) << "This test does nothing.\n";
440#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800441}
Tom Cherry8a311632017-10-09 13:49:17 -0700442
443TEST(properties, __system_property_extra_long_read_only) {
444#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800445 SystemPropertiesTest system_properties;
446 ASSERT_TRUE(system_properties.valid());
Tom Cherry8a311632017-10-09 13:49:17 -0700447
448 std::vector<std::pair<std::string, std::string>> short_properties = {
449 { "ro.0char", std::string() },
450 { "ro.50char", std::string(50, 'x') },
451 { "ro.91char", std::string(91, 'x') },
452 };
453
454 std::vector<std::pair<std::string, std::string>> long_properties = {
455 { "ro.92char", std::string(92, 'x') },
456 { "ro.93char", std::string(93, 'x') },
457 { "ro.1000char", std::string(1000, 'x') },
458 };
459
460 for (const auto& property : short_properties) {
461 const std::string& name = property.first;
462 const std::string& value = property.second;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800463 ASSERT_EQ(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
Tom Cherry8a311632017-10-09 13:49:17 -0700464 }
465
466 for (const auto& property : long_properties) {
467 const std::string& name = property.first;
468 const std::string& value = property.second;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800469 ASSERT_EQ(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
Tom Cherry8a311632017-10-09 13:49:17 -0700470 }
471
Tom Cherrye275d6d2017-12-11 23:31:33 -0800472 auto check_with_legacy_read = [&system_properties](const std::string& name,
473 const std::string& expected_value) {
Tom Cherry8a311632017-10-09 13:49:17 -0700474 char value[PROP_VALUE_MAX];
Tom Cherrye275d6d2017-12-11 23:31:33 -0800475 EXPECT_EQ(static_cast<int>(expected_value.size()), system_properties.Get(name.c_str(), value))
Tom Cherry8a311632017-10-09 13:49:17 -0700476 << name;
477 EXPECT_EQ(expected_value, value) << name;
478 };
479
Tom Cherrye275d6d2017-12-11 23:31:33 -0800480 auto check_with_read_callback = [&system_properties](const std::string& name,
481 const std::string& expected_value) {
482 const prop_info* pi = system_properties.Find(name.c_str());
Tom Cherry8a311632017-10-09 13:49:17 -0700483 ASSERT_NE(nullptr, pi);
484 std::string value;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800485 system_properties.ReadCallback(pi,
486 [](void* cookie, const char*, const char* value, uint32_t) {
487 auto* out_value = reinterpret_cast<std::string*>(cookie);
488 *out_value = value;
489 },
490 &value);
Tom Cherry8a311632017-10-09 13:49:17 -0700491 EXPECT_EQ(expected_value, value) << name;
492 };
493
494 for (const auto& property : short_properties) {
495 const std::string& name = property.first;
496 const std::string& value = property.second;
497 check_with_legacy_read(name, value);
498 check_with_read_callback(name, value);
499 }
500
501 constexpr static const char* kExtraLongLegacyError =
502 "Must use __system_property_read_callback() to read";
503 for (const auto& property : long_properties) {
504 const std::string& name = property.first;
505 const std::string& value = property.second;
506 check_with_legacy_read(name, kExtraLongLegacyError);
507 check_with_read_callback(name, value);
508 }
509
510#else // __BIONIC__
511 GTEST_LOG_(INFO) << "This test does nothing.\n";
512#endif // __BIONIC__
513}
514
515// pa_size is 128 * 1024 currently, if a property is longer then we expect it to fail gracefully.
516TEST(properties, __system_property_extra_long_read_only_too_long) {
517#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800518 SystemPropertiesTest system_properties;
519 ASSERT_TRUE(system_properties.valid());
Tom Cherry8a311632017-10-09 13:49:17 -0700520
521 auto name = "ro.super_long_property"s;
522 auto value = std::string(128 * 1024 + 1, 'x');
Tom Cherrye275d6d2017-12-11 23:31:33 -0800523 ASSERT_NE(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
Tom Cherry8a311632017-10-09 13:49:17 -0700524
525#else // __BIONIC__
526 GTEST_LOG_(INFO) << "This test does nothing.\n";
527#endif // __BIONIC__
528}