Browse Source

[4272a] Improved coverage

Francis Dupont 8 years ago
parent
commit
431bd05e19
2 changed files with 138 additions and 0 deletions
  1. 78 0
      src/lib/eval/tests/context_unittest.cc
  2. 60 0
      src/lib/eval/tests/token_unittest.cc

+ 78 - 0
src/lib/eval/tests/context_unittest.cc

@@ -421,6 +421,42 @@ public:
     bool parsed_; ///< Parsing status
 };
 
+// Test the error method without location
+TEST_F(EvalContextTest, error) {
+
+    EvalContext eval(Option::V4);
+
+    EXPECT_THROW(eval.error("an error"), EvalParseError);
+}
+
+// Test the fatal method
+TEST_F(EvalContextTest, fatal) {
+
+    EvalContext eval(Option::V4);
+
+    EXPECT_THROW(eval.fatal("a fatal error"), isc::Unexpected);
+}
+
+// Test the convertOptionCode method with an illegal input
+TEST_F(EvalContextTest, badOptionCode) {
+
+    EvalContext eval(Option::V4);
+
+    // the option code must be a number
+    EXPECT_THROW(eval.convertOptionCode("bad", location(position())),
+                 EvalParseError);
+}
+
+// Test the convertNestLevelNumber method with an illegal input
+TEST_F(EvalContextTest, badNestLevelNumber) {
+
+    EvalContext eval(Option::V4);
+
+    // the nest level number must be a number
+    EXPECT_THROW(eval.convertNestLevelNumber("bad", location(position())),
+                 EvalParseError);
+}
+
 // Test the parsing of a basic expression
 TEST_F(EvalContextTest, basic) {
 
@@ -699,6 +735,37 @@ TEST_F(EvalContextTest, relay6OptionHex) {
                      2, 85, TokenOption::HEXADECIMAL, 3);
 }
 
+// Test the nest level of a relay6 option should be in [0..32[
+TEST_F(EvalContextTest, relay6OptionLimits) {
+    EvalContext eval(Option::V6);
+
+    // max nest level is hop count limit minus one so 31
+    testRelay6Option("relay6[31].option[123].text == 'foo'",
+                     31, 123, TokenOption::TEXTUAL, 3);
+
+    universe_ = Option::V6;
+
+    checkError("relay6[32].option[123].text == 'foo'",
+               "<string>:1.8-9: Nest level has invalid value in 32. "
+               "Allowed range: 0..31");
+                     
+    // next level must be a positive number
+    checkError("relay6[-1].option[123].text == 'foo'",
+               "<string>:1.8-9: Nest level has invalid value in -1. "
+               "Allowed range: 0..31");
+}
+
+// Verify that relay6[13].option is not usable in v4
+TEST_F(EvalContextTest, relay6OptionError) {
+    universe_ = Option::V4;
+
+    // nest_level is reduced first so raises the error
+    // (if we'd like to get a relay6 error we have to insert an
+    //  intermediate action to check the universe)
+    checkError("relay6[0].option[123].text == 'foo'",
+               "<string>:1.8: Nest level invalid for DHCPv4 packets");
+}
+
 // Tests whether iface metadata in DHCP can be accessed.
 TEST_F(EvalContextTest, pktMetadataIface) {
     testPktMetadata("pkt.iface == 'eth0'", TokenPkt::IFACE, 3);
@@ -776,6 +843,17 @@ TEST_F(EvalContextTest, relay6FieldPeerAddr) {
                     1, TokenRelay6Field::PEERADDR, 3);
 }
 
