mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 14:05:33 +00:00
[5389] Dead code for .spec files removed.
This commit is contained in:
@@ -1209,14 +1209,12 @@ AC_CONFIG_FILES([Makefile
|
||||
src/bin/d2/tests/d2_process_tests.sh
|
||||
src/bin/d2/tests/test_data_files_config.h
|
||||
src/bin/dhcp4/Makefile
|
||||
src/bin/dhcp4/spec_config.h.pre
|
||||
src/bin/dhcp4/tests/Makefile
|
||||
src/bin/dhcp4/tests/dhcp4_process_tests.sh
|
||||
src/bin/dhcp4/tests/marker_file.h
|
||||
src/bin/dhcp4/tests/test_data_files_config.h
|
||||
src/bin/dhcp4/tests/test_libraries.h
|
||||
src/bin/dhcp6/Makefile
|
||||
src/bin/dhcp6/spec_config.h.pre
|
||||
src/bin/dhcp6/tests/Makefile
|
||||
src/bin/dhcp6/tests/dhcp6_process_tests.sh
|
||||
src/bin/dhcp6/tests/marker_file.h
|
||||
@@ -1296,7 +1294,6 @@ AC_CONFIG_FILES([Makefile
|
||||
src/lib/log/tests/severity_test.sh
|
||||
src/lib/log/tests/tempdir.h
|
||||
src/lib/process/Makefile
|
||||
src/lib/process/spec_config.h.pre
|
||||
src/lib/process/tests/Makefile
|
||||
src/lib/process/testutils/Makefile
|
||||
src/lib/stats/Makefile
|
||||
|
@@ -23,7 +23,7 @@ CLEANFILES = *.gcno *.gcda d2_messages.h d2_messages.cc s-messages
|
||||
|
||||
man_MANS = kea-dhcp-ddns.8
|
||||
DISTCLEANFILES = $(man_MANS)
|
||||
EXTRA_DIST = $(man_MANS) kea-dhcp-ddns.xml dhcp-ddns.spec d2.dox
|
||||
EXTRA_DIST = $(man_MANS) kea-dhcp-ddns.xml d2.dox
|
||||
EXTRA_DIST += d2_parser.yy
|
||||
|
||||
EXTRA_DIST += images/abstract_app_classes.svg images/add_state_model.svg
|
||||
@@ -119,7 +119,6 @@ kea_dhcp_ddns_LDFLAGS += $(CQL_LIBS)
|
||||
endif
|
||||
|
||||
kea_dhcp_ddnsdir = $(pkgdatadir)
|
||||
kea_dhcp_ddns_DATA = dhcp-ddns.spec
|
||||
|
||||
if GENERATE_PARSER
|
||||
|
||||
|
@@ -1,228 +0,0 @@
|
||||
{
|
||||
"module_spec":
|
||||
{
|
||||
"module_name": "DhcpDdns",
|
||||
"module_description": "DHPC-DDNS Service",
|
||||
"config_data": [
|
||||
{
|
||||
"item_name": "ip-address",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "127.0.0.1"
|
||||
},
|
||||
{
|
||||
"item_name": "port",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 53001
|
||||
},
|
||||
{
|
||||
"item_name": "dns-server-timeout",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 100
|
||||
},
|
||||
{
|
||||
"item_name": "ncr-protocol",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "UDP"
|
||||
},
|
||||
{
|
||||
"item_name": "ncr-format",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "JSON"
|
||||
},
|
||||
{
|
||||
"item_name": "tsig-keys",
|
||||
"item_type": "list",
|
||||
"item_optional": true,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "tsig-key",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {"algorithm" : "HMAC-MD5"},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "name",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "algorithm",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "digest-bits",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 0
|
||||
},
|
||||
{
|
||||
"item_name": "secret",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"item_name": "forward-ddns",
|
||||
"item_type": "map",
|
||||
"item_optional": true,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "ddns-domains",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "ddns-domain",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "name",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "key-name",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "dns-servers",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "dns-server",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "hostname",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "ip-address",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "port",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 53
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}]
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "reverse-ddns",
|
||||
"item_type": "map",
|
||||
"item_optional": true,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "ddns-domains",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "ddns-domain",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "name",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "key-name",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "dns-servers",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "dns-server",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "hostname",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "ip-address",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "port",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 53
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}],
|
||||
|
||||
"commands": [
|
||||
{
|
||||
"command_name": "shutdown",
|
||||
"command_description": "Shuts down kea-dhcp-ddns module server.",
|
||||
"command_args": [
|
||||
{
|
||||
"item_name": "type",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "normal",
|
||||
"item_description": "values: normal (default), now, or drain_first"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@@ -6,7 +6,6 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <config/module_spec.h>
|
||||
#include <d2/d2_config.h>
|
||||
#include <d2/d2_cfg_mgr.h>
|
||||
#include <d2/d2_simple_parser.h>
|
||||
@@ -28,16 +27,6 @@ using namespace isc::process;
|
||||
|
||||
namespace {
|
||||
|
||||
/// @brief Function to create full path to the spec file
|
||||
///
|
||||
/// The full path is dependent upon the value of D2_SRC_DIR which
|
||||
/// whose value is generated from test_data_files_config.h.in
|
||||
///
|
||||
/// @param name file name to which the path should be prepended
|
||||
std::string specfile(const std::string& name) {
|
||||
return (std::string(D2_SRC_DIR) + "/" + name);
|
||||
}
|
||||
|
||||
/// @brief Function to create full path to test data file
|
||||
///
|
||||
/// The full path is dependent upon the value of D2_TEST_DATA_DIR which
|
||||
@@ -229,14 +218,6 @@ public:
|
||||
#define SYNTAX_ERROR(a,b) ASSERT_TRUE(runConfigOrFail(a,SYNTAX_ERROR,b))
|
||||
#define LOGIC_ERROR(a,b) ASSERT_TRUE(runConfigOrFail(a,LOGIC_ERROR,b))
|
||||
|
||||
/// @brief Tests that the spec file is valid.
|
||||
/// Verifies that the DHCP-DDNS configuration specification file
|
||||
/// is valid.
|
||||
TEST(D2SpecTest, basicSpec) {
|
||||
ASSERT_NO_THROW(isc::config::
|
||||
moduleSpecFromFile(specfile("dhcp-ddns.spec")));
|
||||
}
|
||||
|
||||
/// @brief Tests a basic valid configuration for D2Param.
|
||||
TEST_F(D2CfgMgrTest, validParamsEntry) {
|
||||
// Verify that ip_address can be valid v4 address.
|
||||
|
@@ -20,11 +20,11 @@ if USE_STATIC_LINK
|
||||
AM_LDFLAGS = -static
|
||||
endif
|
||||
|
||||
CLEANFILES = *.gcno *.gcda spec_config.h dhcp4_messages.h dhcp4_messages.cc s-messages
|
||||
CLEANFILES = *.gcno *.gcda dhcp4_messages.h dhcp4_messages.cc s-messages
|
||||
|
||||
man_MANS = kea-dhcp4.8
|
||||
DISTCLEANFILES = $(man_MANS)
|
||||
EXTRA_DIST = $(man_MANS) kea-dhcp4.xml dhcp4.spec
|
||||
EXTRA_DIST = $(man_MANS) kea-dhcp4.xml
|
||||
EXTRA_DIST += dhcp4.dox dhcp4_hooks.dox dhcp4o6.dox
|
||||
EXTRA_DIST += dhcp4_parser.yy
|
||||
|
||||
@@ -42,16 +42,13 @@ $(man_MANS):
|
||||
|
||||
endif
|
||||
|
||||
spec_config.h: spec_config.h.pre
|
||||
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
|
||||
|
||||
dhcp4_messages.h dhcp4_messages.cc: s-messages
|
||||
|
||||
s-messages: dhcp4_messages.mes
|
||||
$(top_builddir)/src/lib/log/compiler/kea-msg-compiler $(top_srcdir)/src/bin/dhcp4/dhcp4_messages.mes
|
||||
touch $@
|
||||
|
||||
BUILT_SOURCES = spec_config.h dhcp4_messages.h dhcp4_messages.cc
|
||||
BUILT_SOURCES = dhcp4_messages.h dhcp4_messages.cc
|
||||
|
||||
# convenience archive
|
||||
|
||||
@@ -105,7 +102,6 @@ kea_dhcp4_LDFLAGS += $(CQL_LIBS)
|
||||
endif
|
||||
|
||||
kea_dhcp4dir = $(pkgdatadir)
|
||||
kea_dhcp4_DATA = dhcp4.spec
|
||||
|
||||
if GENERATE_PARSER
|
||||
|
||||
|
@@ -1,694 +0,0 @@
|
||||
{
|
||||
"module_spec": {
|
||||
"module_name": "Dhcp4",
|
||||
"module_description": "DHCPv4 server daemon",
|
||||
"config_data": [
|
||||
{
|
||||
"item_name": "hooks-libraries",
|
||||
"item_type": "list",
|
||||
"item_optional": true,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "hooks-library-spec",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "library",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
{ "item_name": "interfaces-config",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "interfaces",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [ "*" ],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "interface_name",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "*"
|
||||
}
|
||||
},
|
||||
|
||||
{ "item_name": "dhcp-socket-type",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{ "item_name": "expired-leases-processing",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "reclaim-timer-wait-time",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 10
|
||||
},
|
||||
{
|
||||
"item_name": "flush-reclaimed-timer-wait-time",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 25
|
||||
},
|
||||
{
|
||||
"item_name": "hold-reclaimed-time",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 3600
|
||||
},
|
||||
{
|
||||
"item_name": "max-reclaim-leases",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 100
|
||||
},
|
||||
{
|
||||
"item_name": "max-reclaim-time",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 250
|
||||
},
|
||||
{
|
||||
"item_name": "unwarned-reclaim-cycles",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{ "item_name": "renew-timer",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 1000
|
||||
},
|
||||
|
||||
{ "item_name": "rebind-timer",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 2000
|
||||
},
|
||||
|
||||
{ "item_name": "valid-lifetime",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 4000
|
||||
},
|
||||
|
||||
{ "item_name": "next-server",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
|
||||
{ "item_name": "echo-client-id",
|
||||
"item_type": "boolean",
|
||||
"item_optional": true,
|
||||
"item_default": true
|
||||
},
|
||||
|
||||
{ "item_name": "match-client-id",
|
||||
"item_type": "boolean",
|
||||
"item_optional": true,
|
||||
"item_default": true
|
||||
},
|
||||
|
||||
{ "item_name": "option-def",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "single-option-def",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "name",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
|
||||
{ "item_name": "code",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 0
|
||||
},
|
||||
|
||||
{ "item_name": "type",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
|
||||
{ "item_name": "array",
|
||||
"item_type": "boolean",
|
||||
"item_optional": false,
|
||||
"item_default": false
|
||||
},
|
||||
|
||||
{ "item_name": "record-types",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
|
||||
{ "item_name": "space",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
|
||||
{ "item_name": "encapsulate",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
} ]
|
||||
}
|
||||
},
|
||||
|
||||
{ "item_name": "option-data",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "single-option-data",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "name",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
|
||||
{ "item_name": "code",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 0
|
||||
},
|
||||
{ "item_name": "data",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
{ "item_name": "csv-format",
|
||||
"item_type": "boolean",
|
||||
"item_optional": false,
|
||||
"item_default": false
|
||||
},
|
||||
{ "item_name": "space",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "dhcp4"
|
||||
} ]
|
||||
}
|
||||
},
|
||||
|
||||
{ "item_name": "lease-database",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {"type": "memfile"},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "type",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "name",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "user",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "host",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "password",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "persist",
|
||||
"item_type": "boolean",
|
||||
"item_optional": true,
|
||||
"item_default": true
|
||||
},
|
||||
{
|
||||
"item_name": "lfc-interval",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 0
|
||||
},
|
||||
{
|
||||
"item_name": "readonly",
|
||||
"item_type": "boolean",
|
||||
"item_optional": true,
|
||||
"item_default": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{ "item_name": "client-classes",
|
||||
"item_type": "list",
|
||||
"item_optional": true,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "client-class",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{ "item_name": "name",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
{ "item_name": "test",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{ "item_name": "option-data",
|
||||
"item_type": "list",
|
||||
"item_optional": true,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "single-option-data",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "name",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "code",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 0
|
||||
},
|
||||
{
|
||||
"item_name": "data",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
{ "item_name": "csv-format",
|
||||
"item_type": "boolean",
|
||||
"item_optional": false,
|
||||
"item_default": false
|
||||
},
|
||||
{ "item_name": "space",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "dhcp4"
|
||||
} ]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{ "item_name": "subnet4",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "single-subnet4",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
|
||||
{ "item_name": "subnet",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
|
||||
{ "item_name": "id",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 0
|
||||
},
|
||||
|
||||
{ "item_name": "renew-timer",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 1000
|
||||
},
|
||||
|
||||
{ "item_name": "rebind-timer",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 2000
|
||||
},
|
||||
|
||||
{ "item_name": "valid-lifetime",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 7200
|
||||
},
|
||||
|
||||
{ "item_name": "next-server",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "0.0.0.0"
|
||||
},
|
||||
|
||||
{ "item_name": "match-client-id",
|
||||
"item_type": "boolean",
|
||||
"item_optional": true,
|
||||
"item_default": true
|
||||
},
|
||||
|
||||
{ "item_name": "pool",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "type",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
}
|
||||
},
|
||||
|
||||
{ "item_name": "client-class",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "",
|
||||
"item_description" : "Restricts access to this subnet to specified client class (if defined)"
|
||||
},
|
||||
|
||||
{ "item_name": "relay",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"item_description" : "Structure holding relay information.",
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "ip-address",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "0.0.0.0",
|
||||
"item_description" : "IPv4 address of the relay (defaults to 0.0.0.0 if not specified)."
|
||||
}
|
||||
]
|
||||
},
|
||||
{ "item_name": "option-data",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "single-option-data",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "name",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "code",
|
||||
"item_type": "integer",
|
||||
"item_optional": false,
|
||||
"item_default": 0
|
||||
},
|
||||
{
|
||||
"item_name": "data",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
{ "item_name": "csv-format",
|
||||
"item_type": "boolean",
|
||||
"item_optional": false,
|
||||
"item_default": false
|
||||
},
|
||||
{ "item_name": "space",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "dhcp4"
|
||||
} ]
|
||||
}
|
||||
},
|
||||
{ "item_name": "reservations",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "reservation",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "hw-address",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "duid",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "hostname",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "ip-address",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "0.0.0.0"
|
||||
},
|
||||
{
|
||||
"item_name": "next-server",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "0.0.0.0"
|
||||
},
|
||||
{
|
||||
"item_name": "server-hostname",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "boot-file-name",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": ""
|
||||
},
|
||||
{
|
||||
"item_name": "client-classes",
|
||||
"item_type": "list",
|
||||
"item_optional": true,
|
||||
"item_default": [],
|
||||
"item_description": "list of reserved classes for a client",
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "client-class",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "",
|
||||
"item_description": "one of the classes reserved for a client"
|
||||
}
|
||||
} ]
|
||||
}
|
||||
},
|
||||
{
|
||||
"item_name": "reservation-mode",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "all",
|
||||
"item_description": "Specifies allowed host reservation types. Disabling unused modes may improve performance. Allowed values: disabled, off, out-of-pool, all"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
{ "item_name": "dhcp-ddns",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {"enable-updates": false},
|
||||
"item_description" : "Contains parameters pertaining DHCP-driven DDNS updates",
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "enable-updates",
|
||||
"item_type": "boolean",
|
||||
"item_optional": false,
|
||||
"item_default": false,
|
||||
"item_description" : "Enables DDNS update processing"
|
||||
},
|
||||
{
|
||||
"item_name": "server-ip",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "127.0.0.1",
|
||||
"item_description" : "IP address of kea-dhcp-ddns (IPv4 or IPv6)"
|
||||
},
|
||||
{
|
||||
"item_name": "server-port",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 53001,
|
||||
"item_description" : "port number of kea-dhcp-ddns"
|
||||
},
|
||||
{
|
||||
"item_name": "sender-ip",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "",
|
||||
"item_description" : "IP address from which to send to kea-dhcp-ddns (IPv4 or IPv6)"
|
||||
},
|
||||
{
|
||||
"item_name": "sender-port",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 0,
|
||||
"item_description" : "port number from which to send to kea-dhcp-ddns"
|
||||
},
|
||||
{
|
||||
"item_name": "max-queue-size",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 1024,
|
||||
"item_description" : "maximum number of requests allowed in the send queue"
|
||||
},
|
||||
{
|
||||
"item_name": "ncr-protocol",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "UDP",
|
||||
"item_description" : "Socket protocol to use with kea-dhcp-ddns"
|
||||
},
|
||||
{
|
||||
"item_name": "ncr-format",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "JSON",
|
||||
"item_description" : "Format of the update request packet"
|
||||
},
|
||||
{
|
||||
|
||||
"item_name": "always-include-fqdn",
|
||||
"item_type": "boolean",
|
||||
"item_optional": true,
|
||||
"item_default": false,
|
||||
"item_description": "Enable always including the FQDN option in its response"
|
||||
},
|
||||
{
|
||||
"item_name": "override-no-update",
|
||||
"item_type": "boolean",
|
||||
"item_optional": true,
|
||||
"item_default": false,
|
||||
"item_description": "Do update, even if client requested no updates with N flag"
|
||||
},
|
||||
{
|
||||
"item_name": "override-client-update",
|
||||
"item_type": "boolean",
|
||||
"item_optional": true,
|
||||
"item_default": false,
|
||||
"item_description": "Server performs an update even if client requested delegation"
|
||||
},
|
||||
{
|
||||
"item_name": "replace-client-name",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "never",
|
||||
"item_description": "Should server replace the domain-name supplied by the client"
|
||||
},
|
||||
{
|
||||
"item_name": "generated-prefix",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "myhost",
|
||||
"item_description": "Prefix to use when generating the client's name"
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "qualifying-suffix",
|
||||
"item_type": "string",
|
||||
"item_optional": true,
|
||||
"item_default": "",
|
||||
"item_description": "Fully qualified domain-name suffix if partial name provided by client"
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
],
|
||||
"commands": [
|
||||
{
|
||||
"command_name": "shutdown",
|
||||
"command_description": "Shuts down DHCPv4 server.",
|
||||
"command_args": [
|
||||
{
|
||||
"item_name": "pid",
|
||||
"item_type": "integer",
|
||||
"item_optional": true
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"command_name": "libreload",
|
||||
"command_description": "Reloads the current hooks libraries.",
|
||||
"command_args": []
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
}
|
@@ -1,7 +0,0 @@
|
||||
// Copyright (C) 2011-2015 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/.
|
||||
|
||||
#define DHCP4_SPECFILE_LOCATION "@prefix@/share/@PACKAGE@/dhcp4.spec"
|
@@ -10,7 +10,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cc/command_interpreter.h>
|
||||
#include <config/module_spec.h>
|
||||
#include <dhcp4/dhcp4_srv.h>
|
||||
#include <dhcp4/json_config_parser.h>
|
||||
#include <dhcp/option4_addrlst.h>
|
||||
@@ -132,22 +131,6 @@ const char* PARSER_CONFIGS[] = {
|
||||
"}"
|
||||
};
|
||||
|
||||
/// @brief Prepends the given name with the DHCP4 source directory
|
||||
///
|
||||
/// @param name file name of the desired file
|
||||
/// @return string containing the absolute path of the file in the DHCP source
|
||||
/// directory.
|
||||
std::string specfile(const std::string& name) {
|
||||
return (std::string(DHCP4_SRC_DIR) + "/" + name);
|
||||
}
|
||||
|
||||
/// @brief Tests that the spec file is valid.
|
||||
/// Verifies that the Kea DHCPv4 configuration specification file is valid.
|
||||
TEST(Dhcp4SpecTest, basicSpec) {
|
||||
(isc::config::moduleSpecFromFile(specfile("dhcp4.spec")));
|
||||
ASSERT_NO_THROW(isc::config::moduleSpecFromFile(specfile("dhcp4.spec")));
|
||||
}
|
||||
|
||||
class Dhcp4ParserTest : public ::testing::Test {
|
||||
protected:
|
||||
// Check that no hooks libraries are loaded. This is a pre-condition for
|
||||
|
@@ -20,11 +20,11 @@ if USE_STATIC_LINK
|
||||
AM_LDFLAGS = -static
|
||||
endif
|
||||
|
||||
CLEANFILES = spec_config.h dhcp6_messages.h dhcp6_messages.cc s-messages
|
||||
CLEANFILES = dhcp6_messages.h dhcp6_messages.cc s-messages
|
||||
|
||||
man_MANS = kea-dhcp6.8
|
||||
DISTCLEANFILES = $(man_MANS)
|
||||
EXTRA_DIST = $(man_MANS) kea-dhcp6.xml dhcp6.spec
|
||||
EXTRA_DIST = $(man_MANS) kea-dhcp6.xml
|
||||
EXTRA_DIST += dhcp6.dox dhcp6_hooks.dox dhcp4o6.dox
|
||||
EXTRA_DIST += dhcp6_parser.yy
|
||||
|
||||
@@ -43,16 +43,13 @@ $(man_MANS):
|
||||
|
||||
endif
|
||||
|
||||
spec_config.h: spec_config.h.pre
|
||||
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
|
||||
|
||||
dhcp6_messages.h dhcp6_messages.cc: s-messages
|
||||
|
||||
s-messages: dhcp6_messages.mes
|
||||
$(top_builddir)/src/lib/log/compiler/kea-msg-compiler $(top_srcdir)/src/bin/dhcp6/dhcp6_messages.mes
|
||||
touch $@
|
||||
|
||||
BUILT_SOURCES = spec_config.h dhcp6_messages.h dhcp6_messages.cc
|
||||
BUILT_SOURCES = dhcp6_messages.h dhcp6_messages.cc
|
||||
|
||||
# convenience archive
|
||||
|
||||
@@ -105,7 +102,6 @@ kea_dhcp6_LDFLAGS += $(CQL_LIBS)
|
||||
endif
|
||||
|
||||
kea_dhcp6dir = $(pkgdatadir)
|
||||
kea_dhcp6_DATA = dhcp6.spec
|
||||
|
||||
if GENERATE_PARSER
|
||||
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <cc/command_interpreter.h>
|
||||
#include <config/module_spec.h>
|
||||
#include <dhcp/libdhcp++.h>
|
||||
#include <dhcp/option6_ia.h>
|
||||
#include <dhcp/iface_mgr.h>
|
||||
@@ -209,17 +208,6 @@ const char* PARSER_CONFIGS[] = {
|
||||
"}"
|
||||
};
|
||||
|
||||
std::string specfile(const std::string& name) {
|
||||
return (std::string(DHCP6_SRC_DIR) + "/" + name);
|
||||
}
|
||||
|
||||
/// @brief Tests that the spec file is valid.
|
||||
/// Verifies that the DHCP6 configuration specification file is valid.
|
||||
TEST(Dhcp6SpecTest, basicSpec) {
|
||||
ASSERT_NO_THROW(isc::config::
|
||||
moduleSpecFromFile(specfile("dhcp6.spec")));
|
||||
}
|
||||
|
||||
class Dhcp6ParserTest : public ::testing::Test {
|
||||
protected:
|
||||
// Check that no hooks libraries are loaded. This is a pre-condition for
|
||||
|
@@ -13,9 +13,7 @@ s-messages: config_messages.mes
|
||||
BUILT_SOURCES = config_messages.h config_messages.cc
|
||||
|
||||
lib_LTLIBRARIES = libkea-cfgclient.la
|
||||
libkea_cfgclient_la_SOURCES = config_data.h config_data.cc
|
||||
libkea_cfgclient_la_SOURCES += cmds_impl.h
|
||||
libkea_cfgclient_la_SOURCES += module_spec.h module_spec.cc
|
||||
libkea_cfgclient_la_SOURCES = cmds_impl.h
|
||||
libkea_cfgclient_la_SOURCES += base_command_mgr.cc base_command_mgr.h
|
||||
libkea_cfgclient_la_SOURCES += client_connection.cc client_connection.h
|
||||
libkea_cfgclient_la_SOURCES += command_mgr.cc command_mgr.h
|
||||
@@ -53,7 +51,6 @@ libkea_cfgclient_include_HEADERS = \
|
||||
command_mgr.h \
|
||||
config_data.h \
|
||||
config_log.h \
|
||||
hooked_command_mgr.h \
|
||||
module_spec.h
|
||||
hooked_command_mgr.h
|
||||
|
||||
|
||||
|
@@ -1,494 +0,0 @@
|
||||
// Copyright (C) 2010-2017 Internet Systems Consortium.
|
||||
//
|
||||
// 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/module_spec.h>
|
||||
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <cerrno>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
// todo: add more context to thrown ModuleSpecErrors?
|
||||
|
||||
using namespace isc::data;
|
||||
using namespace isc::config;
|
||||
|
||||
namespace {
|
||||
//
|
||||
// Private functions
|
||||
//
|
||||
|
||||
void
|
||||
check_leaf_item(ConstElementPtr spec, const std::string& name,
|
||||
Element::types type, bool mandatory)
|
||||
{
|
||||
if (spec->contains(name)) {
|
||||
if (type == Element::any || spec->get(name)->getType() == type) {
|
||||
return;
|
||||
} else {
|
||||
isc_throw(ModuleSpecError,
|
||||
name + " not of type " + Element::typeToName(type));
|
||||
}
|
||||
} else if (mandatory) {
|
||||
// todo: want parent item name, and perhaps some info about location
|
||||
// in list? or just catch and throw new...
|
||||
// or make this part non-throwing and check return value...
|
||||
isc_throw(ModuleSpecError, name + " missing in " + spec->str());
|
||||
}
|
||||
}
|
||||
|
||||
void check_config_item_list(ConstElementPtr spec);
|
||||
|
||||
void
|
||||
check_config_item(ConstElementPtr spec) {
|
||||
check_leaf_item(spec, "item_name", Element::string, true);
|
||||
check_leaf_item(spec, "item_type", Element::string, true);
|
||||
check_leaf_item(spec, "item_optional", Element::boolean, true);
|
||||
check_leaf_item(spec, "item_default",
|
||||
Element::nameToType(spec->get("item_type")->stringValue()),
|
||||
!spec->get("item_optional")->boolValue()
|
||||
);
|
||||
|
||||
// if list, check the list specification
|
||||
if (Element::nameToType(spec->get("item_type")->stringValue()) == Element::list) {
|
||||
check_leaf_item(spec, "list_item_spec", Element::map, true);
|
||||
check_config_item(spec->get("list_item_spec"));
|
||||
}
|
||||
|
||||
if (spec->get("item_type")->stringValue() == "map") {
|
||||
check_leaf_item(spec, "map_item_spec", Element::list, true);
|
||||
check_config_item_list(spec->get("map_item_spec"));
|
||||
} else if (spec->get("item_type")->stringValue() == "named_set") {
|
||||
check_leaf_item(spec, "named_set_item_spec", Element::map, true);
|
||||
check_config_item(spec->get("named_set_item_spec"));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
check_config_item_list(ConstElementPtr spec) {
|
||||
if (spec->getType() != Element::list) {
|
||||
isc_throw(ModuleSpecError, "config_data is not a list of elements");
|
||||
}
|
||||
BOOST_FOREACH(ConstElementPtr item, spec->listValue()) {
|
||||
check_config_item(item);
|
||||
}
|
||||
}
|
||||
|
||||
// checks whether the given element is a valid statistics specification
|
||||
// returns false if the specification is bad
|
||||
bool
|
||||
check_format(ConstElementPtr value, ConstElementPtr format_name) {
|
||||
typedef std::map<std::string, std::string> format_types;
|
||||
format_types time_formats;
|
||||
// TODO: should be added other format types if necessary
|
||||
time_formats.insert(
|
||||
format_types::value_type("date-time", "%Y-%m-%dT%H:%M:%SZ") );
|
||||
time_formats.insert(
|
||||
format_types::value_type("date", "%Y-%m-%d") );
|
||||
time_formats.insert(
|
||||
format_types::value_type("time", "%H:%M:%S") );
|
||||
BOOST_FOREACH (const format_types::value_type& f, time_formats) {
|
||||
if (format_name->stringValue() == f.first) {
|
||||
struct tm tm;
|
||||
std::vector<char> buf(32);
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
// reverse check
|
||||
return (strptime(value->stringValue().c_str(),
|
||||
f.second.c_str(), &tm) != NULL
|
||||
&& strftime(&buf[0], buf.size(),
|
||||
f.second.c_str(), &tm) != 0
|
||||
&& strncmp(value->stringValue().c_str(),
|
||||
&buf[0], buf.size()) == 0);
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
void check_statistics_item_list(ConstElementPtr spec);
|
||||
|
||||
void
|
||||
check_statistics_item_list(ConstElementPtr spec) {
|
||||
if (spec->getType() != Element::list) {
|
||||
isc_throw(ModuleSpecError, "statistics is not a list of elements");
|
||||
}
|
||||
BOOST_FOREACH(ConstElementPtr item, spec->listValue()) {
|
||||
check_config_item(item);
|
||||
// additional checks for statistics
|
||||
check_leaf_item(item, "item_title", Element::string, true);
|
||||
check_leaf_item(item, "item_description", Element::string, true);
|
||||
check_leaf_item(item, "item_format", Element::string, false);
|
||||
// checks name of item_format and validation of item_default
|
||||
if (item->contains("item_format")
|
||||
&& item->contains("item_default")) {
|
||||
if(!check_format(item->get("item_default"),
|
||||
item->get("item_format"))) {
|
||||
isc_throw(ModuleSpecError,
|
||||
"item_default not valid type of item_format");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
check_command(ConstElementPtr spec) {
|
||||
check_leaf_item(spec, "command_name", Element::string, true);
|
||||
check_leaf_item(spec, "command_args", Element::list, true);
|
||||
check_config_item_list(spec->get("command_args"));
|
||||
}
|
||||
|
||||
void
|
||||
check_command_list(ConstElementPtr spec) {
|
||||
if (spec->getType() != Element::list) {
|
||||
isc_throw(ModuleSpecError, "commands is not a list of elements");
|
||||
}
|
||||
BOOST_FOREACH(ConstElementPtr item, spec->listValue()) {
|
||||
check_command(item);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
check_data_specification(ConstElementPtr spec) {
|
||||
check_leaf_item(spec, "module_name", Element::string, true);
|
||||
check_leaf_item(spec, "module_description", Element::string, false);
|
||||
// config_data is not mandatory; module could just define
|
||||
// commands and have no config
|
||||
if (spec->contains("config_data")) {
|
||||
check_config_item_list(spec->get("config_data"));
|
||||
}
|
||||
if (spec->contains("commands")) {
|
||||
check_command_list(spec->get("commands"));
|
||||
}
|
||||
if (spec->contains("statistics")) {
|
||||
check_statistics_item_list(spec->get("statistics"));
|
||||
}
|
||||
}
|
||||
|
||||
// checks whether the given element is a valid module specification
|
||||
// throws a ModuleSpecError if the specification is bad
|
||||
void
|
||||
check_module_specification(ConstElementPtr def) {
|
||||
try {
|
||||
check_data_specification(def);
|
||||
} catch (const TypeError& te) {
|
||||
isc_throw(ModuleSpecError, te.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace isc {
|
||||
namespace config {
|
||||
//
|
||||
// Public functions
|
||||
//
|
||||
|
||||
// throw ModuleSpecError
|
||||
ModuleSpec::ModuleSpec(ConstElementPtr module_spec_element,
|
||||
const bool check)
|
||||
|
||||
{
|
||||
module_specification = module_spec_element;
|
||||
if (check) {
|
||||
check_module_specification(module_specification);
|
||||
}
|
||||
}
|
||||
|
||||
ConstElementPtr
|
||||
ModuleSpec::getCommandsSpec() const {
|
||||
if (module_specification->contains("commands")) {
|
||||
return (module_specification->get("commands"));
|
||||
} else {
|
||||
return (ElementPtr());
|
||||
}
|
||||
}
|
||||
|
||||
ConstElementPtr
|
||||
ModuleSpec::getConfigSpec() const {
|
||||
if (module_specification->contains("config_data")) {
|
||||
return (module_specification->get("config_data"));
|
||||
} else {
|
||||
return (ElementPtr());
|
||||
}
|
||||
}
|
||||
|
||||
ConstElementPtr
|
||||
ModuleSpec::getStatisticsSpec() const {
|
||||
if (module_specification->contains("statistics")) {
|
||||
return (module_specification->get("statistics"));
|
||||
} else {
|
||||
return (ElementPtr());
|
||||
}
|
||||
}
|
||||
|
||||
const std::string
|
||||
ModuleSpec::getModuleName() const {
|
||||
return (module_specification->get("module_name")->stringValue());
|
||||
}
|
||||
|
||||
const std::string
|
||||
ModuleSpec::getModuleDescription() const {
|
||||
if (module_specification->contains("module_description")) {
|
||||
return (module_specification->get("module_description")->stringValue());
|
||||
} else {
|
||||
return (std::string(""));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleSpec::validateConfig(ConstElementPtr data, const bool full) const {
|
||||
ConstElementPtr spec = module_specification->find("config_data");
|
||||
return (validateSpecList(spec, data, full, ElementPtr()));
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleSpec::validateStatistics(ConstElementPtr data, const bool full) const {
|
||||
ConstElementPtr spec = module_specification->find("statistics");
|
||||
return (validateSpecList(spec, data, full, ElementPtr()));
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleSpec::validateCommand(const std::string& command,
|
||||
ConstElementPtr args,
|
||||
ElementPtr errors) const
|
||||
{
|
||||
if (args->getType() != Element::map) {
|
||||
errors->add(Element::create("args for command " +
|
||||
command + " is not a map"));
|
||||
return (false);
|
||||
}
|
||||
|
||||
ConstElementPtr commands_spec = module_specification->find("commands");
|
||||
if (!commands_spec) {
|
||||
// there are no commands according to the spec.
|
||||
errors->add(Element::create("The given module has no commands"));
|
||||
return (false);
|
||||
}
|
||||
|
||||
BOOST_FOREACH(ConstElementPtr cur_command, commands_spec->listValue()) {
|
||||
if (cur_command->get("command_name")->stringValue() == command) {
|
||||
return (validateSpecList(cur_command->get("command_args"),
|
||||
args, true, errors));
|
||||
}
|
||||
}
|
||||
|
||||
// this command is unknown
|
||||
errors->add(Element::create("Unknown command " + command));
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleSpec::validateConfig(ConstElementPtr data, const bool full,
|
||||
ElementPtr errors) const
|
||||
{
|
||||
ConstElementPtr spec = module_specification->find("config_data");
|
||||
return (validateSpecList(spec, data, full, errors));
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleSpec::validateStatistics(ConstElementPtr data, const bool full,
|
||||
ElementPtr errors) const
|
||||
{
|
||||
ConstElementPtr spec = module_specification->find("statistics");
|
||||
return (validateSpecList(spec, data, full, errors));
|
||||
}
|
||||
|
||||
// throw JSONError and ModuleSpecError
|
||||
ModuleSpec
|
||||
moduleSpecFromFile(const std::string& file_name, const bool check)
|
||||
{
|
||||
std::ifstream file;
|
||||
|
||||
// zero out the errno to be safe
|
||||
errno = 0;
|
||||
|
||||
file.open(file_name.c_str());
|
||||
if (!file) {
|
||||
std::stringstream errs;
|
||||
errs << "Error opening " << file_name << ": " << strerror(errno);
|
||||
isc_throw(ModuleSpecError, errs.str());
|
||||
}
|
||||
|
||||
ConstElementPtr module_spec_element = Element::fromJSON(file, file_name);
|
||||
if (module_spec_element->contains("module_spec")) {
|
||||
return (ModuleSpec(module_spec_element->get("module_spec"), check));
|
||||
} else {
|
||||
isc_throw(ModuleSpecError, "No module_spec in specification");
|
||||
}
|
||||
}
|
||||
|
||||
// throw JSONError and ModuleSpecError
|
||||
ModuleSpec
|
||||
moduleSpecFromFile(std::ifstream& in, const bool check)
|
||||
{
|
||||
ConstElementPtr module_spec_element = Element::fromJSON(in);
|
||||
if (module_spec_element->contains("module_spec")) {
|
||||
return (ModuleSpec(module_spec_element->get("module_spec"), check));
|
||||
} else {
|
||||
isc_throw(ModuleSpecError, "No module_spec in specification");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
//
|
||||
// private functions
|
||||
//
|
||||
|
||||
//
|
||||
// helper functions for validation
|
||||
//
|
||||
bool
|
||||
check_type(ConstElementPtr spec, ConstElementPtr element) {
|
||||
std::string cur_item_type;
|
||||
cur_item_type = spec->get("item_type")->stringValue();
|
||||
if (cur_item_type == "any") {
|
||||
return (true);
|
||||
}
|
||||
switch (element->getType()) {
|
||||
case Element::integer:
|
||||
return (cur_item_type == "integer");
|
||||
break;
|
||||
case Element::real:
|
||||
return (cur_item_type == "real");
|
||||
break;
|
||||
case Element::boolean:
|
||||
return (cur_item_type == "boolean");
|
||||
break;
|
||||
case Element::string:
|
||||
return (cur_item_type == "string");
|
||||
break;
|
||||
case Element::list:
|
||||
return (cur_item_type == "list");
|
||||
break;
|
||||
case Element::map:
|
||||
return (cur_item_type == "map" ||
|
||||
cur_item_type == "named_set");
|
||||
break;
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleSpec::validateItem(ConstElementPtr spec, ConstElementPtr data,
|
||||
const bool full, ElementPtr errors) const
|
||||
{
|
||||
if (!check_type(spec, data)) {
|
||||
// we should do some proper error feedback here
|
||||
// std::cout << "type mismatch; not " << spec->get("item_type") << ": " << data << std::endl;
|
||||
// std::cout << spec << std::endl;
|
||||
if (errors) {
|
||||
errors->add(Element::create("Type mismatch"));
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
if (data->getType() == Element::list) {
|
||||
ConstElementPtr list_spec = spec->get("list_item_spec");
|
||||
BOOST_FOREACH(ConstElementPtr list_el, data->listValue()) {
|
||||
if (!check_type(list_spec, list_el)) {
|
||||
if (errors) {
|
||||
errors->add(Element::create("Type mismatch"));
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
if (list_spec->get("item_type")->stringValue() == "map") {
|
||||
if (!validateItem(list_spec, list_el, full, errors)) {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (data->getType() == Element::map) {
|
||||
// either a normal 'map' or a 'named set' (determined by which
|
||||
// subspecification it has)
|
||||
if (spec->contains("map_item_spec")) {
|
||||
if (!validateSpecList(spec->get("map_item_spec"), data, full, errors)) {
|
||||
return (false);
|
||||
}
|
||||
} else {
|
||||
typedef std::pair<std::string, ConstElementPtr> maptype;
|
||||
|
||||
BOOST_FOREACH(maptype m, data->mapValue()) {
|
||||
if (!validateItem(spec->get("named_set_item_spec"), m.second, full, errors)) {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (spec->contains("item_format")) {
|
||||
if (!check_format(data, spec->get("item_format"))) {
|
||||
if (errors) {
|
||||
errors->add(Element::create("Format mismatch"));
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
// spec is a map with item_name etc, data is a map
|
||||
bool
|
||||
ModuleSpec::validateSpec(ConstElementPtr spec, ConstElementPtr data,
|
||||
const bool full, ElementPtr errors) const
|
||||
{
|
||||
std::string item_name = spec->get("item_name")->stringValue();
|
||||
bool optional = spec->get("item_optional")->boolValue();
|
||||
ConstElementPtr data_el;
|
||||
data_el = data->get(item_name);
|
||||
|
||||
if (data_el) {
|
||||
if (!validateItem(spec, data_el, full, errors)) {
|
||||
return (false);
|
||||
}
|
||||
} else {
|
||||
if (!optional && full) {
|
||||
if (errors) {
|
||||
errors->add(Element::create("Non-optional value missing"));
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
// spec is a list of maps, data is a map
|
||||
bool
|
||||
ModuleSpec::validateSpecList(ConstElementPtr spec, ConstElementPtr data,
|
||||
const bool full, ElementPtr errors) const
|
||||
{
|
||||
bool validated = true;
|
||||
BOOST_FOREACH(ConstElementPtr cur_spec_el, spec->listValue()) {
|
||||
if (!validateSpec(cur_spec_el, data, full, errors)) {
|
||||
validated = false;
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::pair<std::string, ConstElementPtr> maptype;
|
||||
|
||||
BOOST_FOREACH(maptype m, data->mapValue()) {
|
||||
// Ignore 'version' as a config element
|
||||
if (m.first.compare("version") != 0) {
|
||||
bool found = false;
|
||||
BOOST_FOREACH(ConstElementPtr cur_spec_el, spec->listValue()) {
|
||||
if (cur_spec_el->get("item_name")->stringValue().compare(m.first) == 0) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
validated = false;
|
||||
if (errors) {
|
||||
errors->add(Element::create("Unknown item " + m.first));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (validated);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@@ -1,199 +0,0 @@
|
||||
// Copyright (C) 2010-2017 Internet Systems Consortium.
|
||||
//
|
||||
// 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 MODULE_SPEC_H
|
||||
#define MODULE_SPEC_H 1
|
||||
|
||||
#include <cc/data.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace isc { namespace config {
|
||||
|
||||
///
|
||||
/// A standard ModuleSpec exception that is thrown when a
|
||||
/// specification is not in the correct form.
|
||||
///
|
||||
class ModuleSpecError : public isc::Exception {
|
||||
public:
|
||||
ModuleSpecError(const char* file, size_t line,
|
||||
const char* what = "Module specification is invalid") :
|
||||
isc::Exception(file, line, what) {}
|
||||
};
|
||||
|
||||
///
|
||||
/// The \c ModuleSpec class holds a data specification.
|
||||
/// Each module should have a .spec file containing the specification
|
||||
/// for configuration and commands for that module.
|
||||
/// This class holds that specification, and provides a function to
|
||||
/// validate a set of data, to see whether it conforms to the given
|
||||
/// specification
|
||||
///
|
||||
/// The form of the specification is described in doc/ (TODO)
|
||||
///
|
||||
class ModuleSpec {
|
||||
public:
|
||||
ModuleSpec() {};
|
||||
/// Create a \c ModuleSpec instance with the given data as
|
||||
/// the specification
|
||||
/// \param e The Element containing the data specification
|
||||
/// \param check If false, the module specification in the file
|
||||
/// is not checked to be of the correct form.
|
||||
/// \throw ModuleSpecError
|
||||
explicit ModuleSpec(isc::data::ConstElementPtr e,
|
||||
const bool check = true);
|
||||
|
||||
/// Returns the commands part of the specification as an
|
||||
/// ElementPtr, returns an empty ElementPtr if there is none
|
||||
/// \return ElementPtr Shared pointer to the commands
|
||||
/// part of the specification
|
||||
isc::data::ConstElementPtr getCommandsSpec() const;
|
||||
|
||||
/// Returns the configuration part of the specification as an
|
||||
/// ElementPtr
|
||||
/// \return ElementPtr Shared pointer to the configuration
|
||||
/// part of the specification
|
||||
isc::data::ConstElementPtr getConfigSpec() const;
|
||||
|
||||
/// Returns the statistics part of the specification as an
|
||||
/// ElementPtr
|
||||
/// \return ElementPtr Shared pointer to the statistics
|
||||
/// part of the specification
|
||||
isc::data::ConstElementPtr getStatisticsSpec() const;
|
||||
|
||||
/// Returns the full module specification as an ElementPtr
|
||||
/// \return ElementPtr Shared pointer to the specification
|
||||
isc::data::ConstElementPtr getFullSpec() const {
|
||||
return module_specification;
|
||||
}
|
||||
|
||||
/// Returns the module name as specified by the specification
|
||||
const std::string getModuleName() const;
|
||||
|
||||
/// Returns the module description as specified by the specification
|
||||
/// returns an empty string if there is no description
|
||||
const std::string getModuleDescription() const;
|
||||
|
||||
// returns true if the given element conforms to this data
|
||||
// configuration specification
|
||||
/// Validates the given configuration data for this specification.
|
||||
/// \param data The base \c Element of the data to check
|
||||
/// \param full If true, all non-optional configuration parameters
|
||||
/// must be specified.
|
||||
/// \return true if the data conforms to the specification,
|
||||
/// false otherwise.
|
||||
bool validateConfig(isc::data::ConstElementPtr data,
|
||||
const bool full = false) const;
|
||||
|
||||
// returns true if the given element conforms to this data
|
||||
// statistics specification
|
||||
/// Validates the given statistics data for this specification.
|
||||
/// \param data The base \c Element of the data to check
|
||||
/// \param full If true, all non-optional statistics parameters
|
||||
/// must be specified.
|
||||
/// \return true if the data conforms to the specification,
|
||||
/// false otherwise.
|
||||
bool validateStatistics(isc::data::ConstElementPtr data,
|
||||
const bool full = false) const;
|
||||
|
||||
/// Validates the arguments for the given command
|
||||
///
|
||||
/// This checks the command and argument against the
|
||||
/// specification in the module's .spec file.
|
||||
///
|
||||
/// A command is considered valid if:
|
||||
/// - it is known (the 'command' string must have an entry in
|
||||
/// the specification)
|
||||
/// - the args is a MapElement
|
||||
/// - args contains all mandatory arguments
|
||||
/// - args does not contain unknown arguments
|
||||
/// - all arguments in args match their specification
|
||||
/// If all of these are true, this function returns \c true
|
||||
/// If not, this method returns \c false
|
||||
///
|
||||
/// Example usage:
|
||||
/// \code
|
||||
/// ElementPtr errors = Element::createList();
|
||||
/// if (module_specification_.validateCommand(cmd_str,
|
||||
/// arg,
|
||||
/// errors)) {
|
||||
/// std::cout << "Command is valid" << std::endl;
|
||||
/// } else {
|
||||
/// std::cout << "Command is invalid: " << std::endl;
|
||||
/// BOOST_FOREACH(ConstElementPtr error,
|
||||
/// errors->listValue()) {
|
||||
/// std::cout << error->stringValue() << std::endl;
|
||||
/// }
|
||||
/// }
|
||||
/// \endcode
|
||||
///
|
||||
/// \param command The command to validate the arguments for
|
||||
/// \param args A dict containing the command parameters
|
||||
/// \param errors An ElementPtr pointing to a ListElement. Any
|
||||
/// errors that are found are added as
|
||||
/// StringElements to this list
|
||||
/// \return true if the command is known and the parameters are correct
|
||||
/// false otherwise
|
||||
bool validateCommand(const std::string& command,
|
||||
isc::data::ConstElementPtr args,
|
||||
isc::data::ElementPtr errors) const;
|
||||
|
||||
|
||||
/// errors must be of type ListElement
|
||||
bool validateConfig(isc::data::ConstElementPtr data, const bool full,
|
||||
isc::data::ElementPtr errors) const;
|
||||
|
||||
/// errors must be of type ListElement
|
||||
bool validateStatistics(isc::data::ConstElementPtr data, const bool full,
|
||||
isc::data::ElementPtr errors) const;
|
||||
|
||||
private:
|
||||
bool validateItem(isc::data::ConstElementPtr spec,
|
||||
isc::data::ConstElementPtr data,
|
||||
const bool full,
|
||||
isc::data::ElementPtr errors) const;
|
||||
bool validateSpec(isc::data::ConstElementPtr spec,
|
||||
isc::data::ConstElementPtr data,
|
||||
const bool full,
|
||||
isc::data::ElementPtr errors) const;
|
||||
bool validateSpecList(isc::data::ConstElementPtr spec,
|
||||
isc::data::ConstElementPtr data,
|
||||
const bool full,
|
||||
isc::data::ElementPtr errors) const;
|
||||
|
||||
isc::data::ConstElementPtr module_specification;
|
||||
};
|
||||
|
||||
/// Creates a \c ModuleSpec instance from the contents
|
||||
/// of the file given by file_name.
|
||||
/// If check is true, and the module specification is not of
|
||||
/// the correct form, a ModuleSpecError is thrown. If the file
|
||||
/// could not be parse, a ParseError is thrown.
|
||||
/// \param file_name The file to be opened and parsed
|
||||
/// \param check If true, the module specification in the file
|
||||
/// is checked to be of the correct form
|
||||
/// \throw isc::data::JSONError and ModuleSpecError
|
||||
ModuleSpec
|
||||
moduleSpecFromFile(const std::string& file_name, const bool check = true);
|
||||
|
||||
/// Creates a \c ModuleSpec instance from the given input
|
||||
/// stream that contains the contents of a .spec file.
|
||||
/// If check is true, and the module specification is not of
|
||||
/// the correct form, a ModuleSpecError is thrown. If the
|
||||
/// file could not be parsed, a ParseError is thrown.
|
||||
/// \param in The std::istream containing the .spec file data
|
||||
/// \param check If true, the module specification is checked
|
||||
/// to be of the correct form
|
||||
/// \throw isc::data::JSONError and ModuleSpecError
|
||||
ModuleSpec
|
||||
moduleSpecFromFile(std::ifstream& in, const bool check = true);
|
||||
} }
|
||||
|
||||
#endif // _DATA_DEF_H
|
||||
|
||||
// Local Variables:
|
||||
// mode: c++
|
||||
// End:
|
@@ -18,9 +18,8 @@ TESTS_ENVIRONMENT = \
|
||||
TESTS =
|
||||
if HAVE_GTEST
|
||||
TESTS += run_unittests
|
||||
run_unittests_SOURCES = module_spec_unittests.cc
|
||||
run_unittests_SOURCES += client_connection_unittests.cc
|
||||
run_unittests_SOURCES += config_data_unittests.cc run_unittests.cc
|
||||
run_unittests_SOURCES = client_connection_unittests.cc
|
||||
run_unittests_SOURCES += run_unittests.cc
|
||||
run_unittests_SOURCES += command_mgr_unittests.cc
|
||||
|
||||
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
|
||||
|
@@ -1,147 +0,0 @@
|
||||
|
||||
// Copyright (C) 2009-2015 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 <gtest/gtest.h>
|
||||
|
||||
#include <config/tests/data_def_unittests_config.h>
|
||||
#include <config/config_data.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace isc::data;
|
||||
using namespace isc::config;
|
||||
|
||||
ConfigData
|
||||
setupSpec2() {
|
||||
ModuleSpec spec2 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec22.spec");
|
||||
return (ConfigData(spec2));
|
||||
}
|
||||
|
||||
TEST(ConfigData, Creation) {
|
||||
ConfigData cd = setupSpec2();
|
||||
EXPECT_TRUE(true);
|
||||
}
|
||||
|
||||
TEST(ConfigData, getValue) {
|
||||
ModuleSpec spec22 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec22.spec");
|
||||
ConfigData cd = ConfigData(spec22);
|
||||
//std::cout << "[XX] SPEC2: " << cd.getModuleSpec().getFullSpec() << std::endl;
|
||||
bool is_default;
|
||||
//ElementPtr value = cd.getValue(is_default, "item1");
|
||||
EXPECT_EQ(9, cd.getValue("value1")->intValue());
|
||||
EXPECT_EQ(9, cd.getValue(is_default, "value1")->intValue());
|
||||
EXPECT_TRUE(is_default);
|
||||
EXPECT_EQ(9.9, cd.getValue("value2")->doubleValue());
|
||||
EXPECT_EQ(9.9, cd.getValue(is_default, "value2")->doubleValue());
|
||||
EXPECT_TRUE(is_default);
|
||||
EXPECT_FALSE(cd.getValue("value3")->boolValue());
|
||||
EXPECT_FALSE(cd.getValue(is_default, "value3")->boolValue());
|
||||
EXPECT_TRUE(is_default);
|
||||
EXPECT_EQ("default_string", cd.getValue("value4")->stringValue());
|
||||
EXPECT_EQ("default_string", cd.getValue(is_default, "value4")->stringValue());
|
||||
EXPECT_TRUE(is_default);
|
||||
EXPECT_EQ("a", cd.getValue("value5")->get(0)->stringValue());
|
||||
EXPECT_EQ("a", cd.getValue(is_default, "value5")->get(0)->stringValue());
|
||||
EXPECT_TRUE(is_default);
|
||||
EXPECT_EQ("b", cd.getValue("value5")->get(1)->stringValue());
|
||||
EXPECT_EQ("b", cd.getValue(is_default, "value5")->get(1)->stringValue());
|
||||
EXPECT_EQ("b", cd.getValue(is_default, "value5/")->get(1)->stringValue());
|
||||
EXPECT_TRUE(is_default);
|
||||
EXPECT_EQ("{ }", cd.getValue("value6")->str());
|
||||
EXPECT_EQ("{ }", cd.getValue(is_default, "value6")->str());
|
||||
EXPECT_EQ("{ }", cd.getValue(is_default, "value6/")->str());
|
||||
EXPECT_TRUE(is_default);
|
||||
EXPECT_EQ("[ ]", cd.getValue("value8")->str());
|
||||
EXPECT_EQ("[ ]", cd.getDefaultValue("value8")->str());
|
||||
EXPECT_EQ("empty", cd.getValue("value8/a")->stringValue());
|
||||
|
||||
EXPECT_THROW(cd.getValue("")->str(), DataNotFoundError);
|
||||
EXPECT_THROW(cd.getValue("/")->str(), DataNotFoundError);
|
||||
EXPECT_THROW(cd.getValue("no_such_item")->str(), DataNotFoundError);
|
||||
EXPECT_THROW(cd.getValue("value6/a")->str(), DataNotFoundError);
|
||||
EXPECT_THROW(cd.getValue("value6/no_such_item")->str(), DataNotFoundError);
|
||||
EXPECT_THROW(cd.getValue("value8/b")->str(), DataNotFoundError);
|
||||
|
||||
ModuleSpec spec1 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec1.spec");
|
||||
ConfigData cd1 = ConfigData(spec1);
|
||||
EXPECT_THROW(cd1.getValue("anything")->str(), DataNotFoundError);
|
||||
}
|
||||
|
||||
TEST(ConfigData, getDefaultValue) {
|
||||
ModuleSpec spec31 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec31.spec");
|
||||
ConfigData cd = ConfigData(spec31);
|
||||
EXPECT_EQ("[ ]", cd.getDefaultValue("first_list_items")->str());
|
||||
EXPECT_EQ("\"foo\"", cd.getDefaultValue("first_list_items/foo")->str());
|
||||
EXPECT_EQ("{ }", cd.getDefaultValue("first_list_items/second_list_items/map_element")->str());
|
||||
EXPECT_EQ("[ ]", cd.getDefaultValue("first_list_items/second_list_items/map_element/list1")->str());
|
||||
EXPECT_EQ("1", cd.getDefaultValue("first_list_items/second_list_items/map_element/list1/number")->str());
|
||||
|
||||
EXPECT_THROW(cd.getDefaultValue("doesnotexist")->str(), DataNotFoundError);
|
||||
EXPECT_THROW(cd.getDefaultValue("first_list_items/second_list_items/map_element/list1/doesnotexist")->str(), DataNotFoundError);
|
||||
}
|
||||
|
||||
|
||||
TEST(ConfigData, setLocalConfig) {
|
||||
ModuleSpec spec2 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec2.spec");
|
||||
ConfigData cd = ConfigData(spec2);
|
||||
bool is_default;
|
||||
|
||||
ElementPtr my_config = Element::fromJSON("{ \"item1\": 2 }");
|
||||
ElementPtr my_config2 = Element::fromJSON("{ \"item6\": { \"value1\": \"a\" } }");
|
||||
|
||||
EXPECT_EQ("{ }", cd.getValue("item6")->str());
|
||||
|
||||
cd.setLocalConfig(my_config);
|
||||
EXPECT_EQ(2, cd.getValue(is_default, "item1")->intValue());
|
||||
EXPECT_FALSE(is_default);
|
||||
EXPECT_EQ("{ }", cd.getValue("item6")->str());
|
||||
EXPECT_EQ(1.1, cd.getValue(is_default, "item2")->doubleValue());
|
||||
EXPECT_TRUE(is_default);
|
||||
|
||||
cd.setLocalConfig(my_config2);
|
||||
EXPECT_EQ("{ \"value1\": \"a\" }", cd.getValue("item6")->str());
|
||||
}
|
||||
|
||||
TEST(ConfigData, getLocalConfig) {
|
||||
ModuleSpec spec2 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec2.spec");
|
||||
ConfigData cd = ConfigData(spec2);
|
||||
EXPECT_EQ("{ }", cd.getLocalConfig()->str());
|
||||
|
||||
ElementPtr my_config = Element::fromJSON("{ \"item1\": 2 }");
|
||||
cd.setLocalConfig(my_config);
|
||||
EXPECT_EQ("{ \"item1\": 2 }", cd.getLocalConfig()->str());
|
||||
|
||||
ElementPtr my_config2 = Element::fromJSON("{ \"item6\": { \"value1\": \"a\" } }");
|
||||
cd.setLocalConfig(my_config2);
|
||||
EXPECT_EQ("{ \"item6\": { \"value1\": \"a\" } }", cd.getLocalConfig()->str());
|
||||
}
|
||||
|
||||
TEST(ConfigData, getItemList) {
|
||||
ModuleSpec spec2 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec2.spec");
|
||||
ConfigData cd = ConfigData(spec2);
|
||||
|
||||
EXPECT_EQ("[ \"item1\", \"item2\", \"item3\", \"item4\", \"item5\", \"item6\" ]", cd.getItemList()->str());
|
||||
EXPECT_EQ("[ \"item1\", \"item2\", \"item3\", \"item4\", \"item5\", \"item6/value1\", \"item6/value2\" ]", cd.getItemList("", true)->str());
|
||||
EXPECT_EQ("[ \"item6/value1\", \"item6/value2\" ]", cd.getItemList("item6")->str());
|
||||
}
|
||||
|
||||
TEST(ConfigData, getFullConfig) {
|
||||
ModuleSpec spec2 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec2.spec");
|
||||
ConfigData cd = ConfigData(spec2);
|
||||
|
||||
EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { } }", cd.getFullConfig()->str());
|
||||
ElementPtr my_config = Element::fromJSON("{ \"item1\": 2 }");
|
||||
cd.setLocalConfig(my_config);
|
||||
EXPECT_EQ("{ \"item1\": 2, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { } }", cd.getFullConfig()->str());
|
||||
ElementPtr my_config2 = Element::fromJSON("{ \"item6\": { \"value1\": \"a\" } }");
|
||||
cd.setLocalConfig(my_config2);
|
||||
EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { \"value1\": \"a\" } }", cd.getFullConfig()->str());
|
||||
ElementPtr my_config3 = Element::fromJSON("{ \"item6\": { \"value2\": 123 } }");
|
||||
cd.setLocalConfig(my_config3);
|
||||
EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { \"value2\": 123 } }", cd.getFullConfig()->str());
|
||||
}
|
||||
|
@@ -1,382 +0,0 @@
|
||||
// Copyright (C) 2009-2015 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 <gtest/gtest.h>
|
||||
|
||||
#include <config/module_spec.h>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <config/tests/data_def_unittests_config.h>
|
||||
|
||||
using namespace isc::data;
|
||||
using namespace isc::config;
|
||||
|
||||
std::string specfile(const std::string& name) {
|
||||
return (std::string(TEST_DATA_PATH) + "/" + name);
|
||||
}
|
||||
|
||||
void
|
||||
moduleSpecError(const std::string& file,
|
||||
const std::string& error1,
|
||||
const std::string& error2 = "",
|
||||
const std::string& error3 = "")
|
||||
{
|
||||
EXPECT_THROW(moduleSpecFromFile(specfile(file)), ModuleSpecError);
|
||||
try {
|
||||
ModuleSpec dd = moduleSpecFromFile(specfile(file));
|
||||
} catch (const ModuleSpecError& dde) {
|
||||
std::string ddew = dde.what();
|
||||
EXPECT_EQ(error1 + error2 + error3, ddew);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ModuleSpec, ReadingSpecfiles) {
|
||||
// Tests whether we can open specfiles and if we get the
|
||||
// right parse errors
|
||||
ModuleSpec dd = moduleSpecFromFile(specfile("spec1.spec"));
|
||||
EXPECT_EQ(dd.getFullSpec()->get("module_name")
|
||||
->stringValue(), "Spec1");
|
||||
dd = moduleSpecFromFile(specfile("spec2.spec"));
|
||||
EXPECT_EQ(dd.getFullSpec()->get("config_data")->size(), 6);
|
||||
moduleSpecError("doesnotexist",
|
||||
"Error opening ",
|
||||
specfile("doesnotexist"),
|
||||
": No such file or directory");
|
||||
|
||||
dd = moduleSpecFromFile(specfile("spec2.spec"));
|
||||
EXPECT_EQ("[ { \"command_args\": [ { \"item_default\": \"\", \"item_name\": \"message\", \"item_optional\": false, \"item_type\": \"string\" } ], \"command_description\": \"Print the given message to stdout\", \"command_name\": \"print_message\" }, { \"command_args\": [ ], \"command_description\": \"Shut down Kea\", \"command_name\": \"shutdown\" } ]", dd.getCommandsSpec()->str());
|
||||
EXPECT_EQ("[ { \"item_default\": \"1970-01-01T00:00:00Z\", \"item_description\": \"A dummy date time\", \"item_format\": \"date-time\", \"item_name\": \"dummy_time\", \"item_optional\": false, \"item_title\": \"Dummy Time\", \"item_type\": \"string\" } ]", dd.getStatisticsSpec()->str());
|
||||
EXPECT_EQ("Spec2", dd.getModuleName());
|
||||
EXPECT_EQ("", dd.getModuleDescription());
|
||||
|
||||
dd = moduleSpecFromFile(specfile("spec25.spec"));
|
||||
EXPECT_EQ("Spec25", dd.getModuleName());
|
||||
EXPECT_EQ("Just an empty module", dd.getModuleDescription());
|
||||
EXPECT_THROW(moduleSpecFromFile(specfile("spec26.spec")), ModuleSpecError);
|
||||
EXPECT_THROW(moduleSpecFromFile(specfile("spec34.spec")), ModuleSpecError);
|
||||
EXPECT_THROW(moduleSpecFromFile(specfile("spec35.spec")), ModuleSpecError);
|
||||
EXPECT_THROW(moduleSpecFromFile(specfile("spec36.spec")), ModuleSpecError);
|
||||
EXPECT_THROW(moduleSpecFromFile(specfile("spec37.spec")), ModuleSpecError);
|
||||
EXPECT_THROW(moduleSpecFromFile(specfile("spec38.spec")), ModuleSpecError);
|
||||
|
||||
std::ifstream file;
|
||||
file.open(specfile("spec1.spec").c_str());
|
||||
dd = moduleSpecFromFile(file);
|
||||
EXPECT_EQ(dd.getFullSpec()->get("module_name")
|
||||
->stringValue(), "Spec1");
|
||||
EXPECT_TRUE(isNull(dd.getCommandsSpec()));
|
||||
EXPECT_TRUE(isNull(dd.getStatisticsSpec()));
|
||||
|
||||
std::ifstream file2;
|
||||
file2.open(specfile("spec8.spec").c_str());
|
||||
EXPECT_THROW(moduleSpecFromFile(file2), ModuleSpecError);
|
||||
|
||||
}
|
||||
|
||||
TEST(ModuleSpec, SpecfileItems) {
|
||||
moduleSpecError("spec3.spec",
|
||||
"item_name missing in { \"item_default\": 1, \"item_optional\": false, \"item_type\": \"integer\" }");
|
||||
moduleSpecError("spec4.spec",
|
||||
"item_type missing in { \"item_default\": 1, \"item_name\": \"item1\", \"item_optional\": false }");
|
||||
moduleSpecError("spec5.spec",
|
||||
"item_optional missing in { \"item_default\": 1, \"item_name\": \"item1\", \"item_type\": \"integer\" }");
|
||||
moduleSpecError("spec6.spec",
|
||||
"item_default missing in { \"item_name\": \"item1\", \"item_optional\": false, \"item_type\": \"integer\" }");
|
||||
moduleSpecError("spec9.spec",
|
||||
"item_default not of type integer");
|
||||
moduleSpecError("spec10.spec",
|
||||
"item_default not of type real");
|
||||
moduleSpecError("spec11.spec",
|
||||
"item_default not of type boolean");
|
||||
moduleSpecError("spec12.spec",
|
||||
"item_default not of type string");
|
||||
moduleSpecError("spec13.spec",
|
||||
"item_default not of type list");
|
||||
moduleSpecError("spec14.spec",
|
||||
"item_default not of type map");
|
||||
moduleSpecError("spec15.spec",
|
||||
"badname is not a valid type name");
|
||||
EXPECT_NO_THROW(moduleSpecFromFile(specfile("spec40.spec")));
|
||||
}
|
||||
|
||||
TEST(ModuleSpec, SpecfileConfigData) {
|
||||
moduleSpecError("spec7.spec",
|
||||
"module_name missing in { }");
|
||||
moduleSpecError("spec8.spec",
|
||||
"No module_spec in specification");
|
||||
moduleSpecError("spec16.spec",
|
||||
"config_data is not a list of elements");
|
||||
moduleSpecError("spec21.spec",
|
||||
"commands is not a list of elements");
|
||||
}
|
||||
|
||||
TEST(ModuleSpec, SpecfileStatistics) {
|
||||
moduleSpecError("spec36.spec", "item_default not valid type of item_format");
|
||||
moduleSpecError("spec37.spec", "statistics is not a list of elements");
|
||||
moduleSpecError("spec38.spec", "item_default not valid type of item_format");
|
||||
}
|
||||
|
||||
TEST(ModuleSpec, SpecfileCommands) {
|
||||
moduleSpecError("spec17.spec",
|
||||
"command_name missing in { \"command_args\": [ { \"item_default\": \"\", \"item_name\": \"message\", \"item_optional\": false, \"item_type\": \"string\" } ], \"command_description\": \"Print the given message to stdout\" }");
|
||||
moduleSpecError("spec18.spec",
|
||||
"command_args missing in { \"command_description\": \"Print the given message to stdout\", \"command_name\": \"print_message\" }");
|
||||
moduleSpecError("spec19.spec",
|
||||
"command_args not of type list");
|
||||
moduleSpecError("spec20.spec",
|
||||
"somethingbad is not a valid type name");
|
||||
}
|
||||
|
||||
bool
|
||||
dataTest(const ModuleSpec& dd, const std::string& data_file_name) {
|
||||
std::ifstream data_file;
|
||||
|
||||
data_file.open(specfile(data_file_name).c_str());
|
||||
ConstElementPtr data = Element::fromJSON(data_file, data_file_name);
|
||||
data_file.close();
|
||||
|
||||
return (dd.validateConfig(data));
|
||||
}
|
||||
|
||||
bool
|
||||
statisticsTest(const ModuleSpec& dd, const std::string& data_file_name) {
|
||||
std::ifstream data_file;
|
||||
|
||||
data_file.open(specfile(data_file_name).c_str());
|
||||
ConstElementPtr data = Element::fromJSON(data_file, data_file_name);
|
||||
data_file.close();
|
||||
|
||||
return (dd.validateStatistics(data));
|
||||
}
|
||||
|
||||
bool
|
||||
dataTestWithErrors(const ModuleSpec& dd, const std::string& data_file_name,
|
||||
ElementPtr errors)
|
||||
{
|
||||
std::ifstream data_file;
|
||||
|
||||
data_file.open(specfile(data_file_name).c_str());
|
||||
ConstElementPtr data = Element::fromJSON(data_file, data_file_name);
|
||||
data_file.close();
|
||||
|
||||
return (dd.validateConfig(data, true, errors));
|
||||
}
|
||||
|
||||
bool
|
||||
statisticsTestWithErrors(const ModuleSpec& dd, const std::string& data_file_name,
|
||||
ElementPtr errors)
|
||||
{
|
||||
std::ifstream data_file;
|
||||
|
||||
data_file.open(specfile(data_file_name).c_str());
|
||||
ConstElementPtr data = Element::fromJSON(data_file, data_file_name);
|
||||
data_file.close();
|
||||
|
||||
return (dd.validateStatistics(data, true, errors));
|
||||
}
|
||||
|
||||
TEST(ModuleSpec, DataValidation) {
|
||||
ModuleSpec dd = moduleSpecFromFile(specfile("spec22.spec"));
|
||||
|
||||
EXPECT_TRUE(dataTest(dd, "data22_1.data"));
|
||||
EXPECT_FALSE(dataTest(dd, "data22_2.data"));
|
||||
EXPECT_FALSE(dataTest(dd, "data22_3.data"));
|
||||
EXPECT_FALSE(dataTest(dd, "data22_4.data"));
|
||||
EXPECT_FALSE(dataTest(dd, "data22_5.data"));
|
||||
EXPECT_TRUE(dataTest(dd, "data22_6.data"));
|
||||
EXPECT_TRUE(dataTest(dd, "data22_7.data"));
|
||||
EXPECT_FALSE(dataTest(dd, "data22_8.data"));
|
||||
EXPECT_FALSE(dataTest(dd, "data22_9.data"));
|
||||
|
||||
// Test if "version" is allowed in config data
|
||||
// (same data as 22_7, but added "version")
|
||||
EXPECT_TRUE(dataTest(dd, "data22_10.data"));
|
||||
|
||||
ElementPtr errors = Element::createList();
|
||||
EXPECT_FALSE(dataTestWithErrors(dd, "data22_8.data", errors));
|
||||
EXPECT_EQ("[ \"Type mismatch\" ]", errors->str());
|
||||
|
||||
errors = Element::createList();
|
||||
EXPECT_FALSE(dataTestWithErrors(dd, "data22_9.data", errors));
|
||||
EXPECT_EQ("[ \"Unknown item value_does_not_exist\" ]", errors->str());
|
||||
}
|
||||
|
||||
TEST(ModuleSpec, StatisticsValidation) {
|
||||
ModuleSpec dd = moduleSpecFromFile(specfile("spec33.spec"));
|
||||
|
||||
EXPECT_TRUE(statisticsTest(dd, "data33_1.data"));
|
||||
EXPECT_FALSE(statisticsTest(dd, "data33_2.data"));
|
||||
|
||||
ElementPtr errors = Element::createList();
|
||||
EXPECT_FALSE(statisticsTestWithErrors(dd, "data33_2.data", errors));
|
||||
EXPECT_EQ("[ \"Format mismatch\", \"Format mismatch\", \"Format mismatch\" ]", errors->str());
|
||||
|
||||
dd = moduleSpecFromFile(specfile("spec41.spec"));
|
||||
|
||||
EXPECT_TRUE(statisticsTest(dd, "data41_1.data"));
|
||||
EXPECT_FALSE(statisticsTest(dd, "data41_2.data"));
|
||||
|
||||
errors = Element::createList();
|
||||
EXPECT_FALSE(statisticsTestWithErrors(dd, "data41_2.data", errors));
|
||||
EXPECT_EQ("[ \"Type mismatch\" ]", errors->str());
|
||||
}
|
||||
|
||||
TEST(ModuleSpec, CommandValidation) {
|
||||
ModuleSpec dd = moduleSpecFromFile(specfile("spec2.spec"));
|
||||
ConstElementPtr arg = Element::fromJSON("{}");
|
||||
ElementPtr errors = Element::createList();
|
||||
|
||||
EXPECT_TRUE(dd.validateCommand("shutdown", arg, errors));
|
||||
EXPECT_EQ(errors->size(), 0);
|
||||
|
||||
errors = Element::createList();
|
||||
EXPECT_FALSE(dd.validateCommand("unknowncommand", arg, errors));
|
||||
EXPECT_EQ(errors->size(), 1);
|
||||
EXPECT_EQ(errors->get(0)->stringValue(), "Unknown command unknowncommand");
|
||||
|
||||
errors = Element::createList();
|
||||
EXPECT_FALSE(dd.validateCommand("print_message", arg, errors));
|
||||
EXPECT_EQ(errors->size(), 1);
|
||||
EXPECT_EQ(errors->get(0)->stringValue(), "Non-optional value missing");
|
||||
|
||||
errors = Element::createList();
|
||||
arg = Element::fromJSON("{ \"message\": \"Hello\" }");
|
||||
EXPECT_TRUE(dd.validateCommand("print_message", arg, errors));
|
||||
EXPECT_EQ(errors->size(), 0);
|
||||
|
||||
errors = Element::createList();
|
||||
arg = Element::fromJSON("{ \"message\": \"Hello\", \"unknown_second_arg\": 1 }");
|
||||
EXPECT_FALSE(dd.validateCommand("print_message", arg, errors));
|
||||
EXPECT_EQ(errors->size(), 1);
|
||||
EXPECT_EQ(errors->get(0)->stringValue(), "Unknown item unknown_second_arg");
|
||||
|
||||
errors = Element::createList();
|
||||
arg = Element::fromJSON("{ \"message\": 1 }");
|
||||
EXPECT_FALSE(dd.validateCommand("print_message", arg, errors));
|
||||
EXPECT_EQ(errors->size(), 1);
|
||||
EXPECT_EQ(errors->get(0)->stringValue(), "Type mismatch");
|
||||
|
||||
}
|
||||
|
||||
TEST(ModuleSpec, NamedSetValidation) {
|
||||
ModuleSpec dd = moduleSpecFromFile(specfile("spec32.spec"));
|
||||
|
||||
ElementPtr errors = Element::createList();
|
||||
EXPECT_TRUE(dataTestWithErrors(dd, "data32_1.data", errors));
|
||||
EXPECT_FALSE(dataTest(dd, "data32_2.data"));
|
||||
EXPECT_FALSE(dataTest(dd, "data32_3.data"));
|
||||
}
|
||||
|
||||
TEST(ModuleSpec, CheckFormat) {
|
||||
|
||||
const std::string json_begin = "{ \"module_spec\": { \"module_name\": \"Foo\", \"statistics\": [ { \"item_name\": \"dummy_time\", \"item_type\": \"string\", \"item_optional\": true, \"item_title\": \"Dummy Time\", \"item_description\": \"A dummy date time\"";
|
||||
const std::string json_end = " } ] } }";
|
||||
std::string item_default;
|
||||
std::string item_format;
|
||||
std::vector<std::string> specs;
|
||||
ConstElementPtr el;
|
||||
|
||||
specs.clear();
|
||||
item_default = "\"item_default\": \"2011-05-27T19:42:57Z\",";
|
||||
item_format = "\"item_format\": \"date-time\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
item_default = "\"item_default\": \"2011-05-27\",";
|
||||
item_format = "\"item_format\": \"date\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
item_default = "\"item_default\": \"19:42:57\",";
|
||||
item_format = "\"item_format\": \"time\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
|
||||
item_format = "\"item_format\": \"date-time\"";
|
||||
specs.push_back("," + item_format);
|
||||
item_default = "";
|
||||
item_format = "\"item_format\": \"date\"";
|
||||
specs.push_back("," + item_format);
|
||||
// cppcheck-suppress redundantAssignment
|
||||
item_default = "";
|
||||
item_format = "\"item_format\": \"time\"";
|
||||
specs.push_back("," + item_format);
|
||||
|
||||
// cppcheck-suppress redundantAssignment
|
||||
item_default = "\"item_default\": \"a\"";
|
||||
specs.push_back("," + item_default);
|
||||
item_default = "\"item_default\": \"b\"";
|
||||
specs.push_back("," + item_default);
|
||||
item_default = "\"item_default\": \"c\"";
|
||||
specs.push_back("," + item_default);
|
||||
|
||||
item_format = "\"item_format\": \"dummy\"";
|
||||
specs.push_back("," + item_format);
|
||||
|
||||
specs.push_back("");
|
||||
|
||||
BOOST_FOREACH(std::string s, specs) {
|
||||
el = Element::fromJSON(json_begin + s + json_end)->get("module_spec");
|
||||
EXPECT_NO_THROW(ModuleSpec(el, true));
|
||||
}
|
||||
|
||||
specs.clear();
|
||||
item_default = "\"item_default\": \"2011-05-27T19:42:57Z\",";
|
||||
item_format = "\"item_format\": \"dummy\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
item_default = "\"item_default\": \"2011-05-27\",";
|
||||
item_format = "\"item_format\": \"dummy\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
item_default = "\"item_default\": \"19:42:57Z\",";
|
||||
item_format = "\"item_format\": \"dummy\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
|
||||
item_default = "\"item_default\": \"2011-13-99T99:99:99Z\",";
|
||||
item_format = "\"item_format\": \"date-time\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
item_default = "\"item_default\": \"2011-13-99\",";
|
||||
item_format = "\"item_format\": \"date\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
item_default = "\"item_default\": \"99:99:99Z\",";
|
||||
item_format = "\"item_format\": \"time\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
|
||||
item_default = "\"item_default\": \"1\",";
|
||||
item_format = "\"item_format\": \"date-time\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
item_default = "\"item_default\": \"1\",";
|
||||
item_format = "\"item_format\": \"date\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
item_default = "\"item_default\": \"1\",";
|
||||
item_format = "\"item_format\": \"time\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
|
||||
item_default = "\"item_default\": \"\",";
|
||||
item_format = "\"item_format\": \"date-time\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
item_default = "\"item_default\": \"\",";
|
||||
item_format = "\"item_format\": \"date\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
item_default = "\"item_default\": \"\",";
|
||||
item_format = "\"item_format\": \"time\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
|
||||
// wrong date-time-type format not ending with "Z"
|
||||
item_default = "\"item_default\": \"2011-05-27T19:42:57\",";
|
||||
item_format = "\"item_format\": \"date-time\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
// wrong date-type format ending with "T"
|
||||
item_default = "\"item_default\": \"2011-05-27T\",";
|
||||
item_format = "\"item_format\": \"date\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
// wrong time-type format ending with "Z"
|
||||
item_default = "\"item_default\": \"19:42:57Z\",";
|
||||
item_format = "\"item_format\": \"time\"";
|
||||
specs.push_back("," + item_default + item_format);
|
||||
|
||||
BOOST_FOREACH(std::string s, specs) {
|
||||
el = Element::fromJSON(json_begin + s + json_end)->get("module_spec");
|
||||
EXPECT_THROW(ModuleSpec(el, true), ModuleSpecError);
|
||||
}
|
||||
}
|
@@ -232,9 +232,6 @@ EXTRA_DIST += hosts_messages.mes
|
||||
# Database schema creation script moved to src/bin/admin
|
||||
EXTRA_DIST += database_backends.dox libdhcpsrv.dox
|
||||
|
||||
# Specification file
|
||||
EXTRA_DIST += logging.spec
|
||||
|
||||
# Specify the headers for copying into the installation directory tree.
|
||||
libkea_dhcpsrv_includedir = $(pkgincludedir)/dhcpsrv
|
||||
libkea_dhcpsrv_include_HEADERS = \
|
||||
|
@@ -1,94 +0,0 @@
|
||||
{
|
||||
"module_spec": {
|
||||
"module_name": "Logging",
|
||||
"module_description": "Logging configuration",
|
||||
"config_data": [
|
||||
{
|
||||
"item_name": "loggers",
|
||||
"item_type": "list",
|
||||
"item_optional": false,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "logger",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "name",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "kea",
|
||||
"item_description": "Logging name"
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "output_options",
|
||||
"item_type": "list",
|
||||
"item_optional": true,
|
||||
"item_default": [],
|
||||
"list_item_spec":
|
||||
{
|
||||
"item_name": "output_option",
|
||||
"item_type": "map",
|
||||
"item_optional": false,
|
||||
"item_default": {},
|
||||
"item_description": "Options for a logging destination",
|
||||
"map_item_spec": [
|
||||
{
|
||||
"item_name": "output",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "stdout",
|
||||
"item_description": "Logging destination (stdout, stderr, syslog, syslog:name, file name)"
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "maxver",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 1,
|
||||
"item_description": "Maximum number of log files in rotation"
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "maxsize",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 204800,
|
||||
"item_description": "Maximum log file size"
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "flush",
|
||||
"item_type": "boolean",
|
||||
"item_optional": true,
|
||||
"item_default": true,
|
||||
"item_description": "Immediate flush"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "severity",
|
||||
"item_type": "string",
|
||||
"item_optional": false,
|
||||
"item_default": "INFO",
|
||||
"item_description": "Logging severity"
|
||||
},
|
||||
|
||||
{
|
||||
"item_name": "debuglevel",
|
||||
"item_type": "integer",
|
||||
"item_optional": true,
|
||||
"item_default": 0,
|
||||
"item_description": "Debug level (for DEBUG severity, 0..99 range)"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@@ -5,7 +5,6 @@ AM_CPPFLAGS += $(BOOST_INCLUDES)
|
||||
AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/lib/dhcpsrv/tests\"
|
||||
AM_CPPFLAGS += -DDHCP_DATA_DIR=\"$(abs_top_builddir)/src/lib/dhcpsrv/tests\"
|
||||
AM_CPPFLAGS += -DKEA_LFC_BUILD_DIR=\"$(abs_top_builddir)/src/bin/lfc\"
|
||||
AM_CPPFLAGS += -DLOGGING_SPEC_FILE=\"$(abs_top_srcdir)/src/lib/dhcpsrv/logging.spec\"
|
||||
AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
|
||||
|
||||
AM_CXXFLAGS = $(KEA_CXXFLAGS)
|
||||
|
@@ -6,7 +6,6 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <cc/data.h>
|
||||
#include <config/module_spec.h>
|
||||
#include <dhcpsrv/dhcpsrv_log.h>
|
||||
#include <dhcpsrv/logging.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
@@ -76,12 +75,6 @@ const char* LoggingTest::TEST_LOG_NAME = "kea.test.log";
|
||||
const int LoggingTest::TEST_MAX_SIZE = 204800; // Smallest without disabling rotation
|
||||
const int LoggingTest::TEST_MAX_VERS = 2; // More than the default of 1
|
||||
|
||||
// Tests that the spec file is valid.
|
||||
TEST_F(LoggingTest, basicSpec) {
|
||||
std::string specfile = std::string(LOGGING_SPEC_FILE);
|
||||
ASSERT_NO_THROW(isc::config::moduleSpecFromFile(specfile));
|
||||
}
|
||||
|
||||
// Checks that the constructor is able to process specified storage properly.
|
||||
TEST_F(LoggingTest, constructor) {
|
||||
|
||||
|
@@ -22,18 +22,15 @@ s-messages: process_messages.mes
|
||||
$(top_builddir)/src/lib/log/compiler/kea-msg-compiler $(top_srcdir)/src/lib/process/process_messages.mes
|
||||
touch $@
|
||||
|
||||
spec_config.h: spec_config.h.pre
|
||||
$(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@
|
||||
|
||||
# Tell automake that the message files are built as part of the build process
|
||||
# (so that they are built before the main library is built).
|
||||
BUILT_SOURCES = spec_config.h process_messages.h process_messages.cc
|
||||
BUILT_SOURCES = process_messages.h process_messages.cc
|
||||
|
||||
# Ensure that the message file is included in the distribution
|
||||
EXTRA_DIST = process_messages.mes libprocess.dox
|
||||
|
||||
# Get rid of generated message files on a clean
|
||||
CLEANFILES = *.gcno *.gcda spec_config.h process_messages.h process_messages.cc s-messages
|
||||
CLEANFILES = *.gcno *.gcda process_messages.h process_messages.cc s-messages
|
||||
|
||||
lib_LTLIBRARIES = libkea-process.la
|
||||
libkea_process_la_SOURCES = d_cfg_mgr.cc d_cfg_mgr.h
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <cc/command_interpreter.h>
|
||||
#include <config/module_spec.h>
|
||||
#include <exceptions/exceptions.h>
|
||||
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
||||
#include <process/testutils/d_test_stubs.h>
|
||||
|
Reference in New Issue
Block a user