Home | History | Annotate | Download | only in tests
      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