]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[219-allow-an-option-value-to-be-set-from-an-expression] Checkout: adding call tests
authorFrancis Dupont <fdupont@isc.org>
Fri, 4 Oct 2019 18:02:58 +0000 (20:02 +0200)
committerFrancis Dupont <fdupont@isc.org>
Fri, 25 Oct 2019 08:57:53 +0000 (10:57 +0200)
src/hooks/dhcp/flex_option/libloadtests/Makefile.am
src/hooks/dhcp/flex_option/libloadtests/callout_unittests.cc [new file with mode: 0644]
src/hooks/dhcp/flex_option/tests/flex_option_unittests.cc

index 6ce02d064415ce99ecab24a6695c4e84c7423797..1623fe888d16a6d58192697d0f31e79154288975 100644 (file)
@@ -26,6 +26,7 @@ if HAVE_GTEST
 TESTS += flex_option_unittests
 
 flex_option_unittests_SOURCES = run_unittests.cc
+flex_option_unittests_SOURCES += callout_unittests.cc
 flex_option_unittests_SOURCES += load_unload_unittests.cc
 
 flex_option_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES)
diff --git a/src/hooks/dhcp/flex_option/libloadtests/callout_unittests.cc b/src/hooks/dhcp/flex_option/libloadtests/callout_unittests.cc
new file mode 100644 (file)
index 0000000..ecd58ac
--- /dev/null
@@ -0,0 +1,127 @@
+// Copyright (C) 2019 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+/// @file This file contains tests which exercise the pkt[46]_send callouis
+/// called by the flexible option hook library. In order to test the callouts
+/// one must be able to pass to the load function it hook library parameters
+/// because the only way to populate these parameters is by actually loading
+/// the library via HooksManager::loadLibraries().
+
+#include <config.h>
+
+#include <flex_option.h>
+#include <hooks/hooks.h>
+#include <hooks/hooks_manager.h>
+#include <hooks/callout_manager.h>
+#include <dhcp/pkt4.h>
+
+#include <gtest/gtest.h>
+#include <errno.h>
+
+using namespace std;
+using namespace isc;
+using namespace isc::hooks;
+using namespace isc::data;
+using namespace isc::dhcp;
+
+namespace {
+
+/// @brief Structure that holds registered hook indexes.
+struct TestHooks {
+    /// @brief Index of pkt4_send callout.
+    int hook_index_pkt4_send_;
+
+    /// @brief Index of pkt6_send callout.
+    int hook_index_pkt6_send_;
+
+    /// @brief Constructor
+    ///
+    /// The constructor registers hook points for callout tests.
+    TestHooks() {
+        hook_index_pkt4_send_ = HooksManager::registerHook("pkt4_send");
+        hook_index_pkt6_send_ = HooksManager::registerHook("pkt6_send");
+    }
+};
+
+TestHooks testHooks;
+
+/// @brief Test fixture for testing callouts called by the flex-option library
+class CalloutTest : public ::testing::Test {
+public:
+    /// @brief Constructor
+    CalloutTest() {
+        reset();
+    }
+
+    /// @brief Destructor
+    /// Removes files that may be left over from previous tests
+    virtual ~CalloutTest() {
+        reset();
+    }
+
+    /// @brief Removes files that may be left over from previous tests
+    virtual void reset() {
+        HooksManager::unloadLibraries();
+    }
+
+    void addLib(const std::string& lib, ConstElementPtr params) {
+        libraries_.push_back(make_pair(lib, params));
+    }
+
+    void loadLibs() {
+        EXPECT_TRUE(HooksManager::loadLibraries(libraries_));
+    }
+
+    void unloadLibs() {
+        EXPECT_NO_THROW(HooksManager::unloadLibraries());
+    }
+
+    HookLibsCollection libraries_;
+};
+
+// Simple test which exercises the pkt4_send callout.
+TEST_F(CalloutTest, pkt4Send) {
+    // Prepare load() parameters.
+    ElementPtr params = Element::createMap();
+    ElementPtr options = Element::createList();
+    params->set("options", options);
+    ElementPtr option = Element::createMap();
+    options->add(option);
+    ElementPtr code = Element::create(DHO_HOST_NAME);
+    option->set("code", code);
+    ElementPtr add = Element::create(string("'abc'"));
+    option->set("add", add);
+
+    // Load the library.
+    addLib(FLEX_OPTION_LIB_SO, params);
+    loadLibs();
+
+    // Prepare packets.
+    Pkt4Ptr query(new Pkt4(DHCPDISCOVER, 12345));
+    Pkt4Ptr response(new Pkt4(DHCPOFFER, 12345));
+    EXPECT_FALSE(response->getOption(DHO_HOST_NAME));
+
+    // Get and setup the callout handle.
+    EXPECT_TRUE(HooksManager::calloutsPresent(testHooks.hook_index_pkt4_send_));
+    CalloutHandlePtr handle = HooksManager::createCalloutHandle();
+    handle->setArgument("query4", query);
+    handle->setArgument("response4", response);
+
+    // Execute the callout.
+    EXPECT_NO_THROW(HooksManager::callCallouts(testHooks.hook_index_pkt4_send_,
+                                               *handle));
+    EXPECT_EQ(0, handle->getStatus());
+        
+    // Check the result.
+    OptionPtr opt = response->getOption(DHO_HOST_NAME);
+    ASSERT_TRUE(opt);
+    EXPECT_EQ(DHO_HOST_NAME, opt->getType());
+    const OptionBuffer& buffer = opt->getData();
+    ASSERT_EQ(3, buffer.size());
+    EXPECT_EQ(0, memcmp(&buffer[0], "abc", 3));
+}
+
+} // end of anonymous namespace
index c3a0360d672445aaba11c21a8e97237f6715e539..90a8ee01bdac461948cce713e7f285153f2e159c 100644 (file)
@@ -27,11 +27,6 @@ using namespace isc::eval;
 using namespace isc::hooks;
 using namespace isc::flex_option;
 
