ifaces_config_parser_unittest.cc 5.07 KB
Newer Older
1
2
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
3
4
5
// 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/.
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

#include <config.h>

#include <cc/data.h>
#include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/parsers/ifaces_config_parser.h>
#include <gtest/gtest.h>

using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::dhcp::test;

namespace {

/// @brief Test fixture class for @c IfacesConfigParser
class IfacesConfigParserTest : public ::testing::Test {
protected:

    /// @brief Setup for each test.
    ///
    /// Clears the configuration in the @c CfgMgr.
    virtual void SetUp();

    /// @brief Cleans up after each test.
    ///
    /// Clears the configuration in the @c CfgMgr.
    virtual void TearDown();

};

void
IfacesConfigParserTest::SetUp() {
    CfgMgr::instance().clear();
}

void
IfacesConfigParserTest::TearDown() {
    CfgMgr::instance().clear();
}

// This test checks that the parser correctly parses the list of interfaces
// on which the server should listen.
TEST_F(IfacesConfigParserTest, interfaces) {
    // Creates fake interfaces with fake addresses.
    IfaceMgrTestConfig test_config(true);

    // Configuration with one interface.
54
    std::string config = "{ ""\"interfaces\": [ \"eth0\" ] }";
55
56
57
58
59
60
61
62
63
64

    ElementPtr config_element = Element::fromJSON(config);

    // Parse the configuration.
    IfacesConfigParser4 parser;
    ASSERT_NO_THROW(parser.build(config_element));

    // Open sockets according to the parsed configuration.
    SrvConfigPtr cfg = CfgMgr::instance().getStagingCfg();
    ASSERT_TRUE(cfg);
65
    ASSERT_NO_THROW(cfg->getCfgIface()->openSockets(AF_INET, 10000));
66
67
68
69
70
71

    // Only eth0 should have an open socket.
    EXPECT_TRUE(test_config.socketOpen("eth0", AF_INET));
    EXPECT_FALSE(test_config.socketOpen("eth1", AF_INET));

    // Reset configuration.
72
    cfg->getCfgIface()->closeSockets();
73
74
75
76
    CfgMgr::instance().clear();

    // Try similar configuration but this time add a wildcard interface
    // to see if sockets will open on all interfaces.
77
    config = "{ \"interfaces\": [ \"eth0\", \"*\" ] }";
78
79
80
81
82
    config_element = Element::fromJSON(config);

    ASSERT_NO_THROW(parser.build(config_element));

    cfg = CfgMgr::instance().getStagingCfg();
83
    ASSERT_NO_THROW(cfg->getCfgIface()->openSockets(AF_INET, 10000));
84
85
86
87
88

    EXPECT_TRUE(test_config.socketOpen("eth0", AF_INET));
    EXPECT_TRUE(test_config.socketOpen("eth1", AF_INET));
}

89
90
91
92
93
94
95
96
97
// This test verifies that it is possible to select the raw socket
// use in the configuration for interfaces.
TEST_F(IfacesConfigParserTest, socketTypeRaw) {
    // Create the reference configuration, which we will compare
    // the parsed configuration to.
    CfgIface cfg_ref;

    // Configuration with a raw socket selected.
    std::string config = "{ ""\"interfaces\": [ ],"
98
        " \"dhcp-socket-type\": \"raw\" }";
99
100
101
102
103
104
105
106
107
108
109
110

    ElementPtr config_element = Element::fromJSON(config);

    // Parse the configuration.
    IfacesConfigParser4 parser;
    ASSERT_NO_THROW(parser.build(config_element));

    // Compare the resulting configuration with a reference
    // configuration using the raw socket.
    SrvConfigPtr cfg = CfgMgr::instance().getStagingCfg();
    ASSERT_TRUE(cfg);
    cfg_ref.useSocketType(AF_INET, CfgIface::SOCKET_RAW);
111
    EXPECT_TRUE(*cfg->getCfgIface() == cfg_ref);
112
113
114
115
116
117
118
119
120
121
122
}

// This test verifies that it is possible to select the datagram socket
// use in the configuration for interfaces.
TEST_F(IfacesConfigParserTest, socketTypeDatagram) {
    // Create the reference configuration, which we will compare
    // the parsed configuration to.
    CfgIface cfg_ref;

    // Configuration with a datagram socket selected.
    std::string config = "{ ""\"interfaces\": [ ],"
123
        " \"dhcp-socket-type\": \"udp\" }";
124
125
126
127
128
129
130
131
132
133
134

    ElementPtr config_element = Element::fromJSON(config);

    // Parse the configuration.
    IfacesConfigParser4 parser;
    ASSERT_NO_THROW(parser.build(config_element));

    // Compare the resulting configuration with a reference
    // configuration using the raw socket.
    SrvConfigPtr cfg = CfgMgr::instance().getStagingCfg();
    ASSERT_TRUE(cfg);
135
    cfg_ref.useSocketType(AF_INET, CfgIface::SOCKET_UDP);
136
    EXPECT_TRUE(*cfg->getCfgIface() == cfg_ref);
137
138
139
140
141
142
143
}

// Test that the configuration rejects the invalid socket type.
TEST_F(IfacesConfigParserTest, socketTypeInvalid) {
    // For DHCPv4 we only accept the raw socket or datagram socket.
    IfacesConfigParser4 parser4;
    std::string config = "{ \"interfaces\": [ ],"
144
        "\"dhcp-socket-type\": \"default\" }";
145
146
147
148
149
150
    ElementPtr config_element = Element::fromJSON(config);
    ASSERT_THROW(parser4.build(config_element), DhcpConfigError);

    // For DHCPv6 we don't accept any socket type.
    IfacesConfigParser6 parser6;
    config = "{ \"interfaces\": [ ],"
151
        " \"dhcp-socket-type\": \"udp\" }";
152
153
154
    config_element = Element::fromJSON(config);
    ASSERT_THROW(parser6.build(config_element), DhcpConfigError);
}
155
156

} // end of anonymous namespace