1 /* 2 * Copyright (C) 2014 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 #define LOG_TAG "Properties_test" 18 #include <utils/Log.h> 19 #include <gtest/gtest.h> 20 21 #include <cutils/properties.h> 22 #include <limits.h> 23 #include <string> 24 #include <sstream> 25 #include <iostream> 26 27 namespace android { 28 29 #define STRINGIFY_INNER(x) #x 30 #define STRINGIFY(x) STRINGIFY_INNER(x) 31 #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) 32 #define ASSERT_OK(x) ASSERT_EQ(0, (x)) 33 #define EXPECT_OK(x) EXPECT_EQ(0, (x)) 34 35 #define PROPERTY_TEST_KEY "libcutils.test.key" 36 #define PROPERTY_TEST_VALUE_DEFAULT "<<<default_value>>>" 37 38 template <typename T> 39 static std::string HexString(T value) { 40 std::stringstream ss; 41 ss << "0x" << std::hex << std::uppercase << value; 42 return ss.str(); 43 } 44 45 template <typename T> 46 static ::testing::AssertionResult AssertEqualHex(const char *mExpr, 47 const char *nExpr, 48 T m, 49 T n) { 50 if (m == n) { 51 return ::testing::AssertionSuccess(); 52 } 53 54 return ::testing::AssertionFailure() 55 << mExpr << " and " << nExpr << " (expected: " << HexString(m) << 56 ", actual: " << HexString(n) << ") are not equal"; 57 } 58 59 class PropertiesTest : public testing::Test { 60 public: 61 PropertiesTest() : mValue() {} 62 protected: 63 virtual void SetUp() { 64 EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL)); 65 } 66 67 virtual void TearDown() { 68 EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL)); 69 } 70 71 char mValue[PROPERTY_VALUE_MAX]; 72 73 template <typename T> 74 static std::string ToString(T value) { 75 std::stringstream ss; 76 ss << value; 77 78 return ss.str(); 79 } 80 81 // Return length of property read; value is written into mValue 82 int SetAndGetProperty(const char* value, const char* defaultValue = PROPERTY_TEST_VALUE_DEFAULT) { 83 EXPECT_OK(property_set(PROPERTY_TEST_KEY, value)) << "value: '" << value << "'"; 84 return property_get(PROPERTY_TEST_KEY, mValue, defaultValue); 85 } 86 87 void ResetValue(unsigned char c = 0xFF) { 88 for (size_t i = 0; i < ARRAY_SIZE(mValue); ++i) { 89 mValue[i] = (char) c; 90 } 91 } 92 }; 93 94 TEST_F(PropertiesTest, SetString) { 95 96 // Null key -> unsuccessful set 97 { 98 // Null key -> fails 99 EXPECT_GT(0, property_set(/*key*/NULL, PROPERTY_TEST_VALUE_DEFAULT)); 100 } 101 102 // Null value -> returns default value 103 { 104 // Null value -> OK , and it clears the value 105 EXPECT_OK(property_set(PROPERTY_TEST_KEY, /*value*/NULL)); 106 ResetValue(); 107 108 // Since the value is null, default value will be returned 109 int len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT); 110 EXPECT_EQ(strlen(PROPERTY_TEST_VALUE_DEFAULT), len); 111 EXPECT_STREQ(PROPERTY_TEST_VALUE_DEFAULT, mValue); 112 } 113 114 // Trivial case => get returns what was set 115 { 116 int len = SetAndGetProperty("hello_world"); 117 EXPECT_EQ(strlen("hello_world"), len) << "hello_world key"; 118 EXPECT_STREQ("hello_world", mValue); 119 ResetValue(); 120 } 121 122 // Set to empty string => get returns default always 123 { 124 const char* EMPTY_STRING_DEFAULT = "EMPTY_STRING"; 125 int len = SetAndGetProperty("", EMPTY_STRING_DEFAULT); 126 EXPECT_EQ(strlen(EMPTY_STRING_DEFAULT), len) << "empty key"; 127 EXPECT_STREQ(EMPTY_STRING_DEFAULT, mValue); 128 ResetValue(); 129 } 130 131 // Set to max length => get returns what was set 132 { 133 std::string maxLengthString = std::string(PROPERTY_VALUE_MAX-1, 'a'); 134 135 int len = SetAndGetProperty(maxLengthString.c_str()); 136 EXPECT_EQ(PROPERTY_VALUE_MAX-1, len) << "max length key"; 137 EXPECT_STREQ(maxLengthString.c_str(), mValue); 138 ResetValue(); 139 } 140 141 // Set to max length + 1 => set fails 142 { 143 const char* VALID_TEST_VALUE = "VALID_VALUE"; 144 ASSERT_OK(property_set(PROPERTY_TEST_KEY, VALID_TEST_VALUE)); 145 146 std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a'); 147 148 // Expect that the value set fails since it's too long 149 EXPECT_GT(0, property_set(PROPERTY_TEST_KEY, oneLongerString.c_str())); 150 int len = property_get(PROPERTY_TEST_KEY, mValue, PROPERTY_TEST_VALUE_DEFAULT); 151 152 EXPECT_EQ(strlen(VALID_TEST_VALUE), len) << "set should've failed"; 153 EXPECT_STREQ(VALID_TEST_VALUE, mValue); 154 ResetValue(); 155 } 156 } 157 158 TEST_F(PropertiesTest, GetString) { 159 160 // Try to use a default value that's too long => set fails 161 { 162 ASSERT_OK(property_set(PROPERTY_TEST_KEY, "")); 163 164 std::string maxLengthString = std::string(PROPERTY_VALUE_MAX-1, 'a'); 165 std::string oneLongerString = std::string(PROPERTY_VALUE_MAX, 'a'); 166 167 // Expect that the value is truncated since it's too long (by 1) 168 int len = property_get(PROPERTY_TEST_KEY, mValue, oneLongerString.c_str()); 169 EXPECT_EQ(PROPERTY_VALUE_MAX-1, len); 170 EXPECT_STREQ(maxLengthString.c_str(), mValue); 171 ResetValue(); 172 } 173 } 174 175 TEST_F(PropertiesTest, GetBool) { 176 /** 177 * TRUE 178 */ 179 const char *valuesTrue[] = { "1", "true", "y", "yes", "on", }; 180 for (size_t i = 0; i < ARRAY_SIZE(valuesTrue); ++i) { 181 ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesTrue[i])); 182 bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/false); 183 EXPECT_TRUE(val) << "Property should've been TRUE for value: '" << valuesTrue[i] << "'"; 184 } 185 186 /** 187 * FALSE 188 */ 189 const char *valuesFalse[] = { "0", "false", "n", "no", "off", }; 190 for (size_t i = 0; i < ARRAY_SIZE(valuesFalse); ++i) { 191 ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesFalse[i])); 192 bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/true); 193 EXPECT_FALSE(val) << "Property shoud've been FALSE For string value: '" << valuesFalse[i] << "'"; 194 } 195 196 /** 197 * NEITHER 198 */ 199 const char *valuesNeither[] = { "x0", "x1", "2", "-2", "True", "False", "garbage", "", " ", 200 "+1", " 1 ", " true", " true ", " y ", " yes", "yes ", 201 "+0", "-0", "00", " 00 ", " false", "false ", 202 }; 203 for (size_t i = 0; i < ARRAY_SIZE(valuesNeither); ++i) { 204 ASSERT_OK(property_set(PROPERTY_TEST_KEY, valuesNeither[i])); 205 206 // The default value should always be used 207 bool val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/true); 208 EXPECT_TRUE(val) << "Property should've been NEITHER (true) for string value: '" << valuesNeither[i] << "'"; 209 210 val = property_get_bool(PROPERTY_TEST_KEY, /*default_value*/false); 211 EXPECT_FALSE(val) << "Property should've been NEITHER (false) for string value: '" << valuesNeither[i] << "'"; 212 } 213 } 214 215 TEST_F(PropertiesTest, GetInt64) { 216 const int64_t DEFAULT_VALUE = INT64_C(0xDEADBEEFBEEFDEAD); 217 218 const std::string longMaxString = ToString(INT64_MAX); 219 const std::string longStringOverflow = longMaxString + "0"; 220 221 const std::string longMinString = ToString(INT64_MIN); 222 const std::string longStringUnderflow = longMinString + "0"; 223 224 const char* setValues[] = { 225 // base 10 226 "1", "2", "12345", "-1", "-2", "-12345", 227 // base 16 228 "0xFF", "0x0FF", "0xC0FFEE", 229 // base 8 230 "0", "01234", "07", 231 // corner cases 232 " 2", "2 ", "+0", "-0", " +0 ", longMaxString.c_str(), longMinString.c_str(), 233 // failing cases 234 NULL, "", " ", " ", "hello", " true ", "y", 235 longStringOverflow.c_str(), longStringUnderflow.c_str(), 236 }; 237 238 int64_t getValues[] = { 239 // base 10 240 1, 2, 12345, -1, -2, -12345, 241 // base 16 242 0xFF, 0x0FF, 0xC0FFEE, 243 // base 8 244 0, 01234, 07, 245 // corner cases 246 2, 2, 0, 0, 0, INT64_MAX, INT64_MIN, 247 // failing cases 248 DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, 249 DEFAULT_VALUE, DEFAULT_VALUE, 250 }; 251 252 ASSERT_EQ(ARRAY_SIZE(setValues), ARRAY_SIZE(getValues)); 253 254 for (size_t i = 0; i < ARRAY_SIZE(setValues); ++i) { 255 ASSERT_OK(property_set(PROPERTY_TEST_KEY, setValues[i])); 256 257 int64_t val = property_get_int64(PROPERTY_TEST_KEY, DEFAULT_VALUE); 258 EXPECT_PRED_FORMAT2(AssertEqualHex, getValues[i], val) << "Property was set to '" << setValues[i] << "'"; 259 } 260 } 261 262 TEST_F(PropertiesTest, GetInt32) { 263 const int32_t DEFAULT_VALUE = INT32_C(0xDEADBEEF); 264 265 const std::string intMaxString = ToString(INT32_MAX); 266 const std::string intStringOverflow = intMaxString + "0"; 267 268 const std::string intMinString = ToString(INT32_MIN); 269 const std::string intStringUnderflow = intMinString + "0"; 270 271 const char* setValues[] = { 272 // base 10 273 "1", "2", "12345", "-1", "-2", "-12345", 274 // base 16 275 "0xFF", "0x0FF", "0xC0FFEE", "0Xf00", 276 // base 8 277 "0", "01234", "07", 278 // corner cases 279 " 2", "2 ", "+0", "-0", " +0 ", intMaxString.c_str(), intMinString.c_str(), 280 // failing cases 281 NULL, "", " ", " ", "hello", " true ", "y", 282 intStringOverflow.c_str(), intStringUnderflow.c_str(), 283 }; 284 285 int32_t getValues[] = { 286 // base 10 287 1, 2, 12345, -1, -2, -12345, 288 // base 16 289 0xFF, 0x0FF, 0xC0FFEE, 0Xf00, 290 // base 8 291 0, 01234, 07, 292 // corner cases 293 2, 2, 0, 0, 0, INT32_MAX, INT32_MIN, 294 // failing cases 295 DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, DEFAULT_VALUE, 296 DEFAULT_VALUE, DEFAULT_VALUE, 297 }; 298 299 ASSERT_EQ(ARRAY_SIZE(setValues), ARRAY_SIZE(getValues)); 300 301 for (size_t i = 0; i < ARRAY_SIZE(setValues); ++i) { 302 ASSERT_OK(property_set(PROPERTY_TEST_KEY, setValues[i])); 303 304 int32_t val = property_get_int32(PROPERTY_TEST_KEY, DEFAULT_VALUE); 305 EXPECT_PRED_FORMAT2(AssertEqualHex, getValues[i], val) << "Property was set to '" << setValues[i] << "'"; 306 } 307 } 308 309 } // namespace android 310