Browse Source

[trac703] Add options information class

As part of work tackling the review, add a class giving information
about some of the command-line options.
Stephen Morris 14 years ago
parent
commit
4e9bf13057

+ 13 - 6
tests/tools/badpacket/badpacket.cc

@@ -13,9 +13,11 @@
 // PERFORMANCE OF THIS SOFTWARE.
 
 #include <unistd.h>
+#include <iostream>
 
 #include <config.h>
 
+#include <exceptions/exceptions.h>
 #include "command_options.h"
 #include "scan.h"
 
@@ -41,12 +43,17 @@ using namespace isc::badpacket;
 /// \brief Main Program
 int main(int argc, char* argv[]) {
 
-    CommandOptions command_line;
-    command_line.parse(argc, argv);
-
-    // Construct the scan object and perform the scan.
-    Scan scanner;
-    scanner.scan(command_line);
+    try {
+        CommandOptions options;
+        options.parse(argc, argv);
+
+        // Construct the scan object and perform the scan.
+        Scan scanner;
+        scanner.scan(options);
+    } catch (isc::Exception& e) {
+        std::cout << "ERROR: " << e.what() << "\n";
+        return 1;
+    }
 
     return 0;
 }

+ 45 - 26
tests/tools/badpacket/command_options.cc

@@ -28,7 +28,6 @@
 
 using namespace std;
 using namespace isc;
