uint32_t line_; ///< Line number.
uint32_t pos_; ///< Position within the line.
+ /// \brief Default constructor.
+ Position() : file_(""), line_(0), pos_(0) {
+ }
+
/// \brief Constructor.
///
/// \param file File name.
// **************************** BooleanParser *************************
template<> void ValueParser<bool>::build(isc::data::ConstElementPtr value) {
+ // Invoke common code for all specializations of build().
+ buildCommon(value);
// The Config Manager checks if user specified a
// valid value for a boolean parameter: True or False.
// We should have a boolean Element, use value directly
// **************************** Uin32Parser *************************
template<> void ValueParser<uint32_t>::build(ConstElementPtr value) {
+ // Invoke common code for all specializations of build().
+ buildCommon(value);
+
int64_t check;
string x = value->str();
try {
// **************************** StringParser *************************
template <> void ValueParser<std::string>::build(ConstElementPtr value) {
+ // Invoke common code for all specializations of build().
+ buildCommon(value);
+
value_ = value->str();
boost::erase_all(value_, "\"");
}
/// @brief A template class that stores named elements of a given data type.
///
-/// This template class is provides data value storage for configuration parameters
-/// of a given data type. The values are stored by parameter name and as instances
-/// of type "ValueType".
+/// This template class is provides data value storage for configuration
+/// parameters of a given data type. The values are stored by parameter name
+/// and as instances of type "ValueType". Each value held in the storage has
+/// a corresponding position within a configuration string (file) specified
+/// as a: file name, line number and position within the line. The position
+/// information is used for logging when the particular configuration value
+/// causes a configuration error.
///
-/// @param ValueType is the data type of the elements to store.
+/// @tparam ValueType is the data type of the elements to store.
template<typename ValueType>
class ValueStorage {
- public:
- /// @brief Stores the the parameter and its value in the store.
- ///
- /// If the parameter does not exist in the store, then it will be added,
- /// otherwise its data value will be updated with the given value.
- ///
- /// @param name is the name of the paramater to store.
- /// @param value is the data value to store.
- void setParam(const std::string& name, const ValueType& value) {
- values_[name] = value;
- }
+public:
+ /// @brief Stores the the parameter, its value and the position in the
+ /// store.
+ ///
+ /// If the parameter does not exist in the store, then it will be added,
+ /// otherwise its data value and the position will be updated with the
+ /// given values.
+ ///
+ /// @param name is the name of the paramater to store.
+ /// @param value is the data value to store.
+ /// @param position is the position of the data element within a
+ /// configuration string (file).
+ void setParam(const std::string& name, const ValueType& value,
+ const data::Element::Position& position) {
+ values_[name] = value;
+ positions_[name] = position;
+ }
- /// @brief Returns the data value for the given parameter.
- ///
- /// Finds and returns the data value for the given parameter.
- /// @param name is the name of the parameter for which the data
- /// value is desired.
- ///
- /// @return The paramater's data value of type @c ValueType.
- /// @throw DhcpConfigError if the parameter is not found.
- ValueType getParam(const std::string& name) const {
- typename std::map<std::string, ValueType>::const_iterator param
- = values_.find(name);
-
- if (param == values_.end()) {
- isc_throw(DhcpConfigError, "Missing parameter '"
- << name << "'");
- }
-
- return (param->second);
- }
+ /// @brief Returns the data value for the given parameter.
+ ///
+ /// Finds and returns the data value for the given parameter.
+ /// @param name is the name of the parameter for which the data
+ /// value is desired.
+ ///
+ /// @return The paramater's data value of type @c ValueType.
+ /// @throw DhcpConfigError if the parameter is not found.
+ ValueType getParam(const std::string& name) const {
+ typename std::map<std::string, ValueType>::const_iterator param
+ = values_.find(name);
- /// @brief Returns the data value for an optional parameter.
- ///
- /// Finds and returns the data value for the given parameter or
- /// a supplied default value if it is not found.
- ///
- /// @param name is the name of the parameter for which the data
- /// value is desired.
- /// @param default_value value to use the default
- ///
- /// @return The paramater's data value of type @c ValueType.
- ValueType getOptionalParam(const std::string& name,
- const ValueType& default_value) const {
- typename std::map<std::string, ValueType>::const_iterator param
- = values_.find(name);
-
- if (param == values_.end()) {
- return (default_value);
- }
-
- return (param->second);
+ if (param == values_.end()) {
+ isc_throw(DhcpConfigError, "Missing parameter '"
+ << name << "'");
}
- /// @brief Remove the parameter from the store.
- ///
- /// Deletes the entry for the given parameter from the store if it
- /// exists.
- ///
- /// @param name is the name of the paramater to delete.
- void delParam(const std::string& name) {
- values_.erase(name);
+ return (param->second);
+ }
+
+ /// @brief Returns position of the data element in the configuration string.
+ ///
+ /// The returned object comprises file name, line number and the position
+ /// within the particular line of the configuration string where the data
+ /// element holding a particular value is located.
+ ///
+ /// @param name is the name of the parameter which position is desired.
+ ///
+ /// @return Position of the data element or the position holding empty
+ /// file name and two zeros if the position hasn't been specified for the
+ /// particular value.
+ const data::Element::Position& getPosition(const std::string& name) const {
+ typename std::map<std::string, data::Element::Position>::const_iterator
+ pos = positions_.find(name);
+ if (pos == positions_.end()) {
+ return (data::Element::ZERO_POSITION());
}
- /// @brief Deletes all of the entries from the store.
- ///
- void clear() {
- values_.clear();
+ return (pos->second);
+ }
+
+ /// @brief Returns the data value for an optional parameter.
+ ///
+ /// Finds and returns the data value for the given parameter or
+ /// a supplied default value if it is not found.
+ ///
+ /// @param name is the name of the parameter for which the data
+ /// value is desired.
+ /// @param default_value value to use the default
+ ///
+ /// @return The paramater's data value of type @c ValueType.
+ ValueType getOptionalParam(const std::string& name,
+ const ValueType& default_value) const {
+ typename std::map<std::string, ValueType>::const_iterator param
+ = values_.find(name);
+
+ if (param == values_.end()) {
+ return (default_value);
}
- private:
- /// @brief An std::map of the data values, keyed by parameter names.
- std::map<std::string, ValueType> values_;
+ return (param->second);
+ }
+
+ /// @brief Remove the parameter from the store.
+ ///
+ /// Deletes the entry for the given parameter from the store if it
+ /// exists.
+ ///
+ /// @param name is the name of the paramater to delete.
+ void delParam(const std::string& name) {
+ values_.erase(name);
+ positions_.erase(name);
+ }
+
+ /// @brief Deletes all of the entries from the store.
+ ///
+ void clear() {
+ values_.clear();
+ positions_.clear();
+ }
+
+private:
+ /// @brief An std::map of the data values, keyed by parameter names.
+ std::map<std::string, ValueType> values_;
+
+ /// @brief An std::map holding positions of the data elements in the
+ /// configuration, which values are held in @c values_.
+ ///
+ /// The position is used for logging, when the particular value
+ /// causes a configuration error.
+ std::map<std::string, data::Element::Position> positions_;
+
};
/// @throw isc::dhcp::DhcpConfigError if storage is null.
ValueParser(const std::string& param_name,
boost::shared_ptr<ValueStorage<ValueType> > storage)
- : storage_(storage), param_name_(param_name), value_() {
+ : storage_(storage), param_name_(param_name), value_(), pos_() {
// Empty parameter name is invalid.
if (param_name_.empty()) {
isc_throw(isc::dhcp::DhcpConfigError, "parser logic error:"
}
}
-
/// @brief Parse a given element into a value of type @c ValueType
///
/// @param value a value to be parsed.
void commit() {
// If a given parameter already exists in the storage we override
// its value. If it doesn't we insert a new element.
- storage_->setParam(param_name_, value_);
+ storage_->setParam(param_name_, value_, pos_);
}
private:
+
+ /// @brief Performs operations common for all specializations of the
+ /// @c build function.
+ ///
+ /// This method should be called by all specializations of the @c build
+ /// method.
+ ///
+ /// @param value a value being parsed.
+ void buildCommon(isc::data::ConstElementPtr value) {
+ // Remember position of the data element.
+ pos_ = value->getPosition();
+ }
+
/// Pointer to the storage where committed value is stored.
boost::shared_ptr<ValueStorage<ValueType> > storage_;
/// Parsed value.
ValueType value_;
+
+ data::Element::Position pos_;
};
/// @brief typedefs for simple data type parsers
using namespace std;
using namespace isc::asiolink;
+using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
using namespace isc::util;
namespace {
+template <typename Storage>
+bool isZeroPosition(const Storage& storage, const std::string& param_name) {
+ Element::Position position = storage.getPosition(param_name);
+ return ((position.line_ == 0) && (position.pos_ == 0) &&
+ (position.file_.empty()));
+}
+
// This test verifies that BooleanStorage functions properly.
TEST(ValueStorageTest, BooleanTesting) {
BooleanStorage testStore;
// Verify that we can add and retrieve parameters.
- testStore.setParam("firstBool", false);
- testStore.setParam("secondBool", true);
+ testStore.setParam("firstBool", false, Element::Position("kea.conf", 123, 234));
+ testStore.setParam("secondBool", true, Element::Position("keax.conf", 10, 20));
EXPECT_FALSE(testStore.getParam("firstBool"));
EXPECT_TRUE(testStore.getParam("secondBool"));
+ EXPECT_EQ(123, testStore.getPosition("firstBool").line_);
+ EXPECT_EQ(234, testStore.getPosition("firstBool").pos_);
+ EXPECT_EQ("kea.conf", testStore.getPosition("firstBool").file_);
+
+ EXPECT_EQ(10, testStore.getPosition("secondBool").line_);
+ EXPECT_EQ(20, testStore.getPosition("secondBool").pos_);
+ EXPECT_EQ("keax.conf", testStore.getPosition("secondBool").file_);
+
// Verify that we can update parameters.
- testStore.setParam("firstBool", true);
- testStore.setParam("secondBool", false);
+ testStore.setParam("firstBool", true, Element::Position("keax.conf", 555, 111));
+ testStore.setParam("secondBool", false, Element::Position("kea.conf", 1, 3));
EXPECT_TRUE(testStore.getParam("firstBool"));
EXPECT_FALSE(testStore.getParam("secondBool"));
+ EXPECT_EQ(555, testStore.getPosition("firstBool").line_);
+ EXPECT_EQ(111, testStore.getPosition("firstBool").pos_);
+ EXPECT_EQ("keax.conf", testStore.getPosition("firstBool").file_);
+
+ EXPECT_EQ(1, testStore.getPosition("secondBool").line_);
+ EXPECT_EQ(3, testStore.getPosition("secondBool").pos_);
+ EXPECT_EQ("kea.conf", testStore.getPosition("secondBool").file_);
+
// Verify that we can delete a parameter and it will no longer be found.
testStore.delParam("firstBool");
EXPECT_THROW(testStore.getParam("firstBool"), isc::dhcp::DhcpConfigError);
+ // Verify that the "zero" position is returned when parameter doesn't exist.
+ EXPECT_TRUE(isZeroPosition(testStore, "firstBool"));
+
// Verify that the delete was safe and the store still operates.
EXPECT_FALSE(testStore.getParam("secondBool"));
+ EXPECT_EQ(1, testStore.getPosition("secondBool").line_);
+ EXPECT_EQ(3, testStore.getPosition("secondBool").pos_);
+ EXPECT_EQ("kea.conf", testStore.getPosition("secondBool").file_);
+
// Verify that looking for a parameter that never existed throws.
ASSERT_THROW(testStore.getParam("bogusBool"), isc::dhcp::DhcpConfigError);
+ // Verify that the "zero" position is returned when parameter doesn't exist.
+ EXPECT_TRUE(isZeroPosition(testStore, "bogusBool"));
+
// Verify that attempting to delete a parameter that never existed does not throw.
EXPECT_NO_THROW(testStore.delParam("bogusBool"));
testStore.clear();
EXPECT_THROW(testStore.getParam("secondBool"), isc::dhcp::DhcpConfigError);
+ // Verify that the "zero" position is returned when parameter doesn't exist.
+ EXPECT_TRUE(isZeroPosition(testStore, "secondBool"));
}
// This test verifies that Uint32Storage functions properly.
TEST(ValueStorageTest, Uint32Testing) {
Uint32Storage testStore;
- uint32_t intOne = 77;
- uint32_t intTwo = 33;
+ uint32_t int_one = 77;
+ uint32_t int_two = 33;
// Verify that we can add and retrieve parameters.
- testStore.setParam("firstInt", intOne);
- testStore.setParam("secondInt", intTwo);
+ testStore.setParam("firstInt", int_one, Element::Position("kea.conf", 123, 234));
+ testStore.setParam("secondInt", int_two, Element::Position("keax.conf", 10, 20));
+
+ EXPECT_EQ(testStore.getParam("firstInt"), int_one);
+ EXPECT_EQ(testStore.getParam("secondInt"), int_two);
- EXPECT_EQ(testStore.getParam("firstInt"), intOne);
- EXPECT_EQ(testStore.getParam("secondInt"), intTwo);
+ EXPECT_EQ(123, testStore.getPosition("firstInt").line_);
+ EXPECT_EQ(234, testStore.getPosition("firstInt").pos_);
+ EXPECT_EQ("kea.conf", testStore.getPosition("firstInt").file_);
+
+ EXPECT_EQ(10, testStore.getPosition("secondInt").line_);
+ EXPECT_EQ(20, testStore.getPosition("secondInt").pos_);
+ EXPECT_EQ("keax.conf", testStore.getPosition("secondInt").file_);
// Verify that we can update parameters.
- testStore.setParam("firstInt", --intOne);
- testStore.setParam("secondInt", ++intTwo);
+ testStore.setParam("firstInt", --int_one, Element::Position("keax.conf", 555, 111));
+ testStore.setParam("secondInt", ++int_two, Element::Position("kea.conf", 1, 3));
+
+ EXPECT_EQ(testStore.getParam("firstInt"), int_one);
+ EXPECT_EQ(testStore.getParam("secondInt"), int_two);
+
+ EXPECT_EQ(555, testStore.getPosition("firstInt").line_);
+ EXPECT_EQ(111, testStore.getPosition("firstInt").pos_);
+ EXPECT_EQ("keax.conf", testStore.getPosition("firstInt").file_);
- EXPECT_EQ(testStore.getParam("firstInt"), intOne);
- EXPECT_EQ(testStore.getParam("secondInt"), intTwo);
+ EXPECT_EQ(1, testStore.getPosition("secondInt").line_);
+ EXPECT_EQ(3, testStore.getPosition("secondInt").pos_);
+ EXPECT_EQ("kea.conf", testStore.getPosition("secondInt").file_);
// Verify that we can delete a parameter and it will no longer be found.
testStore.delParam("firstInt");
EXPECT_THROW(testStore.getParam("firstInt"), isc::dhcp::DhcpConfigError);
+ // Verify that the "zero" position is returned when parameter doesn't exist.
+ EXPECT_TRUE(isZeroPosition(testStore, "firstInt"));
+
// Verify that the delete was safe and the store still operates.
- EXPECT_EQ(testStore.getParam("secondInt"), intTwo);
+ EXPECT_EQ(testStore.getParam("secondInt"), int_two);
+
+ EXPECT_EQ(1, testStore.getPosition("secondInt").line_);
+ EXPECT_EQ(3, testStore.getPosition("secondInt").pos_);
+ EXPECT_EQ("kea.conf", testStore.getPosition("secondInt").file_);
// Verify that looking for a parameter that never existed throws.
ASSERT_THROW(testStore.getParam("bogusInt"), isc::dhcp::DhcpConfigError);
// Verify that attempting to delete a parameter that never existed does not throw.
EXPECT_NO_THROW(testStore.delParam("bogusInt"));
+ // Verify that the "zero" position is returned when parameter doesn't exist.
+ EXPECT_TRUE(isZeroPosition(testStore, "bogusInt"));
+
// Verify that we can empty the list.
testStore.clear();
EXPECT_THROW(testStore.getParam("secondInt"), isc::dhcp::DhcpConfigError);
+
+ // Verify that the "zero" position is returned when parameter doesn't exist.
+ EXPECT_TRUE(isZeroPosition(testStore, "secondInt"));
}
// This test verifies that StringStorage functions properly.
TEST(ValueStorageTest, StringTesting) {
StringStorage testStore;
- std::string stringOne = "seventy-seven";
- std::string stringTwo = "thirty-three";
+ std::string string_one = "seventy-seven";
+ std::string string_two = "thirty-three";
// Verify that we can add and retrieve parameters.
- testStore.setParam("firstString", stringOne);
- testStore.setParam("secondString", stringTwo);
+ testStore.setParam("firstString", string_one,
+ Element::Position("kea.conf", 123, 234));
+ testStore.setParam("secondString", string_two,
+ Element::Position("keax.conf", 10, 20));
+
+ EXPECT_EQ(testStore.getParam("firstString"), string_one);
+ EXPECT_EQ(testStore.getParam("secondString"), string_two);
+
+ EXPECT_EQ(123, testStore.getPosition("firstString").line_);
+ EXPECT_EQ(234, testStore.getPosition("firstString").pos_);
+ EXPECT_EQ("kea.conf", testStore.getPosition("firstString").file_);
- EXPECT_EQ(testStore.getParam("firstString"), stringOne);
- EXPECT_EQ(testStore.getParam("secondString"), stringTwo);
+ EXPECT_EQ(10, testStore.getPosition("secondString").line_);
+ EXPECT_EQ(20, testStore.getPosition("secondString").pos_);
+ EXPECT_EQ("keax.conf", testStore.getPosition("secondString").file_);
// Verify that we can update parameters.
- stringOne.append("-boo");
- stringTwo.append("-boo");
+ string_one.append("-boo");
+ string_two.append("-boo");
- testStore.setParam("firstString", stringOne);
- testStore.setParam("secondString", stringTwo);
+ testStore.setParam("firstString", string_one,
+ Element::Position("kea.conf", 555, 111));
+ testStore.setParam("secondString", string_two,
+ Element::Position("keax.conf", 1, 3));
- EXPECT_EQ(testStore.getParam("firstString"), stringOne);
- EXPECT_EQ(testStore.getParam("secondString"), stringTwo);
+ EXPECT_EQ(testStore.getParam("firstString"), string_one);
+ EXPECT_EQ(testStore.getParam("secondString"), string_two);
+
+ EXPECT_EQ(555, testStore.getPosition("firstString").line_);
+ EXPECT_EQ(111, testStore.getPosition("firstString").pos_);
+ EXPECT_EQ("kea.conf", testStore.getPosition("firstString").file_);
+
+ EXPECT_EQ(1, testStore.getPosition("secondString").line_);
+ EXPECT_EQ(3, testStore.getPosition("secondString").pos_);
+ EXPECT_EQ("keax.conf", testStore.getPosition("secondString").file_);
// Verify that we can delete a parameter and it will no longer be found.
testStore.delParam("firstString");
EXPECT_THROW(testStore.getParam("firstString"), isc::dhcp::DhcpConfigError);
+ // Verify that the "zero" position is returned when parameter doesn't exist.
+ EXPECT_TRUE(isZeroPosition(testStore, "firstString"));
+
// Verify that the delete was safe and the store still operates.
- EXPECT_EQ(testStore.getParam("secondString"), stringTwo);
+ EXPECT_EQ(testStore.getParam("secondString"), string_two);
+
+ EXPECT_EQ(1, testStore.getPosition("secondString").line_);
+ EXPECT_EQ(3, testStore.getPosition("secondString").pos_);
+ EXPECT_EQ("keax.conf", testStore.getPosition("secondString").file_);
// Verify that looking for a parameter that never existed throws.
ASSERT_THROW(testStore.getParam("bogusString"), isc::dhcp::DhcpConfigError);
// Verify that attempting to delete a parameter that never existed does not throw.
EXPECT_NO_THROW(testStore.delParam("bogusString"));
+ // Verify that the "zero" position is returned when parameter doesn't exist.
+ EXPECT_TRUE(isZeroPosition(testStore, "bogusString"));
+
// Verify that we can empty the list.
testStore.clear();
EXPECT_THROW(testStore.getParam("secondString"), isc::dhcp::DhcpConfigError);
+
+ // Verify that the "zero" position is returned when parameter doesn't exist.
+ EXPECT_TRUE(isZeroPosition(testStore, "secondString"));
}
#include <config.h>
#include <config/ccsession.h>
+#include <cc/data.h>
#include <dhcp/option.h>
#include <dhcp/option_custom.h>
#include <dhcp/option_int.h>
EXPECT_EQ(ref_values->getParam("foo"), values->getParam("foo"));
}
+ /// @brief Check that the storages of the specific type hold the same
+ /// position.
+ ///
+ /// This function assumes that the @c ref_values storage holds exactly
+ /// one parameter called 'foo'.
+ ///
+ /// @param ref_values A storage holding reference position. In the typical
+ /// case it is a storage held in the original context, which is assigned
+ /// to another context.
+ /// @param values A storage holding position to be checked.
+ /// @tparam ContainerType A type of the storage.
+ /// @tparam ValueType A type of the value in the container.
+ template<typename ContainerType, typename ValueType>
+ void checkPositionEq(const boost::shared_ptr<ContainerType>& ref_values,
+ const boost::shared_ptr<ContainerType>& values) {
+ // Verify that the position is correct.
+ EXPECT_EQ(ref_values->getPosition("foo").line_,
+ values->getPosition("foo").line_);
+
+ EXPECT_EQ(ref_values->getPosition("foo").pos_,
+ values->getPosition("foo").pos_);
+
+ EXPECT_EQ(ref_values->getPosition("foo").file_,
+ values->getPosition("foo").file_);
+ }
+
/// @brief Check that the storages of the specific type hold different
/// value.
///
EXPECT_NE(ref_values->getParam("foo"), values->getParam("foo"));
}
+ /// @brief Check that the storages of the specific type hold fifferent
+ /// position.
+ ///
+ /// This function assumes that the ref_values storage holds exactly
+ /// one parameter called 'foo'.
+ ///
+ /// @param ref_values A storage holding reference position. In the typical
+ /// case it is a storage held in the original context, which is assigned
+ /// to another context.
+ /// @param values A storage holding position to be checked.
+ /// @tparam ContainerType A type of the storage.
+ /// @tparam ValueType A type of the value in the container.
+ template<typename ContainerType, typename ValueType>
+ void checkPositionNeq(const boost::shared_ptr<ContainerType>& ref_values,
+ const boost::shared_ptr<ContainerType>& values) {
+ // At least one of the position fields must be different.
+ EXPECT_TRUE((ref_values->getPosition("foo").line_ !=
+ values->getPosition("foo").line_) ||
+ (ref_values->getPosition("foo").pos_ !=
+ values->getPosition("foo").pos_) ||
+ (ref_values->getPosition("foo").pos_ !=
+ values->getPosition("foo").pos_));
+ }
+
/// @brief Check that option definition storage in the context holds
/// one option definition of the specified type.
///
// Set boolean parameter 'foo'.
ASSERT_TRUE(ctx.boolean_values_);
- ctx.boolean_values_->setParam("foo", true);
+ ctx.boolean_values_->setParam("foo", true,
+ Element::Position("kea.conf", 123, 234));
// Set uint32 parameter 'foo'.
ASSERT_TRUE(ctx.uint32_values_);
- ctx.uint32_values_->setParam("foo", 123);
+ ctx.uint32_values_->setParam("foo", 123,
+ Element::Position("kea.conf", 123, 234));
// Ser string parameter 'foo'.
ASSERT_TRUE(ctx.string_values_);
- ctx.string_values_->setParam("foo", "some string");
+ ctx.string_values_->setParam("foo", "some string",
+ Element::Position("kea.conf", 123, 234));
// Add new option, with option code 10, to the context.
ASSERT_TRUE(ctx.options_);
ctx_new->boolean_values_);
}
+ // New context has the same boolean value position.
+ {
+ SCOPED_TRACE("Check that positions of boolean values are equal"
+ " in both contexts");
+ checkPositionEq<BooleanStorage, bool>(ctx.boolean_values_,
+ ctx_new->boolean_values_);
+ }
+
// New context has the same uint32 value.
ASSERT_TRUE(ctx_new->uint32_values_);
{
ctx_new->uint32_values_);
}
+ // New context has the same uint32 value position.
+ {
+ SCOPED_TRACE("Check that positions of uint32_t values are equal"
+ " in both contexts");
+ checkPositionEq<Uint32Storage, uint32_t>(ctx.uint32_values_,
+ ctx_new->uint32_values_);
+ }
+
// New context has the same string value.
ASSERT_TRUE(ctx_new->string_values_);
{
ctx_new->string_values_);
}
+ // New context has the same string value position.
+ {
+ SCOPED_TRACE("Check that position of string values are equal"
+ " in both contexts");
+ checkPositionEq<StringStorage, std::string>(ctx.string_values_,
+ ctx_new->string_values_);
+ }
+
// New context has the same option.
ASSERT_TRUE(ctx_new->options_);
{
// Change the value of the boolean parameter. This should not affect the
// corresponding value in the new context.
{
- SCOPED_TRACE("Check that boolean value isn't changed when original"
- " value is changed");
- ctx.boolean_values_->setParam("foo", false);
+ SCOPED_TRACE("Check that boolean value and position isn't changed"
+ " when original value and position is changed");
+ ctx.boolean_values_->setParam("foo", false,
+ Element::Position("kea.conf",
+ 12, 10));
checkValueNeq<BooleanStorage, bool>(ctx.boolean_values_,
ctx_new->boolean_values_);
+
+ checkPositionNeq<BooleanStorage, bool>(ctx.boolean_values_,
+ ctx_new->boolean_values_);
}
// Change the value of the uint32_t parameter. This should not affect
// the corresponding value in the new context.
{
- SCOPED_TRACE("Check that uint32_t value isn't changed when original"
- " value is changed");
- ctx.uint32_values_->setParam("foo", 987);
+ SCOPED_TRACE("Check that uint32_t value and position isn't changed"
+ " when original value and position is changed");
+ ctx.uint32_values_->setParam("foo", 987,
+ Element::Position("kea.conf",
+ 10, 11));
checkValueNeq<Uint32Storage, uint32_t>(ctx.uint32_values_,
ctx_new->uint32_values_);
+
+ checkPositionNeq<Uint32Storage, uint32_t>(ctx.uint32_values_,
+ ctx_new->uint32_values_);
+
}
// Change the value of the string parameter. This should not affect the
// corresponding value in the new context.
{
- SCOPED_TRACE("Check that string value isn't changed when original"
- " value is changed");
- ctx.string_values_->setParam("foo", "different string");
+ SCOPED_TRACE("Check that string value and position isn't changed"
+ " when original value and position is changed");
+ ctx.string_values_->setParam("foo", "different string",
+ Element::Position("kea.conf",
+ 10, 11));
checkValueNeq<StringStorage, std::string>(ctx.string_values_,
ctx_new->string_values_);
+
+ checkPositionNeq<
+ StringStorage, std::string>(ctx.string_values_,
+ ctx_new->string_values_);
+
}
// Change the option. This should not affect the option instance in the
EXPECT_EQ(Option::V6, ctx_new->universe_);
}
-
};
// Check that the assignment operator of the ParserContext class copies all