Commit 80707c7c authored by Jelte Jansen's avatar Jelte Jansen

tests for data_def.cc


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/parkinglot@708 e5f2f494-b856-4b98-b285-d166d9295462
parent f55eb123
......@@ -184,6 +184,7 @@ AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
src/bin/msgq/run_msgq.sh
src/bin/auth/config.h
src/bin/parkinglot/config.h
src/lib/config/cpp/data_def_unittests_config.h
src/lib/dns/cpp/gen-rdatacode.py
], [
chmod +x src/bin/cfgmgr/run_b10-cfgmgr.sh
......
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/ext -Wall -Werror
lib_LIBRARIES = libclient.a
libclient_a_SOURCES = data_def.h data_def.cc ccsession.cc ccsession.h
lib_LIBRARIES = libcfgclient.a
libcfgclient_a_SOURCES = data_def.h data_def.cc ccsession.cc ccsession.h
TESTS =
if HAVE_GTEST
TESTS += run_unittests
run_unittests_SOURCES = data_def_unittests.cc run_unittests.cc
run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
run_unittests_LDADD = libcfgclient.a $(GTEST_LDADD)
run_unittests_LDADD += $(top_builddir)/src/lib/dns/cpp/libdns.la
run_unittests_LDADD += $(top_builddir)/src/lib/cc/cpp/libcc.a
endif
noinst_PROGRAMS = $(TESTS)
......@@ -3,6 +3,8 @@
#include <sstream>
#include <iostream>
#include <fstream>
#include <cerrno>
#include <boost/foreach.hpp>
......@@ -88,13 +90,14 @@ check_config_item(const ElementPtr& spec) {
// todo: add stuff for type map
if (getType_value(spec->get("item_type")->stringValue()) == Element::map) {
check_leaf_item(spec, "map_item_spec", Element::list, true);
check_config_item_list(spec);
check_config_item_list(spec->get("map_item_spec"));
}
}
static void
check_config_item_list(const ElementPtr& spec) {
if (spec->getType() != Element::list) {
std::cout << "[XX] ERROR IN: " << spec << std::endl;
throw DataDefinitionError("config_data is not a list of elements");
}
BOOST_FOREACH(ElementPtr item, spec->listValue()) {
......@@ -144,6 +147,24 @@ check_definition(const ElementPtr& def)
}
}
DataDefinition::DataDefinition(const std::string& file_name,
const bool check)
throw(ParseError, DataDefinitionError) {
std::ifstream file;
file.open(file_name.c_str());
if (!file) {
std::stringstream errs;
errs << "Error opening " << file_name << ": " << strerror(errno);
throw DataDefinitionError(errs.str());
}
definition = Element::createFromString(file, file_name);
if (check) {
check_definition(definition);
}
}
DataDefinition::DataDefinition(std::istream& in, const bool check)
throw(ParseError, DataDefinitionError) {
definition = Element::createFromString(in);
......
......@@ -39,9 +39,22 @@ namespace isc { namespace data {
/// the specification
/// \param e The Element containing the data specification
explicit DataDefinition(ElementPtr e) : definition(e) {};
/// Creates a \c DataDefinition instance from the contents
/// of the file given by file_name.
/// If check is true, and the definition is not of the correct
/// form, a DataDefinitionError 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 data definition in the file is
/// checked to be of the correct form
DataDefinition(const std::string& file_name, const bool check = true)
throw(ParseError, DataDefinitionError);
// todo: make check default false, or leave out option completely and always check?
/// Creates a \c DataDefinition instance from the given .spec
/// file stream. If check is true, and the definition is not of
/// Creates a \c DataDefinition instance from the given input
/// stream that contains the contents of a .spec file.
/// If check is true, and the definition is not of
/// the correct form, a DataDefinitionError is thrown. If the
/// file could not be parsed, a ParseError is thrown.
/// \param in The std::istream containing the .spec file data
......
// Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#include <gtest/gtest.h>
#include <data_def.h>
#include "data_def_unittests_config.h"
using namespace isc::data;
std::string specfile(const std::string name) {
return std::string(TEST_DATA_PATH) + "/" + name;
}
void
data_def_error(const std::string& file,
const std::string& error1,
const std::string& error2 = "",
const std::string& error3 = "")
{
EXPECT_THROW(DataDefinition(specfile(file)), DataDefinitionError);
try {
DataDefinition dd = DataDefinition(specfile(file));
} catch (DataDefinitionError dde) {
std::string ddew = dde.what();
EXPECT_EQ(error1 + error2 + error3, ddew);
}
}
TEST(DataDefinition, Specfiles) {
// Tests whether we can open specfiles and if we get the
// right parse errors
DataDefinition dd = DataDefinition(specfile("spec1.spec"));
EXPECT_EQ(dd.getDefinition()->get("data_specification")
->get("module_name")
->stringValue(), "Spec1");
dd = DataDefinition(specfile("spec2.spec"));
EXPECT_EQ(dd.getDefinition()->get("data_specification")
->get("config_data")->size(), 6);
data_def_error("doesnotexist",
"Error opening ",
specfile("doesnotexist"),
": No such file or directory");
data_def_error("spec3.spec",
"item_name missing in {\"item_default\": 1, \"item_optional\": False, \"item_type\": \"integer\"}");
data_def_error("spec4.spec",
"item_type missing in {\"item_default\": 1, \"item_name\": \"item1\", \"item_optional\": False}");
data_def_error("spec5.spec",
"item_optional missing in {\"item_default\": 1, \"item_name\": \"item1\", \"item_type\": \"integer\"}");
data_def_error("spec6.spec",
"item_default missing in {\"item_name\": \"item1\", \"item_optional\": False, \"item_type\": \"integer\"}");
data_def_error("spec7.spec",
"module_name missing in {}");
data_def_error("spec8.spec",
"Data specification does not contain data_specification element");
}
#define TEST_DATA_PATH "@abs_srcdir@/../testdata"
// Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#include <gtest/gtest.h>
int
main(int argc, char* argv[])
{
::testing::InitGoogleTest(&argc, argv);
return (RUN_ALL_TESTS());
}
......@@ -65,6 +65,11 @@ class DataDefinition:
return self._data_spec["data_specification"]["module_name"]
def _check(data_spec):
"""Checks the full specification. This is a dict that contains the
element "data_specification", which is in itself a dict that
must contain at least a "module_name" (string) and optionally
a "config_data" and a "commands" element, both of which are lists
of dicts. Raises a DataDefinitionError if there is a problem."""
if type(data_spec) != dict:
raise DataDefinitionError("data specification not a dict")
if "data_specification" not in data_spec:
......@@ -81,12 +86,17 @@ def _checkConfigSpec(config_data):
# config data is a list of items represented by dicts that contain
# things like "item_name", depending on the type they can have
# specific subitems
"""Checks a list that contains the configuration part of the
specification. Raises a DataDefinitionError if there is a
problem."""
if type(config_data) != list:
raise DataDefinitionError("config_data is not a list of items")
for config_item in config_data:
_checkItemSpec(config_item)
def _checkCommandSpec(commands):
"""Checks the list that contains a set of commands. Raises a
DataDefinitionError is there is an error"""
if type(commands) != list:
raise DataDefinitionError("commands is not a list of commands")
for command in commands:
......@@ -110,8 +120,9 @@ def _checkCommandSpec(commands):
pass
def _checkItemSpec(config_item):
# checks the dict that defines one config item
# (i.e. containing "item_name", "item_type", etc
"""Checks the dict that defines one config item
(i.e. containing "item_name", "item_type", etc.
Raises a DataDefinitionError if there is an error"""
if type(config_item) != dict:
raise DataDefinitionError("item spec not a dict")
if "item_name" not in config_item:
......
{
"data_specification": {
"module_name": "Spec1"
}
}
{
"data_specification": {
"module_name": "Spec2",
"config_data": [
{ "item_name": "item1",
"item_type": "integer",
"item_optional": False,
"item_default": 1
},
{ "item_name": "item2",
"item_type": "real",
"item_optional": False,
"item_default": 1.1
},
{ "item_name": "item3",
"item_type": "boolean",
"item_optional": False,
"item_default": True
},
{ "item_name": "item4",
"item_type": "string",
"item_optional": False,
"item_default": "test"
},
{ "item_name": "item5",
"item_type": "list",
"item_optional": False,
"item_default": [ "a", "b" ],
"list_item_spec": {
"item_name": "list_element",
"item_type": "string",
"item_optional": False,
"item_default": ""
}
},
{ "item_name": "item6",
"item_type": "map",
"item_optional": False,
"item_default": {},
"map_item_spec": [
{ "item_name": "value1",
"item_type": "string",
"item_optional": True,
"item_default": "default"
},
{ "item_name": "value2",
"item_type": "integer",
"item_optional": True
}
]
}
]
}
}
{
"data_specification": {
"module_name": "Spec2",
"config_data": [
{
"item_type": "integer",
"item_optional": False,
"item_default": 1
}
]
}
}
{
"data_specification": {
"module_name": "Spec2",
"config_data": [
{ "item_name": "item1",
"item_optional": False,
"item_default": 1
}
]
}
}
{
"data_specification": {
"module_name": "Spec2",
"config_data": [
{ "item_name": "item1",
"item_type": "integer",
"item_default": 1
}
]
}
}
{
"data_specification": {
"module_name": "Spec2",
"config_data": [
{ "item_name": "item1",
"item_type": "integer",
"item_optional": False
}
]
}
}
{
"data_specification": {
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment