properties_test.cpp 12 KB

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