Browse Source

[1960] Support spaces in packet template files.

With this commit the unit testing for packet templates is improved.
Marcin Siodelski 12 years ago
parent
commit
2538cdc225

+ 1 - 1
tests/tools/perfdhcp/Makefile.am

@@ -1,4 +1,4 @@
-1SUBDIRS = . tests templates
+SUBDIRS = . tests templates
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_srcdir)/src/lib/log -I$(top_builddir)/src/lib/log

+ 2 - 2
tests/tools/perfdhcp/templates/Makefile.am

@@ -1,8 +1,8 @@
 SUBDIRS = .
 
-# The test1.hex and test2.hex are created by the TestControl.PacketTemplates
+# The test[1-5].hex are created by the TestControl.PacketTemplates
 # unit tests and have to be removed.
-CLEANFILES = test1.hex test2.hex
+CLEANFILES = test1.hex test2.hex test3.hex test4.hex test5.hex
 
 perfdhcpdir = $(pkgdatadir)
 perfdhcp_DATA = discover-example.hex request4-example.hex

+ 26 - 9
tests/tools/perfdhcp/test_control.cc

@@ -884,21 +884,38 @@ TestControl::readPacketTemplate(const std::string& file_name) {
     if (!temp_file.is_open()) {
         isc_throw(BadValue, "unable to open template file " << file_name);
     }
+    // Read template file contents.
     std::ifstream::pos_type temp_size = temp_file.tellg();
-    if (temp_size % 2 != 0) {
+    if (temp_size == 0) {
         temp_file.close();
-        isc_throw(BadValue, "odd number of digits in template file");
+        isc_throw(OutOfRange, "the template file " << file_name << " is empty");
     }
     temp_file.seekg(0, ios::beg);
-    std::vector<char> hex_digits(temp_size);
-    std::vector<uint8_t> binary_stream;
-    temp_file.read(&hex_digits[0], temp_size);
+    std::vector<char> file_contents(temp_size);
+    temp_file.read(&file_contents[0], temp_size);
     temp_file.close();
-    for (int i = 0; i < hex_digits.size(); i += 2) {
-        if (!isxdigit(hex_digits[i]) || !isxdigit(hex_digits[i+1])) {
-            isc_throw(BadValue, "the '" << hex_digits[i] << hex_digits[i+1]
-                      << "' is not hexadecimal digit");
+    // Spaces are allowed so we have to strip the contents
+    // from them. In the same time we want to make sure that
+    // apart from spaces the file contains hexadecimal digits
+    // only.
+    std::vector<char> hex_digits;
+    for (int i = 0; i < file_contents.size(); ++i) {
+        if (isxdigit(file_contents[i])) {
+            hex_digits.push_back(file_contents[i]);
+        } else if (!isxdigit(file_contents[i]) &&
+                   !isspace(file_contents[i])) {
+            isc_throw(BadValue, "the '" << file_contents[i] << "' is not a"
+                      " heaxadecimal digit");
         }
+    }
+    // Expect even number of digits.
+    if (hex_digits.size() % 2 != 0) {
+        isc_throw(OutOfRange, "odd number of digits in template file");
+    } else if (hex_digits.size() == 0) {
+        isc_throw(OutOfRange, "template file " << file_name << " is empty");
+    }
+    std::vector<uint8_t> binary_stream;
+    for (int i = 0; i < hex_digits.size(); i += 2) {
         stringstream s;
         s << "0x" << hex_digits[i] << hex_digits[i+1];
         int b;

+ 10 - 1
tests/tools/perfdhcp/test_control.h

@@ -448,7 +448,10 @@ protected:
     /// their content and stores it in class internal buffers. Template
     /// file names are specified from the command line with -T option.
     ///
-    /// \throw isc::BadValue if any of the template files does not exist
+    /// \throw isc::BadValue if any of the template files does not exist,
+    /// contains characters other than hexadecimal digits or spaces.
+    /// \throw OutOfRange if any of the template files is empty or has
+    /// odd number of hexadecimal digits.
     void initPacketTemplates();
 
     /// \brief Initializes Statistics Manager.
@@ -907,6 +910,12 @@ private:
     /// Method reads DHCP message template from file and
     /// converts it to binary format. Read data is appended
     /// to template_buffers_ vector.
+    ///
+    /// \param file_name name of the packet template file.
+    /// \throw isc::OutOfRange if file is empty or has odd number
+    /// of hexadecimal digits.
+    /// \throw isc::BadValue if file contains characters other than
+    /// spaces or hexadecimal digits.
     void readPacketTemplate(const std::string& file_name);
 
     /// \brief Run wrapped command.

+ 57 - 5
tests/tools/perfdhcp/tests/test_control_unittest.cc

@@ -117,12 +117,20 @@ public:
     /// \brief Create packet template file from binary data.
     ///
     /// Function creates file containing data from the provided buffer
-    /// in hexadecimal format.
+    /// in hexadecimal format. The size parameter specifies the maximum
+    /// size of the file. If total number of hexadecimal digits resulting
+    /// from buffer size is greater than maximum file size the file is
+    /// truncated.
+    ///
     /// \param filename template file to be created.
     /// \param buffer with binary datato be stored in file.
+    /// \param size target size of the file.
+    /// \param invalid_chars inject invalid chars to the template file.
     /// \return true if file creation successful.
     bool createTemplateFile(const std::string& filename,
-                            const std::vector<uint8_t>& buf) const {
+                            const std::vector<uint8_t>& buf,
+                            const size_t size,
+                            const bool invalid_chars = false) const {
         std::ofstream temp_file;
         temp_file.open(filename.c_str(), ios::out | ios::trunc);
         if (!temp_file.is_open()) {
@@ -131,7 +139,24 @@ public:
         for (int i = 0; i < buf.size(); ++i) {
             int first_digit = buf[i] / 16;
             int second_digit = buf[i] % 16;
-            temp_file << std::hex << first_digit << second_digit << std::dec;
+            // Insert two spaces between two hexadecimal digits.
+            // Spaces are allowed in template files.
+            temp_file << std::string(2, ' ');
+            if (2 * i + 1 < size) {
+                if (!invalid_chars) {
+                    temp_file << std::hex << first_digit << second_digit << std::dec;
+                } else {
+                    temp_file << "XY";
+                }
+            } else if (2 * i < size) {
+                if (!invalid_chars) {
+                    temp_file << std::hex << first_digit;
+                } else {
+                    temp_file << "X";
+                }
+            } else {
+                break;
+            }
         }
         temp_file.close();
         return (true);
@@ -965,8 +990,9 @@ TEST_F(TestControlTest, PacketTemplates) {
     for (int i = 0; i < template2.size(); ++i) {
         template2[i] = static_cast<uint8_t>(random() % 256);
     }
-    ASSERT_TRUE(createTemplateFile(file1, template1));
-    ASSERT_TRUE(createTemplateFile(file2, template2));
+    // Size of the file is 2 times larger than binary data size.
+    ASSERT_TRUE(createTemplateFile(file1, template1, template1.size() * 2));
+    ASSERT_TRUE(createTemplateFile(file2, template2, template2.size() * 2));
     CommandOptions& options = CommandOptions::instance();
     NakedTestControl tc;
 
@@ -983,6 +1009,32 @@ TEST_F(TestControlTest, PacketTemplates) {
     ASSERT_EQ(template2.size(), buf2.size());
     EXPECT_TRUE(std::equal(template1.begin(), template1.end(), buf1.begin()));
     EXPECT_TRUE(std::equal(template2.begin(), template2.end(), buf2.begin()));
+
+    // Try to read template file with odd number of digits.
+    std::string file3("../templates/test3.hex");
+    // Size of the file is 2 times larger than binary data size and it is always
+    // even number. Substracting 1 makes file size odd.
+    ASSERT_TRUE(createTemplateFile(file3, template1, template1.size() * 2 - 1));
+    ASSERT_NO_THROW(
+        processCmdLine("perfdhcp -l 127.0.0.1 -T " + file3 + " all")
+    );
+    EXPECT_THROW(tc.initPacketTemplates(), isc::OutOfRange);
+
+    // Try to read empty file.
+    std::string file4("../templates/test4.hex");
+    ASSERT_TRUE(createTemplateFile(file4, template2, 0));
+    ASSERT_NO_THROW(
+        processCmdLine("perfdhcp -l 127.0.0.1 -T " + file4 + " all")
+    );
+    EXPECT_THROW(tc.initPacketTemplates(), isc::OutOfRange);
+
+    // Try reading file with non hexadecimal characters.
+    std::string file5("../templates/test5.hex");
+    ASSERT_TRUE(createTemplateFile(file5, template1, template1.size() * 2, true));
+    ASSERT_NO_THROW(
+        processCmdLine("perfdhcp -l 127.0.0.1 -T " + file5 + " all")
+    );
+    EXPECT_THROW(tc.initPacketTemplates(), isc::BadValue);
 }
 
 TEST_F(TestControlTest, RateControl) {