// Get client classes list
ElementPtr client_classes = (*(first_binding + 13))->getJSON();
- if (client_classes) {
- if (client_classes->getType() != Element::list) {
- isc_throw(BadValue, "invalid client_classes value "
- << (*(first_binding + 13))->getString());
- }
-
- for (auto i = 0; i < client_classes->size(); ++i) {
- auto cclass = client_classes->get(i);
- if (cclass->getType() != Element::string) {
- isc_throw(BadValue, "elements of client_classes list must be valid strings");
- }
-
- desc->addClientClass(cclass->stringValue());
- }
+ try {
+ desc->client_classes_.fromElement(client_classes);
+ } catch (const std::exception& ex) {
+ isc_throw(BadValue, "invalid 'client_classes' : "
+ << (*(first_binding + 13))->getString()
+ << ex.what());
}
return (desc);
return (0);
}
-db::MySqlBindingPtr
+db::MySqlBindingPtr
MySqlConfigBackendImpl::createInputClientClassesBinding(const ClientClasses& client_classes) {
if (client_classes.empty()) {
return(db::MySqlBinding::createNull());
}
ElementPtr cclasses_element = worker.getJSON(col);
- if (cclasses_element->getType() != Element::list) {
+ // Get client classes list
+ try {
+ client_classes.fromElement(cclasses_element);
+ } catch (const std::exception& ex) {
std::ostringstream ss;
cclasses_element->toJSON(ss);
- isc_throw(BadValue, "invalid client_classes value " << ss.str());
- }
-
- for (auto i = 0; i < cclasses_element->size(); ++i) {
- auto cclasses_item = cclasses_element->get(i);
- if (cclasses_item->getType() != Element::string) {
- isc_throw(BadValue, "elements of client_classes list must"
- "be valid strings");
- }
-
- client_classes.insert(cclasses_item->stringValue());
+ isc_throw(BadValue, "invalid 'client_classes' : " << ss.str() << ex.what());
}
}
return (result);
}
+void
+ClientClasses::fromElement(isc::data::ElementPtr cc_list) {
+ if (cc_list) {
+ clear();
+ if (cc_list->getType() != Element::list) {
+ isc_throw(BadValue, "not a List element");
+ }
+
+ for (auto i = 0; i < cc_list->size(); ++i) {
+ auto cclass = cc_list->get(i);
+ if (cclass->getType() != Element::string) {
+ isc_throw(BadValue, "elements of list must be valid strings");
+ }
+
+ insert(cclass->stringValue());
+ }
+ }
+}
+
bool
ClientClasses::equals(const ClientClasses& other) const {
return ((size() == other.size()) && std::equal(cbegin(), cend(), other.cbegin()));
#include <config.h>
#include <dhcp/classify.h>
+#include <exceptions/exceptions.h>
+#include <cc/data.h>
+#include <testutils/gtest_utils.h>
+
#include <gtest/gtest.h>
+using namespace isc;
using namespace isc::dhcp;
+using namespace isc::data;
// Trivial test for now as ClientClass is a std::string.
TEST(ClassifyTest, ClientClass) {
EXPECT_FALSE(classes.contains("alpha"));
EXPECT_FALSE(classes.contains("beta"));
}
+
+// Check that the ClientClasses::fromElement function.
+TEST(ClassifyTest, ClientClassesFromElement) {
+ // No classes.
+ ClientClasses classes;
+ EXPECT_TRUE(classes.toElement()->empty());
+
+ ElementPtr cclasses_element;
+ // Verify a empty element pointer is harmless.
+ ASSERT_NO_THROW(classes.fromElement(cclasses_element));
+
+ // Verify A non-list element is caught.
+ cclasses_element = Element::create("bogus");
+ ASSERT_THROW_MSG(classes.fromElement(cclasses_element), BadValue,
+ "not a List element");
+
+ // Verify an empty list is harmless.
+ cclasses_element = Element::createList();
+
+ // Verify a empty element pointer is harmless.
+ ASSERT_NO_THROW(classes.fromElement(cclasses_element));
+
+ // Verify an invalid list is caught.
+ cclasses_element->add(Element::create(123));
+ ASSERT_THROW_MSG(classes.fromElement(cclasses_element), BadValue,
+ "elements of list must be valid strings");
+
+ cclasses_element = Element::createList();
+ cclasses_element->add(Element::create("one"));
+ cclasses_element->add(Element::create("two"));
+
+ // Verify a valid list works.
+ ASSERT_NO_THROW(classes.fromElement(cclasses_element));
+ EXPECT_TRUE(classes.contains("one"));
+ EXPECT_TRUE(classes.contains("two"));
+
+ // Verify a second invocation replaces the contents.
+ cclasses_element = Element::createList();
+ cclasses_element->add(Element::create("three"));
+ ASSERT_NO_THROW(classes.fromElement(cclasses_element));
+ EXPECT_FALSE(classes.contains("one"));
+ EXPECT_FALSE(classes.contains("two"));
+ EXPECT_TRUE(classes.contains("three"));
+
+ // Verify another invocation with an empty pointer is harmless.
+ cclasses_element.reset();
+ ASSERT_NO_THROW(classes.fromElement(cclasses_element));
+ EXPECT_TRUE(classes.contains("three"));
+
+ // Verify another third invocation with an empty list
+ // clears the contents.
+ cclasses_element = Element::createList();
+ ASSERT_NO_THROW(classes.fromElement(cclasses_element));
+ EXPECT_TRUE(classes.empty());
+}