diff options
Diffstat (limited to 'src/lib/hooks/tests/common_test_class.h')
-rw-r--r-- | src/lib/hooks/tests/common_test_class.h | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/src/lib/hooks/tests/common_test_class.h b/src/lib/hooks/tests/common_test_class.h new file mode 100644 index 0000000..aa34bcf --- /dev/null +++ b/src/lib/hooks/tests/common_test_class.h @@ -0,0 +1,174 @@ +// Copyright (C) 2013-2021 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/. + +#ifndef COMMON_HOOKS_TEST_CLASS_H +#define COMMON_HOOKS_TEST_CLASS_H + +#include <hooks/callout_handle.h> +#include <hooks/callout_manager.h> +#include <hooks/server_hooks.h> +#include <hooks/tests/marker_file.h> + +#include <boost/shared_ptr.hpp> +#include <gtest/gtest.h> + +/// @brief Common hooks test class +/// +/// This class is a shared parent of the test fixture class in the tests of the +/// higher-level hooks classes (LibraryManager, LibraryManagerCollection and +/// HooksManager). It +/// +/// - sets the ServerHooks object with three hooks and stores their +/// indexes. +/// - executes the callouts (which are assumed to perform a calculation) +/// and checks the results. + +class HooksCommonTestClass { +public: + /// @brief Constructor + HooksCommonTestClass() { + + // Set up the server hooks. ServerHooks is a singleton, so we reset it + // between each test. + isc::hooks::ServerHooks& hooks = + isc::hooks::ServerHooks::getServerHooks(); + hooks.reset(); + hookpt_one_index_ = hooks.registerHook("hookpt_one"); + hookpt_two_index_ = hooks.registerHook("hookpt_two"); + hookpt_three_index_ = hooks.registerHook("hookpt_three"); + } + + /// @brief Call callouts test + /// + /// All of the loaded libraries for which callouts are called register four + /// callouts: a context_create callout and three callouts that are attached + /// to hooks hookpt_one, hookpt_two and hookpt_three. These four callouts, + /// executed in sequence, perform a series of calculations. Data is passed + /// between callouts in the argument list, in a variable named "result". + /// + /// context_create initializes the calculation by setting a seed + /// value, called r0 here. This value is dependent on the library being + /// loaded. Prior to that, the argument "result" is initialized to -1, + /// the purpose being to avoid exceptions when running this test with no + /// libraries loaded. + /// + /// Callout hookpt_one is passed a value d1 and performs a simple arithmetic + /// operation on it and r0 yielding a result r1. Hence we can say that + /// @f[ r1 = hookpt_one(r0, d1) @f] + /// + /// Callout hookpt_two is passed a value d2 and performs another simple + /// arithmetic operation on it and d2, yielding r2, i.e. + /// @f[ r2 = hookpt_two(d1, d2) @f] + /// + /// hookpt_three does a similar operation giving + /// @f[ r3 = hookpt_three(r2, d3) @f]. + /// + /// The details of the operations hookpt_one, hookpt_two and hookpt_three + /// depend on the library, so the results obtained not only depend on + /// the data, but also on the library loaded. This method is passed both + /// data and expected results. It executes the three callouts in sequence, + /// checking the intermediate and final results. Only if the expected + /// library has been loaded correctly and the callouts in it registered + /// correctly will be the results be as expected. + /// + /// It is assumed that callout_manager_ has been set up appropriately. + /// + /// @note The CalloutHandle used in the calls is declared locally here. + /// The advantage of this (apart from scope reduction) is that on + /// exit, it is destroyed. This removes any references to memory + /// allocated by loaded libraries while they are still loaded. + /// + /// @param manager CalloutManager to use for the test + /// @param r0...r3, d1..d3 Data (dN) and expected results (rN) - both + /// intermediate and final. The arguments are ordered so that they + /// appear in the argument list in the order they are used. + void executeCallCallouts( + const boost::shared_ptr<isc::hooks::CalloutManager>& manager, + int r0, int d1, int r1, int d2, int r2, int d3, int r3) { + static const char* COMMON_TEXT = " callout returned the wrong value"; + static const char* RESULT = "result"; + + int result; + + // Set up a callout handle for the calls. + isc::hooks::CalloutHandle handle(manager); + + // Initialize the argument RESULT. This simplifies testing by + // eliminating the generation of an exception when we try the unload + // test. In that case, RESULT is unchanged. + handle.setArgument(RESULT, -1); + + // Seed the calculation. + manager->callCallouts(isc::hooks::ServerHooks::CONTEXT_CREATE, handle); + handle.getArgument(RESULT, result); + EXPECT_EQ(r0, result) << "context_create" << COMMON_TEXT; + + // Perform the first calculation. + handle.setArgument("data_1", d1); + manager->callCallouts(hookpt_one_index_, handle); + handle.getArgument(RESULT, result); + EXPECT_EQ(r1, result) << "hookpt_one" << COMMON_TEXT; + + // ... the second ... + handle.setArgument("data_2", d2); + manager->callCallouts(hookpt_two_index_, handle); + handle.getArgument(RESULT, result); + EXPECT_EQ(r2, result) << "hookpt_two" << COMMON_TEXT; + + // ... and the third. + handle.setArgument("data_3", d3); + manager->callCallouts(hookpt_three_index_, handle); + handle.getArgument(RESULT, result); + EXPECT_EQ(r3, result) << "hookpt_three" << COMMON_TEXT; + } + + /// @brief Call command handlers test. + /// + /// This test is similar to @c executeCallCallouts but it uses + /// @ref CalloutManager::callCommandHandlers to execute the command + /// handlers for the following commands: 'command-one' and 'command-two'. + /// + /// @param manager CalloutManager to use for the test + /// @param r1..r2, d1..d2 Data (dN) and expected results (rN). + void executeCallCommandHandlers( + const boost::shared_ptr<isc::hooks::CalloutManager>& manager, + int d1, int r1, int d2, int r2) { + static const char* COMMON_TEXT = " command handler returned the wrong value"; + static const char* RESULT = "result"; + + int result; + + // Set up a callout handle for the calls. + isc::hooks::CalloutHandle handle(manager); + + // Initialize the argument RESULT. This simplifies testing by + // eliminating the generation of an exception when we try the unload + // test. In that case, RESULT is unchanged. + handle.setArgument(RESULT, -1); + + // Perform the first calculation: it should assign the data to the + // result. + handle.setArgument("data_1", d1); + manager->callCommandHandlers("command-one", handle); + handle.getArgument(RESULT, result); + EXPECT_EQ(r1, result) << "command-one" << COMMON_TEXT; + + // Perform the second calculation: it should multiply the data by 10 + // and return in the result. + handle.setArgument("data_2", d2); + manager->callCommandHandlers("command-two", handle); + handle.getArgument(RESULT, result); + EXPECT_EQ(r2, result) << "command-two" << COMMON_TEXT; + } + + + /// Hook indexes. These are are made public for ease of reference. + int hookpt_one_index_; + int hookpt_two_index_; + int hookpt_three_index_; +}; + +#endif // COMMON_HOOKS_TEST_CLASS_H |