mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 05:27:55 +00:00
[3436] Added configuration permutations test from file to D2
Added the unit test D2CfgMgrTest.configPermutations to d2_cfg_mgr_unittests.cc. This test iterates through the list of test configurations defined in a specialzed JSON data file. It provides a relatively painless way to test a large number configurations without hard-coding them. Added the test data file: It currently contains over sixty tests. The vast majority of these tests are invalid content tests.
This commit is contained in:
parent
c2b4e2554a
commit
d1a0a7fa5c
@ -349,7 +349,8 @@ TSIGKeyInfoParser::build(isc::data::ConstElementPtr key_config) {
|
||||
// data to the parser's local storage.
|
||||
BOOST_FOREACH (config_pair, key_config->mapValue()) {
|
||||
isc::dhcp::ParserPtr parser(createConfigParser(config_pair.first,
|
||||
config_pair.second->getPosition()));
|
||||
config_pair.second->
|
||||
getPosition()));
|
||||
parser->build(config_pair.second);
|
||||
parser->commit();
|
||||
}
|
||||
@ -387,8 +388,7 @@ TSIGKeyInfoParser::build(isc::data::ConstElementPtr key_config) {
|
||||
try {
|
||||
TSIGKeyInfo::stringToAlgorithmName(algorithm);
|
||||
} catch (const std::exception& ex) {
|
||||
isc_throw(D2CfgError, "TSIG key invalid algorithm : "
|
||||
<< algorithm << " : " << pos[1]);
|
||||
isc_throw(D2CfgError, "TSIG key : " << ex.what() << " : " << pos[1]);
|
||||
}
|
||||
|
||||
// Secret cannot be blank.
|
||||
@ -513,7 +513,8 @@ DnsServerInfoParser::build(isc::data::ConstElementPtr server_config) {
|
||||
// data to the parser's local storage.
|
||||
BOOST_FOREACH (config_pair, server_config->mapValue()) {
|
||||
isc::dhcp::ParserPtr parser(createConfigParser(config_pair.first,
|
||||
config_pair.second->getPosition()));
|
||||
config_pair.second->
|
||||
getPosition()));
|
||||
parser->build(config_pair.second);
|
||||
parser->commit();
|
||||
}
|
||||
@ -682,7 +683,8 @@ DdnsDomainParser::build(isc::data::ConstElementPtr domain_config) {
|
||||
isc::dhcp::ConfigPair config_pair;
|
||||
BOOST_FOREACH(config_pair, domain_config->mapValue()) {
|
||||
isc::dhcp::ParserPtr parser(createConfigParser(config_pair.first,
|
||||
config_pair.second->getPosition()));
|
||||
config_pair.second->
|
||||
getPosition()));
|
||||
parser->build(config_pair.second);
|
||||
parser->commit();
|
||||
}
|
||||
@ -838,7 +840,9 @@ DdnsDomainListMgrParser::build(isc::data::ConstElementPtr domain_config) {
|
||||
// data to the parser's local storage.
|
||||
isc::dhcp::ConfigPair config_pair;
|
||||
BOOST_FOREACH(config_pair, domain_config->mapValue()) {
|
||||
isc::dhcp::ParserPtr parser(createConfigParser(config_pair.first));
|
||||
isc::dhcp::ParserPtr parser(createConfigParser(config_pair.first,
|
||||
config_pair.second->
|
||||
getPosition()));
|
||||
parser->build(config_pair.second);
|
||||
parser->commit();
|
||||
}
|
||||
@ -848,7 +852,9 @@ DdnsDomainListMgrParser::build(isc::data::ConstElementPtr domain_config) {
|
||||
}
|
||||
|
||||
isc::dhcp::ParserPtr
|
||||
DdnsDomainListMgrParser::createConfigParser(const std::string& config_id) {
|
||||
DdnsDomainListMgrParser::createConfigParser(const std::string& config_id,
|
||||
const isc::data::Element::
|
||||
Position& pos) {
|
||||
DhcpConfigParser* parser = NULL;
|
||||
if (config_id == "ddns_domains") {
|
||||
// Domain list parser is given our local domain storage. It will pass
|
||||
@ -857,7 +863,8 @@ DdnsDomainListMgrParser::createConfigParser(const std::string& config_id) {
|
||||
parser = new DdnsDomainListParser(config_id, local_domains_, keys_);
|
||||
} else {
|
||||
isc_throw(NotImplemented, "parser error: "
|
||||
"DdnsDomainListMgr parameter not supported: " << config_id);
|
||||
"DdnsDomainListMgr parameter not supported: " << config_id
|
||||
<< " : " << pos);
|
||||
}
|
||||
|
||||
// Return the new domain parser instance.
|
||||
|
@ -1145,10 +1145,16 @@ public:
|
||||
///
|
||||
/// @param config_id is the "item_name" for a specific member element of
|
||||
/// the manager specification.
|
||||
/// @param pos position within the configuration text (or file) of element
|
||||
/// to be parsed. This is passed for error messaging.
|
||||
///
|
||||
/// @return returns a pointer to newly created parser.
|
||||
virtual isc::dhcp::ParserPtr createConfigParser(const std::string&
|
||||
config_id);
|
||||
///
|
||||
/// @throw D2CfgError if configuration contains an unknown parameter
|
||||
virtual isc::dhcp::ParserPtr
|
||||
createConfigParser(const std::string& config_id,
|
||||
const isc::data::Element::Position& pos =
|
||||
isc::data::Element::ZERO_POSITION());
|
||||
|
||||
/// @brief Commits the configured DdsnDomainListMgr
|
||||
/// Currently this method is a NOP, as the manager instance is created
|
||||
|
@ -12,6 +12,7 @@ noinst_SCRIPTS = d2_process_tests.sh
|
||||
|
||||
EXTRA_DIST = $(PYTESTS)
|
||||
EXTRA_DIST += d2_process_tests.sh.in
|
||||
EXTRA_DIST += testdata/d2_cfg_tests.json
|
||||
|
||||
# Explicitly specify paths to dynamic libraries required by loadable python
|
||||
# modules. That is required on Mac OS systems. Otherwise we will get exception
|
||||
|
@ -32,6 +32,10 @@ std::string specfile(const std::string& name) {
|
||||
return (std::string(D2_SRC_DIR) + "/" + name);
|
||||
}
|
||||
|
||||
std::string testDataFile(const std::string& name) {
|
||||
return (std::string(D2_TEST_DATA_DIR) + "/" + name);
|
||||
}
|
||||
|
||||
/// @brief Test fixture class for testing D2CfgMgr class.
|
||||
/// It maintains an member instance of D2CfgMgr and provides methods for
|
||||
/// converting JSON strings to configuration element sets, checking parse
|
||||
@ -1564,4 +1568,101 @@ TEST_F(D2CfgMgrTest, matchReverse) {
|
||||
ASSERT_THROW(cfg_mgr_->matchReverse("", match), D2CfgError);
|
||||
}
|
||||
|
||||
/// @brief Tests D2 config parsing against a wide range of config permutations.
|
||||
/// It iterates over all of the test configurations described in given file.
|
||||
/// The file content is JSON specialized to this test. The format of the file
|
||||
/// is:
|
||||
///
|
||||
/// @code
|
||||
/// # The file must open with a list. It's name is arbitrary.
|
||||
///
|
||||
/// { "test_list" :
|
||||
/// [
|
||||
///
|
||||
/// # Test one starts here:
|
||||
/// {
|
||||
///
|
||||
/// # Each test has:
|
||||
/// # 1. description - optional text description
|
||||
/// # 2. should_fail - bool indicator if parsing is expected to file
|
||||
/// # (defaults to false)
|
||||
/// # 3. data - configuration text to parse
|
||||
/// #
|
||||
/// "description" : "<text describing test>",
|
||||
/// "should_fail" : <true|false> ,
|
||||
/// "data" :
|
||||
/// {
|
||||
/// # configuration elements here
|
||||
/// "bool_val" : false,
|
||||
/// "some_map" : {}
|
||||
/// # :
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # Next test would start here
|
||||
/// ,
|
||||
/// {
|
||||
/// }
|
||||
///
|
||||
/// ]}
|
||||
///
|
||||
/// @endcode
|
||||
///
|
||||
/// (The file supports comments per Element::fromJSONFile())
|
||||
///
|
||||
TEST_F(D2CfgMgrTest, configPermutations) {
|
||||
std::string test_file = testDataFile("d2_cfg_tests.json");
|
||||
isc::data::ConstElementPtr tests;
|
||||
|
||||
// Read contents of the file and parse it as JSON. Note it must contain
|
||||
// all valid JSON, we aren't testing JSON parsing.
|
||||
try {
|
||||
tests = isc::data::Element::fromJSONFile(test_file, true);
|
||||
} catch (const std::exception& ex) {
|
||||
FAIL() << "ERROR parsing file : " << test_file << " : " << ex.what();
|
||||
}
|
||||
|
||||
// Read in each test For each test, read:
|
||||
// 1. description - optional text description
|
||||
// 2. should_fail - bool indicator if parsing is expected to file (defaults
|
||||
// to false
|
||||
// 3. data - configuration text to parse
|
||||
//
|
||||
// Next attempt to parse the configuration by passing it into
|
||||
// D2CfgMgr::parseConfig(). Then check the parsing outcome against the
|
||||
// expected outcome as given by should_fail.
|
||||
isc::data::ConstElementPtr test;
|
||||
BOOST_FOREACH(test, tests->get("test_list")->listValue()) {
|
||||
|
||||
// Grab the description.
|
||||
std::string description = "<no desc>";
|
||||
isc::data::ConstElementPtr elem = test->get("description");
|
||||
if (elem) {
|
||||
elem->getValue(description);
|
||||
}
|
||||
|
||||
// Grab the outcome flag, should_fail, defaults to false if it's
|
||||
// not specified.
|
||||
bool should_fail = false;
|
||||
elem = test->get("should_fail");
|
||||
if (elem) {
|
||||
elem->getValue(should_fail);
|
||||
}
|
||||
|
||||
// Grab the test's configuration data.
|
||||
isc::data::ConstElementPtr data = test->get("data");
|
||||
ASSERT_TRUE(data) << "No data for test: "
|
||||
<< " : " << test->getPosition();
|
||||
|
||||
// Verify that we can parse the configuration.
|
||||
answer_ = cfg_mgr_->parseConfig(data);
|
||||
if (checkAnswer(!should_fail)) {
|
||||
ADD_FAILURE() << "Parsing should have "
|
||||
<< (should_fail ? "failed" : "passed")
|
||||
<< " for : " << description
|
||||
<< " : " << test->getPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
@ -15,3 +15,4 @@
|
||||
/// @brief Path to D2 source dir so tests against the dhcp-ddns.spec file
|
||||
/// can find it reliably.
|
||||
#define D2_SRC_DIR "@abs_top_srcdir@/src/bin/d2"
|
||||
#define D2_TEST_DATA_DIR "@abs_top_srcdir@/src/bin/d2/tests/testdata"
|
||||
|
1273
src/bin/d2/tests/testdata/d2_cfg_tests.json
vendored
Normal file
1273
src/bin/d2/tests/testdata/d2_cfg_tests.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user