-extern "C" {
-extern int pkt4_send(CalloutHandle& handle);
-extern int pkt6_send(CalloutHandle& handle);
-}
-
 namespace {
 
 /// @brief Test class derived from FlexOptionImpl
@@ -361,12 +356,13 @@ TEST_F(FlexOptionTest, optionConfigBadAdd) {
     options->add(option);
     ElementPtr code = Element::create(DHO_HOST_NAME);
     option->set("code", code);
-    ElementPtr add = Element::create(string("if"));
+    ElementPtr add = Element::create(string("ifelse('a','b','c')"));
     option->set("add", add);
     EXPECT_THROW(impl_->testConfigure(options), BadValue);
-    EXPECT_EQ("can't parse add expression [if] error: "
-              "<string>:1.1: Invalid character: i",
-              impl_->getErrMsg());
+    string expected = "can't parse add expression [ifelse('a','b','c')] ";
+    expected += "error: <string>:1.11: syntax error, ";
+    expected += "unexpected \",\", expecting ==";
+    EXPECT_EQ(expected, impl_->getErrMsg());
 }
 
 // Verify that a valid v4 add value is accepted.
@@ -464,11 +460,12 @@ TEST_F(FlexOptionTest, optionConfigBadSupersede) {
     options->add(option);
     ElementPtr code = Element::create(DHO_HOST_NAME);
     option->set("code", code);
-    ElementPtr supersede = Element::create(string("if"));
+    ElementPtr supersede = Element::create(string("ifelse('a','b','c')"));
     option->set("supersede", supersede);
     EXPECT_THROW(impl_->testConfigure(options), BadValue);
-    string expected = "can't parse supersede expression [if] error: ";
-    expected += "<string>:1.1: Invalid character: i";
+    string expected = "can't parse supersede expression [ifelse('a','b','c')] ";
+    expected += "error: <string>:1.11: syntax error, ";
+    expected += "unexpected \",\", expecting ==";
     EXPECT_EQ(expected, impl_->getErrMsg());
 }