From: Tomek Mrugalski Date: Wed, 24 Aug 2016 17:23:51 +0000 (+0200) Subject: [4626] Unit-tests implemented for parser. X-Git-Tag: trac4631_base~1^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=524830e575905ca6c6b46aef59b037cf3da6a437;p=thirdparty%2Fkea.git [4626] Unit-tests implemented for parser. --- diff --git a/src/lib/dhcpsrv/client_class_def.cc b/src/lib/dhcpsrv/client_class_def.cc index 7709804e32..bc9cd48641 100644 --- a/src/lib/dhcpsrv/client_class_def.cc +++ b/src/lib/dhcpsrv/client_class_def.cc @@ -44,6 +44,10 @@ ClientClassDef::ClientClassDef(const ClientClassDef& rhs) if (rhs.cfg_option_) { rhs.cfg_option_->copyTo(*cfg_option_); } + + next_server_ = rhs.next_server_; + sname_ = rhs.sname_; + filename_ = rhs.filename_; } ClientClassDef::~ClientClassDef() { @@ -87,7 +91,10 @@ ClientClassDef::equals(const ClientClassDef& other) const { (*match_expr_ == *(other.match_expr_)))) && ((!cfg_option_ && !other.cfg_option_) || (cfg_option_ && other.cfg_option_ && - (*cfg_option_ == *other.cfg_option_)))); + (*cfg_option_ == *other.cfg_option_))) && + (next_server_ == other.next_server_) && + (sname_ == other.sname_) && + (filename_ == other.filename_)); } std::ostream& operator<<(std::ostream& os, const ClientClassDef& x) { diff --git a/src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc b/src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc index c6bead00f7..f61d0074ba 100644 --- a/src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc +++ b/src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,7 @@ using namespace isc::data; using namespace isc::dhcp; +using namespace isc::asiolink; namespace { @@ -583,4 +585,183 @@ TEST_F(ClientClassDefListParserTest, invalidClass) { DhcpConfigError); } +TEST_F(ClientClassDefParserTest, noFixedFields) { + + std::string cfg_text = + "{ \n" + " \"name\": \"MICROSOFT\", \n" + " \"option-data\": [ \n" + " { \n" + " \"name\": \"domain-name-servers\", \n" + " \"data\": \"192.0.2.1, 192.0.2.2\" \n" + " } \n" + " ] \n" + "} \n"; + + ClientClassDefPtr cclass; + ASSERT_NO_THROW(cclass = parseClientClassDef(cfg_text, Option::V4)); + + // We should find our class. + ASSERT_TRUE(cclass); + + // And it should not have any fixed fields set + EXPECT_EQ(IOAddress("0.0.0.0"), cclass->getNextServer()); + EXPECT_EQ(0, cclass->getSname().size()); + EXPECT_EQ(0, cclass->getFilename().size()); +} + + +TEST_F(ClientClassDefParserTest, nextServer) { + + std::string cfg_text = + "{ \n" + " \"name\": \"MICROSOFT\", \n" + " \"next-server\": \"192.0.2.254\",\n" + " \"option-data\": [ \n" + " { \n" + " \"name\": \"domain-name-servers\", \n" + " \"data\": \"192.0.2.1, 192.0.2.2\" \n" + " } \n" + " ] \n" + "} \n"; + + ClientClassDefPtr cclass; + ASSERT_NO_THROW(cclass = parseClientClassDef(cfg_text, Option::V4)); + + // We should find our class. + ASSERT_TRUE(cclass); + + // And it should have next-server set, but everything else not set. + EXPECT_EQ(IOAddress("192.0.2.254"), cclass->getNextServer()); + EXPECT_EQ(0, cclass->getSname().size()); + EXPECT_EQ(0, cclass->getFilename().size()); +} + +TEST_F(ClientClassDefParserTest, nextServerBogus) { + + std::string bogus_v6 = + "{ \n" + " \"name\": \"MICROSOFT\", \n" + " \"next-server\": \"2001:db8::1\",\n" + " \"option-data\": [ \n" + " { \n" + " \"name\": \"domain-name-servers\", \n" + " \"data\": \"192.0.2.1, 192.0.2.2\" \n" + " } \n" + " ] \n" + "} \n"; + std::string bogus_junk = + "{ \n" + " \"name\": \"MICROSOFT\", \n" + " \"next-server\": \"not-an-address\",\n" + " \"option-data\": [ \n" + " { \n" + " \"name\": \"domain-name-servers\", \n" + " \"data\": \"192.0.2.1, 192.0.2.2\" \n" + " } \n" + " ] \n" + "} \n"; + + EXPECT_THROW(parseClientClassDef(bogus_v6, Option::V4), DhcpConfigError); + EXPECT_THROW(parseClientClassDef(bogus_junk, Option::V4), DhcpConfigError); +} + +TEST_F(ClientClassDefParserTest, serverName) { + + std::string cfg_text = + "{ \n" + " \"name\": \"MICROSOFT\", \n" + " \"server-hostname\": \"hal9000\",\n" + " \"option-data\": [ \n" + " { \n" + " \"name\": \"domain-name-servers\", \n" + " \"data\": \"192.0.2.1, 192.0.2.2\" \n" + " } \n" + " ] \n" + "} \n"; + + ClientClassDefPtr cclass; + ASSERT_NO_THROW(cclass = parseClientClassDef(cfg_text, Option::V4)); + + // We should find our class. + ASSERT_TRUE(cclass); + + // And it should not have any fixed fields set + std::string exp_txt("hal9000"); + std::vector exp_sname(exp_txt.begin(), exp_txt.end()); + + EXPECT_EQ(exp_sname, cclass->getSname()); +} + +TEST_F(ClientClassDefParserTest, serverNameInvalid) { + + std::string cfg_too_long = + "{ \n" + " \"name\": \"MICROSOFT\", \n" + " \"server-hostname\": \"1234567890123456789012345678901234567890" + "1234567890123456789012345\", \n" + " \"option-data\": [ \n" + " { \n" + " \"name\": \"domain-name-servers\", \n" + " \"data\": \"192.0.2.1, 192.0.2.2\" \n" + " } \n" + " ] \n" + "} \n"; + + EXPECT_THROW(parseClientClassDef(cfg_too_long, Option::V4), DhcpConfigError); +} + + +TEST_F(ClientClassDefParserTest, filename) { + + std::string cfg_text = + "{ \n" + " \"name\": \"MICROSOFT\", \n" + " \"boot-file-name\": \"ipxe.efi\", \n" + " \"option-data\": [ \n" + " { \n" + " \"name\": \"domain-name-servers\", \n" + " \"data\": \"192.0.2.1, 192.0.2.2\" \n" + " } \n" + " ] \n" + "} \n"; + + ClientClassDefPtr cclass; + ASSERT_NO_THROW(cclass = parseClientClassDef(cfg_text, Option::V4)); + + // We should find our class. + ASSERT_TRUE(cclass); + + // And it should not have any fixed fields set + std::string exp_txt("ipxe.efi"); + std::vector exp_filename(exp_txt.begin(), exp_txt.end()); + + EXPECT_EQ(exp_filename, cclass->getFilename()); +} + +TEST_F(ClientClassDefParserTest, filenameBogus) { + + // boot-file-name is allowed up to 128 bytes, this one is 129. + std::string cfg_too_long = + "{ \n" + " \"name\": \"MICROSOFT\", \n" + " \"boot-file-name\": \"1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890" + "123456789\", \n" + " \"option-data\": [ \n" + " { \n" + " \"name\": \"domain-name-servers\", \n" + " \"data\": \"192.0.2.1, 192.0.2.2\" \n" + " } \n" + " ] \n" + "} \n"; + + EXPECT_THROW(parseClientClassDef(cfg_too_long, Option::V4), DhcpConfigError); +} + + } // end of anonymous namespace diff --git a/src/lib/dhcpsrv/tests/client_class_def_unittest.cc b/src/lib/dhcpsrv/tests/client_class_def_unittest.cc index 643c8f967a..04523c2152 100644 --- a/src/lib/dhcpsrv/tests/client_class_def_unittest.cc +++ b/src/lib/dhcpsrv/tests/client_class_def_unittest.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -17,6 +18,7 @@ using namespace std; using namespace isc::dhcp; using namespace isc::util; +using namespace isc::asiolink; using namespace isc; namespace { @@ -298,4 +300,59 @@ TEST(ClientClassDictionary, copyAndEquality) { EXPECT_TRUE(*dictionary != *dictionary2); } +// Tests the default constructor regarding fixed fields +TEST(ClientClassDef, fixedFieldsDefaults) { + boost::scoped_ptr cclass; + + std::string name = "class1"; + ExpressionPtr expr; + CfgOptionPtr cfg_option; + + // Classes cannot have blank names + ASSERT_THROW(cclass.reset(new ClientClassDef("", expr, cfg_option)), + BadValue); + + // Verify we can create a class with a name, expression, and no cfg_option + ASSERT_NO_THROW(cclass.reset(new ClientClassDef(name, expr))); + + // Let's checks that it doesn't return any nonsense + vector empty; + ASSERT_EQ(IOAddress("0.0.0.0"), cclass->getNextServer()); + EXPECT_EQ(empty, cclass->getSname()); + EXPECT_EQ(empty, cclass->getFilename()); +} + +// Tests basic operations of fixed fields +TEST(ClientClassDef, fixedFieldsBasics) { + boost::scoped_ptr cclass; + + std::string name = "class1"; + ExpressionPtr expr; + CfgOptionPtr cfg_option; + + // Classes cannot have blank names + ASSERT_THROW(cclass.reset(new ClientClassDef("", expr, cfg_option)), + BadValue); + + // Verify we can create a class with a name, expression, and no cfg_option + ASSERT_NO_THROW(cclass.reset(new ClientClassDef(name, expr))); + + + string sname_txt = "This is a very long string that can be a server name"; + vector sname(sname_txt.begin(), sname_txt.end()); + + string filename_txt = "this-is-a-slightly-longish-name-of-a-file.txt"; + vector filename(sname_txt.begin(), sname_txt.end()); + + cclass->setNextServer(IOAddress("1.2.3.4")); + cclass->setSname(sname); + cclass->setFilename(filename); + + // Let's checks that it doesn't return any nonsense + ASSERT_EQ(IOAddress("1.2.3.4"), cclass->getNextServer()); + EXPECT_EQ(sname, cclass->getSname()); + EXPECT_EQ(filename, cclass->getFilename()); +} + + } // end of anonymous namespace