blob: 960f6898eb42122a80d790b9513aed690e3a2638 [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
Elliott Hughese4375192013-10-21 17:09:52 -070019#include <errno.h>
Yabin Cui9df70402014-11-05 18:01:01 -080020#include <sys/wait.h>
Greg Hackmanncb215a72013-02-13 14:41:48 -080021#include <unistd.h>
Elliott Hughesa0d374d2017-02-10 18:13:46 -080022
Greg Hackmanncb215a72013-02-13 14:41:48 -080023#include <string>
Elliott Hughesa0d374d2017-02-10 18:13:46 -080024#include <thread>
Colin Crossb27e2002013-01-28 17:19:43 -080025
Mark Salyzynba1a7232018-11-14 15:19:53 -080026#include <android-base/file.h>
Elliott Hughes141b9172021-04-09 17:13:09 -070027#include <android-base/silent_death_test.h>
Nate Myrenb8c87b12023-08-28 16:46:39 -070028#include <android-base/stringprintf.h>
29
30#include "utils.h"
Tom Cherrye275d6d2017-12-11 23:31:33 -080031
Tom Cherry8a311632017-10-09 13:49:17 -070032using namespace std::literals;
33
Christopher Ferrisf04935c2013-12-20 18:43:21 -080034#if defined(__BIONIC__)
Colin Crossb27e2002013-01-28 17:19:43 -080035
36#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
37#include <sys/_system_properties.h>
Nate Myrenb8c87b12023-08-28 16:46:39 -070038#include <sys/mount.h>
Colin Crossb27e2002013-01-28 17:19:43 -080039
Tom Cherrye275d6d2017-12-11 23:31:33 -080040#include <system_properties/system_properties.h>
Greg Hackmanncb215a72013-02-13 14:41:48 -080041
Tom Cherrye275d6d2017-12-11 23:31:33 -080042class SystemPropertiesTest : public SystemProperties {
43 public:
44 SystemPropertiesTest() : SystemProperties(false) {
Nate Myrenb8c87b12023-08-28 16:46:39 -070045 appcompat_path = android::base::StringPrintf("%s/appcompat_override", dir_.path);
46 mkdir(appcompat_path.c_str(), S_IRWXU | S_IXGRP | S_IXOTH);
47 valid_ = AreaInit(dir_.path, nullptr, true);
Tom Cherrye275d6d2017-12-11 23:31:33 -080048 }
49 ~SystemPropertiesTest() {
50 if (valid_) {
Tom Cherryee8e3dd2018-02-21 15:01:22 -080051 contexts_->FreeAndUnmap();
Colin Crossb27e2002013-01-28 17:19:43 -080052 }
Nate Myrenb8c87b12023-08-28 16:46:39 -070053 umount(dir_.path);
Tom Cherrye275d6d2017-12-11 23:31:33 -080054 }
Colin Crossb27e2002013-01-28 17:19:43 -080055
Tom Cherrye275d6d2017-12-11 23:31:33 -080056 bool valid() const {
57 return valid_;
58 }
Greg Hackmanncb215a72013-02-13 14:41:48 -080059
Nate Myrenb8c87b12023-08-28 16:46:39 -070060 const char* get_path() const { return dir_.path; }
61
62 const char* get_appcompat_path() const { return appcompat_path.c_str(); }
63
64 std::string appcompat_path;
65
Tom Cherrye275d6d2017-12-11 23:31:33 -080066 private:
67 TemporaryDir dir_;
68 bool valid_;
Colin Crossb27e2002013-01-28 17:19:43 -080069};
70
Christopher Ferrisf04935c2013-12-20 18:43:21 -080071static void foreach_test_callback(const prop_info *pi, void* cookie) {
72 size_t *count = static_cast<size_t *>(cookie);
73
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +000074 ASSERT_TRUE(pi != nullptr);
Christopher Ferrisf04935c2013-12-20 18:43:21 -080075 (*count)++;
76}
77
78static void hierarchical_test_callback(const prop_info *pi, void *cookie) {
79 bool (*ok)[8][8] = static_cast<bool (*)[8][8]>(cookie);
80
81 char name[PROP_NAME_MAX];
82 char value[PROP_VALUE_MAX];
83
84 __system_property_read(pi, name, value);
85
86 int name_i, name_j, name_k;
87 int value_i, value_j, value_k;
88 ASSERT_EQ(3, sscanf(name, "property_%d.%d.%d", &name_i, &name_j, &name_k));
89 ASSERT_EQ(3, sscanf(value, "value_%d.%d.%d", &value_i, &value_j, &value_k));
90 ASSERT_EQ(name_i, value_i);
91 ASSERT_GE(name_i, 0);
92 ASSERT_LT(name_i, 8);
93 ASSERT_EQ(name_j, value_j);
94 ASSERT_GE(name_j, 0);
95 ASSERT_LT(name_j, 8);
96 ASSERT_EQ(name_k, value_k);
97 ASSERT_GE(name_k, 0);
98 ASSERT_LT(name_k, 8);
99
100 ok[name_i][name_j][name_k] = true;
101}
102
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800103#endif // __BIONIC__
104
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800105TEST(properties, __system_property_add) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800106#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800107 SystemPropertiesTest system_properties;
108 ASSERT_TRUE(system_properties.valid());
Colin Crossb27e2002013-01-28 17:19:43 -0800109
Tom Cherrye275d6d2017-12-11 23:31:33 -0800110 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
111 ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
112 ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
Colin Crossb27e2002013-01-28 17:19:43 -0800113
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000114 // check that there is no limit on property name length
115 char name[PROP_NAME_MAX + 11];
116 name[0] = 'p';
117 for (size_t i = 1; i < sizeof(name); i++) {
118 name[i] = 'x';
119 }
120
121 name[sizeof(name)-1] = '\0';
Tom Cherrye275d6d2017-12-11 23:31:33 -0800122 ASSERT_EQ(0, system_properties.Add(name, strlen(name), "value", 5));
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000123
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800124 char propvalue[PROP_VALUE_MAX];
Tom Cherrye275d6d2017-12-11 23:31:33 -0800125 ASSERT_EQ(6, system_properties.Get("property", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800126 ASSERT_STREQ(propvalue, "value1");
127
Tom Cherrye275d6d2017-12-11 23:31:33 -0800128 ASSERT_EQ(6, system_properties.Get("other_property", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800129 ASSERT_STREQ(propvalue, "value2");
130
Tom Cherrye275d6d2017-12-11 23:31:33 -0800131 ASSERT_EQ(6, system_properties.Get("property_other", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800132 ASSERT_STREQ(propvalue, "value3");
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000133
Tom Cherrye275d6d2017-12-11 23:31:33 -0800134 ASSERT_EQ(5, system_properties.Get(name, propvalue));
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000135 ASSERT_STREQ(propvalue, "value");
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800136#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800137 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800138#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800139}
140
Nate Myrenb8c87b12023-08-28 16:46:39 -0700141TEST(properties, __system_property_add_appcompat) {
142#if defined(__BIONIC__)
143 if (getuid() != 0) GTEST_SKIP() << "test requires root";
144 SystemPropertiesTest system_properties;
145 ASSERT_TRUE(system_properties.valid());
146
147 char name[] = "ro.property";
148 char override_name[] = "ro.appcompat_override.ro.property";
149 char name_not_written[] = "ro.property_other";
150 char override_with_no_real[] = "ro.appcompat_override.ro.property_other";
151 ASSERT_EQ(0, system_properties.Add(name, strlen(name), "value1", 6));
152 ASSERT_EQ(0, system_properties.Add(override_name, strlen(override_name), "value2", 6));
153 ASSERT_EQ(0, system_properties.Add(override_with_no_real, strlen(override_with_no_real),
154 "value3", 6));
155
156 char propvalue[PROP_VALUE_MAX];
157 ASSERT_EQ(6, system_properties.Get(name, propvalue));
158 ASSERT_STREQ(propvalue, "value1");
159
160 ASSERT_EQ(6, system_properties.Get(override_name, propvalue));
161 ASSERT_STREQ(propvalue, "value2");
162
163 ASSERT_EQ(0, system_properties.Get(name_not_written, propvalue));
164 ASSERT_STREQ(propvalue, "");
165
166 ASSERT_EQ(6, system_properties.Get(override_with_no_real, propvalue));
167 ASSERT_STREQ(propvalue, "value3");
168
169 int ret = mount(system_properties.get_appcompat_path(), system_properties.get_path(), nullptr,
170 MS_BIND | MS_REC, nullptr);
171 if (ret != 0) {
172 ASSERT_ERRNO(0);
173 }
174 system_properties.Reload(true);
175
176 ASSERT_EQ(6, system_properties.Get(name, propvalue));
177 ASSERT_STREQ(propvalue, "value2");
178
179 ASSERT_EQ(0, system_properties.Get(override_name, propvalue));
180 ASSERT_STREQ(propvalue, "");
181
182 ASSERT_EQ(6, system_properties.Get(name_not_written, propvalue));
183 ASSERT_STREQ(propvalue, "value3");
184
185 ASSERT_EQ(0, system_properties.Get(override_with_no_real, propvalue));
186 ASSERT_STREQ(propvalue, "");
187
188#else // __BIONIC__
189 GTEST_SKIP() << "bionic-only test";
190#endif // __BIONIC__
191}
192
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800193TEST(properties, __system_property_update) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800194#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800195 SystemPropertiesTest system_properties;
196 ASSERT_TRUE(system_properties.valid());
Colin Crossb27e2002013-01-28 17:19:43 -0800197
Tom Cherrye275d6d2017-12-11 23:31:33 -0800198 ASSERT_EQ(0, system_properties.Add("property", 8, "oldvalue1", 9));
199 ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
200 ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
Colin Crossb27e2002013-01-28 17:19:43 -0800201
Tom Cherrye275d6d2017-12-11 23:31:33 -0800202 const prop_info* pi = system_properties.Find("property");
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800203 ASSERT_TRUE(pi != nullptr);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800204 system_properties.Update(const_cast<prop_info*>(pi), "value4", 6);
Colin Crossb27e2002013-01-28 17:19:43 -0800205
Tom Cherrye275d6d2017-12-11 23:31:33 -0800206 pi = system_properties.Find("other_property");
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800207 ASSERT_TRUE(pi != nullptr);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800208 system_properties.Update(const_cast<prop_info*>(pi), "newvalue5", 9);
Colin Crossb27e2002013-01-28 17:19:43 -0800209
Tom Cherrye275d6d2017-12-11 23:31:33 -0800210 pi = system_properties.Find("property_other");
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800211 ASSERT_TRUE(pi != nullptr);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800212 system_properties.Update(const_cast<prop_info*>(pi), "value6", 6);
Colin Crossb27e2002013-01-28 17:19:43 -0800213
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800214 char propvalue[PROP_VALUE_MAX];
Tom Cherrye275d6d2017-12-11 23:31:33 -0800215 ASSERT_EQ(6, system_properties.Get("property", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800216 ASSERT_STREQ(propvalue, "value4");
217
Tom Cherrye275d6d2017-12-11 23:31:33 -0800218 ASSERT_EQ(9, system_properties.Get("other_property", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800219 ASSERT_STREQ(propvalue, "newvalue5");
220
Tom Cherrye275d6d2017-12-11 23:31:33 -0800221 ASSERT_EQ(6, system_properties.Get("property_other", propvalue));
Colin Crossb27e2002013-01-28 17:19:43 -0800222 ASSERT_STREQ(propvalue, "value6");
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800223#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800224 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800225#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800226}
227
Greg Hackmanncb215a72013-02-13 14:41:48 -0800228TEST(properties, fill) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800229#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800230 SystemPropertiesTest system_properties;
231 ASSERT_TRUE(system_properties.valid());
232
Colin Crossb27e2002013-01-28 17:19:43 -0800233 char prop_name[PROP_NAME_MAX];
234 char prop_value[PROP_VALUE_MAX];
235 char prop_value_ret[PROP_VALUE_MAX];
Greg Hackmanncb215a72013-02-13 14:41:48 -0800236 int count = 0;
Colin Crossb27e2002013-01-28 17:19:43 -0800237 int ret;
238
Greg Hackmanncb215a72013-02-13 14:41:48 -0800239 while (true) {
240 ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d", count);
Colin Crossb27e2002013-01-28 17:19:43 -0800241 memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
Greg Hackmanncb215a72013-02-13 14:41:48 -0800242 ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d", count);
Colin Crossb27e2002013-01-28 17:19:43 -0800243 memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
244 prop_name[PROP_NAME_MAX - 1] = 0;
245 prop_value[PROP_VALUE_MAX - 1] = 0;
246
Tom Cherrye275d6d2017-12-11 23:31:33 -0800247 ret = system_properties.Add(prop_name, PROP_NAME_MAX - 1, prop_value, PROP_VALUE_MAX - 1);
Greg Hackmanncb215a72013-02-13 14:41:48 -0800248 if (ret < 0)
249 break;
250
251 count++;
Colin Crossb27e2002013-01-28 17:19:43 -0800252 }
253
Greg Hackmanncb215a72013-02-13 14:41:48 -0800254 // For historical reasons at least 247 properties must be supported
255 ASSERT_GE(count, 247);
256
257 for (int i = 0; i < count; i++) {
Colin Crossb27e2002013-01-28 17:19:43 -0800258 ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d", i);
259 memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
260 ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d", i);
261 memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
262 prop_name[PROP_NAME_MAX - 1] = 0;
263 prop_value[PROP_VALUE_MAX - 1] = 0;
264 memset(prop_value_ret, '\0', PROP_VALUE_MAX);
265
Tom Cherrye275d6d2017-12-11 23:31:33 -0800266 ASSERT_EQ(PROP_VALUE_MAX - 1, system_properties.Get(prop_name, prop_value_ret));
Colin Crossb27e2002013-01-28 17:19:43 -0800267 ASSERT_EQ(0, memcmp(prop_value, prop_value_ret, PROP_VALUE_MAX));
268 }
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800269#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800270 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800271#endif // __BIONIC__
Greg Hackmannc6ff8442013-02-12 16:39:31 -0800272}
273
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800274TEST(properties, __system_property_foreach) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800275#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800276 SystemPropertiesTest system_properties;
277 ASSERT_TRUE(system_properties.valid());
Greg Hackmannc6ff8442013-02-12 16:39:31 -0800278
Tom Cherrye275d6d2017-12-11 23:31:33 -0800279 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
280 ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
281 ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
Greg Hackmannc6ff8442013-02-12 16:39:31 -0800282
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800283 size_t count = 0;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800284 ASSERT_EQ(0, system_properties.Foreach(foreach_test_callback, &count));
Greg Hackmannc6ff8442013-02-12 16:39:31 -0800285 ASSERT_EQ(3U, count);
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800286#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800287 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800288#endif // __BIONIC__
Greg Hackmannc6ff8442013-02-12 16:39:31 -0800289}
290
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800291TEST(properties, __system_property_find_nth) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800292#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800293 SystemPropertiesTest system_properties;
294 ASSERT_TRUE(system_properties.valid());
Colin Crossb27e2002013-01-28 17:19:43 -0800295
Tom Cherrye275d6d2017-12-11 23:31:33 -0800296 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
297 ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
298 ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
Colin Crossb27e2002013-01-28 17:19:43 -0800299
Elliott Hughes438e0192017-04-17 14:53:07 -0700300 char name[PROP_NAME_MAX];
301 char value[PROP_VALUE_MAX];
Tom Cherrye275d6d2017-12-11 23:31:33 -0800302 EXPECT_EQ(6, system_properties.Read(system_properties.FindNth(0), name, value));
Elliott Hughes438e0192017-04-17 14:53:07 -0700303 EXPECT_STREQ("property", name);
304 EXPECT_STREQ("value1", value);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800305 EXPECT_EQ(6, system_properties.Read(system_properties.FindNth(1), name, value));
Elliott Hughes438e0192017-04-17 14:53:07 -0700306 EXPECT_STREQ("other_property", name);
307 EXPECT_STREQ("value2", value);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800308 EXPECT_EQ(6, system_properties.Read(system_properties.FindNth(2), name, value));
Elliott Hughes438e0192017-04-17 14:53:07 -0700309 EXPECT_STREQ("property_other", name);
310 EXPECT_STREQ("value3", value);
311
312 for (unsigned i = 3; i < 1024; ++i) {
Tom Cherrye275d6d2017-12-11 23:31:33 -0800313 ASSERT_TRUE(system_properties.FindNth(i) == nullptr);
Elliott Hughes438e0192017-04-17 14:53:07 -0700314 }
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800315#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800316 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800317#endif // __BIONIC__
Greg Hackmannd5276422013-06-17 12:37:09 -0700318}
319
320TEST(properties, fill_hierarchical) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800321#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800322 SystemPropertiesTest system_properties;
323 ASSERT_TRUE(system_properties.valid());
324
Greg Hackmannd5276422013-06-17 12:37:09 -0700325 char prop_name[PROP_NAME_MAX];
326 char prop_value[PROP_VALUE_MAX];
327 char prop_value_ret[PROP_VALUE_MAX];
328 int ret;
329
330 for (int i = 0; i < 8; i++) {
331 for (int j = 0; j < 8; j++) {
332 for (int k = 0; k < 8; k++) {
333 ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d.%d.%d", i, j, k);
334 memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
335 ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d.%d.%d", i, j, k);
336 memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
337 prop_name[PROP_NAME_MAX - 1] = 0;
338 prop_value[PROP_VALUE_MAX - 1] = 0;
339
Tom Cherrye275d6d2017-12-11 23:31:33 -0800340 ASSERT_EQ(0, system_properties.Add(
341 prop_name, PROP_NAME_MAX - 1, prop_value, PROP_VALUE_MAX - 1));
Greg Hackmannd5276422013-06-17 12:37:09 -0700342 }
343 }
344 }
345
346 for (int i = 0; i < 8; i++) {
347 for (int j = 0; j < 8; j++) {
348 for (int k = 0; k < 8; k++) {
349 ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d.%d.%d", i, j, k);
350 memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
351 ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d.%d.%d", i, j, k);
352 memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
353 prop_name[PROP_NAME_MAX - 1] = 0;
354 prop_value[PROP_VALUE_MAX - 1] = 0;
355 memset(prop_value_ret, '\0', PROP_VALUE_MAX);
356
Tom Cherrye275d6d2017-12-11 23:31:33 -0800357 ASSERT_EQ(PROP_VALUE_MAX - 1, system_properties.Get(prop_name, prop_value_ret));
Greg Hackmannd5276422013-06-17 12:37:09 -0700358 ASSERT_EQ(0, memcmp(prop_value, prop_value_ret, PROP_VALUE_MAX));
359 }
360 }
361 }
362
363 bool ok[8][8][8];
364 memset(ok, 0, sizeof(ok));
Tom Cherrye275d6d2017-12-11 23:31:33 -0800365 system_properties.Foreach(hierarchical_test_callback, ok);
Greg Hackmannd5276422013-06-17 12:37:09 -0700366
367 for (int i = 0; i < 8; i++) {
368 for (int j = 0; j < 8; j++) {
369 for (int k = 0; k < 8; k++) {
370 ASSERT_TRUE(ok[i][j][k]);
371 }
372 }
373 }
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800374#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800375 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800376#endif // __BIONIC__
Greg Hackmannd5276422013-06-17 12:37:09 -0700377}
378
Colin Crossb27e2002013-01-28 17:19:43 -0800379TEST(properties, errors) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800380#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800381 SystemPropertiesTest system_properties;
382 ASSERT_TRUE(system_properties.valid());
383
Colin Crossb27e2002013-01-28 17:19:43 -0800384 char prop_value[PROP_NAME_MAX];
385
Tom Cherrye275d6d2017-12-11 23:31:33 -0800386 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
387 ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
388 ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
Colin Crossb27e2002013-01-28 17:19:43 -0800389
Tom Cherrye275d6d2017-12-11 23:31:33 -0800390 ASSERT_EQ(0, system_properties.Find("property1"));
391 ASSERT_EQ(0, system_properties.Get("property1", prop_value));
Colin Crossb27e2002013-01-28 17:19:43 -0800392
Tom Cherrye275d6d2017-12-11 23:31:33 -0800393 ASSERT_EQ(-1, system_properties.Add("name", 4, "value", PROP_VALUE_MAX));
394 ASSERT_EQ(-1, system_properties.Update(NULL, "value", PROP_VALUE_MAX));
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800395#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800396 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800397#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800398}
399
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800400TEST(properties, __system_property_serial) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800401#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800402 SystemPropertiesTest system_properties;
403 ASSERT_TRUE(system_properties.valid());
Colin Crossb27e2002013-01-28 17:19:43 -0800404
Tom Cherrye275d6d2017-12-11 23:31:33 -0800405 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
406 const prop_info* pi = system_properties.Find("property");
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800407 ASSERT_TRUE(pi != nullptr);
Raman Tennetib481a2e2019-11-12 20:41:55 +0000408 unsigned serial = __system_property_serial(pi);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800409 ASSERT_EQ(0, system_properties.Update(const_cast<prop_info*>(pi), "value2", 6));
Raman Tennetib481a2e2019-11-12 20:41:55 +0000410 ASSERT_NE(serial, __system_property_serial(pi));
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800411#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800412 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800413#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800414}
415
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800416TEST(properties, __system_property_wait_any) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800417#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800418 SystemPropertiesTest system_properties;
419 ASSERT_TRUE(system_properties.valid());
Colin Crossb27e2002013-01-28 17:19:43 -0800420
Tom Cherrye275d6d2017-12-11 23:31:33 -0800421 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
422 unsigned serial = system_properties.WaitAny(0);
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000423
Tom Cherrye275d6d2017-12-11 23:31:33 -0800424 prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
Dimitry Ivanov16b2a4d2017-01-24 20:43:29 +0000425 ASSERT_TRUE(pi != nullptr);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800426 system_properties.Update(pi, "value2", 6);
427 serial = system_properties.WaitAny(serial);
Colin Crossb27e2002013-01-28 17:19:43 -0800428
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800429 int flag = 0;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800430 std::thread thread([&system_properties, &flag]() {
431 prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
432 usleep(100000);
433
434 flag = 1;
435 system_properties.Update(pi, "value3", 6);
436 });
Colin Crossb27e2002013-01-28 17:19:43 -0800437 ASSERT_EQ(flag, 0);
Tom Cherrye275d6d2017-12-11 23:31:33 -0800438 serial = system_properties.WaitAny(serial);
Colin Crossb27e2002013-01-28 17:19:43 -0800439 ASSERT_EQ(flag, 1);
440
Tom Cherrye275d6d2017-12-11 23:31:33 -0800441 thread.join();
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800442#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800443 GTEST_SKIP() << "bionic-only test";
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800444#endif // __BIONIC__
445}
446
447TEST(properties, __system_property_wait) {
448#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800449 SystemPropertiesTest system_properties;
450 ASSERT_TRUE(system_properties.valid());
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800451
Tom Cherrye275d6d2017-12-11 23:31:33 -0800452 ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800453
Tom Cherrye275d6d2017-12-11 23:31:33 -0800454 prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800455 ASSERT_TRUE(pi != nullptr);
456
Raman Tennetib481a2e2019-11-12 20:41:55 +0000457 unsigned serial = __system_property_serial(pi);
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800458
Tom Cherrye275d6d2017-12-11 23:31:33 -0800459 std::thread thread([&system_properties]() {
460 prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800461 ASSERT_TRUE(pi != nullptr);
462
Tom Cherrye275d6d2017-12-11 23:31:33 -0800463 system_properties.Update(pi, "value2", 6);
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800464 });
465
Elliott Hughes40c885a2017-02-16 17:13:04 -0800466 uint32_t new_serial;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800467 system_properties.Wait(pi, serial, &new_serial, nullptr);
Elliott Hughes40c885a2017-02-16 17:13:04 -0800468 ASSERT_GT(new_serial, serial);
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800469
470 char value[PROP_VALUE_MAX];
Tom Cherrye275d6d2017-12-11 23:31:33 -0800471 ASSERT_EQ(6, system_properties.Get("property", value));
Elliott Hughesa0d374d2017-02-10 18:13:46 -0800472 ASSERT_STREQ("value2", value);
473
474 thread.join();
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800475#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800476 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800477#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800478}
479
480class KilledByFault {
481 public:
482 explicit KilledByFault() {};
483 bool operator()(int exit_status) const;
484};
485
486bool KilledByFault::operator()(int exit_status) const {
487 return WIFSIGNALED(exit_status) &&
488 (WTERMSIG(exit_status) == SIGSEGV ||
489 WTERMSIG(exit_status) == SIGBUS ||
490 WTERMSIG(exit_status) == SIGABRT);
491}
492
Elliott Hughes141b9172021-04-09 17:13:09 -0700493using properties_DeathTest = SilentDeathTest;
Yabin Cui9df70402014-11-05 18:01:01 -0800494
495TEST_F(properties_DeathTest, read_only) {
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800496#if defined(__BIONIC__)
Elliott Hughese4375192013-10-21 17:09:52 -0700497
498 // This test only makes sense if we're talking to the real system property service.
499 struct stat sb;
Nate Myrenb8c87b12023-08-28 16:46:39 -0700500 ASSERT_FALSE(stat(PROP_DIRNAME, &sb) == -1 && errno == ENOENT);
Elliott Hughese4375192013-10-21 17:09:52 -0700501
502 ASSERT_EXIT(__system_property_add("property", 8, "value", 5), KilledByFault(), "");
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800503#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800504 GTEST_SKIP() << "bionic-only test";
Christopher Ferrisf04935c2013-12-20 18:43:21 -0800505#endif // __BIONIC__
Colin Crossb27e2002013-01-28 17:19:43 -0800506}
Tom Cherry8a311632017-10-09 13:49:17 -0700507
508TEST(properties, __system_property_extra_long_read_only) {
509#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800510 SystemPropertiesTest system_properties;
511 ASSERT_TRUE(system_properties.valid());
Tom Cherry8a311632017-10-09 13:49:17 -0700512
513 std::vector<std::pair<std::string, std::string>> short_properties = {
514 { "ro.0char", std::string() },
515 { "ro.50char", std::string(50, 'x') },
516 { "ro.91char", std::string(91, 'x') },
517 };
518
519 std::vector<std::pair<std::string, std::string>> long_properties = {
520 { "ro.92char", std::string(92, 'x') },
521 { "ro.93char", std::string(93, 'x') },
522 { "ro.1000char", std::string(1000, 'x') },
523 };
524
525 for (const auto& property : short_properties) {
526 const std::string& name = property.first;
527 const std::string& value = property.second;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800528 ASSERT_EQ(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
Tom Cherry8a311632017-10-09 13:49:17 -0700529 }
530
531 for (const auto& property : long_properties) {
532 const std::string& name = property.first;
533 const std::string& value = property.second;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800534 ASSERT_EQ(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
Tom Cherry8a311632017-10-09 13:49:17 -0700535 }
536
Tom Cherrye275d6d2017-12-11 23:31:33 -0800537 auto check_with_legacy_read = [&system_properties](const std::string& name,
538 const std::string& expected_value) {
Tom Cherry8a311632017-10-09 13:49:17 -0700539 char value[PROP_VALUE_MAX];
Tom Cherrye275d6d2017-12-11 23:31:33 -0800540 EXPECT_EQ(static_cast<int>(expected_value.size()), system_properties.Get(name.c_str(), value))
Tom Cherry8a311632017-10-09 13:49:17 -0700541 << name;
542 EXPECT_EQ(expected_value, value) << name;
543 };
544
Tom Cherrye275d6d2017-12-11 23:31:33 -0800545 auto check_with_read_callback = [&system_properties](const std::string& name,
546 const std::string& expected_value) {
547 const prop_info* pi = system_properties.Find(name.c_str());
Tom Cherry8a311632017-10-09 13:49:17 -0700548 ASSERT_NE(nullptr, pi);
549 std::string value;
Tom Cherrye275d6d2017-12-11 23:31:33 -0800550 system_properties.ReadCallback(pi,
551 [](void* cookie, const char*, const char* value, uint32_t) {
552 auto* out_value = reinterpret_cast<std::string*>(cookie);
553 *out_value = value;
554 },
555 &value);
Tom Cherry8a311632017-10-09 13:49:17 -0700556 EXPECT_EQ(expected_value, value) << name;
557 };
558
559 for (const auto& property : short_properties) {
560 const std::string& name = property.first;
561 const std::string& value = property.second;
562 check_with_legacy_read(name, value);
563 check_with_read_callback(name, value);
564 }
565
Elliott Hughes30088842023-09-14 18:35:11 +0000566 static constexpr const char* kExtraLongLegacyError =
Tom Cherry8a311632017-10-09 13:49:17 -0700567 "Must use __system_property_read_callback() to read";
568 for (const auto& property : long_properties) {
569 const std::string& name = property.first;
570 const std::string& value = property.second;
571 check_with_legacy_read(name, kExtraLongLegacyError);
572 check_with_read_callback(name, value);
573 }
574
575#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800576 GTEST_SKIP() << "bionic-only test";
Tom Cherry8a311632017-10-09 13:49:17 -0700577#endif // __BIONIC__
578}
579
580// pa_size is 128 * 1024 currently, if a property is longer then we expect it to fail gracefully.
581TEST(properties, __system_property_extra_long_read_only_too_long) {
582#if defined(__BIONIC__)
Tom Cherrye275d6d2017-12-11 23:31:33 -0800583 SystemPropertiesTest system_properties;
584 ASSERT_TRUE(system_properties.valid());
Tom Cherry8a311632017-10-09 13:49:17 -0700585
586 auto name = "ro.super_long_property"s;
587 auto value = std::string(128 * 1024 + 1, 'x');
Tom Cherrye275d6d2017-12-11 23:31:33 -0800588 ASSERT_NE(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
Tom Cherry8a311632017-10-09 13:49:17 -0700589
590#else // __BIONIC__
Elliott Hughesbcaa4542019-03-08 15:20:23 -0800591 GTEST_SKIP() << "bionic-only test";
Tom Cherry8a311632017-10-09 13:49:17 -0700592#endif // __BIONIC__
593}