summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrancis Dupont <fdupont@isc.org>2024-11-14 15:52:32 +0100
committerFrancis Dupont <fdupont@isc.org>2024-11-22 09:55:31 +0100
commit3193b4f7b410bd2c91e0a5266eda3399de1378f8 (patch)
tree9e8712f9aa673ab1f922b50c1e198aa00b042516 /src
parent[#3609] Checkpoint: error UT to add (diff)
downloadkea-3193b4f7b410bd2c91e0a5266eda3399de1378f8.tar.xz
kea-3193b4f7b410bd2c91e0a5266eda3399de1378f8.zip
[#3609] Checkpoint: added error UT
Diffstat (limited to 'src')
-rw-r--r--src/bin/agent/ca_cfg_mgr.cc2
-rw-r--r--src/lib/http/cfg_http_header.cc6
-rw-r--r--src/lib/http/cfg_http_header.h2
-rw-r--r--src/lib/http/tests/cfg_http_header_unittests.cc111
4 files changed, 106 insertions, 15 deletions
diff --git a/src/bin/agent/ca_cfg_mgr.cc b/src/bin/agent/ca_cfg_mgr.cc
index 4cb9da5480..95057f6231 100644
--- a/src/bin/agent/ca_cfg_mgr.cc
+++ b/src/bin/agent/ca_cfg_mgr.cc
@@ -189,7 +189,7 @@ CtrlAgentCfgContext::toElement() const {
ca->set("http-port", Element::create(static_cast<int64_t>(http_port_)));
// Set http-headers
if (!http_headers_.empty()) {
- ca->set("http-headers", toElement(http_headers_));
+ ca->set("http-headers", CfgHttpHeaderstoElement(http_headers_));
}
// Set TLS setup when enabled
if (!trust_anchor_.empty()) {
diff --git a/src/lib/http/cfg_http_header.cc b/src/lib/http/cfg_http_header.cc
index 7c7edf3e6b..098e95cc3f 100644
--- a/src/lib/http/cfg_http_header.cc
+++ b/src/lib/http/cfg_http_header.cc
@@ -25,7 +25,7 @@ CfgHttpHeader::toElement() const {
}
ElementPtr
-toElement(const CfgHttpHeaders& headers) {
+CfgHttpHeaderstoElement(const CfgHttpHeaders& headers) {
ElementPtr list = Element::createList();
for (auto const& header : headers) {
list->add(header.toElement());
@@ -57,12 +57,12 @@ parseCfgHttpHeader(const ConstElementPtr& config) {
SimpleParser::checkRequired(HTTP_HEADER_REQUIRED, config);
string name = config->get("name")->stringValue();
if (name.empty()) {
- isc_throw(DhcpConfigError, "empty 'name' ("
+ isc_throw(DhcpConfigError, "empty 'name' parameter ("
<< config->get("name")->getPosition() << ")");
}
string value = config->get("value")->stringValue();
if (value.empty()) {
- isc_throw(DhcpConfigError, "empty 'value' ("
+ isc_throw(DhcpConfigError, "empty 'value' parameter ("
<< config->get("value")->getPosition() << ")");
}
CfgHttpHeader header(name, value);
diff --git a/src/lib/http/cfg_http_header.h b/src/lib/http/cfg_http_header.h
index 8adb34f802..ae3301e453 100644
--- a/src/lib/http/cfg_http_header.h
+++ b/src/lib/http/cfg_http_header.h
@@ -56,7 +56,7 @@ void copyHttpHeaders(const CfgHttpHeaders& headers, const HTTP_MSG& message) {
///
/// @param headers Config HTTP headers.
/// @return A pointer to unparsed headers configuration.
-isc::data::ElementPtr toElement(const CfgHttpHeaders& headers);
+isc::data::ElementPtr CfgHttpHeaderstoElement(const CfgHttpHeaders& headers);
/// @brief Parse config HTTP headers.
///
diff --git a/src/lib/http/tests/cfg_http_header_unittests.cc b/src/lib/http/tests/cfg_http_header_unittests.cc
index b88cdd092a..acd9934157 100644
--- a/src/lib/http/tests/cfg_http_header_unittests.cc
+++ b/src/lib/http/tests/cfg_http_header_unittests.cc
@@ -7,9 +7,11 @@
#include <config.h>
#include <http/cfg_http_header.h>
+#include <cc/simple_parser.h>
#include <gtest/gtest.h>
using namespace isc::data;
+using namespace isc::dhcp;
using namespace isc::http;
using namespace std;
@@ -43,21 +45,21 @@ TEST(CfgHttpHeaderTest, copy) {
expected += "{ \"name\": \"Strict-Transport-Security\", ";
expected += "\"value\": \"max-age=31536000\" }, ";
expected += "{ \"name\": \"Foo\", \"value\": \"bar\" } ]";
- EXPECT_EQ(expected, toElement(headers)->str());
+ EXPECT_EQ(expected, CfgHttpHeaderstoElement(headers)->str());
}
// This test verifies parse and toElement behavior.
TEST(CfgHttpHeaderTest, parse) {
// Config.
string config = "[\n"
- " {\n"
- " \"name\": \"Strict-Transport-Security\",\n"
- " \"value\": \"max-age=31536000\",\n"
- " \"user-context\": { \"comment\": \"HSTS header\" }\n"
- " },{\n"
- " \"name\": \"Foo\", \"value\": \"bar\"\n"
- " }\n"
- " ]\n";
+ " {\n"
+ " \"name\": \"Strict-Transport-Security\",\n"
+ " \"value\": \"max-age=31536000\",\n"
+ " \"user-context\": { \"comment\": \"HSTS header\" }\n"
+ " },{\n"
+ " \"name\": \"Foo\", \"value\": \"bar\"\n"
+ " }\n"
+ " ]\n";
ConstElementPtr json;
ASSERT_NO_THROW(json = Element::fromJSON(config));
CfgHttpHeaders headers;
@@ -72,8 +74,97 @@ TEST(CfgHttpHeaderTest, parse) {
EXPECT_EQ("bar", headers[1].value_);
EXPECT_FALSE(headers[1].getContext());
ConstElementPtr unparsed;
- ASSERT_NO_THROW(unparsed = toElement(headers));
+ ASSERT_NO_THROW(unparsed = CfgHttpHeaderstoElement(headers));
EXPECT_TRUE(json->equals(*unparsed));
}
+// This test verifies parse error cases.
+TEST(CfgHttpHeaderTest, parseErrors) {
+ // Scenarios.
+ struct Scenario{
+ string desc_; // Description.
+ string config_; // Configuration.
+ string errmsg_; // Error message.
+ };
+ vector<Scenario> scenarios = {
+ {
+ "Not a list",
+ "{ \"name\": \"Foo\", \"value\": \"bar\" }",
+ "invalid type specified for parameter 'http-headers' "
+ "(<string>:1:2)"
+ },
+ {
+ "Not a map",
+ "[ \"Foo\", \"bar\" ]",
+ "invalid type specified for 'http-headers' item (<string>:1:3)"
+ },
+ {
+ "Unknown keyword",
+ "[ { \"foo\": \"bar\" } ]",
+ "spurious 'foo' parameter"
+ },
+ {
+ "Bad name type",
+ "[ { \"name\": 1 } ]",
+ "'name' parameter is not a string"
+ },
+ {
+ "Bad value type",
+ "[ { \"value\": false } ]",
+ "'value' parameter is not a string"
+ },
+ {
+ "Bad user context type",
+ "[ { \"user-context\": \"bad\" } ]",
+ "'user-context' parameter is not a map"
+ },
+ {
+ "Missing name",
+ "[ { } ]",
+ "missing 'name' parameter"
+ },
+ {
+ "Missing value",
+ "[ { \"name\": \"Foo\" } ]",
+ "missing 'value' parameter"
+ },
+ {
+ "Empty name",
+ "[ { \"name\": \"\", \"value\": \"\" } ]",
+ "empty 'name' parameter (<string>:1:13)"
+ },
+ {
+ "Empty value",
+ "[ { \"name\": \"Foo\", \"value\": \"\" } ]",
+ "empty 'value' parameter (<string>:1:29)"
+ }
+ };
+
+ // Iterate over Scenarios.
+ ConstElementPtr json;
+ CfgHttpHeaders headers;
+ for (auto const& scenario : scenarios) {
+ SCOPED_TRACE(scenario.desc_);
+ {
+ ASSERT_NO_THROW(json = Element::fromJSON(scenario.config_));
+ try {
+ headers = parseCfgHttpHeaders(json);
+ ADD_FAILURE() << "exception is expected";
+ } catch (const DhcpConfigError& ex) {
+ EXPECT_EQ(scenario.errmsg_, ex.what());
+ } catch (...) {
+ ADD_FAILURE() << "DhcpConfigError is expected";
+ }
+ }
+ }
+
+ // No error cases.
+ ConstElementPtr null_json;
+ ASSERT_NO_THROW(headers = parseCfgHttpHeaders(null_json));
+ EXPECT_TRUE(headers.empty());
+ ConstElementPtr empty_json = Element::createList();
+ ASSERT_NO_THROW(headers = parseCfgHttpHeaders(empty_json));
+ EXPECT_TRUE(headers.empty());
+}
+
}