mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-06 00:45:23 +00:00
172 lines
5.7 KiB
C++
172 lines
5.7 KiB
C++
![]() |
// 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 a packet and properly store the option's value.
|
||
|
TEST_F(TokenTest, optionString) {
|
||
|
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 == 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());
|
||
|
}
|
||
|
|
||
|
};
|