|
@@ -22,18 +22,21 @@
|
|
#include <dhcpsrv/dhcp_parsers.h>
|
|
#include <dhcpsrv/dhcp_parsers.h>
|
|
#include <dhcpsrv/tests/test_libraries.h>
|
|
#include <dhcpsrv/tests/test_libraries.h>
|
|
#include <exceptions/exceptions.h>
|
|
#include <exceptions/exceptions.h>
|
|
|
|
+#include <hooks/hooks_manager.h>
|
|
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <gtest/gtest.h>
|
|
#include <boost/foreach.hpp>
|
|
#include <boost/foreach.hpp>
|
|
|
|
+#include <boost/pointer_cast.hpp>
|
|
|
|
|
|
#include <map>
|
|
#include <map>
|
|
#include <string>
|
|
#include <string>
|
|
|
|
|
|
using namespace std;
|
|
using namespace std;
|
|
using namespace isc;
|
|
using namespace isc;
|
|
-using namespace isc::dhcp;
|
|
|
|
-using namespace isc::data;
|
|
|
|
using namespace isc::config;
|
|
using namespace isc::config;
|
|
|
|
+using namespace isc::data;
|
|
|
|
+using namespace isc::dhcp;
|
|
|
|
+using namespace isc::hooks;
|
|
|
|
|
|
namespace {
|
|
namespace {
|
|
|
|
|
|
@@ -277,7 +280,7 @@ public:
|
|
|
|
|
|
ConfigPair config_pair;
|
|
ConfigPair config_pair;
|
|
try {
|
|
try {
|
|
- // Iteraate over the config elements.
|
|
|
|
|
|
+ // Iterate over the config elements.
|
|
const std::map<std::string, ConstElementPtr>& values_map =
|
|
const std::map<std::string, ConstElementPtr>& values_map =
|
|
config_set->mapValue();
|
|
config_set->mapValue();
|
|
BOOST_FOREACH(config_pair, values_map) {
|
|
BOOST_FOREACH(config_pair, values_map) {
|
|
@@ -317,24 +320,34 @@ public:
|
|
|
|
|
|
/// @brief Create an element parser based on the element name.
|
|
/// @brief Create an element parser based on the element name.
|
|
///
|
|
///
|
|
- /// Note that currently it only supports option-defs and option-data,
|
|
|
|
|
|
+ /// Creates a parser for the appropriate element and stores a pointer to it
|
|
|
|
+ /// in the appropriate class variable.
|
|
|
|
+ ///
|
|
|
|
+ /// Note that the method currently it only supports option-defs, option-data
|
|
|
|
+ /// and hooks-libraries.
|
|
///
|
|
///
|
|
/// @param config_id is the name of the configuration element.
|
|
/// @param config_id is the name of the configuration element.
|
|
- /// @return returns a raw pointer to DhcpConfigParser. Note caller is
|
|
|
|
- /// responsible for deleting it once no longer needed.
|
|
|
|
|
|
+ ///
|
|
|
|
+ /// @return returns a shared pointer to DhcpConfigParser.
|
|
|
|
+ ///
|
|
/// @throw throws NotImplemented if element name isn't supported.
|
|
/// @throw throws NotImplemented if element name isn't supported.
|
|
- DhcpConfigParser* createConfigParser(const std::string& config_id) {
|
|
|
|
- DhcpConfigParser* parser = NULL;
|
|
|
|
|
|
+ ParserPtr createConfigParser(const std::string& config_id) {
|
|
|
|
+ ParserPtr parser;
|
|
if (config_id.compare("option-data") == 0) {
|
|
if (config_id.compare("option-data") == 0) {
|
|
- parser = new OptionDataListParser(config_id,
|
|
|
|
- parser_context_->options_,
|
|
|
|
- parser_context_,
|
|
|
|
- UtestOptionDataParser::factory);
|
|
|
|
|
|
+ parser.reset(new OptionDataListParser(config_id,
|
|
|
|
+ parser_context_->options_,
|
|
|
|
+ parser_context_,
|
|
|
|
+ UtestOptionDataParser::factory));
|
|
|
|
+
|
|
} else if (config_id.compare("option-def") == 0) {
|
|
} else if (config_id.compare("option-def") == 0) {
|
|
- parser = new OptionDefListParser(config_id,
|
|
|
|
- parser_context_->option_defs_);
|
|
|
|
- } else if (config_id.compare("hooks_libraries") == 0) {
|
|
|
|
- parser = new HooksLibrariesParser(config_id, parser_context_);
|
|
|
|
|
|
+ parser.reset(new OptionDefListParser(config_id,
|
|
|
|
+ parser_context_->option_defs_));
|
|
|
|
+
|
|
|
|
+ } else if (config_id.compare("hooks-libraries") == 0) {
|
|
|
|
+ parser.reset(new HooksLibrariesParser(config_id));
|
|
|
|
+ hooks_libraries_parser_ =
|
|
|
|
+ boost::dynamic_pointer_cast<HooksLibrariesParser>(parser);
|
|
|
|
+
|
|
} else {
|
|
} else {
|
|
isc_throw(NotImplemented,
|
|
isc_throw(NotImplemented,
|
|
"Parser error: configuration parameter not supported: "
|
|
"Parser error: configuration parameter not supported: "
|
|
@@ -344,7 +357,7 @@ public:
|
|
return (parser);
|
|
return (parser);
|
|
}
|
|
}
|
|
|
|
|
|
- /// @brief Convenicee method for parsing a configuration
|
|
|
|
|
|
+ /// @brief Convenience method for parsing a configuration
|
|
///
|
|
///
|
|
/// Given a configuration string, convert it into Elements
|
|
/// Given a configuration string, convert it into Elements
|
|
/// and parse them.
|
|
/// and parse them.
|
|
@@ -360,7 +373,8 @@ public:
|
|
EXPECT_TRUE(json);
|
|
EXPECT_TRUE(json);
|
|
if (json) {
|
|
if (json) {
|
|
ConstElementPtr status = parseElementSet(json);
|
|
ConstElementPtr status = parseElementSet(json);
|
|
- ConstElementPtr comment_ = parseAnswer(rcode_, status);
|
|
|
|
|
|
+ ConstElementPtr comment = parseAnswer(rcode_, status);
|
|
|
|
+ error_text_ = comment->stringValue();
|
|
}
|
|
}
|
|
|
|
|
|
return (rcode_);
|
|
return (rcode_);
|
|
@@ -424,14 +438,6 @@ public:
|
|
return (option_ptr);
|
|
return (option_ptr);
|
|
}
|
|
}
|
|
|
|
|
|
- /// @brief Returns hooks libraries from the parser context
|
|
|
|
- ///
|
|
|
|
- /// Returns the pointer to the vector of strings from the parser context.
|
|
|
|
- HooksLibrariesStoragePtr getHooksLibrariesPtr() {
|
|
|
|
- return (parser_context_->hooks_libraries_);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
/// @brief Wipes the contents of the context to allowing another parsing
|
|
/// @brief Wipes the contents of the context to allowing another parsing
|
|
/// during a given test if needed.
|
|
/// during a given test if needed.
|
|
void reset_context(){
|
|
void reset_context(){
|
|
@@ -440,10 +446,21 @@ public:
|
|
CfgMgr::instance().deleteSubnets6();
|
|
CfgMgr::instance().deleteSubnets6();
|
|
CfgMgr::instance().deleteOptionDefs();
|
|
CfgMgr::instance().deleteOptionDefs();
|
|
parser_context_.reset(new ParserContext(Option::V6));
|
|
parser_context_.reset(new ParserContext(Option::V6));
|
|
|
|
+
|
|
|
|
+ // Ensure no hooks libraries are loaded.
|
|
|
|
+ HooksManager::unloadLibraries();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /// @brief Parsers used in the parsing of the configuration
|
|
|
|
+ ///
|
|
|
|
+ /// Allows the tests to interrogate the state of the parsers (if required).
|
|
|
|
+ boost::shared_ptr<HooksLibrariesParser> hooks_libraries_parser_;
|
|
|
|
+
|
|
/// @brief Parser context - provides storage for options and definitions
|
|
/// @brief Parser context - provides storage for options and definitions
|
|
ParserContextPtr parser_context_;
|
|
ParserContextPtr parser_context_;
|
|
|
|
+
|
|
|
|
+ /// @brief Error string if the parsing failed
|
|
|
|
+ std::string error_text_;
|
|
};
|
|
};
|
|
|
|
|
|
/// @brief Check Basic parsing of option definitions.
|
|
/// @brief Check Basic parsing of option definitions.
|
|
@@ -471,6 +488,7 @@ TEST_F(ParseConfigTest, basicOptionDefTest) {
|
|
int rcode = parseConfiguration(config);
|
|
int rcode = parseConfiguration(config);
|
|
ASSERT_TRUE(rcode == 0);
|
|
ASSERT_TRUE(rcode == 0);
|
|
|
|
|
|
|
|
+
|
|
// Verify that the option definition can be retrieved.
|
|
// Verify that the option definition can be retrieved.
|
|
OptionDefinitionPtr def = getOptionDef("isc", 100);
|
|
OptionDefinitionPtr def = getOptionDef("isc", 100);
|
|
ASSERT_TRUE(def);
|
|
ASSERT_TRUE(def);
|
|
@@ -528,41 +546,58 @@ TEST_F(ParseConfigTest, basicOptionDataTest) {
|
|
|
|
|
|
}; // Anonymous namespace
|
|
}; // Anonymous namespace
|
|
|
|
|
|
-/// @brief Check Basic parsing of hooks libraries
|
|
|
|
-///
|
|
|
|
/// These tests check basic operation of the HooksLibrariesParser.
|
|
/// These tests check basic operation of the HooksLibrariesParser.
|
|
-TEST_F(ParseConfigTest, emptyHooksLibrariesTest) {
|
|
|
|
|
|
|
|
- // @todo Initialize global library context to null
|
|
|
|
|
|
+// hooks-libraries that do not contain anything.
|
|
|
|
+TEST_F(ParseConfigTest, noHooksLibrariesTest) {
|
|
|
|
|
|
- // Configuration string. This contains a valid library.
|
|
|
|
- const std::string config =
|
|
|
|
- "{ \"hooks_libraries\": [ "
|
|
|
|
- " ]"
|
|
|
|
- "}";
|
|
|
|
|
|
+ // Configuration with hooks-libraries not present.
|
|
|
|
+ string config = "{ \"hooks-libraries\": [] }";
|
|
|
|
|
|
// Verify that the configuration string parses.
|
|
// Verify that the configuration string parses.
|
|
int rcode = parseConfiguration(config);
|
|
int rcode = parseConfiguration(config);
|
|
- ASSERT_TRUE(rcode == 0);
|
|
|
|
|
|
+ ASSERT_TRUE(rcode == 0) << error_text_;
|
|
|
|
+
|
|
|
|
+ // Check that the parser recorded no change to the current state
|
|
|
|
+ // (as the test starts with no hooks libraries loaded).
|
|
|
|
+ std::vector<std::string> libraries;
|
|
|
|
+ bool changed;
|
|
|
|
+ hooks_libraries_parser_->getLibraries(libraries, changed);
|
|
|
|
+ EXPECT_TRUE(libraries.empty());
|
|
|
|
+ EXPECT_FALSE(changed);
|
|
|
|
+
|
|
|
|
+ // Load a single library and repeat the parse.
|
|
|
|
+ vector<string> basic_library;
|
|
|
|
+ basic_library.push_back(string(BASIC_CALLOUT_LIBRARY));
|
|
|
|
+ HooksManager::loadLibraries(basic_library);
|
|
|
|
+
|
|
|
|
+ rcode = parseConfiguration(config);
|
|
|
|
+ ASSERT_TRUE(rcode == 0) << error_text_;
|
|
|
|
+
|
|
|
|
+ // This time the change should have been recorded.
|
|
|
|
+ hooks_libraries_parser_->getLibraries(libraries, changed);
|
|
|
|
+ EXPECT_TRUE(libraries.empty());
|
|
|
|
+ EXPECT_TRUE(changed);
|
|
|
|
+
|
|
|
|
+ // But repeating it again and we are back to no change.
|
|
|
|
+ rcode = parseConfiguration(config);
|
|
|
|
+ ASSERT_TRUE(rcode == 0) << error_text_;
|
|
|
|
+ hooks_libraries_parser_->getLibraries(libraries, changed);
|
|
|
|
+ EXPECT_TRUE(libraries.empty());
|
|
|
|
+ EXPECT_FALSE(changed);
|
|
|
|
|
|
- // @todo modify after the hooks check has been added. At the moment, the
|
|
|
|
- // string should parse to an empty string.
|
|
|
|
- HooksLibrariesStoragePtr ptr = getHooksLibrariesPtr();
|
|
|
|
- EXPECT_TRUE(ptr);
|
|
|
|
- EXPECT_EQ(0, ptr->size());
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-TEST_F(ParseConfigTest, validHooksLibrariesTest) {
|
|
|
|
|
|
|
|
- // @todo Initialize global library context to null
|
|
|
|
|
|
+TEST_F(ParseConfigTest, validHooksLibrariesTest) {
|
|
|
|
|
|
- // Configuration string. This contains a valid library.
|
|
|
|
|
|
+ // Configuration string. This contains a set of valid libraries.
|
|
const std::string quote("\"");
|
|
const std::string quote("\"");
|
|
const std::string comma(", ");
|
|
const std::string comma(", ");
|
|
|
|
|
|
const std::string config =
|
|
const std::string config =
|
|
std::string("{ ") +
|
|
std::string("{ ") +
|
|
- std::string("\"hooks_libraries\": [") +
|
|
|
|
|
|
+ std::string("\"hooks-libraries\": [") +
|
|
quote + std::string(BASIC_CALLOUT_LIBRARY) + quote + comma +
|
|
quote + std::string(BASIC_CALLOUT_LIBRARY) + quote + comma +
|
|
quote + std::string(FULL_CALLOUT_LIBRARY) + quote +
|
|
quote + std::string(FULL_CALLOUT_LIBRARY) + quote +
|
|
std::string("]") +
|
|
std::string("]") +
|
|
@@ -570,24 +605,34 @@ TEST_F(ParseConfigTest, validHooksLibrariesTest) {
|
|
|
|
|
|
// Verify that the configuration string parses.
|
|
// Verify that the configuration string parses.
|
|
int rcode = parseConfiguration(config);
|
|
int rcode = parseConfiguration(config);
|
|
- ASSERT_TRUE(rcode == 0);
|
|
|
|
|
|
+ ASSERT_TRUE(rcode == 0) << error_text_;
|
|
|
|
|
|
- // @todo modify after the hooks check has been added. At the moment, the
|
|
|
|
- // string should parse to an empty string.
|
|
|
|
- HooksLibrariesStoragePtr ptr = getHooksLibrariesPtr();
|
|
|
|
- EXPECT_TRUE(ptr);
|
|
|
|
|
|
+ // Check that the parser holds two libraries and the configuration is
|
|
|
|
+ // recorded as having changed.
|
|
|
|
+ std::vector<std::string> libraries;
|
|
|
|
+ bool changed;
|
|
|
|
+ hooks_libraries_parser_->getLibraries(libraries, changed);
|
|
|
|
+ EXPECT_EQ(2, libraries.size());
|
|
|
|
+ EXPECT_TRUE(changed);
|
|
|
|
|
|
// The expected libraries should be the list of libraries specified
|
|
// The expected libraries should be the list of libraries specified
|
|
// in the given order.
|
|
// in the given order.
|
|
std::vector<std::string> expected;
|
|
std::vector<std::string> expected;
|
|
expected.push_back(BASIC_CALLOUT_LIBRARY);
|
|
expected.push_back(BASIC_CALLOUT_LIBRARY);
|
|
expected.push_back(FULL_CALLOUT_LIBRARY);
|
|
expected.push_back(FULL_CALLOUT_LIBRARY);
|
|
|
|
+ EXPECT_TRUE(expected == libraries);
|
|
|
|
+
|
|
|
|
+ // Parse the string again.
|
|
|
|
+ rcode = parseConfiguration(config);
|
|
|
|
+ ASSERT_TRUE(rcode == 0) << error_text_;
|
|
|
|
|
|
- ASSERT_TRUE(ptr);
|
|
|
|
- EXPECT_TRUE(expected == *ptr);
|
|
|
|
|
|
+ // The list has not changed, and this is what we should see.
|
|
|
|
+ hooks_libraries_parser_->getLibraries(libraries, changed);
|
|
|
|
+ EXPECT_EQ(2, libraries.size());
|
|
|
|
+ EXPECT_FALSE(changed);
|
|
}
|
|
}
|
|
|
|
|
|
-// Now parse
|
|
|
|
|
|
+// Check with a set of libraries, some of which are invalid.
|
|
TEST_F(ParseConfigTest, invalidHooksLibrariesTest) {
|
|
TEST_F(ParseConfigTest, invalidHooksLibrariesTest) {
|
|
|
|
|
|
// @todo Initialize global library context to null
|
|
// @todo Initialize global library context to null
|
|
@@ -599,29 +644,19 @@ TEST_F(ParseConfigTest, invalidHooksLibrariesTest) {
|
|
|
|
|
|
const std::string config =
|
|
const std::string config =
|
|
std::string("{ ") +
|
|
std::string("{ ") +
|
|
- std::string("\"hooks_libraries\": [") +
|
|
|
|
|
|
+ std::string("\"hooks-libraries\": [") +
|
|
quote + std::string(BASIC_CALLOUT_LIBRARY) + quote + comma +
|
|
quote + std::string(BASIC_CALLOUT_LIBRARY) + quote + comma +
|
|
quote + std::string(NOT_PRESENT_LIBRARY) + quote + comma +
|
|
quote + std::string(NOT_PRESENT_LIBRARY) + quote + comma +
|
|
quote + std::string(FULL_CALLOUT_LIBRARY) + quote +
|
|
quote + std::string(FULL_CALLOUT_LIBRARY) + quote +
|
|
std::string("]") +
|
|
std::string("]") +
|
|
std::string("}");
|
|
std::string("}");
|
|
|
|
|
|
- // Verify that the configuration string parses.
|
|
|
|
|
|
+ // Verify that the configuration fails to parse. (Syntactically it's OK,
|
|
|
|
+ // but the library is invalid).
|
|
int rcode = parseConfiguration(config);
|
|
int rcode = parseConfiguration(config);
|
|
- ASSERT_TRUE(rcode == 0);
|
|
|
|
-
|
|
|
|
- // @todo modify after the hooks check has been added. At the moment, the
|
|
|
|
- // string should parse to an empty string.
|
|
|
|
- HooksLibrariesStoragePtr ptr = getHooksLibrariesPtr();
|
|
|
|
- EXPECT_TRUE(ptr);
|
|
|
|
-
|
|
|
|
- // The expected libraries should be the list of libraries specified
|
|
|
|
- // in the given order.
|
|
|
|
- std::vector<std::string> expected;
|
|
|
|
- expected.push_back(BASIC_CALLOUT_LIBRARY);
|
|
|
|
- expected.push_back(NOT_PRESENT_LIBRARY);
|
|
|
|
- expected.push_back(FULL_CALLOUT_LIBRARY);
|
|
|
|
|
|
+ ASSERT_FALSE(rcode == 0) << error_text_;
|
|
|
|
|
|
- ASSERT_TRUE(ptr);
|
|
|
|
- EXPECT_TRUE(expected == *ptr);
|
|
|
|
|
|
+ // Check that the message contains the library in error.
|
|
|
|
+ EXPECT_FALSE(error_text_.find(NOT_PRESENT_LIBRARY) == string::npos) <<
|
|
|
|
+ "Error text returned from parse failure is " << error_text_;
|
|
}
|
|
}
|