1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright (C) 2018-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/.

#include <config.h>

#include <dhcp/packet_queue_ring.h>
#include <dhcp/packet_queue_mgr6.h>
#include <dhcp/tests/packet_queue_testutils.h>

#include <boost/shared_ptr.hpp><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <gtest/gtest.h><--- Include file:  not found. Please note: Cppcheck does not need standard library headers to get proper results.

using namespace std;
using namespace isc;
using namespace isc::dhcp;
using namespace isc::dhcp::test;

namespace {

/// @brief Test fixture for exercising the DHCPv6 Packet Queue Manager (PQM)
class PacketQueueMgr6Test : public ::testing::Test {
public:
    /// @brief Constructor
    ///
    /// Note that it instantiates the PQM singleton.
    PacketQueueMgr6Test()
        : default_queue_type_(PacketQueueMgr6::DEFAULT_QUEUE_TYPE6) {
        packet_queue_mgr6_.reset(new PacketQueueMgr6());

    }

    /// @brief Destructor
    ///
    /// It destroys the PQM singleton.
    virtual ~PacketQueueMgr6Test(){}

    /// @brief Registers a queue type factory
    ///
    /// @param queue_type logical name of the queue implementation
    ///
    /// @return true if the registration succeeded, false otherwise
    bool addCustomQueueType(const std::string& queue_type) {
        bool did_it =
            mgr().registerPacketQueueFactory(queue_type,
                                            [](data::ConstElementPtr parameters)
                                            -> PacketQueue6Ptr {
                std::string queue_type ;
                try {
                    queue_type = data::SimpleParser::getString(parameters, "queue-type");
                } catch (const std::exception& ex) {
                    isc_throw(InvalidQueueParameter,
                              "queue-type missing or invalid: " << ex.what());
                }

                size_t capacity;
                try {
                    capacity = data::SimpleParser::getInteger(parameters, "capacity");
                } catch (const std::exception& ex) {
                    isc_throw(InvalidQueueParameter,
                              "'capacity' missing or invalid: " << ex.what());
                }

                return (PacketQueue6Ptr(new PacketQueueRing6(queue_type, capacity)));
            });

        return did_it;
    }

    /// @brief Fetches a pointer to the PQM singleton
    PacketQueueMgr6& mgr() {
        return (*packet_queue_mgr6_);
    };

    /// @brief Tests the current packet queue info against expected content
    ///
    /// @param exp_json JSON text describing the expected packet queue info
    /// contents
    void checkMyInfo(const std::string& exp_json) {
        checkInfo((mgr().getPacketQueue()), exp_json);
    }

    /// @brief default queue type used for a given test
    std::string default_queue_type_;

    /// @brief Packet Queue manager instance
    PacketQueueMgr6Ptr packet_queue_mgr6_;
};

// Verifies that DHCPv6 PQM provides a default queue factory
TEST_F(PacketQueueMgr6Test, defaultQueue) {<--- syntax error
    // Should not be a queue at start-up
    ASSERT_FALSE(mgr().getPacketQueue());

    // Verify that we can create a queue with default factory.
    data::ConstElementPtr config = makeQueueConfig(default_queue_type_, 2000);
    ASSERT_NO_THROW(mgr().createPacketQueue(config));
    CHECK_QUEUE_INFO (mgr().getPacketQueue(), "{ \"capacity\": 2000, \"queue-type\": \""
                      << default_queue_type_ << "\", \"size\": 0 }");
}

// Verifies that PQM registry and creation of custom queue implementations.
TEST_F(PacketQueueMgr6Test, customQueueType) {

    // Verify that we cannot create a queue for a non-existant type
    data::ConstElementPtr config = makeQueueConfig("custom-queue", 2000);
    ASSERT_THROW(mgr().createPacketQueue(config), InvalidQueueType);

    // Register our adjustable-type factory
    ASSERT_TRUE(addCustomQueueType("custom-queue"));

    // Verify that we can create a custom queue.
    ASSERT_NO_THROW(mgr().createPacketQueue(config));
    checkMyInfo("{ \"capacity\": 2000, \"queue-type\": \"custom-queue\", \"size\": 0 }");

    // Now unregister the factory.
    ASSERT_NO_THROW(mgr().unregisterPacketQueueFactory("custom-queue"));
    // Queue should be gone too.
    ASSERT_FALSE(mgr().getPacketQueue());

    // Try and recreate the custom queue, type should be invalid.
    ASSERT_THROW(mgr().createPacketQueue(config), InvalidQueueType);

    // Verify we can create a default type queue with non-default capacity.
    config = makeQueueConfig(default_queue_type_, 2000);
    ASSERT_NO_THROW(mgr().createPacketQueue(config));
    CHECK_QUEUE_INFO (mgr().getPacketQueue(), "{ \"capacity\": 2000, \"queue-type\": \""
                      << default_queue_type_ << "\", \"size\": 0 }");
}

} // end of anonymous namespace