-namespace po = boost::program_options;
 
 namespace isc {
 namespace badpacket {
@@ -43,7 +42,6 @@ CommandOptions::parse(int argc, char* const argv[]) {
     // structure (as opposed to just putting a string literal there) is
     // occasioned by a version of solaris which declares the first field
     // as "char*" (instead of the correct "const char*").
-
     char HELP[] = {"help"};
     char VERSION[] = {"version"};
     char ADDRESS[] = {"address"};
@@ -72,7 +70,7 @@ CommandOptions::parse(int argc, char* const argv[]) {
         {TC,      1, NULL, 'T'},  // Truncated
         {RD,      1, NULL, 'D'},  // recursion Desired
         {RA,      1, NULL, 'R'},  // Recursion available
-        {Z,       1, NULL, 'Z'},  // Must be Zero (reserved bit)
+        {Z,       1, NULL, 'Z'},  // must be Zero (reserved bit)
         {AD,      1, NULL, 'U'},  // aUthenticated data
         {CD,      1, NULL, 'C'},  // Checking disabled
         {RC,      1, NULL, 'E'},  // rEsult code
@@ -110,47 +108,48 @@ CommandOptions::parse(int argc, char* const argv[]) {
                 break;
 
             case 'Q':   // --qr (query/response)
-                processOptionValue(optarg, values_.qr, 0, 1);
+                processOptionValue("qr", optarg, values_.qr, 0, 1);
                 break;
 
             case 'O':   // --op (operation code)
-                processOptionValue(optarg, values_.op, 0, 15);
+                processOptionValue("op", optarg, values_.op, 0, 15);
                 break;
 
             case 'A':   // --aa (authoritative answer)
-                processOptionValue(optarg, values_.aa, 0, 1);
+                processOptionValue("aa", optarg, values_.aa, 0, 1);
                 break;
 
             case 'T':   // --tc (truncated)
-                processOptionValue(optarg, values_.tc, 0, 1);
+                processOptionValue("tc", optarg, values_.tc, 0, 1);
                 break;
 
             case 'D':   // --rd (recursion desired)
-                processOptionValue(optarg, values_.rd, 0, 1);
+                processOptionValue("rd", optarg, values_.rd, 0, 1);
                 break;
 
             case 'R':   // --ra (recursion available)
-                processOptionValue(optarg, values_.ra, 0, 1);
+                processOptionValue("ra", optarg, values_.ra, 0, 1);
                 break;
 
             case 'Z':   // --z (zero: reserved bit)
-                processOptionValue(optarg, values_.z, 0, 1);
+                processOptionValue("z", optarg, values_.z, 0, 1);
                 break;
 
             case 'U':   // --ad (authenticated data)
-                processOptionValue(optarg, values_.ad, 0, 1);
+                processOptionValue("ad", optarg, values_.ad, 0, 1);
                 break;
 
             case 'C':   // --cd (checking disabled)
-                processOptionValue(optarg, values_.cd, 0, 1);
+                processOptionValue("cd", optarg, values_.cd, 0, 1);
                 break;
 
             case 'E':   // --rc (result code)
-                processOptionValue(optarg, values_.rc, 0, 15);
+                processOptionValue("rc", optarg, values_.rc, 0, 15);
                 break;
 
             default:
-                isc_throw(isc::InvalidParameter, "Unknown switch");
+                isc_throw(isc::InvalidParameter,
+                          "unknown option '" << argv[optind] << "' given on the command line");
         }
     }
 
@@ -213,29 +212,49 @@ CommandOptions::version() {
 
 // Process single flag
 void
-CommandOptions::processOptionValue(const char* arg, uint32_t* where, uint32_t minval,
-                     uint32_t maxval)
+CommandOptions::processOptionValue(const char* what, const char* arg,
+                                   uint32_t* where, uint32_t minval, uint32_t maxval)
 {
     // Split the string up into one or two tokens
     vector<string> values = isc::strutil::tokens(string(arg), "-");
     if ((values.size() < 1) || (values.size() > 2)) {
-        isc_throw(isc::BadValue, "command argument is '" << arg << "': it must "
-                  "be in the form 'int' or 'int1-int2'");
+        isc_throw(isc::BadValue, "value given for " << what << " is '" << arg <<
+                  "': it must be in the form 'int' or 'int1-int2'");
     }
 
     // Convert to uint32.
-    uint32_t start = boost::lexical_cast<uint32_t>(values[0]);
-    uint32_t end = start;
-    if (values.size() == 2) {
-        end = boost::lexical_cast<uint32_t>(values[1]);
+    int i = 0;
+    try {
+        do {
+            where[i] = boost::lexical_cast<uint32_t>(values[i]);
+            ++i;
+        } while (i < values.size());
+    } catch (boost::bad_lexical_cast) {
+        isc_throw(isc::BadValue, "value given for " << what << " is '" << arg <<
+                  "': it must be in the form 'int' or 'int1-int2'");
     }
-    if (start > end) {
-        swap(start, end);
+
+    // Set the limits in the correct order.
+    if (values.size() == 1) {
+        where[1] = where[0];
+    } else if (where[0] > where[1]) {
+        swap(where[0], where[1]);
     }
 
     // Coerce values into the desired range
-    where[0] = max(minval, min(start, maxval));
-    where[1] = min(maxval, max(end, minval));
+    if ((values.size() == 1) && ((where[0] < minval) || (where[0] > maxval))) {
+        isc_throw(isc::BadValue, "the values of " << where[0] <<
+                  " given for " << what << " is outside the range of " <<
+                  minval << " to " << maxval);
+    } else if (where[0] < minval) {
+        isc_throw(isc::BadValue, "the lower limit of " << where[0] <<
+                  " given for " << what << " is below the minimum permitted"
+                  " value of " << minval);
+    } else if (where[1] > maxval) {
+        isc_throw(isc::BadValue, "the upper limit of " << where[1] <<
+                  " given for " << what << " is above the maximum permitted"
+                  " value of " << maxval);
+    }
 }
 
 } // namespace badpacket

+ 4 - 6
tests/tools/badpacket/command_options.h

@@ -19,8 +19,6 @@
 #include <stdint.h>
 #include <utility>
 
-#include <boost/program_options.hpp>
-
 namespace isc {
 namespace badpacket {
 
@@ -53,7 +51,6 @@ public:
     /// variables are two-ewlement arrays: element 0 of the array holds the low
     /// value in the range given, and element 1 the high value.  If only a
     /// single value is given, both elements hold the same value.
-
     struct FlagValues {
         uint32_t qr[2];         // QR bit
         uint32_t op[2];         // OPCODE field
@@ -160,12 +157,13 @@ protected:
     /// placing it in the appropriate location.  On error a BadValue exception
     /// is thrown.
     ///
-    /// \param arg flag argument read from the command line
+    /// \param what (Long) name of the command switch being parsed
+    /// \param arg Switch argument read from the command line
     /// \param where Two-element uint32_t array into which the data is put
     /// \param minval Minimum allowed value
     /// \param maxval Maximum allowed value
-    void processOptionValue(const char* arg, uint32_t* where, uint32_t minval,
-                     uint32_t maxval);
+    void processOptionValue(const char* what, const char* arg, uint32_t* where,
+                            uint32_t minval,  uint32_t maxval);
 
     // Member variables
 

+ 73 - 0
tests/tools/badpacket/option_info.cc

@@ -0,0 +1,73 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include "option_info.h"
+
+// Define the various options for the command switches
+
+
+namespace {
+
+    isc::badpacket::OptionInfo::Parameter option_information[] = {
+    {"qr", 0x8000, 15, 0,  1},
+    {"op", 0x7800, 11, 0, 15},
+    {"aa", 0x0400, 10, 0,  1},
+    {"tc", 0x0200,  9, 0,  1},
+    {"rd", 0x0100,  8, 0,  1},
+    {"ra", 0x0080,  7, 0,  1},
+    {"z",  0x0040,  6, 0,  1},
+    {"ad", 0x0020,  5, 0,  1},
+    {"cd", 0x0010,  4, 0,  1},
+    {"rc", 0x000F,  0, 0, 15}
+};
+
+}   // Anonymous namespace
+
+namespace isc {
+namespace badpacket {
+
+// Methods to return values from the array
+
+const char*
+OptionInfo::name(OptionInfo::Index i) {
+    checkIndex(i);
+    return (option_information[i].long_form);
+}
+
+uint16_t
+OptionInfo::mask(OptionInfo::Index i) {
+    checkIndex(i);
+    return (option_information[i].mask);
+}
+
+int
+OptionInfo::offset(OptionInfo::Index i) {
+    checkIndex(i);
+    return (option_information[i].offset);
+}
+
+uint32_t
+OptionInfo::minval(OptionInfo::Index i) {
+    checkIndex(i);
+    return (option_information[i].minval);
+}
+
+uint32_t
+OptionInfo::maxval(OptionInfo::Index i) {
+    checkIndex(i);
+    return (option_information[i].maxval);
+}
+
+} // namespace badpacket
+} // namespace isc

+ 93 - 0
tests/tools/badpacket/option_info.h

@@ -0,0 +1,93 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef __OPTION_INFO_H
+#define __OPTION_INFO_H
+
+#include <stdint.h>
+#include "exceptions/exceptions.h"
+
+namespace isc {
+namespace badpacket {
+
+/// \brief Option Information
+///
+/// Holds details about the options that can be specified on the command line
+/// that require values.  Some of these options correspond to fields in the
+/// DNS message header, and information about these fields is supplied.
+
+class OptionInfo {
+public:
+
+    /// \brief Array Indexes
+    ///
+    /// The data for the flags options are held in an array.  This enum
+    /// specifies the position of the data for each flags field.
+    enum Index {
+        QR = 0,
+        OP = 1,
+        AA = 2,
+        TC = 3,
+        RD = 4,
+        RA = 5,
+        Z  = 6,
+        AD = 7,
+        CD = 8,
+        RC = 9,
+        SIZE = 10   // Number of index values
+    };
+
+    /// \brief Option Parameters
+    ///
+    /// Defines a structure that holds information associated with each of the
+    /// flags field command options.
+    struct Parameter {
+        const char*     long_form;      // Long form of the command switch
+        uint16_t        mask;           // Bit mask of the field in the flags word
+        int             offset;         // Offset of field in flags word
+        uint32_t        minval;         // Minimum valid value for this field
+        uint32_t        maxval;         // Maximum valid value for this field
+    };
+
+    /// \brief Return long form of command switch for this field
+    static const char* name(Index i);
+
+    /// \brief Return mask associated with switch field
+    static uint16_t mask(Index i);
+
+    /// \brief Return offset associated with switch field
+    static int offset(Index i);
+
+    /// \brief Return minimum allowed value of field
+    static uint32_t minval(Index i);
+
+    /// \brief Return maximum allowed value of field
+    static uint32_t maxval(Index i);
+
+private:
+    /// \brief Check Array Index
+    ///
+    /// Checks the passed field index and throws an exception if out of range.
+    static void checkIndex(Index i) {
+        if ((i < 0) || (i >= SIZE)) {
+            isc_throw(isc::OutOfRange, "option index must be in the range "
+                      "0 to " << SIZE);
+        }
+    }
+};
+
+} // namespace badpacket
+} // namespace isc
+
+#endif // __OPTION_INFO_H

+ 2 - 0
tests/tools/badpacket/tests/Makefile.am

@@ -15,8 +15,10 @@ if HAVE_GTEST
 TESTS += run_unittests
 run_unittests_SOURCES  = run_unittests.cc
 run_unittests_SOURCES += command_options_unittest.cc
+run_unittests_SOURCES += option_info_unittest.cc
 run_unittests_SOURCES += header_flags_unittest.cc
 run_unittests_SOURCES += $(top_builddir)/tests/tools/badpacket/command_options.cc
+run_unittests_SOURCES += $(top_builddir)/tests/tools/badpacket/option_info.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)

+ 46 - 62
tests/tools/badpacket/tests/command_options_unittest.cc

@@ -41,54 +41,47 @@ TEST_F(CommandOptionsTest, processOptionValue) {
     uint32_t    result[2];
 
     // Check valid data
-    processOptionValue("1", result, 0, 1);
+    processOptionValue("dummy", "1", result, 0, 1);
     EXPECT_EQ(1, result[0]);
     EXPECT_EQ(1, result[1]);
 
-    processOptionValue("0-2", result, 0, 5);
+    processOptionValue("dummy", "0-2", result, 0, 5);
     EXPECT_EQ(0, result[0]);
     EXPECT_EQ(2, result[1]);
 
-    processOptionValue("4-8", result, 0, 10);
+    processOptionValue("dummy", "4-8", result, 0, 10);
     EXPECT_EQ(4, result[0]);
     EXPECT_EQ(8, result[1]);
 
-    processOptionValue("172-103", result, 0, 200);
+    processOptionValue("dummy", "172-103", result, 0, 200);
     EXPECT_EQ(103, result[0]);
     EXPECT_EQ(172, result[1]);
 
-    // Check coercion is as expected
-    processOptionValue("1", result, 3, 4);    // Single value below range
-    EXPECT_EQ(3, result[0]);
-    EXPECT_EQ(3, result[1]);
-
-    processOptionValue("7", result, 3, 6);    // Single value above range
-    EXPECT_EQ(6, result[0]);
-    EXPECT_EQ(6, result[1]);
-
-    processOptionValue("2-6", result, 5, 10); // Range overlaps valid range on low side
-    EXPECT_EQ(5, result[0]);
-    EXPECT_EQ(6, result[1]);
-
-    processOptionValue("4-7", result, 5, 9);  // Range overlaps valid range on high side
-    EXPECT_EQ(5, result[0]);
-    EXPECT_EQ(7, result[1]);
-
-    processOptionValue("9-1", result, 4, 8);  // Range overlaps valid range
-    EXPECT_EQ(4, result[0]);
-    EXPECT_EQ(8, result[1]);
-
-    processOptionValue("4-8", result, 1, 9);  // Range inside valid range
-    EXPECT_EQ(4, result[0]);
-    EXPECT_EQ(8, result[1]);
-
-    // Now the invalid ones.
-    EXPECT_ANY_THROW(processOptionValue("", result, 0, 1));
-    EXPECT_ANY_THROW(processOptionValue(" ", result, 0, 1));
-    EXPECT_ANY_THROW(processOptionValue("abc", result, 0, 1));
-    EXPECT_ANY_THROW(processOptionValue("xyz-def", result, 0, 1));
-    EXPECT_ANY_THROW(processOptionValue("0.7", result, 0, 1));
-    EXPECT_ANY_THROW(processOptionValue("0.7-2.3", result, 0, 1));
+    // Check out of range values cause a BadValue exception
+    EXPECT_THROW(processOptionValue("dummy", "1", result, 3, 4),
+                 isc::BadValue);    // Single value below range
+    EXPECT_THROW(processOptionValue("dummy", "7", result, 3, 6),
+                 isc::BadValue);    // Single value above range
+    EXPECT_THROW(processOptionValue("dummy", "2-6", result, 5, 10),
+                 isc::BadValue);    // Range overlaps valid range on low side
+    EXPECT_THROW(processOptionValue("dummy", "4-7", result, 5, 9),
+                 isc::BadValue);   // Range overlaps valid range on high side
+    EXPECT_THROW(processOptionValue("dummy", "9-1", result, 4, 8),
+                 isc::BadValue);   // Range overlaps valid range
+
+    // ... and that any invalid string does the same
+    EXPECT_THROW(processOptionValue("dummy", "", result, 0, 1),
+                 isc::BadValue);
+    EXPECT_THROW(processOptionValue("dummy", " ", result, 0, 1),
+                 isc::BadValue);
+    EXPECT_THROW(processOptionValue("dummy", "abc", result, 0, 1),
+                 isc::BadValue);
+    EXPECT_THROW(processOptionValue("dummy", "xyz-def", result, 0, 1),
+                 isc::BadValue);
+    EXPECT_THROW(processOptionValue("dummy", "0.7", result, 0, 1),
+                 isc::BadValue);
+    EXPECT_THROW(processOptionValue("dummy", "0.7-2.3", result, 0, 1),
+                 isc::BadValue);
 }
 
 
@@ -253,16 +246,15 @@ TEST_F(CommandOptionsTest, op) {
     checkValuePair(values.cd);
     checkValuePair(values.rc);
 
-    // Check that a range is accepted (in this case, specified backwards and
-    // outside the range - so it should be truncated).
-    const char* argv3[] = {"badpacket",  "--op", "21-0"};
+    // Check that a range is accepted (in this case, specified backwards)
+    const char* argv3[] = {"badpacket",  "--op", "14-2"};
     int argc3 = sizeof(argv3) / sizeof(const char*);
 
     parse(argc3, const_cast<char**>(argv3));
     checkDefaultOtherValues(*this);
     values = getFlagValues();
     checkValuePair(values.qr);
-    checkValuePair(values.op, 0, 15);
+    checkValuePair(values.op, 2, 14);
     checkValuePair(values.aa);
     checkValuePair(values.tc);
     checkValuePair(values.z);
@@ -298,9 +290,8 @@ TEST_F(CommandOptionsTest, aa) {
     checkValuePair(values.cd);
     checkValuePair(values.rc);
 
-    // Check that a range is accepted (in this case, specified backwards and
-    // outside the range - so it should be truncated).
-    const char* argv3[] = {"badpacket",  "--aa", "21-0"};
+    // Check that a range is accepted.
+    const char* argv3[] = {"badpacket",  "--aa", "1-0"};
     int argc3 = sizeof(argv3) / sizeof(const char*);
 
     parse(argc3, const_cast<char**>(argv3));
@@ -343,9 +334,8 @@ TEST_F(CommandOptionsTest, tc) {
     checkValuePair(values.cd);
     checkValuePair(values.rc);
 
-    // Check that a range is accepted (in this case, specified backwards and
-    // outside the range - so it should be truncated).
-    const char* argv3[] = {"badpacket",  "--tc", "21-0"};
+    // Check that a range is accepted.
+    const char* argv3[] = {"badpacket",  "--tc", "1-0"};
     int argc3 = sizeof(argv3) / sizeof(const char*);
 
     parse(argc3, const_cast<char**>(argv3));
@@ -388,9 +378,8 @@ TEST_F(CommandOptionsTest, z) {
     checkValuePair(values.cd);
     checkValuePair(values.rc);
 
-    // Check that a range is accepted (in this case, specified backwards and
-    // outside the range - so it should be truncated).
-    const char* argv3[] = {"badpacket",  "--z", "21-0"};
+    // Check that a range is accepted.
+    const char* argv3[] = {"badpacket",  "--z", "1-0"};
     int argc3 = sizeof(argv3) / sizeof(const char*);
 
     parse(argc3, const_cast<char**>(argv3));
@@ -433,9 +422,8 @@ TEST_F(CommandOptionsTest, ad) {
     checkValuePair(values.cd);
     checkValuePair(values.rc);
 
-    // Check that a range is accepted (in this case, specified backwards and
-    // outside the range - so it should be truncated).
-    const char* argv3[] = {"badpacket",  "--ad", "21-0"};
+    // Check that a range is accepted.
+    const char* argv3[] = {"badpacket",  "--ad", "0-1"};
     int argc3 = sizeof(argv3) / sizeof(const char*);
 
     parse(argc3, const_cast<char**>(argv3));
@@ -478,9 +466,8 @@ TEST_F(CommandOptionsTest, cd) {
     checkValuePair(values.cd, 1, 1);
     checkValuePair(values.rc);
 
-    // Check that a range is accepted (in this case, specified backwards and
-    // outside the range - so it should be truncated).
-    const char* argv3[] = {"badpacket",  "--cd", "21-0"};
+    // Check that a range is accepted.
+    const char* argv3[] = {"badpacket",  "--cd", "1-0"};
     int argc3 = sizeof(argv3) / sizeof(const char*);
 
     parse(argc3, const_cast<char**>(argv3));
@@ -507,8 +494,8 @@ TEST_F(CommandOptionsTest, rc) {
     FlagValues values = getFlagValues();
     checkDefaultFlagValues(values);
 
-    // Check that a value of 1 is accepted
-    const char* argv2[] = {"badpacket",  "--rc", "21"};
+    // Check that a valid value is accepted.
+    const char* argv2[] = {"badpacket",  "--rc", "15"};
     int argc2 = sizeof(argv2) / sizeof(const char*);
 
     parse(argc2, const_cast<char**>(argv2));
@@ -525,7 +512,7 @@ TEST_F(CommandOptionsTest, rc) {
 
     // Check that a range is accepted (in this case, specified backwards and
     // outside the range - so it should be truncated).
-    const char* argv3[] = {"badpacket",  "--rc", "21-0"};
+    const char* argv3[] = {"badpacket",  "--rc", "8-4"};
     int argc3 = sizeof(argv3) / sizeof(const char*);
 
     parse(argc3, const_cast<char**>(argv3));
@@ -538,8 +525,5 @@ TEST_F(CommandOptionsTest, rc) {
     checkValuePair(values.z);
     checkValuePair(values.ad);
     checkValuePair(values.cd);
-    checkValuePair(values.rc, 0, 15);
+    checkValuePair(values.rc, 4, 8);
 }
-
-
-// Check that the other flags work

+ 95 - 0
tests/tools/badpacket/tests/option_info_unittest.cc

@@ -0,0 +1,95 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <cstddef>
+#include <stdint.h>
+#include <gtest/gtest.h>
+
+#include "../option_info.h"
+
+using namespace isc::badpacket;
+
+
+// Test fixture class
+
+class OptionInfoTest : public ::testing::Test {
+public:
+    OptionInfoTest() {}
+};
+
+
+// Check the values are as expected
+
+TEST_F(OptionInfoTest, values) {
+
+    EXPECT_STREQ("qr", OptionInfo::name(OptionInfo::QR));
+    EXPECT_EQ(0x8000,  OptionInfo::mask(OptionInfo::QR));
+    EXPECT_EQ(15,      OptionInfo::offset(OptionInfo::QR));
+    EXPECT_EQ(0,       OptionInfo::minval(OptionInfo::QR));
+    EXPECT_EQ(1,       OptionInfo::maxval(OptionInfo::QR));
+
+    EXPECT_STREQ("op", OptionInfo::name(OptionInfo::OP));
+    EXPECT_EQ(0x7800,  OptionInfo::mask(OptionInfo::OP));
+    EXPECT_EQ(11,      OptionInfo::offset(OptionInfo::OP));
+    EXPECT_EQ(0,       OptionInfo::minval(OptionInfo::OP));
+    EXPECT_EQ(15,      OptionInfo::maxval(OptionInfo::OP));
+
+    EXPECT_STREQ("aa", OptionInfo::name(OptionInfo::AA));
+    EXPECT_EQ(0x0400,  OptionInfo::mask(OptionInfo::AA));
+    EXPECT_EQ(10,      OptionInfo::offset(OptionInfo::AA));
+    EXPECT_EQ(0,       OptionInfo::minval(OptionInfo::AA));
+    EXPECT_EQ(1,       OptionInfo::maxval(OptionInfo::AA));
+
+    EXPECT_STREQ("tc", OptionInfo::name(OptionInfo::TC));
+    EXPECT_EQ(0x0200,  OptionInfo::mask(OptionInfo::TC));
+    EXPECT_EQ(9,       OptionInfo::offset(OptionInfo::TC));
+    EXPECT_EQ(0,       OptionInfo::minval(OptionInfo::TC));
+    EXPECT_EQ(1,       OptionInfo::maxval(OptionInfo::TC));
+
+    EXPECT_STREQ("rd", OptionInfo::name(OptionInfo::RD));
+    EXPECT_EQ(0x0100,  OptionInfo::mask(OptionInfo::RD));
+    EXPECT_EQ(8,       OptionInfo::offset(OptionInfo::RD));
+    EXPECT_EQ(0,       OptionInfo::minval(OptionInfo::RD));
+    EXPECT_EQ(1,       OptionInfo::maxval(OptionInfo::RD));
+
+    EXPECT_STREQ("ra", OptionInfo::name(OptionInfo::RA));
+    EXPECT_EQ(0x0080,  OptionInfo::mask(OptionInfo::RA));
+    EXPECT_EQ(7,       OptionInfo::offset(OptionInfo::RA));
+    EXPECT_EQ(0,       OptionInfo::minval(OptionInfo::RA));
+    EXPECT_EQ(1,       OptionInfo::maxval(OptionInfo::RA));
+
+    EXPECT_STREQ("z",  OptionInfo::name(OptionInfo::Z));
+    EXPECT_EQ(0x0040,  OptionInfo::mask(OptionInfo::Z));
+    EXPECT_EQ(6,       OptionInfo::offset(OptionInfo::Z));
+    EXPECT_EQ(0,       OptionInfo::minval(OptionInfo::Z));
+    EXPECT_EQ(1,       OptionInfo::maxval(OptionInfo::Z));
+
+    EXPECT_STREQ("ad", OptionInfo::name(OptionInfo::AD));
+    EXPECT_EQ(0x0020,  OptionInfo::mask(OptionInfo::AD));
+    EXPECT_EQ(5,       OptionInfo::offset(OptionInfo::AD));
+    EXPECT_EQ(0,       OptionInfo::minval(OptionInfo::AD));
+    EXPECT_EQ(1,       OptionInfo::maxval(OptionInfo::AD));
+
+    EXPECT_STREQ("cd", OptionInfo::name(OptionInfo::CD));
+    EXPECT_EQ(0x0010,  OptionInfo::mask(OptionInfo::CD));
+    EXPECT_EQ(4,       OptionInfo::offset(OptionInfo::CD));
+    EXPECT_EQ(0,       OptionInfo::minval(OptionInfo::CD));
+    EXPECT_EQ(1,       OptionInfo::maxval(OptionInfo::CD));
+
+    EXPECT_STREQ("rc", OptionInfo::name(OptionInfo::RC));
+    EXPECT_EQ(0x000F,  OptionInfo::mask(OptionInfo::RC));
+    EXPECT_EQ(0,       OptionInfo::offset(OptionInfo::RC));
+    EXPECT_EQ(0,       OptionInfo::minval(OptionInfo::RC));
+    EXPECT_EQ(15,      OptionInfo::maxval(OptionInfo::RC));
+}