2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-09-06 00:45:23 +00:00
Files
kea/src/lib/eval/tests/token_unittest.cc

200 lines
6.7 KiB
C++
Raw Normal View History

// Copyright (C) 2015 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 <config.h>
#include <eval/token.h>
#include <dhcp/pkt4.h>
#include <dhcp/pkt6.h>
#include <dhcp/dhcp4.h>
#include <dhcp/dhcp6.h>
#include <dhcp/option_string.h>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h>
using namespace std;
using namespace isc::dhcp;
namespace {
/// @brief Test fixture for testing Tokens.
///
/// This class provides several convenience objects to be used during testing
/// of the Token family of classes.
class TokenTest : public ::testing::Test {
public:
/// @brief Initializes Pkt4,Pkt6 and options that can be useful for
/// evaluation tests.
TokenTest() {
pkt4_.reset(new Pkt4(DHCPDISCOVER, 12345));
pkt6_.reset(new Pkt6(DHCPV6_SOLICIT, 12345));
// Add options with easily identifiable strings in them
option_str4_.reset(new OptionString(Option::V4, 100, "hundred4"));
option_str6_.reset(new OptionString(Option::V6, 100, "hundred6"));
pkt4_->addOption(option_str4_);
pkt6_->addOption(option_str6_);
}
TokenPtr t_; ///< Just a convenience pointer
ValueStack values_; ///< evaluated values will be stored here
Pkt4Ptr pkt4_; ///< A stub DHCPv4 packet
Pkt6Ptr pkt6_; ///< A stub DHCPv6 packet
OptionPtr option_str4_; ///< A string option for DHCPv4
OptionPtr option_str6_; ///< A string option for DHCPv6
/// @todo: Add more option types here
};
// This simple test checks that a TokenString, representing a constant string,
// can be used in Pkt4 evaluation. (The actual packet is not used)
TEST_F(TokenTest, string4) {
// Store constant string "foo" in the TokenString object.
ASSERT_NO_THROW(t_.reset(new TokenString("foo")));
// Make sure that the token can be evaluated without exceptions.
ASSERT_NO_THROW(t_->evaluate(*pkt4_, values_));
// Check that the evaluation put its value on the values stack.
ASSERT_EQ(1, values_.size());
EXPECT_EQ("foo", values_.top());
}
// This simple test checks that a TokenString, representing a constant string,
// can be used in Pkt6 evaluation. (The actual packet is not used)
TEST_F(TokenTest, string6) {
// Store constant string "foo" in the TokenString object.
ASSERT_NO_THROW(t_.reset(new TokenString("foo")));
// Make sure that the token can be evaluated without exceptions.
ASSERT_NO_THROW(t_->evaluate(*pkt6_, values_));
// Check that the evaluation put its value on the values stack.
ASSERT_EQ(1, values_.size());
EXPECT_EQ("foo", values_.top());
}
// This test checks if a token representing an option value is able to extract
// the option from an IPv4 packet and properly store the option's value.
TEST_F(TokenTest, optionString4) {
TokenPtr found;
TokenPtr not_found;
// The packets we use have option 100 with a string in them.
ASSERT_NO_THROW(found.reset(new TokenOption(100)));
ASSERT_NO_THROW(not_found.reset(new TokenOption(101)));
// This should evaluate to the content of the option 100 (i.e. "hundred4")
ASSERT_NO_THROW(found->evaluate(*pkt4_, values_));
// This should evaluate to "" as there is no option 101.
ASSERT_NO_THROW(not_found->evaluate(*pkt4_, values_));
// There should be 2 values evaluated.
ASSERT_EQ(2, values_.size());
// This is a stack, so the pop order is inversed. We should get the empty
// string first.
EXPECT_EQ("", values_.top());
values_.pop();
// Then the content of the option 100.
EXPECT_EQ("hundred4", values_.top());
}
// This test checks if a token representing an option value is able to extract
// the option from an IPv6 packet and properly store the option's value.
TEST_F(TokenTest, optionString6) {
TokenPtr found;
TokenPtr not_found;
// The packets we use have option 100 with a string in them.
ASSERT_NO_THROW(found.reset(new TokenOption(100)));
ASSERT_NO_THROW(not_found.reset(new TokenOption(101)));
// This should evaluate to the content of the option 100 (i.e. "hundred6")
ASSERT_NO_THROW(found->evaluate(*pkt6_, values_));
// This should evaluate to "" as there is no option 101.
ASSERT_NO_THROW(not_found->evaluate(*pkt6_, values_));
// There should be 2 values evaluated.
ASSERT_EQ(2, values_.size());
// This is a stack, so the pop order is inversed. We should get the empty
// string first.
EXPECT_EQ("", values_.top());
values_.pop();
// Then the content of the option 100.
EXPECT_EQ("hundred6", values_.top());
}
// This test checks if a token representing an == operator is able to
// compare two values (with incorrectly built stack).
TEST_F(TokenTest, optionEqualInvalid) {
ASSERT_NO_THROW(t_.reset(new TokenEqual()));
// CASE 1: There's not enough values on the stack. == is an operator that
// takes two parameters. There are 0 on the stack.
EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalBadStack);
// CASE 2: One value is still not enough.
values_.push("foo");
EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalBadStack);
}
// This test checks if a token representing an == operator is able to
// compare two different values.
TEST_F(TokenTest, optionEqualFalse) {
ASSERT_NO_THROW(t_.reset(new TokenEqual()));
values_.push("foo");
values_.push("bar");
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
// After evaluation there should be a single value that represents
// result of "foo" == "bar" comparision.
ASSERT_EQ(1, values_.size());
EXPECT_EQ("false", values_.top());
}
// This test checks if a token representing an == operator is able to
// compare two identical values.
TEST_F(TokenTest, optionEqualTrue) {
ASSERT_NO_THROW(t_.reset(new TokenEqual()));
values_.push("foo");
values_.push("foo");
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
// After evaluation there should be a single value that represents
// result of "foo" == "foo" comparision.
ASSERT_EQ(1, values_.size());
EXPECT_EQ("true", values_.top());
}
};