• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  /*
2   * Copyright (C) 2017 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>
18  
19  #include <errno.h>
20  #include <sys/wait.h>
21  #include <unistd.h>
22  #include <sstream>
23  #include <string>
24  
25  #if defined(__BIONIC__)
26  #include <sys/system_properties.h>
27  
NanoTime()28  static uint64_t NanoTime() {
29    timespec now;
30    clock_gettime(CLOCK_MONOTONIC, &now);
31    return static_cast<uint64_t>(now.tv_sec) * UINT64_C(1000000000) + now.tv_nsec;
32  }
33  #endif
34  
35  // Note that this test affects global state of the system
36  // this tests tries to mitigate this by using utime+pid
37  // prefix for the property name. It is still results in
38  // pollution of property service since properties cannot
39  // be removed.
40  //
41  // Note that there is also possibility to run into "out-of-memory"
42  // if this test if it is executed often enough without reboot.
TEST(properties,smoke)43  TEST(properties, smoke) {
44  #if defined(__BIONIC__)
45      char propvalue[PROP_VALUE_MAX];
46  
47      std::stringstream ss;
48      ss << "debug.test." << getpid() << "." << NanoTime() << ".";
49      const std::string property_prefix = ss.str();
50      const std::string property_name = property_prefix + "property1";
51  
52      // Set brand new property
53      ASSERT_EQ(0, __system_property_set(property_name.c_str(), "value1"));
54      ASSERT_EQ(6, __system_property_get(property_name.c_str(), propvalue));
55      ASSERT_STREQ("value1", propvalue);
56  
57      std::string long_value = "property-";
58      for (size_t i = 0; i < PROP_VALUE_MAX; i++) {
59        long_value += "y";
60      }
61  
62      // Make sure that attempts to set invalid property value fails and preserves
63      // previous value.
64      propvalue[0] = '\0';
65      ASSERT_EQ(-1, __system_property_set(property_name.c_str(), long_value.c_str()));
66      ASSERT_EQ(6, __system_property_get(property_name.c_str(), propvalue));
67      ASSERT_STREQ("value1", propvalue);
68  
69      // Update property
70      ASSERT_EQ(0, __system_property_set(property_name.c_str(), "value1-1"));
71      ASSERT_EQ(8, __system_property_get(property_name.c_str(), propvalue));
72      ASSERT_STREQ("value1-1", propvalue);
73  
74  
75      // check that there is no limit on property name length
76      char suffix[1024];
77      for (size_t i = 0; i < sizeof(suffix); i++) {
78        suffix[i] = 'x';
79      }
80  
81      suffix[sizeof(suffix)-1] = '\0';
82      const std::string long_property_name = property_prefix + suffix;
83  
84      ASSERT_EQ(0, __system_property_set(long_property_name.c_str(), "value2"));
85      ASSERT_EQ(6, __system_property_get(long_property_name.c_str(), propvalue));
86      ASSERT_STREQ("value2", propvalue);
87  
88      // test find and read_callback
89      const prop_info* pi = __system_property_find(property_name.c_str());
90      ASSERT_TRUE(pi != nullptr);
91  
92      std::string expected_name = property_name;
93      __system_property_read_callback(pi,
94        [](void* cookie, const char* name, const char* value, unsigned /*serial*/) {
95          const std::string* expected_name = static_cast<const std::string*>(cookie);
96          ASSERT_EQ(*expected_name, name);
97          ASSERT_STREQ("value1-1", value);
98      }, &expected_name);
99  
100      pi = __system_property_find(long_property_name.c_str());
101      ASSERT_TRUE(pi != nullptr);
102  
103      expected_name = long_property_name;
104      __system_property_read_callback(pi,
105        [](void* cookie, const char* name, const char* value, unsigned /*serial*/) {
106          const std::string* expected_name = static_cast<const std::string*>(cookie);
107          ASSERT_EQ(*expected_name, name);
108          ASSERT_STREQ("value2", value);
109      }, &expected_name);
110  
111      // Check that read() for long names still works but returns truncated version of the name
112      pi = __system_property_find(property_name.c_str());
113      ASSERT_TRUE(pi != nullptr);
114      char legacy_name[PROP_NAME_MAX];
115      expected_name = std::string(property_name.c_str(), PROP_NAME_MAX-1);
116      ASSERT_EQ(8, __system_property_read(pi, &legacy_name[0], propvalue));
117      ASSERT_EQ(expected_name, legacy_name);
118      ASSERT_STREQ("value1-1", propvalue);
119  
120      const prop_info* pi_long = __system_property_find(long_property_name.c_str());
121      ASSERT_TRUE(pi != nullptr);
122      expected_name = std::string(long_property_name.c_str(), PROP_NAME_MAX-1);
123      ASSERT_EQ(6, __system_property_read(pi_long, &legacy_name[0], propvalue));
124      ASSERT_EQ(expected_name, legacy_name);
125      ASSERT_STREQ("value2", propvalue);
126  #else // __BIONIC__
127      GTEST_LOG_(INFO) << "This test does nothing.\n";
128  #endif // __BIONIC__
129  }
130  
TEST(properties,empty_value)131  TEST(properties, empty_value) {
132  #if defined(__BIONIC__)
133      char propvalue[PROP_VALUE_MAX];
134  
135      std::stringstream ss;
136      ss << "debug.test." << getpid() << "." << NanoTime() << "." << "property_empty";
137      const std::string property_name = ss.str();
138  
139      for (size_t i=0; i<1000; ++i) {
140        ASSERT_EQ(0, __system_property_set(property_name.c_str(), ""));
141        ASSERT_EQ(0, __system_property_get(property_name.c_str(), propvalue));
142        ASSERT_STREQ("", propvalue);
143      }
144  
145  #else // __BIONIC__
146      GTEST_LOG_(INFO) << "This test does nothing.\n";
147  #endif // __BIONIC__
148  }
149