Browse Source

[2317] Test configuration of option definition comprising a record.

Marcin Siodelski 12 years ago
parent
commit
c924b23383
2 changed files with 55 additions and 22 deletions
  1. 4 20
      src/bin/dhcp4/config_parser.cc
  2. 51 2
      src/bin/dhcp4/tests/config_parser_unittest.cc

+ 4 - 20
src/bin/dhcp4/config_parser.cc

@@ -1145,32 +1145,16 @@ public:
 
         CfgMgr& cfg_mgr = CfgMgr::instance();
 
+        cfg_mgr.deleteOptionDefs();
+
         // We need to move option definitions from the temporary
-        // storage to the global storage. However for new definition
-        // we need to check whether such a definition already exists
-        // or we are adding it for the fitsy time.
+        // storage to the global storage.
         BOOST_FOREACH(std::string space_name,
                       option_defs_local_.getOptionSpaceNames()) {
-            // For the particular option space we have to get all
-            // items in the temporary storage and store it in the
-            // global storage.
+
             BOOST_FOREACH(OptionDefinitionPtr def,
                           *option_defs_local_.getItems(space_name)) {
                 assert(def);
-                // For the particular option space get all definitions
-                // existing in the global storage.
-                OptionDefContainerPtr global_defs = cfg_mgr.getOptionDefs(space_name);
-                assert(global_defs);
-                // Find the option definition for the particular
-                // option code.
-                OptionDefContainerTypeIndex& idx = global_defs->get<1>();
-                const OptionDefContainerTypeRange& range =
-                    idx.equal_range(def->getCode());
-                // If there is one in the global storage, erase it.
-                if (std::distance(range.first, range.second) > 0) {
-                    idx.erase(range.first, range.second);
-                }
-                // Add the newly created option definition.
                 cfg_mgr.addOptionDef(def, space_name);
             }
         }

+ 51 - 2
src/bin/dhcp4/tests/config_parser_unittest.cc

@@ -234,6 +234,7 @@ public:
             "\"renew-timer\": 1000, "
             "\"valid-lifetime\": 4000, "
             "\"subnet4\": [ ], "
+            "\"option-def\": [ ], "
             "\"option-data\": [ ] }";
 
         try {
@@ -437,8 +438,8 @@ TEST_F(Dhcp4ParserTest, poolPrefixLen) {
 }
 
 // The goal of this test is to check whether an option definition
-// can be added to the dhcp4 option space.
-TEST_F(Dhcp4ParserTest, optionDefAdd) {
+// that defines an option carrying an IPv4 address can be created.
+TEST_F(Dhcp4ParserTest, optionDefIpv4Address) {
 
     // Configuration string.
     std::string config =
@@ -473,6 +474,54 @@ TEST_F(Dhcp4ParserTest, optionDefAdd) {
     EXPECT_EQ(OPT_IPV4_ADDRESS_TYPE, def->getType());
 }
 
+// The goal of this test is to check whether an option definiiton
+// that defines an option carrying a record of data fields can
+// be created.
+TEST_F(Dhcp4ParserTest, optionDefRecord) {
+
+    // Configuration string.
+    std::string config =
+        "{ \"option-def\": [ {"
+        "      \"name\": \"foo\","
+        "      \"code\": 100,"
+        "      \"type\": \"record\","
+        "      \"array\": False,"
+        "      \"record-types\": \"uint16, ipv4-address, ipv6-address, string\","
+        "      \"space\": \"isc\""
+        "  } ]"
+        "}";
+    ElementPtr json = Element::fromJSON(config);
+
+    // Make sure that the particular option definition does not exist.
+    OptionDefinitionPtr def = CfgMgr::instance().getOptionDef("isc", 100);
+    ASSERT_FALSE(def);
+
+    // Use the configuration string to create new option definition.
+    ConstElementPtr status;
+    EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json));
+    ASSERT_TRUE(status);
+
+    // The option definition should now be available in the CfgMgr.
+    def = CfgMgr::instance().getOptionDef("isc", 100);
+    ASSERT_TRUE(def);
+
+    // Check the option data.
+    EXPECT_EQ("foo", def->getName());
+    EXPECT_EQ(100, def->getCode());
+    EXPECT_EQ(OPT_RECORD_TYPE, def->getType());
+    EXPECT_FALSE(def->getArrayType());
+    
+    // The option comprises the record of data fields. Verify that all
+    // fields are present and they are of the expected types.
+    const OptionDefinition::RecordFieldsCollection& record_fields =
+        def->getRecordFields();
+    ASSERT_EQ(4, record_fields.size());
+    EXPECT_EQ(OPT_UINT16_TYPE, record_fields[0]);
+    EXPECT_EQ(OPT_IPV4_ADDRESS_TYPE, record_fields[1]);
+    EXPECT_EQ(OPT_IPV6_ADDRESS_TYPE, record_fields[2]);
+    EXPECT_EQ(OPT_STRING_TYPE, record_fields[3]);
+}
+
 // Goal of this test is to verify that global option
 // data is configured for the subnet if the subnet
 // configuration does not include options configuration.