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) {
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);
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
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");
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.
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.
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
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
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) {