-// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
#include <dhcpsrv/parsers/dbaccess_parser.h>
#include <boost/foreach.hpp>
+#include <boost/lexical_cast.hpp>
#include <map>
#include <string>
// use of it).
values_copy["universe"] = ctx_.universe_ == Option::V4 ? "4" : "6";
+ int64_t lfc_interval = 0;
// 3. Update the copy with the passed keywords.
BOOST_FOREACH(ConfigPair param, config_value->mapValue()) {
try {
- // The persist parameter is the only boolean parameter at the
- // moment. It needs special handling.
- if (param.first != "persist") {
- values_copy[param.first] = param.second->stringValue();
-
- } else {
+ if (param.first == "persist") {
values_copy[param.first] = (param.second->boolValue() ?
"true" : "false");
+
+ } else if (param.first == "lfc-interval") {
+ lfc_interval = param.second->intValue();
+ values_copy[param.first] =
+ boost::lexical_cast<std::string>(lfc_interval);
+
+ } else {
+ values_copy[param.first] = param.second->stringValue();
}
} catch (const isc::data::TypeError& ex) {
// Append position of the element.
"to be accessed (" << config_value->getPosition() << ")");
}
- // b. Check if the 'type; keyword known and throw an exception if not.
+ // b. Check if the 'type' keyword known and throw an exception if not.
string dbtype = type_ptr->second;
if ((dbtype != "memfile") && (dbtype != "mysql") && (dbtype != "postgresql")) {
isc_throw(BadValue, "unknown backend database type: " << dbtype
<< " (" << config_value->getPosition() << ")");
}
+ // c. Check that the lfc-interval is a number and it is within a resonable
+ // range.
+ if ((lfc_interval < 0) || (lfc_interval > std::numeric_limits<uint32_t>::max())) {
+ isc_throw(BadValue, "lfc-interval value: " << lfc_interval
+ << " is out of range, expected value: 0.."
+ << std::numeric_limits<uint32_t>::max());
+ }
+
// 5. If all is OK, update the stored keyword/value pairs. We do this by
// swapping contents - values_copy is destroyed immediately after the
// operation (when the method exits), so we are not interested in its new
-// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
/// Parses the set of strings forming the database access specification and
/// checks that all are OK. In particular it checks:
///
- /// - "type" is "memfile" or "mysql"
- /// - If "type" is "memfile", checks that no other values are present: if
- /// they are, logs a warning that they will be ignored.
+ /// - "type" is "memfile", "mysql" or "postgresql"
+ /// - "lfc-interval" is a number from the range of 0 to 4294967295.
///
/// Once all has been validated, constructs the database access string
/// expected by the lease manager.
-// Copyright (C) 2012-2014 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
}
// Add the keyword and value - make sure that they are quoted.
- // The only parameter which is not quoted is persist as it
- // is a boolean value.
+ // The parameters which are not quoted are persist and
+ // lfc-interval as they are boolean and integer respectively.
result += quote + keyval[i] + quote + colon + space;
- if (std::string(keyval[i]) != "persist") {
- result += quote + keyval[i + 1] + quote;
- } else {
+ if (getNonQuotedParams().find(std::string(keyval[i])) !=
+ getNonQuotedParams().end()) {
result += keyval[i + 1];
+
+ } else {
+ result += quote + keyval[i + 1] + quote;
}
}
EXPECT_EQ(corresponding->second, actual->second);
}
}
+
+private:
+
+ /// @brief Returns a set of parameters which should be quoted in the
+ /// test configuration.
+ ///
+ /// In particular, this method is called by the @c toJson to determine
+ /// that the parameter being included in the JSON configuration should
+ /// be quoted or not.
+ const std::set<std::string>& getNonQuotedParams() const {
+ static const char* params[] = { "persist", "lfc-interval" };
+ static std::set<std::string> params_set(params, params + sizeof(params));
+ return (params_set);
+ }
+
};
config, Option::V6);
}
+// This test checks that the parser accepts the valid value of the
+// lfc-interval parameter.
+TEST_F(DbAccessParserTest, validLFCInterval) {
+ const char* config[] = {"type", "memfile",
+ "name", "/opt/kea/var/kea-leases6.csv",
+ "lfc-interval", "3600",
+ NULL};
+
+ string json_config = toJson(config);
+ ConstElementPtr json_elements = Element::fromJSON(json_config);
+ EXPECT_TRUE(json_elements);
+
+ TestDbAccessParser parser("lease-database", ParserContext(Option::V6));
+ ASSERT_NO_THROW(parser.build(json_elements));
+ checkAccessString("Valid LFC Interval", parser.getDbAccessParameters(),
+ config, Option::V6);
+}
+
+// This test checks that the parser rejects the negative value of the
+// lfc-interval parameter.
+TEST_F(DbAccessParserTest, negativeLFCInterval) {
+ const char* config[] = {"type", "memfile",
+ "name", "/opt/kea/var/kea-leases6.csv",
+ "lfc-interval", "-1",
+ NULL};
+
+ string json_config = toJson(config);
+ ConstElementPtr json_elements = Element::fromJSON(json_config);
+ EXPECT_TRUE(json_elements);
+
+ TestDbAccessParser parser("lease-database", ParserContext(Option::V6));
+ EXPECT_THROW(parser.build(json_elements), BadValue);
+}
+
+// This test checks that the parser rejects the too large (greater than
+// the max uint32_t) value of the lfc-interval parameter.
+TEST_F(DbAccessParserTest, largeLFCInterval) {
+ const char* config[] = {"type", "memfile",
+ "name", "/opt/kea/var/kea-leases6.csv",
+ "lfc-interval", "4294967296",
+ NULL};
+
+ string json_config = toJson(config);
+ ConstElementPtr json_elements = Element::fromJSON(json_config);
+ EXPECT_TRUE(json_elements);
+
+ TestDbAccessParser parser("lease-database", ParserContext(Option::V6));
+ EXPECT_THROW(parser.build(json_elements), BadValue);
+}
+
// Check that the parser works with a valid MySQL configuration
TEST_F(DbAccessParserTest, validTypeMysql) {
const char* config[] = {"type", "mysql",