116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov/* 216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * Copyright (C) 2017 The Android Open Source Project 316b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * 416b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * Licensed under the Apache License, Version 2.0 (the "License"); 516b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * you may not use this file except in compliance with the License. 616b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * You may obtain a copy of the License at 716b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * 816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * http://www.apache.org/licenses/LICENSE-2.0 916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * 1016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * Unless required by applicable law or agreed to in writing, software 1116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * distributed under the License is distributed on an "AS IS" BASIS, 1216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1316b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * See the License for the specific language governing permissions and 1416b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov * limitations under the License. 1516b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov */ 1616b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 1716b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#include <gtest/gtest.h> 1816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 1916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#include <errno.h> 2016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#include <sys/wait.h> 2116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#include <unistd.h> 2216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#include <sstream> 2316b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#include <string> 2416b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 2516b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#if defined(__BIONIC__) 2616b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#include <sys/system_properties.h> 2716b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 2816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanovstatic uint64_t NanoTime() { 2916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov timespec now; 3016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov clock_gettime(CLOCK_MONOTONIC, &now); 3116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec; 3216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov} 3316b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#endif 3416b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 3516b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov// Note that this test affects global state of the system 3616b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov// this tests tries to mitigate this by using utime+pid 3716b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov// prefix for the property name. It is still results in 3816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov// pollution of property service since properties cannot 3916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov// be removed. 4016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov// 4116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov// Note that there is also possibility to run into "out-of-memory" 4216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov// if this test if it is executed often enough without reboot. 4316b2a4de143a026b8d467b7d242126adcf67242bDimitry IvanovTEST(properties, smoke) { 4416b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#if defined(__BIONIC__) 4516b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov char propvalue[PROP_VALUE_MAX]; 4616b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 4716b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov std::stringstream ss; 4816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ss << "debug.test." << getpid() << "." << NanoTime() << "."; 4916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov const std::string property_prefix = ss.str(); 5016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov const std::string property_name = property_prefix + "property1"; 5116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 5216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov // Set brand new property 5316b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(0, __system_property_set(property_name.c_str(), "value1")); 5416b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(6, __system_property_get(property_name.c_str(), propvalue)); 5516b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_STREQ("value1", propvalue); 5616b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 5716b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov std::string long_value = "property-"; 5816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov for (size_t i = 0; i < PROP_VALUE_MAX; i++) { 5916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov long_value += "y"; 6016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov } 6116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 6216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov // Make sure that attempts to set invalid property value fails and preserves 6316b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov // previous value. 6416b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov propvalue[0] = '\0'; 6516b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(-1, __system_property_set(property_name.c_str(), long_value.c_str())); 6616b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(6, __system_property_get(property_name.c_str(), propvalue)); 6716b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_STREQ("value1", propvalue); 6816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 6916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov // Update property 7016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(0, __system_property_set(property_name.c_str(), "value1-1")); 7116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(8, __system_property_get(property_name.c_str(), propvalue)); 7216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_STREQ("value1-1", propvalue); 7316b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 7416b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 7516b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov // check that there is no limit on property name length 7616b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov char suffix[1024]; 7716b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov for (size_t i = 0; i < sizeof(suffix); i++) { 7816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov suffix[i] = 'x'; 7916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov } 8016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 8116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov suffix[sizeof(suffix)-1] = '\0'; 8216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov const std::string long_property_name = property_prefix + suffix; 8316b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 8416b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(0, __system_property_set(long_property_name.c_str(), "value2")); 8516b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(6, __system_property_get(long_property_name.c_str(), propvalue)); 8616b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_STREQ("value2", propvalue); 8716b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 8816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov // test find and read_callback 8916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov const prop_info* pi = __system_property_find(property_name.c_str()); 9016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_TRUE(pi != nullptr); 9116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 9216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov std::string expected_name = property_name; 93a0d374d587ec18d437d0dd15ba1332aceaa188afElliott Hughes __system_property_read_callback(pi, 94a0d374d587ec18d437d0dd15ba1332aceaa188afElliott Hughes [](void* cookie, const char* name, const char* value, unsigned /*serial*/) { 95a0d374d587ec18d437d0dd15ba1332aceaa188afElliott Hughes const std::string* expected_name = static_cast<const std::string*>(cookie); 96a0d374d587ec18d437d0dd15ba1332aceaa188afElliott Hughes ASSERT_EQ(*expected_name, name); 97a0d374d587ec18d437d0dd15ba1332aceaa188afElliott Hughes ASSERT_STREQ("value1-1", value); 9816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov }, &expected_name); 9916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 10016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov pi = __system_property_find(long_property_name.c_str()); 10116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_TRUE(pi != nullptr); 10216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 10316b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov expected_name = long_property_name; 104a0d374d587ec18d437d0dd15ba1332aceaa188afElliott Hughes __system_property_read_callback(pi, 105a0d374d587ec18d437d0dd15ba1332aceaa188afElliott Hughes [](void* cookie, const char* name, const char* value, unsigned /*serial*/) { 106a0d374d587ec18d437d0dd15ba1332aceaa188afElliott Hughes const std::string* expected_name = static_cast<const std::string*>(cookie); 107a0d374d587ec18d437d0dd15ba1332aceaa188afElliott Hughes ASSERT_EQ(*expected_name, name); 108a0d374d587ec18d437d0dd15ba1332aceaa188afElliott Hughes ASSERT_STREQ("value2", value); 10916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov }, &expected_name); 11016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 11116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov // Check that read() for long names still works but returns truncated version of the name 11216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov pi = __system_property_find(property_name.c_str()); 11316b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_TRUE(pi != nullptr); 11416b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov char legacy_name[PROP_NAME_MAX]; 11516b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov expected_name = std::string(property_name.c_str(), PROP_NAME_MAX-1); 11616b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(8, __system_property_read(pi, &legacy_name[0], propvalue)); 11716b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(expected_name, legacy_name); 11816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_STREQ("value1-1", propvalue); 11916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 12016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov const prop_info* pi_long = __system_property_find(long_property_name.c_str()); 12116b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_TRUE(pi != nullptr); 12216b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov expected_name = std::string(long_property_name.c_str(), PROP_NAME_MAX-1); 12316b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(6, __system_property_read(pi_long, &legacy_name[0], propvalue)); 12416b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_EQ(expected_name, legacy_name); 12516b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov ASSERT_STREQ("value2", propvalue); 12616b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#else // __BIONIC__ 12716b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov GTEST_LOG_(INFO) << "This test does nothing.\n"; 12816b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov#endif // __BIONIC__ 12916b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov} 13016b2a4de143a026b8d467b7d242126adcf67242bDimitry Ivanov 131cafd3553751dfb524316884fb213eb80c75a26a2Dimitry IvanovTEST(properties, empty_value) { 132cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov#if defined(__BIONIC__) 133cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov char propvalue[PROP_VALUE_MAX]; 134cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov 135cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov std::stringstream ss; 136cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov ss << "debug.test." << getpid() << "." << NanoTime() << "." << "property_empty"; 137cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov const std::string property_name = ss.str(); 138cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov 139cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov for (size_t i=0; i<1000; ++i) { 140cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov ASSERT_EQ(0, __system_property_set(property_name.c_str(), "")); 141cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov ASSERT_EQ(0, __system_property_get(property_name.c_str(), propvalue)); 142cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov ASSERT_STREQ("", propvalue); 143cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov } 144cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov 145cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov#else // __BIONIC__ 146cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov GTEST_LOG_(INFO) << "This test does nothing.\n"; 147cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov#endif // __BIONIC__ 148cafd3553751dfb524316884fb213eb80c75a26a2Dimitry Ivanov} 149