1*8d67ca89SAndroid Build Coastguard Worker /*
2*8d67ca89SAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project
3*8d67ca89SAndroid Build Coastguard Worker *
4*8d67ca89SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*8d67ca89SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*8d67ca89SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*8d67ca89SAndroid Build Coastguard Worker *
8*8d67ca89SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*8d67ca89SAndroid Build Coastguard Worker *
10*8d67ca89SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*8d67ca89SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*8d67ca89SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8d67ca89SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*8d67ca89SAndroid Build Coastguard Worker * limitations under the License.
15*8d67ca89SAndroid Build Coastguard Worker */
16*8d67ca89SAndroid Build Coastguard Worker
17*8d67ca89SAndroid Build Coastguard Worker #include <gtest/gtest.h>
18*8d67ca89SAndroid Build Coastguard Worker
19*8d67ca89SAndroid Build Coastguard Worker #include <errno.h>
20*8d67ca89SAndroid Build Coastguard Worker #include <sys/wait.h>
21*8d67ca89SAndroid Build Coastguard Worker #include <unistd.h>
22*8d67ca89SAndroid Build Coastguard Worker
23*8d67ca89SAndroid Build Coastguard Worker #include <string>
24*8d67ca89SAndroid Build Coastguard Worker #include <thread>
25*8d67ca89SAndroid Build Coastguard Worker
26*8d67ca89SAndroid Build Coastguard Worker #include <android-base/file.h>
27*8d67ca89SAndroid Build Coastguard Worker #include <android-base/silent_death_test.h>
28*8d67ca89SAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
29*8d67ca89SAndroid Build Coastguard Worker
30*8d67ca89SAndroid Build Coastguard Worker #include "utils.h"
31*8d67ca89SAndroid Build Coastguard Worker
32*8d67ca89SAndroid Build Coastguard Worker using namespace std::literals;
33*8d67ca89SAndroid Build Coastguard Worker
34*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
35*8d67ca89SAndroid Build Coastguard Worker
36*8d67ca89SAndroid Build Coastguard Worker #include <stdlib.h>
37*8d67ca89SAndroid Build Coastguard Worker #include <sys/mount.h>
38*8d67ca89SAndroid Build Coastguard Worker #include <sys/system_properties.h>
39*8d67ca89SAndroid Build Coastguard Worker
40*8d67ca89SAndroid Build Coastguard Worker #include <system_properties/system_properties.h>
41*8d67ca89SAndroid Build Coastguard Worker
42*8d67ca89SAndroid Build Coastguard Worker class SystemPropertiesTest : public SystemProperties {
43*8d67ca89SAndroid Build Coastguard Worker public:
SystemPropertiesTest()44*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest() : SystemProperties(false) {
45*8d67ca89SAndroid Build Coastguard Worker appcompat_path = android::base::StringPrintf("%s/appcompat_override", dir_.path);
46*8d67ca89SAndroid Build Coastguard Worker mount_path = android::base::StringPrintf("%s/__properties__", dir_.path);
47*8d67ca89SAndroid Build Coastguard Worker mkdir(appcompat_path.c_str(), S_IRWXU | S_IXGRP | S_IXOTH);
48*8d67ca89SAndroid Build Coastguard Worker valid_ = AreaInit(dir_.path, nullptr, true);
49*8d67ca89SAndroid Build Coastguard Worker }
~SystemPropertiesTest()50*8d67ca89SAndroid Build Coastguard Worker ~SystemPropertiesTest() {
51*8d67ca89SAndroid Build Coastguard Worker if (valid_) {
52*8d67ca89SAndroid Build Coastguard Worker contexts_->FreeAndUnmap();
53*8d67ca89SAndroid Build Coastguard Worker }
54*8d67ca89SAndroid Build Coastguard Worker umount2(dir_.path, MNT_DETACH);
55*8d67ca89SAndroid Build Coastguard Worker umount2(real_sysprop_dir.c_str(), MNT_DETACH);
56*8d67ca89SAndroid Build Coastguard Worker }
57*8d67ca89SAndroid Build Coastguard Worker
valid() const58*8d67ca89SAndroid Build Coastguard Worker bool valid() const {
59*8d67ca89SAndroid Build Coastguard Worker return valid_;
60*8d67ca89SAndroid Build Coastguard Worker }
61*8d67ca89SAndroid Build Coastguard Worker
get_path() const62*8d67ca89SAndroid Build Coastguard Worker const char* get_path() const { return dir_.path; }
63*8d67ca89SAndroid Build Coastguard Worker
get_appcompat_path() const64*8d67ca89SAndroid Build Coastguard Worker const char* get_appcompat_path() const { return appcompat_path.c_str(); }
65*8d67ca89SAndroid Build Coastguard Worker
get_mount_path() const66*8d67ca89SAndroid Build Coastguard Worker const char* get_mount_path() const { return mount_path.c_str(); }
67*8d67ca89SAndroid Build Coastguard Worker
get_real_sysprop_dir() const68*8d67ca89SAndroid Build Coastguard Worker const char* get_real_sysprop_dir() const { return real_sysprop_dir.c_str(); }
69*8d67ca89SAndroid Build Coastguard Worker
70*8d67ca89SAndroid Build Coastguard Worker std::string appcompat_path;
71*8d67ca89SAndroid Build Coastguard Worker std::string mount_path;
72*8d67ca89SAndroid Build Coastguard Worker std::string real_sysprop_dir = "/dev/__properties__";
73*8d67ca89SAndroid Build Coastguard Worker
74*8d67ca89SAndroid Build Coastguard Worker private:
75*8d67ca89SAndroid Build Coastguard Worker TemporaryDir dir_;
76*8d67ca89SAndroid Build Coastguard Worker bool valid_;
77*8d67ca89SAndroid Build Coastguard Worker };
78*8d67ca89SAndroid Build Coastguard Worker
foreach_test_callback(const prop_info * pi,void * cookie)79*8d67ca89SAndroid Build Coastguard Worker static void foreach_test_callback(const prop_info *pi, void* cookie) {
80*8d67ca89SAndroid Build Coastguard Worker size_t *count = static_cast<size_t *>(cookie);
81*8d67ca89SAndroid Build Coastguard Worker
82*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pi != nullptr);
83*8d67ca89SAndroid Build Coastguard Worker (*count)++;
84*8d67ca89SAndroid Build Coastguard Worker }
85*8d67ca89SAndroid Build Coastguard Worker
hierarchical_test_callback(const prop_info * pi,void * cookie)86*8d67ca89SAndroid Build Coastguard Worker static void hierarchical_test_callback(const prop_info *pi, void *cookie) {
87*8d67ca89SAndroid Build Coastguard Worker bool (*ok)[8][8] = static_cast<bool (*)[8][8]>(cookie);
88*8d67ca89SAndroid Build Coastguard Worker
89*8d67ca89SAndroid Build Coastguard Worker char name[PROP_NAME_MAX];
90*8d67ca89SAndroid Build Coastguard Worker char value[PROP_VALUE_MAX];
91*8d67ca89SAndroid Build Coastguard Worker
92*8d67ca89SAndroid Build Coastguard Worker __system_property_read(pi, name, value);
93*8d67ca89SAndroid Build Coastguard Worker
94*8d67ca89SAndroid Build Coastguard Worker int name_i, name_j, name_k;
95*8d67ca89SAndroid Build Coastguard Worker int value_i, value_j, value_k;
96*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(3, sscanf(name, "property_%d.%d.%d", &name_i, &name_j, &name_k));
97*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(3, sscanf(value, "value_%d.%d.%d", &value_i, &value_j, &value_k));
98*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(name_i, value_i);
99*8d67ca89SAndroid Build Coastguard Worker ASSERT_GE(name_i, 0);
100*8d67ca89SAndroid Build Coastguard Worker ASSERT_LT(name_i, 8);
101*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(name_j, value_j);
102*8d67ca89SAndroid Build Coastguard Worker ASSERT_GE(name_j, 0);
103*8d67ca89SAndroid Build Coastguard Worker ASSERT_LT(name_j, 8);
104*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(name_k, value_k);
105*8d67ca89SAndroid Build Coastguard Worker ASSERT_GE(name_k, 0);
106*8d67ca89SAndroid Build Coastguard Worker ASSERT_LT(name_k, 8);
107*8d67ca89SAndroid Build Coastguard Worker
108*8d67ca89SAndroid Build Coastguard Worker ok[name_i][name_j][name_k] = true;
109*8d67ca89SAndroid Build Coastguard Worker }
110*8d67ca89SAndroid Build Coastguard Worker
111*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
112*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,__system_property_add)113*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_add) {
114*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
115*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
116*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
117*8d67ca89SAndroid Build Coastguard Worker
118*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
119*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
120*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
121*8d67ca89SAndroid Build Coastguard Worker
122*8d67ca89SAndroid Build Coastguard Worker // check that there is no limit on property name length
123*8d67ca89SAndroid Build Coastguard Worker char name[PROP_NAME_MAX + 11];
124*8d67ca89SAndroid Build Coastguard Worker name[0] = 'p';
125*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 1; i < sizeof(name); i++) {
126*8d67ca89SAndroid Build Coastguard Worker name[i] = 'x';
127*8d67ca89SAndroid Build Coastguard Worker }
128*8d67ca89SAndroid Build Coastguard Worker
129*8d67ca89SAndroid Build Coastguard Worker name[sizeof(name)-1] = '\0';
130*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add(name, strlen(name), "value", 5));
131*8d67ca89SAndroid Build Coastguard Worker
132*8d67ca89SAndroid Build Coastguard Worker char propvalue[PROP_VALUE_MAX];
133*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(6, system_properties.Get("property", propvalue));
134*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "value1");
135*8d67ca89SAndroid Build Coastguard Worker
136*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(6, system_properties.Get("other_property", propvalue));
137*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "value2");
138*8d67ca89SAndroid Build Coastguard Worker
139*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(6, system_properties.Get("property_other", propvalue));
140*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "value3");
141*8d67ca89SAndroid Build Coastguard Worker
142*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(5, system_properties.Get(name, propvalue));
143*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "value");
144*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
145*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
146*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
147*8d67ca89SAndroid Build Coastguard Worker }
148*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,__system_property_add_appcompat)149*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_add_appcompat) {
150*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
151*8d67ca89SAndroid Build Coastguard Worker if (getuid() != 0) GTEST_SKIP() << "test requires root";
152*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
153*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
154*8d67ca89SAndroid Build Coastguard Worker
155*8d67ca89SAndroid Build Coastguard Worker char name[] = "ro.property";
156*8d67ca89SAndroid Build Coastguard Worker char override_name[] = "ro.appcompat_override.ro.property";
157*8d67ca89SAndroid Build Coastguard Worker char name_not_written[] = "ro.property_other";
158*8d67ca89SAndroid Build Coastguard Worker char override_with_no_real[] = "ro.appcompat_override.ro.property_other";
159*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add(name, strlen(name), "value1", 6));
160*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add(override_name, strlen(override_name), "value2", 6));
161*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add(override_with_no_real, strlen(override_with_no_real),
162*8d67ca89SAndroid Build Coastguard Worker "value3", 6));
163*8d67ca89SAndroid Build Coastguard Worker
164*8d67ca89SAndroid Build Coastguard Worker char propvalue[PROP_VALUE_MAX];
165*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(6, system_properties.Get(name, propvalue));
166*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "value1");
167*8d67ca89SAndroid Build Coastguard Worker
168*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(6, system_properties.Get(override_name, propvalue));
169*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "value2");
170*8d67ca89SAndroid Build Coastguard Worker
171*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Get(name_not_written, propvalue));
172*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "");
173*8d67ca89SAndroid Build Coastguard Worker
174*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(6, system_properties.Get(override_with_no_real, propvalue));
175*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "value3");
176*8d67ca89SAndroid Build Coastguard Worker
177*8d67ca89SAndroid Build Coastguard Worker int ret = mount(system_properties.get_appcompat_path(), system_properties.get_path(), nullptr,
178*8d67ca89SAndroid Build Coastguard Worker MS_BIND | MS_REC, nullptr);
179*8d67ca89SAndroid Build Coastguard Worker if (ret != 0) {
180*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(0);
181*8d67ca89SAndroid Build Coastguard Worker }
182*8d67ca89SAndroid Build Coastguard Worker system_properties.Reload(true);
183*8d67ca89SAndroid Build Coastguard Worker
184*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(6, system_properties.Get(name, propvalue));
185*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "value2");
186*8d67ca89SAndroid Build Coastguard Worker
187*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Get(override_name, propvalue));
188*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "");
189*8d67ca89SAndroid Build Coastguard Worker
190*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(6, system_properties.Get(name_not_written, propvalue));
191*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "value3");
192*8d67ca89SAndroid Build Coastguard Worker
193*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Get(override_with_no_real, propvalue));
194*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "");
195*8d67ca89SAndroid Build Coastguard Worker
196*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
197*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
198*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
199*8d67ca89SAndroid Build Coastguard Worker }
200*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,__system_property_update)201*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_update) {
202*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
203*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
204*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
205*8d67ca89SAndroid Build Coastguard Worker
206*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property", 8, "oldvalue1", 9));
207*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
208*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
209*8d67ca89SAndroid Build Coastguard Worker
210*8d67ca89SAndroid Build Coastguard Worker const prop_info* pi = system_properties.Find("property");
211*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pi != nullptr);
212*8d67ca89SAndroid Build Coastguard Worker system_properties.Update(const_cast<prop_info*>(pi), "value4", 6);
213*8d67ca89SAndroid Build Coastguard Worker
214*8d67ca89SAndroid Build Coastguard Worker pi = system_properties.Find("other_property");
215*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pi != nullptr);
216*8d67ca89SAndroid Build Coastguard Worker system_properties.Update(const_cast<prop_info*>(pi), "newvalue5", 9);
217*8d67ca89SAndroid Build Coastguard Worker
218*8d67ca89SAndroid Build Coastguard Worker pi = system_properties.Find("property_other");
219*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pi != nullptr);
220*8d67ca89SAndroid Build Coastguard Worker system_properties.Update(const_cast<prop_info*>(pi), "value6", 6);
221*8d67ca89SAndroid Build Coastguard Worker
222*8d67ca89SAndroid Build Coastguard Worker char propvalue[PROP_VALUE_MAX];
223*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(6, system_properties.Get("property", propvalue));
224*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "value4");
225*8d67ca89SAndroid Build Coastguard Worker
226*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(9, system_properties.Get("other_property", propvalue));
227*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "newvalue5");
228*8d67ca89SAndroid Build Coastguard Worker
229*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(6, system_properties.Get("property_other", propvalue));
230*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ(propvalue, "value6");
231*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
232*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
233*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
234*8d67ca89SAndroid Build Coastguard Worker }
235*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,fill)236*8d67ca89SAndroid Build Coastguard Worker TEST(properties, fill) {
237*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
238*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
239*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
240*8d67ca89SAndroid Build Coastguard Worker
241*8d67ca89SAndroid Build Coastguard Worker char prop_name[PROP_NAME_MAX];
242*8d67ca89SAndroid Build Coastguard Worker char prop_value[PROP_VALUE_MAX];
243*8d67ca89SAndroid Build Coastguard Worker char prop_value_ret[PROP_VALUE_MAX];
244*8d67ca89SAndroid Build Coastguard Worker int count = 0;
245*8d67ca89SAndroid Build Coastguard Worker int ret;
246*8d67ca89SAndroid Build Coastguard Worker
247*8d67ca89SAndroid Build Coastguard Worker while (true) {
248*8d67ca89SAndroid Build Coastguard Worker ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d", count);
249*8d67ca89SAndroid Build Coastguard Worker memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
250*8d67ca89SAndroid Build Coastguard Worker ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d", count);
251*8d67ca89SAndroid Build Coastguard Worker memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
252*8d67ca89SAndroid Build Coastguard Worker prop_name[PROP_NAME_MAX - 1] = 0;
253*8d67ca89SAndroid Build Coastguard Worker prop_value[PROP_VALUE_MAX - 1] = 0;
254*8d67ca89SAndroid Build Coastguard Worker
255*8d67ca89SAndroid Build Coastguard Worker ret = system_properties.Add(prop_name, PROP_NAME_MAX - 1, prop_value, PROP_VALUE_MAX - 1);
256*8d67ca89SAndroid Build Coastguard Worker if (ret < 0)
257*8d67ca89SAndroid Build Coastguard Worker break;
258*8d67ca89SAndroid Build Coastguard Worker
259*8d67ca89SAndroid Build Coastguard Worker count++;
260*8d67ca89SAndroid Build Coastguard Worker }
261*8d67ca89SAndroid Build Coastguard Worker
262*8d67ca89SAndroid Build Coastguard Worker // For historical reasons at least 247 properties must be supported
263*8d67ca89SAndroid Build Coastguard Worker ASSERT_GE(count, 247);
264*8d67ca89SAndroid Build Coastguard Worker
265*8d67ca89SAndroid Build Coastguard Worker for (int i = 0; i < count; i++) {
266*8d67ca89SAndroid Build Coastguard Worker ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d", i);
267*8d67ca89SAndroid Build Coastguard Worker memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
268*8d67ca89SAndroid Build Coastguard Worker ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d", i);
269*8d67ca89SAndroid Build Coastguard Worker memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
270*8d67ca89SAndroid Build Coastguard Worker prop_name[PROP_NAME_MAX - 1] = 0;
271*8d67ca89SAndroid Build Coastguard Worker prop_value[PROP_VALUE_MAX - 1] = 0;
272*8d67ca89SAndroid Build Coastguard Worker memset(prop_value_ret, '\0', PROP_VALUE_MAX);
273*8d67ca89SAndroid Build Coastguard Worker
274*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(PROP_VALUE_MAX - 1, system_properties.Get(prop_name, prop_value_ret));
275*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(prop_value, prop_value_ret, PROP_VALUE_MAX));
276*8d67ca89SAndroid Build Coastguard Worker }
277*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
278*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
279*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
280*8d67ca89SAndroid Build Coastguard Worker }
281*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,__system_property_foreach)282*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_foreach) {
283*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
284*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
285*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
286*8d67ca89SAndroid Build Coastguard Worker
287*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
288*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
289*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
290*8d67ca89SAndroid Build Coastguard Worker
291*8d67ca89SAndroid Build Coastguard Worker size_t count = 0;
292*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Foreach(foreach_test_callback, &count));
293*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(3U, count);
294*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
295*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
296*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
297*8d67ca89SAndroid Build Coastguard Worker }
298*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,__system_property_find_nth)299*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_find_nth) {
300*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
301*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
302*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
303*8d67ca89SAndroid Build Coastguard Worker
304*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
305*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
306*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
307*8d67ca89SAndroid Build Coastguard Worker
308*8d67ca89SAndroid Build Coastguard Worker char name[PROP_NAME_MAX];
309*8d67ca89SAndroid Build Coastguard Worker char value[PROP_VALUE_MAX];
310*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(6, system_properties.Read(system_properties.FindNth(0), name, value));
311*8d67ca89SAndroid Build Coastguard Worker EXPECT_STREQ("property", name);
312*8d67ca89SAndroid Build Coastguard Worker EXPECT_STREQ("value1", value);
313*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(6, system_properties.Read(system_properties.FindNth(1), name, value));
314*8d67ca89SAndroid Build Coastguard Worker EXPECT_STREQ("other_property", name);
315*8d67ca89SAndroid Build Coastguard Worker EXPECT_STREQ("value2", value);
316*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(6, system_properties.Read(system_properties.FindNth(2), name, value));
317*8d67ca89SAndroid Build Coastguard Worker EXPECT_STREQ("property_other", name);
318*8d67ca89SAndroid Build Coastguard Worker EXPECT_STREQ("value3", value);
319*8d67ca89SAndroid Build Coastguard Worker
320*8d67ca89SAndroid Build Coastguard Worker for (unsigned i = 3; i < 1024; ++i) {
321*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.FindNth(i) == nullptr);
322*8d67ca89SAndroid Build Coastguard Worker }
323*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
324*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
325*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
326*8d67ca89SAndroid Build Coastguard Worker }
327*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,fill_hierarchical)328*8d67ca89SAndroid Build Coastguard Worker TEST(properties, fill_hierarchical) {
329*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
330*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
331*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
332*8d67ca89SAndroid Build Coastguard Worker
333*8d67ca89SAndroid Build Coastguard Worker char prop_name[PROP_NAME_MAX];
334*8d67ca89SAndroid Build Coastguard Worker char prop_value[PROP_VALUE_MAX];
335*8d67ca89SAndroid Build Coastguard Worker char prop_value_ret[PROP_VALUE_MAX];
336*8d67ca89SAndroid Build Coastguard Worker int ret;
337*8d67ca89SAndroid Build Coastguard Worker
338*8d67ca89SAndroid Build Coastguard Worker for (int i = 0; i < 8; i++) {
339*8d67ca89SAndroid Build Coastguard Worker for (int j = 0; j < 8; j++) {
340*8d67ca89SAndroid Build Coastguard Worker for (int k = 0; k < 8; k++) {
341*8d67ca89SAndroid Build Coastguard Worker ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d.%d.%d", i, j, k);
342*8d67ca89SAndroid Build Coastguard Worker memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
343*8d67ca89SAndroid Build Coastguard Worker ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d.%d.%d", i, j, k);
344*8d67ca89SAndroid Build Coastguard Worker memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
345*8d67ca89SAndroid Build Coastguard Worker prop_name[PROP_NAME_MAX - 1] = 0;
346*8d67ca89SAndroid Build Coastguard Worker prop_value[PROP_VALUE_MAX - 1] = 0;
347*8d67ca89SAndroid Build Coastguard Worker
348*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add(
349*8d67ca89SAndroid Build Coastguard Worker prop_name, PROP_NAME_MAX - 1, prop_value, PROP_VALUE_MAX - 1));
350*8d67ca89SAndroid Build Coastguard Worker }
351*8d67ca89SAndroid Build Coastguard Worker }
352*8d67ca89SAndroid Build Coastguard Worker }
353*8d67ca89SAndroid Build Coastguard Worker
354*8d67ca89SAndroid Build Coastguard Worker for (int i = 0; i < 8; i++) {
355*8d67ca89SAndroid Build Coastguard Worker for (int j = 0; j < 8; j++) {
356*8d67ca89SAndroid Build Coastguard Worker for (int k = 0; k < 8; k++) {
357*8d67ca89SAndroid Build Coastguard Worker ret = snprintf(prop_name, PROP_NAME_MAX - 1, "property_%d.%d.%d", i, j, k);
358*8d67ca89SAndroid Build Coastguard Worker memset(prop_name + ret, 'a', PROP_NAME_MAX - 1 - ret);
359*8d67ca89SAndroid Build Coastguard Worker ret = snprintf(prop_value, PROP_VALUE_MAX - 1, "value_%d.%d.%d", i, j, k);
360*8d67ca89SAndroid Build Coastguard Worker memset(prop_value + ret, 'b', PROP_VALUE_MAX - 1 - ret);
361*8d67ca89SAndroid Build Coastguard Worker prop_name[PROP_NAME_MAX - 1] = 0;
362*8d67ca89SAndroid Build Coastguard Worker prop_value[PROP_VALUE_MAX - 1] = 0;
363*8d67ca89SAndroid Build Coastguard Worker memset(prop_value_ret, '\0', PROP_VALUE_MAX);
364*8d67ca89SAndroid Build Coastguard Worker
365*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(PROP_VALUE_MAX - 1, system_properties.Get(prop_name, prop_value_ret));
366*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, memcmp(prop_value, prop_value_ret, PROP_VALUE_MAX));
367*8d67ca89SAndroid Build Coastguard Worker }
368*8d67ca89SAndroid Build Coastguard Worker }
369*8d67ca89SAndroid Build Coastguard Worker }
370*8d67ca89SAndroid Build Coastguard Worker
371*8d67ca89SAndroid Build Coastguard Worker bool ok[8][8][8];
372*8d67ca89SAndroid Build Coastguard Worker memset(ok, 0, sizeof(ok));
373*8d67ca89SAndroid Build Coastguard Worker system_properties.Foreach(hierarchical_test_callback, ok);
374*8d67ca89SAndroid Build Coastguard Worker
375*8d67ca89SAndroid Build Coastguard Worker for (int i = 0; i < 8; i++) {
376*8d67ca89SAndroid Build Coastguard Worker for (int j = 0; j < 8; j++) {
377*8d67ca89SAndroid Build Coastguard Worker for (int k = 0; k < 8; k++) {
378*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(ok[i][j][k]);
379*8d67ca89SAndroid Build Coastguard Worker }
380*8d67ca89SAndroid Build Coastguard Worker }
381*8d67ca89SAndroid Build Coastguard Worker }
382*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
383*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
384*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
385*8d67ca89SAndroid Build Coastguard Worker }
386*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,errors)387*8d67ca89SAndroid Build Coastguard Worker TEST(properties, errors) {
388*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
389*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
390*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
391*8d67ca89SAndroid Build Coastguard Worker
392*8d67ca89SAndroid Build Coastguard Worker char prop_value[PROP_NAME_MAX];
393*8d67ca89SAndroid Build Coastguard Worker
394*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
395*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("other_property", 14, "value2", 6));
396*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property_other", 14, "value3", 6));
397*8d67ca89SAndroid Build Coastguard Worker
398*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Find("property1"));
399*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Get("property1", prop_value));
400*8d67ca89SAndroid Build Coastguard Worker
401*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(-1, system_properties.Add("name", 4, "value", PROP_VALUE_MAX));
402*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(-1, system_properties.Update(NULL, "value", PROP_VALUE_MAX));
403*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
404*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
405*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
406*8d67ca89SAndroid Build Coastguard Worker }
407*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,__system_property_serial)408*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_serial) {
409*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
410*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
411*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
412*8d67ca89SAndroid Build Coastguard Worker
413*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
414*8d67ca89SAndroid Build Coastguard Worker const prop_info* pi = system_properties.Find("property");
415*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pi != nullptr);
416*8d67ca89SAndroid Build Coastguard Worker unsigned serial = __system_property_serial(pi);
417*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Update(const_cast<prop_info*>(pi), "value2", 6));
418*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(serial, __system_property_serial(pi));
419*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
420*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
421*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
422*8d67ca89SAndroid Build Coastguard Worker }
423*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,__system_property_wait_any)424*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_wait_any) {
425*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
426*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
427*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
428*8d67ca89SAndroid Build Coastguard Worker
429*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
430*8d67ca89SAndroid Build Coastguard Worker unsigned serial = system_properties.WaitAny(0);
431*8d67ca89SAndroid Build Coastguard Worker
432*8d67ca89SAndroid Build Coastguard Worker prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
433*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pi != nullptr);
434*8d67ca89SAndroid Build Coastguard Worker system_properties.Update(pi, "value2", 6);
435*8d67ca89SAndroid Build Coastguard Worker serial = system_properties.WaitAny(serial);
436*8d67ca89SAndroid Build Coastguard Worker
437*8d67ca89SAndroid Build Coastguard Worker int flag = 0;
438*8d67ca89SAndroid Build Coastguard Worker std::thread thread([&system_properties, &flag]() {
439*8d67ca89SAndroid Build Coastguard Worker prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
440*8d67ca89SAndroid Build Coastguard Worker usleep(100000);
441*8d67ca89SAndroid Build Coastguard Worker
442*8d67ca89SAndroid Build Coastguard Worker flag = 1;
443*8d67ca89SAndroid Build Coastguard Worker system_properties.Update(pi, "value3", 6);
444*8d67ca89SAndroid Build Coastguard Worker });
445*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(flag, 0);
446*8d67ca89SAndroid Build Coastguard Worker serial = system_properties.WaitAny(serial);
447*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(flag, 1);
448*8d67ca89SAndroid Build Coastguard Worker
449*8d67ca89SAndroid Build Coastguard Worker thread.join();
450*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
451*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
452*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
453*8d67ca89SAndroid Build Coastguard Worker }
454*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,__system_property_wait)455*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_wait) {
456*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
457*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
458*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
459*8d67ca89SAndroid Build Coastguard Worker
460*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add("property", 8, "value1", 6));
461*8d67ca89SAndroid Build Coastguard Worker
462*8d67ca89SAndroid Build Coastguard Worker prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
463*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pi != nullptr);
464*8d67ca89SAndroid Build Coastguard Worker
465*8d67ca89SAndroid Build Coastguard Worker unsigned serial = __system_property_serial(pi);
466*8d67ca89SAndroid Build Coastguard Worker
467*8d67ca89SAndroid Build Coastguard Worker std::thread thread([&system_properties]() {
468*8d67ca89SAndroid Build Coastguard Worker prop_info* pi = const_cast<prop_info*>(system_properties.Find("property"));
469*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(pi != nullptr);
470*8d67ca89SAndroid Build Coastguard Worker
471*8d67ca89SAndroid Build Coastguard Worker system_properties.Update(pi, "value2", 6);
472*8d67ca89SAndroid Build Coastguard Worker });
473*8d67ca89SAndroid Build Coastguard Worker
474*8d67ca89SAndroid Build Coastguard Worker uint32_t new_serial;
475*8d67ca89SAndroid Build Coastguard Worker system_properties.Wait(pi, serial, &new_serial, nullptr);
476*8d67ca89SAndroid Build Coastguard Worker ASSERT_GT(new_serial, serial);
477*8d67ca89SAndroid Build Coastguard Worker
478*8d67ca89SAndroid Build Coastguard Worker char value[PROP_VALUE_MAX];
479*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(6, system_properties.Get("property", value));
480*8d67ca89SAndroid Build Coastguard Worker ASSERT_STREQ("value2", value);
481*8d67ca89SAndroid Build Coastguard Worker
482*8d67ca89SAndroid Build Coastguard Worker thread.join();
483*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
484*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
485*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
486*8d67ca89SAndroid Build Coastguard Worker }
487*8d67ca89SAndroid Build Coastguard Worker
488*8d67ca89SAndroid Build Coastguard Worker class KilledByFault {
489*8d67ca89SAndroid Build Coastguard Worker public:
KilledByFault()490*8d67ca89SAndroid Build Coastguard Worker explicit KilledByFault() {};
491*8d67ca89SAndroid Build Coastguard Worker bool operator()(int exit_status) const;
492*8d67ca89SAndroid Build Coastguard Worker };
493*8d67ca89SAndroid Build Coastguard Worker
operator ()(int exit_status) const494*8d67ca89SAndroid Build Coastguard Worker bool KilledByFault::operator()(int exit_status) const {
495*8d67ca89SAndroid Build Coastguard Worker return WIFSIGNALED(exit_status) &&
496*8d67ca89SAndroid Build Coastguard Worker (WTERMSIG(exit_status) == SIGSEGV ||
497*8d67ca89SAndroid Build Coastguard Worker WTERMSIG(exit_status) == SIGBUS ||
498*8d67ca89SAndroid Build Coastguard Worker WTERMSIG(exit_status) == SIGABRT);
499*8d67ca89SAndroid Build Coastguard Worker }
500*8d67ca89SAndroid Build Coastguard Worker
501*8d67ca89SAndroid Build Coastguard Worker using properties_DeathTest = SilentDeathTest;
502*8d67ca89SAndroid Build Coastguard Worker
TEST_F(properties_DeathTest,read_only)503*8d67ca89SAndroid Build Coastguard Worker TEST_F(properties_DeathTest, read_only) {
504*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
505*8d67ca89SAndroid Build Coastguard Worker
506*8d67ca89SAndroid Build Coastguard Worker // This test only makes sense if we're talking to the real system property service.
507*8d67ca89SAndroid Build Coastguard Worker struct stat sb;
508*8d67ca89SAndroid Build Coastguard Worker ASSERT_FALSE(stat(PROP_DIRNAME, &sb) == -1 && errno == ENOENT);
509*8d67ca89SAndroid Build Coastguard Worker
510*8d67ca89SAndroid Build Coastguard Worker ASSERT_EXIT(__system_property_add("property", 8, "value", 5), KilledByFault(), "");
511*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
512*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
513*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
514*8d67ca89SAndroid Build Coastguard Worker }
515*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,__system_property_extra_long_read_only)516*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_extra_long_read_only) {
517*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
518*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
519*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
520*8d67ca89SAndroid Build Coastguard Worker
521*8d67ca89SAndroid Build Coastguard Worker std::vector<std::pair<std::string, std::string>> short_properties = {
522*8d67ca89SAndroid Build Coastguard Worker { "ro.0char", std::string() },
523*8d67ca89SAndroid Build Coastguard Worker { "ro.50char", std::string(50, 'x') },
524*8d67ca89SAndroid Build Coastguard Worker { "ro.91char", std::string(91, 'x') },
525*8d67ca89SAndroid Build Coastguard Worker };
526*8d67ca89SAndroid Build Coastguard Worker
527*8d67ca89SAndroid Build Coastguard Worker std::vector<std::pair<std::string, std::string>> long_properties = {
528*8d67ca89SAndroid Build Coastguard Worker { "ro.92char", std::string(92, 'x') },
529*8d67ca89SAndroid Build Coastguard Worker { "ro.93char", std::string(93, 'x') },
530*8d67ca89SAndroid Build Coastguard Worker { "ro.1000char", std::string(1000, 'x') },
531*8d67ca89SAndroid Build Coastguard Worker };
532*8d67ca89SAndroid Build Coastguard Worker
533*8d67ca89SAndroid Build Coastguard Worker for (const auto& property : short_properties) {
534*8d67ca89SAndroid Build Coastguard Worker const std::string& name = property.first;
535*8d67ca89SAndroid Build Coastguard Worker const std::string& value = property.second;
536*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
537*8d67ca89SAndroid Build Coastguard Worker }
538*8d67ca89SAndroid Build Coastguard Worker
539*8d67ca89SAndroid Build Coastguard Worker for (const auto& property : long_properties) {
540*8d67ca89SAndroid Build Coastguard Worker const std::string& name = property.first;
541*8d67ca89SAndroid Build Coastguard Worker const std::string& value = property.second;
542*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
543*8d67ca89SAndroid Build Coastguard Worker }
544*8d67ca89SAndroid Build Coastguard Worker
545*8d67ca89SAndroid Build Coastguard Worker auto check_with_legacy_read = [&system_properties](const std::string& name,
546*8d67ca89SAndroid Build Coastguard Worker const std::string& expected_value) {
547*8d67ca89SAndroid Build Coastguard Worker char value[PROP_VALUE_MAX];
548*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<int>(expected_value.size()), system_properties.Get(name.c_str(), value))
549*8d67ca89SAndroid Build Coastguard Worker << name;
550*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(expected_value, value) << name;
551*8d67ca89SAndroid Build Coastguard Worker };
552*8d67ca89SAndroid Build Coastguard Worker
553*8d67ca89SAndroid Build Coastguard Worker auto check_with_read_callback = [&system_properties](const std::string& name,
554*8d67ca89SAndroid Build Coastguard Worker const std::string& expected_value) {
555*8d67ca89SAndroid Build Coastguard Worker const prop_info* pi = system_properties.Find(name.c_str());
556*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(nullptr, pi);
557*8d67ca89SAndroid Build Coastguard Worker std::string value;
558*8d67ca89SAndroid Build Coastguard Worker system_properties.ReadCallback(pi,
559*8d67ca89SAndroid Build Coastguard Worker [](void* cookie, const char*, const char* value, uint32_t) {
560*8d67ca89SAndroid Build Coastguard Worker auto* out_value = reinterpret_cast<std::string*>(cookie);
561*8d67ca89SAndroid Build Coastguard Worker *out_value = value;
562*8d67ca89SAndroid Build Coastguard Worker },
563*8d67ca89SAndroid Build Coastguard Worker &value);
564*8d67ca89SAndroid Build Coastguard Worker EXPECT_EQ(expected_value, value) << name;
565*8d67ca89SAndroid Build Coastguard Worker };
566*8d67ca89SAndroid Build Coastguard Worker
567*8d67ca89SAndroid Build Coastguard Worker for (const auto& property : short_properties) {
568*8d67ca89SAndroid Build Coastguard Worker const std::string& name = property.first;
569*8d67ca89SAndroid Build Coastguard Worker const std::string& value = property.second;
570*8d67ca89SAndroid Build Coastguard Worker check_with_legacy_read(name, value);
571*8d67ca89SAndroid Build Coastguard Worker check_with_read_callback(name, value);
572*8d67ca89SAndroid Build Coastguard Worker }
573*8d67ca89SAndroid Build Coastguard Worker
574*8d67ca89SAndroid Build Coastguard Worker static constexpr const char* kExtraLongLegacyError =
575*8d67ca89SAndroid Build Coastguard Worker "Must use __system_property_read_callback() to read";
576*8d67ca89SAndroid Build Coastguard Worker for (const auto& property : long_properties) {
577*8d67ca89SAndroid Build Coastguard Worker const std::string& name = property.first;
578*8d67ca89SAndroid Build Coastguard Worker const std::string& value = property.second;
579*8d67ca89SAndroid Build Coastguard Worker check_with_legacy_read(name, kExtraLongLegacyError);
580*8d67ca89SAndroid Build Coastguard Worker check_with_read_callback(name, value);
581*8d67ca89SAndroid Build Coastguard Worker }
582*8d67ca89SAndroid Build Coastguard Worker
583*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
584*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
585*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
586*8d67ca89SAndroid Build Coastguard Worker }
587*8d67ca89SAndroid Build Coastguard Worker
588*8d67ca89SAndroid Build Coastguard Worker // pa_size is 128 * 1024 currently, if a property is longer then we expect it to fail gracefully.
TEST(properties,__system_property_extra_long_read_only_too_long)589*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_extra_long_read_only_too_long) {
590*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
591*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
592*8d67ca89SAndroid Build Coastguard Worker ASSERT_TRUE(system_properties.valid());
593*8d67ca89SAndroid Build Coastguard Worker
594*8d67ca89SAndroid Build Coastguard Worker auto name = "ro.super_long_property"s;
595*8d67ca89SAndroid Build Coastguard Worker
596*8d67ca89SAndroid Build Coastguard Worker #ifdef LARGE_SYSTEM_PROPERTY_NODE
597*8d67ca89SAndroid Build Coastguard Worker auto value = std::string(1024 * 1024 + 1, 'x');
598*8d67ca89SAndroid Build Coastguard Worker #else
599*8d67ca89SAndroid Build Coastguard Worker auto value = std::string(128 * 1024 + 1, 'x');
600*8d67ca89SAndroid Build Coastguard Worker #endif
601*8d67ca89SAndroid Build Coastguard Worker
602*8d67ca89SAndroid Build Coastguard Worker ASSERT_NE(0, system_properties.Add(name.c_str(), name.size(), value.c_str(), value.size()));
603*8d67ca89SAndroid Build Coastguard Worker
604*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
605*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
606*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
607*8d67ca89SAndroid Build Coastguard Worker }
608*8d67ca89SAndroid Build Coastguard Worker
609*8d67ca89SAndroid Build Coastguard Worker // Note that this test affects global state of the system
610*8d67ca89SAndroid Build Coastguard Worker // this tests tries to mitigate this by using utime+pid
611*8d67ca89SAndroid Build Coastguard Worker // prefix for the property name. It is still results in
612*8d67ca89SAndroid Build Coastguard Worker // pollution of property service since properties cannot
613*8d67ca89SAndroid Build Coastguard Worker // be removed.
614*8d67ca89SAndroid Build Coastguard Worker //
615*8d67ca89SAndroid Build Coastguard Worker // Note that there is also possibility to run into "out-of-memory"
616*8d67ca89SAndroid Build Coastguard Worker // if this test if it is executed often enough without reboot.
TEST(properties,__system_property_reload_no_op)617*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_reload_no_op) {
618*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
619*8d67ca89SAndroid Build Coastguard Worker std::string property_name =
620*8d67ca89SAndroid Build Coastguard Worker android::base::StringPrintf("debug.test.%d.%" PRId64 ".property", getpid(), NanoTime());
621*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, __system_property_find(property_name.c_str()));
622*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, __system_property_set(property_name.c_str(), "test value"));
623*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, __system_properties_zygote_reload());
624*8d67ca89SAndroid Build Coastguard Worker const prop_info* readptr = __system_property_find(property_name.c_str());
625*8d67ca89SAndroid Build Coastguard Worker std::string expected_name = property_name;
626*8d67ca89SAndroid Build Coastguard Worker __system_property_read_callback(
627*8d67ca89SAndroid Build Coastguard Worker readptr,
628*8d67ca89SAndroid Build Coastguard Worker [](void*, const char*, const char* value, unsigned) { ASSERT_STREQ("test value", value); },
629*8d67ca89SAndroid Build Coastguard Worker &expected_name);
630*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
631*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
632*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
633*8d67ca89SAndroid Build Coastguard Worker }
634*8d67ca89SAndroid Build Coastguard Worker
TEST(properties,__system_property_reload_invalid)635*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_reload_invalid) {
636*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
637*8d67ca89SAndroid Build Coastguard Worker if (getuid() != 0) GTEST_SKIP() << "test requires root";
638*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
639*8d67ca89SAndroid Build Coastguard Worker
640*8d67ca89SAndroid Build Coastguard Worker // Create an invalid property_info file, so the system will attempt to initialize a
641*8d67ca89SAndroid Build Coastguard Worker // ContextSerialized
642*8d67ca89SAndroid Build Coastguard Worker std::string property_info_file =
643*8d67ca89SAndroid Build Coastguard Worker android::base::StringPrintf("%s/property_info", system_properties.get_path());
644*8d67ca89SAndroid Build Coastguard Worker fclose(fopen(property_info_file.c_str(), "w"));
645*8d67ca89SAndroid Build Coastguard Worker int ret = mount(system_properties.get_path(), system_properties.get_real_sysprop_dir(), nullptr,
646*8d67ca89SAndroid Build Coastguard Worker MS_BIND | MS_REC, nullptr);
647*8d67ca89SAndroid Build Coastguard Worker if (ret != 0) {
648*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(0);
649*8d67ca89SAndroid Build Coastguard Worker }
650*8d67ca89SAndroid Build Coastguard Worker
651*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(-1, __system_properties_zygote_reload());
652*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
653*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
654*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
655*8d67ca89SAndroid Build Coastguard Worker }
656*8d67ca89SAndroid Build Coastguard Worker
657*8d67ca89SAndroid Build Coastguard Worker // Note that this test affects global state of the system
658*8d67ca89SAndroid Build Coastguard Worker // this tests tries to mitigate this by using utime+pid
659*8d67ca89SAndroid Build Coastguard Worker // prefix for the property name. It is still results in
660*8d67ca89SAndroid Build Coastguard Worker // pollution of property service since properties cannot
661*8d67ca89SAndroid Build Coastguard Worker // be removed.
662*8d67ca89SAndroid Build Coastguard Worker //
663*8d67ca89SAndroid Build Coastguard Worker // Note that there is also possibility to run into "out-of-memory"
664*8d67ca89SAndroid Build Coastguard Worker // if this test if it is executed often enough without reboot.
TEST(properties,__system_property_reload_valid)665*8d67ca89SAndroid Build Coastguard Worker TEST(properties, __system_property_reload_valid) {
666*8d67ca89SAndroid Build Coastguard Worker #if defined(__BIONIC__)
667*8d67ca89SAndroid Build Coastguard Worker if (getuid() != 0) GTEST_SKIP() << "test requires root";
668*8d67ca89SAndroid Build Coastguard Worker SystemPropertiesTest system_properties;
669*8d67ca89SAndroid Build Coastguard Worker
670*8d67ca89SAndroid Build Coastguard Worker // Copy the system properties files into the temp directory
671*8d67ca89SAndroid Build Coastguard Worker std::string shell_cmd = android::base::StringPrintf(
672*8d67ca89SAndroid Build Coastguard Worker "cp -r %s %s", system_properties.get_real_sysprop_dir(), system_properties.get_path());
673*8d67ca89SAndroid Build Coastguard Worker system(shell_cmd.c_str());
674*8d67ca89SAndroid Build Coastguard Worker
675*8d67ca89SAndroid Build Coastguard Worker // Write a system property to the current set of system properties
676*8d67ca89SAndroid Build Coastguard Worker std::string property_name =
677*8d67ca89SAndroid Build Coastguard Worker android::base::StringPrintf("debug.test.%d.%" PRId64 ".property", getpid(), NanoTime());
678*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, __system_property_find(property_name.c_str()));
679*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, __system_property_set(property_name.c_str(), "test value"));
680*8d67ca89SAndroid Build Coastguard Worker
681*8d67ca89SAndroid Build Coastguard Worker // Mount the temp directory (which doesn't have the property we just wrote) in place of the
682*8d67ca89SAndroid Build Coastguard Worker // real one
683*8d67ca89SAndroid Build Coastguard Worker int ret = mount(system_properties.get_mount_path(), system_properties.get_real_sysprop_dir(),
684*8d67ca89SAndroid Build Coastguard Worker nullptr, MS_BIND | MS_REC, nullptr);
685*8d67ca89SAndroid Build Coastguard Worker if (ret != 0) {
686*8d67ca89SAndroid Build Coastguard Worker ASSERT_ERRNO(0);
687*8d67ca89SAndroid Build Coastguard Worker }
688*8d67ca89SAndroid Build Coastguard Worker
689*8d67ca89SAndroid Build Coastguard Worker // reload system properties in the new dir, and verify the property we wrote after we copied the
690*8d67ca89SAndroid Build Coastguard Worker // files isn't there
691*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, __system_properties_zygote_reload());
692*8d67ca89SAndroid Build Coastguard Worker ASSERT_EQ(0, __system_property_find(property_name.c_str()));
693*8d67ca89SAndroid Build Coastguard Worker
694*8d67ca89SAndroid Build Coastguard Worker #else // __BIONIC__
695*8d67ca89SAndroid Build Coastguard Worker GTEST_SKIP() << "bionic-only test";
696*8d67ca89SAndroid Build Coastguard Worker #endif // __BIONIC__
697*8d67ca89SAndroid Build Coastguard Worker }
698