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
// Copyright (C) 2024-2025 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 <config/command_mgr.h>
#include <config/unix_command_config.h>
#include <http/basic_auth_config.h>
#include <testutils/gtest_utils.h>
#include <testutils/test_to_element.h>

using namespace isc;
using namespace isc::asiolink;
using namespace isc::config;
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::http;
using namespace isc::test;
using namespace std;

namespace {

/// @brief Test fixture for UNIX control socket configuration.
class UnixCommandConfigTest : public ::testing::Test {
public:
    /// @brief Constructor.
    UnixCommandConfigTest() : unix_config_() {
    }

    /// @brief Destructor.
    ~UnixCommandConfigTest() {
    }

    /// @brief UNIX control socket configuration.
    UnixCommandConfigPtr unix_config_;
};

// This test verifies the default UNIX control socket configuration.
TEST_F(UnixCommandConfigTest, default) {
    ElementPtr json = Element::createMap();
    ASSERT_THROW(unix_config_.reset(new UnixCommandConfig(json)), BadSocketInfo);
    json->set("socket-name", Element::create("name"));
    ASSERT_NO_THROW_LOG(unix_config_.reset(new UnixCommandConfig(json)));

    // Check default values.
    EXPECT_EQ("unix", unix_config_->getSocketType());
    EXPECT_EQ("name", unix_config_->getSocketName());

    // Check unparse.
    string expected = R"(
        {
            "socket-type": "unix",
            "socket-name": "name"
        }
    )";
    runToElementTest(expected, *unix_config_);
}

// This test verifies direct error cases.
TEST_F(UnixCommandConfigTest, errors) {
    // Error scenarios.
    struct scenario {
        string title;
        string input;
        string msg;
    } scenarios[] = {
        {
            "bad type",
            "[ ]",
            "expected map type (<string>:1:2)"
        },
        {
            "bad socket-type type",
            R"( { "socket-type": 1 } )",
            "invalid type specified for parameter 'socket-type' "
            "(<string>:1:19)"
        },
        {
            "unsupported socket-type",
            R"( { "socket-type": "http" } )",
            "unsupported 'socket-type' 'http' not 'unix'"
        },
        {
            "unsupported socket-address",
            R"( { "socket-address": "::1" } )",
            "parameter 'socket-address' is not supported by UNIX control sockets"
        },
        {
            "bad socket-name type",
            R"( { "socket-name": 8000 } )",
            "invalid type specified for parameter 'socket-name' "
            "(<string>:1:19)"
        }
    };
    for (auto const& s : scenarios) {
        SCOPED_TRACE(s.title);
        ElementPtr json;
        ASSERT_NO_THROW(json = Element::fromJSON(s.input));
        EXPECT_THROW_MSG(unix_config_.reset(new UnixCommandConfig(json)),
                         DhcpConfigError, s.msg);
    }
}

} // end of anonymous namespace