+// Verify that relay6[13].<field> is not usable in v4
+TEST_F(EvalContextTest, relay6FieldError) {
+    universe_ = Option::V4;
+
+    // nest_level is reduced first so raises the error
+    // (if we'd like to get a relay6 error we have to insert an
+    //  intermediate action to check the universe)
+    checkError("relay6[0].linkaddr == ::",
+               "<string>:1.8: Nest level invalid for DHCPv4 packets");
+}
+
 // Test parsing of logical operators
 TEST_F(EvalContextTest, logicalOps) {
     // option.exists

+ 60 - 0
src/lib/eval/tests/token_unittest.cc

@@ -885,6 +885,15 @@ TEST_F(TokenTest, relay6Option) {
     EXPECT_TRUE(checkFile());
 }
 
+// Verifies that relay6 option requires DHCPv6
+TEST_F(TokenTest, relay6OptionError) {
+    // Create a relay6 option token
+    ASSERT_NO_THROW(t_.reset(new TokenRelay6Option(0, 13, TokenOption::TEXTUAL)));
+
+    // A DHCPv6 packet is required
+    EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalTypeError);
+}
+
 // Verifies that DHCPv4 packet metadata can be extracted.
 TEST_F(TokenTest, pkt4MetaData) {
     pkt4_->setIface("eth0");
@@ -925,6 +934,20 @@ TEST_F(TokenTest, pkt4MetaData) {
     uint32_t length = htonl(static_cast<uint32_t>(pkt4_->len()));
     ASSERT_EQ(4, values_.top().size());
     EXPECT_EQ(0, memcmp(&length, &values_.top()[0], 4));
+
+    // Unknown metadata type fails
+    clearStack();
+    ASSERT_NO_THROW(t_.reset(new TokenPkt(TokenPkt::MetadataType(100))));
+    EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalTypeError);
+
+    // Check that the debug output was correct.  Add the strings
+    // to the test vector in the class and then call checkFile
+    // for comparison
+    addString("EVAL_DEBUG_PKT Pushing PKT meta data iface with value eth0");
+    addString("EVAL_DEBUG_PKT Pushing PKT meta data src with value 0x0A000002");
+    addString("EVAL_DEBUG_PKT Pushing PKT meta data dst with value 0x0A000001");
+    addString("EVAL_DEBUG_PKT Pushing PKT meta data len with value 0x000000F9");
+    EXPECT_TRUE(checkFile());
 }
 
 // Verifies that DHCPv6 packet metadata can be extracted.
@@ -970,6 +993,22 @@ TEST_F(TokenTest, pkt6MetaData) {
     uint32_t length = htonl(static_cast<uint32_t>(pkt6_->len()));
     ASSERT_EQ(4, values_.top().size());
     EXPECT_EQ(0, memcmp(&length, &values_.top()[0], 4));
+
+    // Unknown meta data type fails
+    clearStack();
+    ASSERT_NO_THROW(t_.reset(new TokenPkt(TokenPkt::MetadataType(100))));
+    EXPECT_THROW(t_->evaluate(*pkt6_, values_), EvalTypeError);
+
+    // Check that the debug output was correct.  Add the strings
+    // to the test vector in the class and then call checkFile
+    // for comparison
+    addString("EVAL_DEBUG_PKT Pushing PKT meta data iface with value eth0");
+    addString("EVAL_DEBUG_PKT Pushing PKT meta data src with value "
+              "0xFE800000000000000000000000001234");
+    addString("EVAL_DEBUG_PKT Pushing PKT meta data dst with value "
+              "0xFF020000000000000000000000010002");
+    addString("EVAL_DEBUG_PKT Pushing PKT meta data len with value 0x00000010");
+    EXPECT_TRUE(checkFile());
 }
 
 // Verifies if the DHCPv4 packet fields can be extracted.
@@ -1051,6 +1090,11 @@ TEST_F(TokenTest, pkt4Fields) {
     ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::HLEN)));
     EXPECT_THROW(t_->evaluate(*pkt6_, values_), EvalTypeError);
 
+    // Unknown field fails
+    clearStack();
+    ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::FieldType(100))));
+    EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalTypeError);
+
     // Check that the debug output was correct.  Add the strings
     // to the test vector in the class and then call checkFile
     // for comparison
@@ -1089,6 +1133,11 @@ TEST_F(TokenTest, pkt6Fields) {
     ASSERT_NO_THROW(t_.reset(new TokenPkt6(TokenPkt6::TRANSID)));
     EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalTypeError);
 
+    // Unknown field fails
+    clearStack();
+    ASSERT_NO_THROW(t_.reset(new TokenPkt6(TokenPkt6::FieldType(100))));
+    EXPECT_THROW(t_->evaluate(*pkt6_, values_), EvalTypeError);
+
     // Check that the debug output was correct.  Add the strings
     // to the test vector in the class and then call checkFile
     // for comparison
@@ -1174,6 +1223,17 @@ TEST_F(TokenTest, relay6Field) {
     EXPECT_TRUE(checkFile());
 }
 
+// This test checks some error cases for a relay6 field token
+TEST_F(TokenTest, relay6FieldError) {
+    // Create a valid relay6 field token
+    ASSERT_NO_THROW(t_.reset(new TokenRelay6Field(0, TokenRelay6Field::LINKADDR)));
+
+    // a DHCPv6 packet is required
+    ASSERT_THROW(t_->evaluate(*pkt4_, values_), EvalTypeError);
+
+    // No test for unknown field as it is not (yet) checked?!
+}
+
 // This test checks if a token representing an == operator is able to
 // compare two values (with incorrectly built stack).
 TEST_F(TokenTest, optionEqualInvalid) {