You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1026 lines
33 KiB
1026 lines
33 KiB
/* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License, version 2.0,
|
|
as published by the Free Software Foundation.
|
|
|
|
This program is also distributed with certain software (including
|
|
but not limited to OpenSSL) that is licensed under separate terms,
|
|
as designated in a particular file or component or in included license
|
|
documentation. The authors of MySQL hereby grant you an additional
|
|
permission to link the program and your derivative works with the
|
|
separately licensed software that they have included with MySQL.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License, version 2.0, for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <stddef.h>
|
|
|
|
#include "my_inttypes.h"
|
|
#include "sql/dd/impl/properties_impl.h"
|
|
#include "sql/dd/properties.h"
|
|
#include "unittest/gunit/test_utils.h"
|
|
|
|
namespace dd_properties_unittest {
|
|
|
|
/**
|
|
The fixture for testing the dd::Properties and Properties_impl classes.
|
|
A fresh instance of this class will be created for each of the
|
|
TEST_F functions below.
|
|
The functions SetUp(), TearDown(), SetUpTestCase(), TearDownTestCase() are
|
|
inherited from ::testing::Test (google naming style differs from MySQL).
|
|
*/
|
|
|
|
class PropertiesTest : public ::testing::Test {
|
|
protected:
|
|
PropertiesTest() {}
|
|
|
|
virtual void SetUp() { m_props = new dd::Properties_impl(); }
|
|
|
|
virtual void TearDown() { delete m_props; }
|
|
|
|
static void SetUpTestCase() {}
|
|
|
|
static void TearDownTestCase() {}
|
|
|
|
dd::Properties *m_props;
|
|
|
|
private:
|
|
// Declares (but does not define) copy constructor and assignment operator.
|
|
GTEST_DISALLOW_COPY_AND_ASSIGN_(PropertiesTest);
|
|
};
|
|
|
|
static const dd::String_type value(const dd::Properties &p,
|
|
const dd::String_type &key) {
|
|
dd::String_type val;
|
|
(void)p.get(key, &val);
|
|
return val;
|
|
}
|
|
|
|
// Tests that valid option parsing is handled
|
|
TEST_F(PropertiesTest, ValidStringParsing) {
|
|
dd::Properties *p = dd::Properties_impl::parse_properties("a=b;b=c");
|
|
EXPECT_TRUE(value(*p, "a") == "b");
|
|
EXPECT_TRUE(value(*p, "b") == "c");
|
|
EXPECT_TRUE(p->raw_string() == "a=b;b=c;");
|
|
delete p;
|
|
|
|
p = dd::Properties_impl::parse_properties("a=b;b=c;");
|
|
EXPECT_TRUE(value(*p, "a") == "b");
|
|
EXPECT_TRUE(value(*p, "b") == "c");
|
|
EXPECT_TRUE(p->raw_string() == "a=b;b=c;");
|
|
delete p;
|
|
|
|
p = dd::Properties_impl::parse_properties("\\=a=\\;b;b\\==\\=c");
|
|
EXPECT_TRUE(value(*p, "=a") == ";b");
|
|
EXPECT_TRUE(value(*p, "b=") == "=c");
|
|
EXPECT_TRUE(p->raw_string() == "\\=a=\\;b;b\\==\\=c;");
|
|
delete p;
|
|
|
|
p = dd::Properties_impl::parse_properties("");
|
|
EXPECT_TRUE(p != NULL);
|
|
EXPECT_FALSE(p->exists(""));
|
|
delete p;
|
|
|
|
p = dd::Properties_impl::parse_properties("a=;");
|
|
EXPECT_TRUE(p != NULL);
|
|
EXPECT_TRUE(value(*p, "a") == "");
|
|
delete p;
|
|
}
|
|
|
|
// Tests that option parsing errors are handled
|
|
TEST_F(PropertiesTest, FailingStringParsing) {
|
|
dd::Properties *p = dd::Properties_impl::parse_properties("a");
|
|
EXPECT_TRUE(p == NULL);
|
|
delete p;
|
|
|
|
p = dd::Properties_impl::parse_properties("a");
|
|
EXPECT_TRUE(p == NULL);
|
|
delete p;
|
|
|
|
p = dd::Properties_impl::parse_properties(";");
|
|
EXPECT_TRUE(p == NULL);
|
|
delete p;
|
|
|
|
p = dd::Properties_impl::parse_properties("a\\=b");
|
|
EXPECT_TRUE(p == NULL);
|
|
delete p;
|
|
|
|
p = dd::Properties_impl::parse_properties("=");
|
|
EXPECT_TRUE(p == NULL);
|
|
delete p;
|
|
|
|
p = dd::Properties_impl::parse_properties("=a");
|
|
EXPECT_TRUE(p == NULL);
|
|
delete p;
|
|
}
|
|
|
|
// Tests empty value behavior
|
|
TEST_F(PropertiesTest, EmptyValue) {
|
|
dd::Properties *p = dd::Properties_impl::parse_properties("k=;");
|
|
dd::String_type string_value("");
|
|
|
|
EXPECT_TRUE(value(*p, "k") == "");
|
|
EXPECT_TRUE(!p->get("k", &string_value) && string_value == "");
|
|
delete p;
|
|
}
|
|
|
|
// Tests utf-8 behavior
|
|
TEST_F(PropertiesTest, UTF8) {
|
|
const dd::String_type EUR("\xE2\x82\xAC");
|
|
const dd::String_type CNY("\xe5\x85\x83");
|
|
const dd::String_type JPY("\xe5\x86\x86");
|
|
const dd::String_type GBP("\xc2\xa3");
|
|
const dd::String_type USD("\x24");
|
|
const dd::String_type CNT("\xC2\xA2");
|
|
|
|
// Parse a utf-8 string and add more key=value pairs
|
|
dd::Properties *p = dd::Properties_impl::parse_properties("EUR=" + EUR);
|
|
p->set("CNY", CNY);
|
|
p->set("JPY", JPY);
|
|
p->set("GBP", GBP);
|
|
p->set("USD", USD);
|
|
|
|
p->set("1/100 " + EUR, "Cent, but not " + CNT);
|
|
p->set("1/100 " + GBP, "Pence, whatever that symbol is");
|
|
p->set("1/100 " + CNY, "Who knows, but not " + JPY + " for sure");
|
|
p->set("1/100 " + USD, "Half of my 2 " + CNT + "s worth");
|
|
|
|
EXPECT_TRUE(value(*p, "EUR") == EUR);
|
|
EXPECT_TRUE(value(*p, "1/100 " + value(*p, "EUR")) == "Cent, but not " + CNT);
|
|
|
|
EXPECT_TRUE(value(*p, "CNY") == CNY);
|
|
EXPECT_TRUE(value(*p, "1/100 " + value(*p, "CNY")) ==
|
|
"Who knows, but not " + JPY + " for sure");
|
|
|
|
EXPECT_TRUE(value(*p, "JPY") == JPY);
|
|
|
|
EXPECT_TRUE(value(*p, "GBP") == GBP);
|
|
EXPECT_TRUE(value(*p, "1/100 " + value(*p, "GBP")) ==
|
|
"Pence, whatever that symbol is");
|
|
|
|
EXPECT_TRUE(value(*p, "USD") == USD);
|
|
EXPECT_TRUE(value(*p, "1/100 " + value(*p, "USD")) ==
|
|
"Half of my 2 " + CNT + "s worth");
|
|
delete p;
|
|
}
|
|
|
|
// Tests setting and getting options
|
|
TEST_F(PropertiesTest, SetGetStrings) {
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
dd::String_type str("");
|
|
|
|
p->set("a", "b");
|
|
EXPECT_TRUE(value(*p, "a") == "b");
|
|
EXPECT_TRUE(!p->get("a", &str) && str == "b");
|
|
|
|
p->set("b=", "c;");
|
|
EXPECT_TRUE(value(*p, "b=") == "c;");
|
|
EXPECT_TRUE(!p->get("b=", &str) && str == "c;");
|
|
|
|
p->set("d\\=", "e\\;");
|
|
EXPECT_TRUE(value(*p, "d\\=") == "e\\;");
|
|
EXPECT_TRUE(!p->get("d\\=", &str) && str == "e\\;");
|
|
|
|
p->set(";f", "=g");
|
|
EXPECT_TRUE(value(*p, ";f") == "=g");
|
|
EXPECT_TRUE(!p->get(";f", &str) && str == "=g");
|
|
|
|
p->set("\\;h", "\\=i");
|
|
EXPECT_TRUE(value(*p, "\\;h") == "\\=i");
|
|
EXPECT_TRUE(!p->get("\\;h", &str) && str == "\\=i");
|
|
|
|
// Key "" is illegal and will not be added
|
|
p->set("", "");
|
|
|
|
#if !defined(DBUG_OFF)
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("", &str), ".*UTC - mysqld got.*");
|
|
#else
|
|
EXPECT_TRUE(p->get("", &str));
|
|
#endif
|
|
|
|
EXPECT_FALSE(p->exists(""));
|
|
EXPECT_TRUE(p->remove(""));
|
|
|
|
EXPECT_TRUE(p->raw_string() ==
|
|
"\\;f=\\=g;\\\\\\;h=\\\\\\=i;a=b;b\\==c\\;;d\\\\\\==e\\\\\\;;");
|
|
|
|
// Create another object with the raw string as input
|
|
dd::Properties *p_copy =
|
|
dd::Properties_impl::parse_properties(p->raw_string());
|
|
// Verify same values
|
|
EXPECT_TRUE(value(*p, "a") == value(*p_copy, "a"));
|
|
EXPECT_TRUE(value(*p, "b=") == value(*p_copy, "b="));
|
|
EXPECT_TRUE(value(*p, "d\\=") == value(*p_copy, "d\\="));
|
|
EXPECT_TRUE(value(*p, ";f") == value(*p_copy, ";f"));
|
|
EXPECT_TRUE(value(*p, "\\;h") == value(*p_copy, "\\;h"));
|
|
|
|
EXPECT_TRUE(p->raw_string() == p_copy->raw_string());
|
|
|
|
delete p;
|
|
delete p_copy;
|
|
}
|
|
|
|
// Tests valid setting and getting of int and bool options
|
|
TEST_F(PropertiesTest, ValidSetGetIntBool) {
|
|
int64 val1_int64 = 0;
|
|
int64 val2_int64 = 0;
|
|
uint64 val1_uint64 = 0;
|
|
uint64 val2_uint64 = 0;
|
|
int32 val1_int32 = 0;
|
|
int32 val2_int32 = 0;
|
|
uint32 val1_uint32 = 0;
|
|
uint32 val2_uint32 = 0;
|
|
|
|
const char *MAX_INT64_STR = "9223372036854775807";
|
|
const int64 MAX_INT64 = std::numeric_limits<int64>::max();
|
|
const char *MIN_INT64_STR = "-9223372036854775808";
|
|
const int64 MIN_INT64 = std::numeric_limits<int64>::min();
|
|
|
|
const char *MAX_UINT64_STR = "18446744073709551615";
|
|
const uint64 MAX_UINT64 = std::numeric_limits<uint64>::max();
|
|
const char *MIN_UINT64_STR = "0";
|
|
const uint64 MIN_UINT64 = 0;
|
|
|
|
const char *MAX_INT32_STR = "2147483647";
|
|
const int32 MAX_INT32 = std::numeric_limits<int32>::max();
|
|
const char *MIN_INT32_STR = "-2147483648";
|
|
const int32 MIN_INT32 = std::numeric_limits<int32>::min();
|
|
|
|
const char *MAX_UINT32_STR = "4294967295";
|
|
const uint32 MAX_UINT32 = std::numeric_limits<uint32>::max();
|
|
const char *MIN_UINT32_STR = "0";
|
|
const uint32 MIN_UINT32 = 0;
|
|
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
|
|
// Set and get as strings and ints, int64
|
|
p->set("str_int64", MAX_INT64_STR);
|
|
p->set("num_int64", MAX_INT64);
|
|
|
|
EXPECT_TRUE(value(*p, "str_int64") == value(*p, "num_int64") &&
|
|
value(*p, "str_int64") == MAX_INT64_STR);
|
|
EXPECT_TRUE(!p->get("str_int64", &val1_int64) &&
|
|
!p->get("num_int64", &val2_int64));
|
|
EXPECT_TRUE(val1_int64 == val2_int64 && val1_int64 == MAX_INT64);
|
|
|
|
p->set("str_int64", MIN_INT64_STR);
|
|
p->set("num_int64", MIN_INT64);
|
|
|
|
EXPECT_TRUE(value(*p, "str_int64") == value(*p, "num_int64") &&
|
|
value(*p, "str_int64") == MIN_INT64_STR);
|
|
EXPECT_TRUE(!p->get("str_int64", &val1_int64) &&
|
|
!p->get("num_int64", &val2_int64));
|
|
EXPECT_TRUE(val1_int64 == val2_int64 && val1_int64 == MIN_INT64);
|
|
|
|
// Set and get as strings and ints, uint64
|
|
p->set("str_uint64", MAX_UINT64_STR);
|
|
p->set("num_uint64", MAX_UINT64);
|
|
|
|
EXPECT_TRUE(value(*p, "str_uint64") == value(*p, "num_uint64") &&
|
|
value(*p, "str_uint64") == MAX_UINT64_STR);
|
|
EXPECT_TRUE(!p->get("str_uint64", &val1_uint64) &&
|
|
!p->get("num_uint64", &val2_uint64));
|
|
EXPECT_TRUE(val1_uint64 == val2_uint64 && val1_uint64 == MAX_UINT64);
|
|
|
|
p->set("str_uint64", MIN_UINT64_STR);
|
|
p->set("num_uint64", MIN_UINT64);
|
|
|
|
EXPECT_TRUE(value(*p, "str_uint64") == value(*p, "num_uint64") &&
|
|
value(*p, "str_uint64") == MIN_UINT64_STR);
|
|
EXPECT_TRUE(!p->get("str_uint64", &val1_uint64) &&
|
|
!p->get("num_uint64", &val2_uint64));
|
|
EXPECT_TRUE(val1_uint64 == val2_uint64 && val1_uint64 == MIN_UINT64);
|
|
|
|
// Set and get as strings and ints, int32
|
|
p->set("str_int32", MAX_INT32_STR);
|
|
p->set("num_int32", MAX_INT32);
|
|
|
|
EXPECT_TRUE(value(*p, "str_int32") == value(*p, "num_int32") &&
|
|
value(*p, "str_int32") == MAX_INT32_STR);
|
|
EXPECT_TRUE(!p->get("str_int32", &val1_int32) &&
|
|
!p->get("num_int32", &val2_int32));
|
|
EXPECT_TRUE(val1_int32 == val2_int32 && val1_int32 == MAX_INT32);
|
|
|
|
p->set("str_int32", MIN_INT32_STR);
|
|
p->set("num_int32", MIN_INT32);
|
|
|
|
EXPECT_TRUE(value(*p, "str_int32") == value(*p, "num_int32") &&
|
|
value(*p, "str_int32") == MIN_INT32_STR);
|
|
EXPECT_TRUE(!p->get("str_int32", &val1_int32) &&
|
|
!p->get("num_int32", &val2_int32));
|
|
EXPECT_TRUE(val1_int32 == val2_int32 && val1_int32 == MIN_INT32);
|
|
|
|
// Set and get as strings and ints, uint32
|
|
p->set("str_uint32", MAX_UINT32_STR);
|
|
p->set("num_uint32", MAX_UINT32);
|
|
|
|
EXPECT_TRUE(value(*p, "str_uint32") == value(*p, "num_uint32") &&
|
|
value(*p, "str_uint32") == MAX_UINT32_STR);
|
|
EXPECT_TRUE(!p->get("str_uint32", &val1_uint32) &&
|
|
!p->get("num_uint32", &val2_uint32));
|
|
EXPECT_TRUE(val1_uint32 == val2_uint32 && val1_uint32 == MAX_UINT32);
|
|
|
|
p->set("str_uint32", MIN_UINT32_STR);
|
|
p->set("num_uint32", MIN_UINT32);
|
|
|
|
EXPECT_TRUE(value(*p, "str_uint32") == value(*p, "num_uint32") &&
|
|
value(*p, "str_uint32") == MIN_UINT32_STR);
|
|
EXPECT_TRUE(!p->get("str_uint32", &val1_uint32) &&
|
|
!p->get("num_uint32", &val2_uint32));
|
|
EXPECT_TRUE(val1_uint32 == val2_uint32 && val1_uint32 == MIN_UINT32);
|
|
|
|
// Set and get as strings and bool
|
|
bool maybe = false;
|
|
|
|
p->set("bool", true);
|
|
EXPECT_TRUE(value(*p, "bool") == "1");
|
|
EXPECT_TRUE(!p->get("bool", &maybe) && maybe == true);
|
|
EXPECT_TRUE(!p->get("bool", &val1_int64) && val1_int64 == 1);
|
|
EXPECT_TRUE(!p->get("bool", &val1_uint64) && val1_uint64 == 1);
|
|
EXPECT_TRUE(!p->get("bool", &val1_int32) && val1_int32 == 1);
|
|
EXPECT_TRUE(!p->get("bool", &val1_uint32) && val1_uint32 == 1);
|
|
p->set("bool", false);
|
|
EXPECT_TRUE(value(*p, "bool") == "0");
|
|
EXPECT_TRUE(!p->get("bool", &maybe) && maybe == false);
|
|
EXPECT_TRUE(!p->get("bool", &val1_int64) && val1_int64 == 0);
|
|
EXPECT_TRUE(!p->get("bool", &val1_uint64) && val1_uint64 == 0);
|
|
EXPECT_TRUE(!p->get("bool", &val1_int32) && val1_int32 == 0);
|
|
EXPECT_TRUE(!p->get("bool", &val1_uint32) && val1_uint32 == 0);
|
|
p->remove("bool");
|
|
|
|
p->set("str_int_bool", 0);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == false);
|
|
p->set("str_int_bool", 1);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == true);
|
|
p->set("str_int_bool", MAX_INT64);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == true);
|
|
p->set("str_int_bool", MIN_INT64);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == true);
|
|
|
|
p->set("str_int_bool", 0);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == false);
|
|
p->set("str_int_bool", 1);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == true);
|
|
p->set("str_int_bool", MAX_UINT64);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == true);
|
|
p->set("str_int_bool", MIN_UINT64);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == false);
|
|
|
|
p->set("str_int_bool", 0);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == false);
|
|
p->set("str_int_bool", 1);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == true);
|
|
p->set("str_int_bool", MAX_INT32);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == true);
|
|
p->set("str_int_bool", MIN_INT32);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == true);
|
|
|
|
p->set("str_int_bool", 0);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == false);
|
|
p->set("str_int_bool", 1);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == true);
|
|
p->set("str_int_bool", MAX_UINT32);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == true);
|
|
p->set("str_int_bool", MIN_UINT32);
|
|
EXPECT_TRUE(!p->get("str_int_bool", &maybe) && maybe == false);
|
|
|
|
EXPECT_TRUE(p->raw_string() ==
|
|
"num_int32=-2147483648;num_int64=-9223372036854775808;num_uint32="
|
|
"0;num_uint64=0;str_int32=-2147483648;str_int64=-"
|
|
"9223372036854775808;str_int_bool=0;str_uint32=0;str_uint64=0;");
|
|
|
|
delete p;
|
|
}
|
|
|
|
#if !defined(DBUG_OFF)
|
|
|
|
// Tests invalid setting and getting of int and bool options
|
|
typedef PropertiesTest PropertiesTestDeathTest;
|
|
|
|
TEST_F(PropertiesTestDeathTest, FailingSetGetIntBool) {
|
|
::testing::FLAGS_gtest_death_test_style = "threadsafe";
|
|
int32 val_int32 = 0;
|
|
uint32 val_uint32 = 0;
|
|
int64 val_int64 = 0;
|
|
uint64 val_uint64 = 0;
|
|
|
|
const char *OFL_INT64_STR = "9223372036854775808";
|
|
const char *UFL_INT64_STR = "-9223372036854775809";
|
|
|
|
const char *OFL_UINT64_STR = "18446744073709551616";
|
|
|
|
const char *OFL_INT32_STR = "2147483648";
|
|
const char *UFL_INT32_STR = "-2147483649";
|
|
|
|
const char *OFL_UINT32_STR = "4294967296";
|
|
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
|
|
p->set("num_int64", OFL_INT64_STR);
|
|
EXPECT_TRUE(value(*p, "num_int64") == OFL_INT64_STR);
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("num_int64", &val_int64),
|
|
".*UTC - mysqld got.*");
|
|
|
|
p->set("num_int64", UFL_INT64_STR);
|
|
EXPECT_TRUE(value(*p, "num_int64") == UFL_INT64_STR);
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("num_int64", &val_int64),
|
|
".*UTC - mysqld got.*");
|
|
|
|
p->set("num_uint64", OFL_UINT64_STR);
|
|
EXPECT_TRUE(value(*p, "num_uint64") == OFL_UINT64_STR);
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("num_uint64", &val_uint64),
|
|
".*UTC - mysqld got.*");
|
|
|
|
p->set("num_int32", OFL_INT32_STR);
|
|
EXPECT_TRUE(value(*p, "num_int32") == OFL_INT32_STR);
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("num_int32", &val_int32),
|
|
".*UTC - mysqld got.*");
|
|
|
|
p->set("num_int32", UFL_INT32_STR);
|
|
EXPECT_TRUE(value(*p, "num_int32") == UFL_INT32_STR);
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("num_int32", &val_int32),
|
|
".*UTC - mysqld got.*");
|
|
|
|
p->set("num_uint32", OFL_UINT32_STR);
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("num_uint32", &val_uint32),
|
|
".*UTC - mysqld got.*");
|
|
|
|
// The overflowed unit32 may be retrieved as 64 bit
|
|
EXPECT_TRUE(!p->get("num_uint32", &val_uint64) &&
|
|
!p->get("num_uint32", &val_int64));
|
|
|
|
// An overflowing 64 bit int should not be accepted as a bool
|
|
bool maybe = false;
|
|
|
|
p->set("bool", OFL_UINT64_STR);
|
|
EXPECT_TRUE(value(*p, "bool") == OFL_UINT64_STR);
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("bool", &val_uint64),
|
|
".*UTC - mysqld got.*");
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("bool", &maybe), ".*UTC - mysqld got.*");
|
|
|
|
p->set("bool", UFL_INT64_STR);
|
|
EXPECT_TRUE(value(*p, "bool") == UFL_INT64_STR);
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("bool", &val_int64), ".*UTC - mysqld got.*");
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("bool", &maybe), ".*UTC - mysqld got.*");
|
|
p->remove("bool");
|
|
|
|
// Integers with empty keys and non existing keys.
|
|
p->set("", 0);
|
|
EXPECT_FALSE(p->exists(""));
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("non_existing", &val_int64),
|
|
".*UTC - mysqld got.*");
|
|
EXPECT_DEATH_IF_SUPPORTED(p->get("", &val_int64), ".*UTC - mysqld got.*");
|
|
EXPECT_DEATH_IF_SUPPORTED(value(*p, ""), ".*UTC - mysqld got.*");
|
|
EXPECT_TRUE(p->remove(""));
|
|
|
|
EXPECT_TRUE(p->raw_string() ==
|
|
"num_int32=-2147483649;num_int64=-9223372036854775809;num_uint32="
|
|
"4294967296;num_uint64=18446744073709551616;");
|
|
|
|
delete p;
|
|
}
|
|
|
|
#endif // DBUG_OFF
|
|
|
|
// Tests the exists function
|
|
TEST_F(PropertiesTest, OptionsExist) {
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
EXPECT_FALSE(p->exists(""));
|
|
EXPECT_FALSE(p->exists("a"));
|
|
|
|
p->set("", "");
|
|
EXPECT_FALSE(p->exists(""));
|
|
|
|
p->set("empty", "");
|
|
EXPECT_TRUE(p->exists("empty"));
|
|
EXPECT_TRUE(value(*p, "empty") == "");
|
|
|
|
p->set("a", "b");
|
|
EXPECT_TRUE(p->exists("a"));
|
|
EXPECT_TRUE(value(*p, "a") == "b");
|
|
|
|
// Create another object with the raw string as input
|
|
dd::Properties *p_copy =
|
|
dd::Properties_impl::parse_properties(p->raw_string());
|
|
EXPECT_TRUE(p->exists("empty"));
|
|
EXPECT_TRUE(value(*p, "empty") == "");
|
|
|
|
EXPECT_TRUE(p->exists("a"));
|
|
EXPECT_TRUE(value(*p, "a") == "b");
|
|
|
|
delete p;
|
|
delete p_copy;
|
|
}
|
|
|
|
// Tests replacing values
|
|
TEST_F(PropertiesTest, ReplaceValues) {
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
EXPECT_FALSE(p->exists(""));
|
|
EXPECT_FALSE(p->exists("a"));
|
|
|
|
p->set("empty", "");
|
|
EXPECT_TRUE(p->exists("empty"));
|
|
EXPECT_TRUE(value(*p, "empty") == "");
|
|
|
|
p->set("empty too", "");
|
|
EXPECT_TRUE(p->exists("empty too"));
|
|
EXPECT_TRUE(value(*p, "empty too") == "");
|
|
|
|
p->set("empty", " ");
|
|
EXPECT_TRUE(p->exists("empty"));
|
|
EXPECT_TRUE(value(*p, "empty") == " ");
|
|
|
|
p->set("a", "b");
|
|
EXPECT_TRUE(p->exists("a"));
|
|
EXPECT_TRUE(value(*p, "a") == "b");
|
|
|
|
p->set("a", "b too");
|
|
EXPECT_TRUE(p->exists("a"));
|
|
EXPECT_TRUE(value(*p, "a") == "b too");
|
|
|
|
p->set("a", "");
|
|
EXPECT_TRUE(p->exists("a"));
|
|
EXPECT_TRUE(value(*p, "a") == "");
|
|
|
|
EXPECT_TRUE(p->raw_string() == "a=;empty= ;empty too=;");
|
|
|
|
delete p;
|
|
}
|
|
|
|
// Tests removing options
|
|
TEST_F(PropertiesTest, RemoveOptions) {
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
|
|
EXPECT_FALSE(p->exists(""));
|
|
EXPECT_FALSE(p->exists("a"));
|
|
|
|
EXPECT_TRUE(p->remove(""));
|
|
EXPECT_TRUE(p->remove("a"));
|
|
|
|
p->set("a", "");
|
|
EXPECT_TRUE(p->exists("a"));
|
|
EXPECT_TRUE(value(*p, "a") == "");
|
|
EXPECT_FALSE(p->remove("a"));
|
|
EXPECT_FALSE(p->exists("a"));
|
|
EXPECT_TRUE(p->remove("a"));
|
|
|
|
p->set("a", "b");
|
|
EXPECT_TRUE(p->exists("a"));
|
|
EXPECT_TRUE(value(*p, "a") == "b");
|
|
EXPECT_FALSE(p->remove("a"));
|
|
EXPECT_FALSE(p->exists("a"));
|
|
EXPECT_TRUE(p->remove("a"));
|
|
|
|
EXPECT_TRUE(p->raw_string() == "");
|
|
|
|
delete p;
|
|
}
|
|
|
|
// Tests iterating over options
|
|
TEST_F(PropertiesTest, IterationSize) {
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
|
|
EXPECT_TRUE(p->size() == 0);
|
|
|
|
p->set("a", "b");
|
|
EXPECT_TRUE(p->size() == 1);
|
|
|
|
p->set("a", "b too");
|
|
EXPECT_TRUE(p->size() == 1);
|
|
|
|
p->set("b", "c");
|
|
EXPECT_TRUE(p->size() == 2);
|
|
|
|
p->set("c", "d");
|
|
EXPECT_TRUE(p->size() == 3);
|
|
|
|
EXPECT_FALSE(p->remove("a"));
|
|
EXPECT_TRUE(p->size() == 2);
|
|
EXPECT_TRUE(p->remove("a"));
|
|
EXPECT_TRUE(p->size() == 2);
|
|
|
|
p->set("", "");
|
|
EXPECT_TRUE(p->size() == 2);
|
|
|
|
int i = 0;
|
|
for (dd::Properties::iterator it = p->begin(); it != p->end(); ++it, ++i)
|
|
if (it->first == "b")
|
|
EXPECT_TRUE(it->second == "c");
|
|
else if (it->first == "c")
|
|
EXPECT_TRUE(it->second == "d");
|
|
else
|
|
EXPECT_TRUE(false);
|
|
|
|
EXPECT_TRUE(i == 2);
|
|
|
|
EXPECT_FALSE(p->remove("b"));
|
|
EXPECT_FALSE(p->remove("c"));
|
|
EXPECT_TRUE(p->remove(""));
|
|
|
|
EXPECT_TRUE(p->size() == 0);
|
|
|
|
for (dd::Properties::iterator it MY_ATTRIBUTE((unused)) = p->begin();
|
|
it != p->end(); ++it, ++i)
|
|
EXPECT_TRUE(false);
|
|
|
|
delete p;
|
|
}
|
|
|
|
// Tests that valid integer conversions are handled
|
|
TEST_F(PropertiesTest, ValidIntConversions) {
|
|
int32 val_int32 = 0;
|
|
uint32 val_uint32 = 0;
|
|
int64 val_int64 = 0;
|
|
uint64 val_uint64 = 0;
|
|
|
|
const char *MAX_INT64_STR = "9223372036854775807";
|
|
const int64 MAX_INT64 = std::numeric_limits<int64>::max();
|
|
const char *MIN_INT64_STR = "-9223372036854775808";
|
|
const int64 MIN_INT64 = std::numeric_limits<int64>::min();
|
|
|
|
const char *MAX_UINT64_STR = "18446744073709551615";
|
|
const uint64 MAX_UINT64 = std::numeric_limits<uint64>::max();
|
|
const char *MIN_UINT64_STR = "0";
|
|
const uint64 MIN_UINT64 = 0;
|
|
|
|
const char *MAX_INT32_STR = "2147483647";
|
|
const int32 MAX_INT32 = std::numeric_limits<int32>::max();
|
|
const char *MIN_INT32_STR = "-2147483648";
|
|
const int32 MIN_INT32 = std::numeric_limits<int32>::min();
|
|
|
|
const char *MAX_UINT32_STR = "4294967295";
|
|
const uint32 MAX_UINT32 = std::numeric_limits<uint32>::max();
|
|
const char *MIN_UINT32_STR = "0";
|
|
const uint32 MIN_UINT32 = 0;
|
|
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
|
|
// ======================================
|
|
// Positive test cases
|
|
// ======================================
|
|
// TC# Operation Source Target
|
|
// -----+------------+-----------+-------
|
|
// PTC1 Convert +num int64
|
|
// PTC2 Convert -num int64
|
|
// PTC3 Convert 0 int64
|
|
// PTC4 Convert MAX_INT64 int64
|
|
// PTC5 Convert MIN_INT64 int64
|
|
// -----+------------+-----------+-------
|
|
// PTC6 Convert +num uint64
|
|
// PTC7 Convert 0 uint64
|
|
// PTC8 Convert MAX_UINT32 uint64
|
|
// PTC9 Convert MIN_UINT32 uint64
|
|
// -----+------------+-----------+-------
|
|
// PTC10 Convert +num int32
|
|
// PTC11 Convert -num int32
|
|
// PTC12 Convert 0 int32
|
|
// PTC13 Convert MAX_INT32 int32
|
|
// PTC14 Convert MIN_INT32 int32
|
|
// -----+------------+-----------+-------
|
|
// PTC15 Convert +num uint32
|
|
// PTC16 Convert 0 uint32
|
|
// PTC17 Convert MAX_UINT32 uint32
|
|
// PTC18 Convert MIN_UINT32 uint32
|
|
// ======================================
|
|
|
|
// PTC1
|
|
EXPECT_TRUE(!p->from_str("123", &val_int64) && val_int64 == 123);
|
|
// PTC2
|
|
EXPECT_TRUE(!p->from_str("-123", &val_int64) && val_int64 == -123);
|
|
// PTC3
|
|
EXPECT_TRUE(!p->from_str("0", &val_int64) && val_int64 == 0);
|
|
// PTC4
|
|
EXPECT_TRUE(!p->from_str(MAX_INT64_STR, &val_int64) &&
|
|
val_int64 == MAX_INT64);
|
|
// PTC5
|
|
EXPECT_TRUE(!p->from_str(MIN_INT64_STR, &val_int64) &&
|
|
val_int64 == MIN_INT64);
|
|
|
|
// PTC6
|
|
EXPECT_TRUE(!p->from_str("123", &val_uint64) && val_uint64 == 123);
|
|
// PTC7
|
|
EXPECT_TRUE(!p->from_str("0", &val_uint64) && val_uint64 == 0);
|
|
// PTC8
|
|
EXPECT_TRUE(!p->from_str(MAX_UINT64_STR, &val_uint64) &&
|
|
val_uint64 == MAX_UINT64);
|
|
// PTC9
|
|
EXPECT_TRUE(!p->from_str(MIN_UINT64_STR, &val_uint64) &&
|
|
val_uint64 == MIN_UINT64);
|
|
|
|
// PTC10
|
|
EXPECT_TRUE(!p->from_str("123", &val_int32) && val_int32 == 123);
|
|
// PTC11
|
|
EXPECT_TRUE(!p->from_str("-123", &val_int32) && val_int32 == -123);
|
|
// PTC12
|
|
EXPECT_TRUE(!p->from_str("0", &val_int32) && val_int32 == 0);
|
|
// PTC13
|
|
EXPECT_TRUE(!p->from_str(MAX_INT32_STR, &val_int32) &&
|
|
val_int32 == MAX_INT32);
|
|
// PTC14
|
|
EXPECT_TRUE(!p->from_str(MIN_INT32_STR, &val_int32) &&
|
|
val_int32 == MIN_INT32);
|
|
|
|
// PTC15
|
|
EXPECT_TRUE(!p->from_str("123", &val_uint32) && val_uint32 == 123);
|
|
// PTC16
|
|
EXPECT_TRUE(!p->from_str("0", &val_uint32) && val_uint32 == 0);
|
|
// PTC17
|
|
EXPECT_TRUE(!p->from_str(MAX_UINT32_STR, &val_uint32) &&
|
|
val_uint32 == MAX_UINT32);
|
|
// PTC18
|
|
EXPECT_TRUE(!p->from_str(MIN_UINT32_STR, &val_uint32) &&
|
|
val_uint32 == MIN_UINT32);
|
|
|
|
delete p;
|
|
}
|
|
|
|
// Tests that integer conversion errors are handled
|
|
TEST_F(PropertiesTest, FailingIntConversions) {
|
|
int32 val_int32 = 0;
|
|
uint32 val_uint32 = 0;
|
|
int64 val_int64 = 0;
|
|
uint64 val_uint64 = 0;
|
|
|
|
const char *OFL_INT64_STR = "9223372036854775808";
|
|
const char *UFL_INT64_STR = "-9223372036854775809";
|
|
|
|
const char *OFL_UINT64_STR = "18446744073709551616";
|
|
|
|
const char *OFL_INT32_STR = "2147483648";
|
|
const char *UFL_INT32_STR = "-2147483649";
|
|
|
|
const char *OFL_UINT32_STR = "4294967296";
|
|
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
|
|
// ======================================
|
|
// Negative test cases
|
|
// ======================================
|
|
// TC# Operation Source Target
|
|
// -----+------------+-----------+-------
|
|
// NTC1 Overflow OFL_INT64 int64
|
|
// NTC2 Underflow UFL_INT64 int64
|
|
// NTC3 Malformed str int64
|
|
|
|
// NTC4 Overflow OFL_UINT64 uint64
|
|
// NTC5 Malformed str uint64
|
|
// NTC6 Sign -num uint64
|
|
|
|
// NTC7 Overflow OFL_INT32 int32
|
|
// NTC8 Underflow UFL_INT32 int32
|
|
// NTC9 Malformed str int32
|
|
|
|
// NTC10 Overflow OFL_UINT32 uint32
|
|
// NTC11 Malformed str uint32
|
|
// NTC12 Sign -num uint32
|
|
// ======================================
|
|
|
|
// NTC1
|
|
EXPECT_TRUE(p->from_str(OFL_INT64_STR, &val_int64));
|
|
// NTC2
|
|
EXPECT_TRUE(p->from_str(UFL_INT64_STR, &val_int64));
|
|
// NTC3
|
|
EXPECT_TRUE(p->from_str("abc", &val_int64));
|
|
|
|
// NTC4
|
|
EXPECT_TRUE(p->from_str(OFL_UINT64_STR, &val_uint64));
|
|
// NTC5
|
|
EXPECT_TRUE(p->from_str("abc", &val_uint64));
|
|
// NTC6
|
|
EXPECT_TRUE(p->from_str("-1", &val_uint64));
|
|
|
|
// NTC7
|
|
EXPECT_TRUE(p->from_str(OFL_INT32_STR, &val_int32));
|
|
// NTC8
|
|
EXPECT_TRUE(p->from_str(UFL_INT32_STR, &val_int32));
|
|
// NTC9
|
|
EXPECT_TRUE(p->from_str("abc", &val_int32));
|
|
|
|
// NTC10
|
|
EXPECT_TRUE(p->from_str(OFL_UINT32_STR, &val_uint32));
|
|
// NTC11
|
|
EXPECT_TRUE(p->from_str("abc", &val_uint32));
|
|
// NTC12
|
|
EXPECT_TRUE(p->from_str("-1", &val_uint32));
|
|
|
|
delete p;
|
|
}
|
|
|
|
// Tests that valid boolean conversions are handled
|
|
TEST_F(PropertiesTest, ValidBoolConversions) {
|
|
bool val = false;
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
|
|
const char *MIN_INT64_STR = "-9223372036854775808";
|
|
const char *MAX_INT64_STR = "9223372036854775807";
|
|
const char *MAX_UINT64_STR = "18446744073709551615";
|
|
const char *OFL_INT64_STR = "9223372036854775808";
|
|
|
|
// =======================================
|
|
// Positive test cases
|
|
// =======================================
|
|
// TC# Operation Source Target
|
|
// -----+------------+-------------+------
|
|
// PTC1 Convert true bool
|
|
// PTC2 Convert 1 bool
|
|
// PTC3 Convert true bool
|
|
// PTC4 Convert 0 bool
|
|
// PTC5 Convert MIN_INT64_STR bool
|
|
// PTC6 Convert MAX_INT64_STR bool
|
|
// PTC7 Convert MAX_UINT64_STR bool
|
|
// PTC8 Convert OFL_INT64_STR bool
|
|
// =======================================
|
|
|
|
// PTC1
|
|
EXPECT_TRUE(!p->from_str("true", &val) && val == true);
|
|
// PTC2
|
|
EXPECT_TRUE(!p->from_str("1", &val) && val == true);
|
|
// PTC3
|
|
EXPECT_TRUE(!p->from_str("false", &val) && val == false);
|
|
// PTC4
|
|
EXPECT_TRUE(!p->from_str("0", &val) && val == false);
|
|
// PTC5
|
|
EXPECT_TRUE(!p->from_str(MIN_INT64_STR, &val) && val == true);
|
|
// PTC6
|
|
EXPECT_TRUE(!p->from_str(MAX_INT64_STR, &val) && val == true);
|
|
// PTC7
|
|
EXPECT_TRUE(!p->from_str(MAX_UINT64_STR, &val) && val == true);
|
|
// PTC8
|
|
EXPECT_TRUE(!p->from_str(OFL_INT64_STR, &val) && val == true);
|
|
|
|
delete p;
|
|
}
|
|
|
|
// Tests that boolean conversion errors are handled
|
|
TEST_F(PropertiesTest, FailingBoolConversions) {
|
|
bool val = false;
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
|
|
const char *UFL_INT64_STR = "-9223372036854775809";
|
|
const char *OFL_UINT64_STR = "18446744073709551616";
|
|
|
|
// =======================================
|
|
// Negative test cases
|
|
// =======================================
|
|
// TC# Operation Source Target
|
|
// -----+------------+-------------+------
|
|
// NTC1 Convert TRUE bool
|
|
// NTC2 Convert FALSE bool
|
|
// NTC3 Convert <empty> bool
|
|
// NTC4 Convert ttrue bool
|
|
// NTC5 Convert truee bool
|
|
// NTC6 Convert ffalse bool
|
|
// NTC7 Convert falsee bool
|
|
// NTC8 Convert UFL_INT64_STR bool
|
|
// NTC9 Convert OFL_UINT64_STR bool
|
|
// =======================================
|
|
|
|
// NTC1
|
|
EXPECT_TRUE(p->from_str("TRUE", &val));
|
|
// NTC2
|
|
EXPECT_TRUE(p->from_str("FALSE", &val));
|
|
// NTC3
|
|
EXPECT_TRUE(p->from_str("", &val));
|
|
// NTC4
|
|
EXPECT_TRUE(p->from_str("ttrue", &val));
|
|
// NTC5
|
|
EXPECT_TRUE(p->from_str("truee", &val));
|
|
// NTC6
|
|
EXPECT_TRUE(p->from_str("ffalse", &val));
|
|
// NTC7
|
|
EXPECT_TRUE(p->from_str("falsee", &val));
|
|
// NTC8
|
|
EXPECT_TRUE(p->from_str(UFL_INT64_STR, &val));
|
|
// NTC9
|
|
EXPECT_TRUE(p->from_str(OFL_UINT64_STR, &val));
|
|
|
|
delete p;
|
|
}
|
|
|
|
// Invoke conversion functions through class name
|
|
TEST_F(PropertiesTest, StaticConversionMethods) {
|
|
int32 val_int32 = 0;
|
|
uint32 val_uint32 = 0;
|
|
int64 val_int64 = 0;
|
|
uint64 val_uint64 = 0;
|
|
bool maybe = false;
|
|
|
|
EXPECT_TRUE(!dd::Properties::from_str("-123", &val_int64) &&
|
|
val_int64 == -123);
|
|
|
|
EXPECT_TRUE(dd::Properties::from_str("-123", &val_uint64));
|
|
EXPECT_TRUE(!dd::Properties::from_str("0", &val_uint64) && val_uint64 == 0);
|
|
|
|
EXPECT_TRUE(!dd::Properties::from_str("-123", &val_int32) &&
|
|
val_int32 == -123);
|
|
|
|
EXPECT_TRUE(dd::Properties::from_str("-123", &val_uint32));
|
|
EXPECT_TRUE(!dd::Properties::from_str("0", &val_uint32) && val_uint32 == 0);
|
|
|
|
EXPECT_TRUE(!dd::Properties::from_str("true", &maybe) && maybe == true);
|
|
EXPECT_TRUE(!dd::Properties::from_str("1", &maybe) && maybe == true);
|
|
EXPECT_TRUE(!dd::Properties::from_str("false", &maybe) && maybe == false);
|
|
EXPECT_TRUE(!dd::Properties::from_str("0", &maybe) && maybe == false);
|
|
|
|
EXPECT_TRUE(dd::Properties::from_str("", &maybe));
|
|
}
|
|
|
|
// Test assignment operator for deep copy of Property objects
|
|
TEST_F(PropertiesTest, Assign) {
|
|
dd::Properties *p = new dd::Properties_impl();
|
|
p->set("a", 1);
|
|
|
|
// Assign to a different object
|
|
dd::Properties *p_copy = new dd::Properties_impl();
|
|
p_copy->insert_values(*p);
|
|
|
|
// The "a" key should be present with the same value in both objects
|
|
int32 val_p = 0;
|
|
int32 val_p_copy = 0;
|
|
EXPECT_TRUE(!p->get("a", &val_p) && val_p == 1 &&
|
|
!p_copy->get("a", &val_p_copy) && val_p_copy == 1);
|
|
|
|
// Changing the value in one object should not be reflected in the other
|
|
p->set("a", 2);
|
|
EXPECT_TRUE(!p->get("a", &val_p) && val_p == 2 &&
|
|
!p_copy->get("a", &val_p_copy) && val_p_copy == 1);
|
|
delete p_copy;
|
|
delete p;
|
|
}
|
|
|
|
TEST_F(PropertiesTest, ValidKeys) {
|
|
// Create a property object with valid keys.
|
|
dd::Properties_impl p({"a"});
|
|
|
|
EXPECT_FALSE(p.set("a", "1"));
|
|
#if defined(DBUG_OFF)
|
|
EXPECT_TRUE(p.set("b", "2"));
|
|
#else
|
|
EXPECT_DEATH_IF_SUPPORTED(p.set("b", "2"), ".*UTC - mysqld got.*");
|
|
#endif
|
|
EXPECT_TRUE(p.raw_string() == "a=1;");
|
|
// Adding a valid key makes it possible to set it.
|
|
p.add_valid_keys({"b"});
|
|
EXPECT_FALSE(p.set("b", "2"));
|
|
EXPECT_TRUE(p.raw_string() == "a=1;b=2;");
|
|
|
|
// Clearing the valid keys still gives us the
|
|
// same raw string.
|
|
p.clear_valid_keys();
|
|
EXPECT_TRUE(p.raw_string() == "a=1;b=2;");
|
|
|
|
// And we can get the keys present.
|
|
dd::String_type str;
|
|
EXPECT_TRUE(!p.get("b", &str) && str == "2");
|
|
|
|
#if !defined(DBUG_OFF)
|
|
// Then adding a valid key asserts in dbug, though, because
|
|
// we might then hide keys present.
|
|
EXPECT_DEATH_IF_SUPPORTED(p.add_valid_keys({"c"}), ".*UTC - mysqld got.*");
|
|
#endif
|
|
|
|
// Removing all key-values will
|
|
// allow us to add a valid key, though.
|
|
p.clear();
|
|
p.clear_valid_keys();
|
|
p.add_valid_keys({"c"});
|
|
|
|
// Adding another valid key is allowed even if there are
|
|
// key-values present as long as there is already
|
|
// a set of valid keys.
|
|
EXPECT_FALSE(p.set("c", "3"));
|
|
p.add_valid_keys({"c"});
|
|
|
|
// Copying values from a raw string will skip invalid keys.
|
|
p.clear();
|
|
p.add_valid_keys({"b"});
|
|
p.insert_values("a=1;b=2;");
|
|
p.clear_valid_keys();
|
|
EXPECT_TRUE(p.raw_string() == "b=2;");
|
|
EXPECT_TRUE(p.size() == 1);
|
|
|
|
// Copying values from another property object will skip keys
|
|
// that are invalid.
|
|
p.clear();
|
|
p.add_valid_keys({"b", "c"});
|
|
dd::Properties_impl p_other;
|
|
EXPECT_FALSE(p_other.set("a", "1_other"));
|
|
EXPECT_FALSE(p_other.set("b", "2_other"));
|
|
EXPECT_FALSE(p_other.set("c", "3_other"));
|
|
EXPECT_TRUE(p_other.raw_string() == "a=1_other;b=2_other;c=3_other;");
|
|
|
|
// Now, only "b" and "c" will be copied, since "a" is invalid in p.
|
|
p.insert_values(p_other);
|
|
p.clear_valid_keys();
|
|
EXPECT_TRUE(p.raw_string() == "b=2_other;c=3_other;");
|
|
}
|
|
|
|
} // namespace dd_properties_unittest
|
|
|