Modules subscribe to configuration sections they are interested in by name and provide a callback function. After parsing the configuration file, ConfigFile will iterate through the top level tree and invoke all subscribed callbacks for each section it comes across. ConfigFile has no concept of the specific tags or structure of the file other than there being a single root tag (not a specific name) under which all sections fall. refs: #1120 Change-Id: Ic06fbdc85a9ac9740d46a6c2457ff5a9bd38e8a5
348 lines
6.5 KiB
C++
348 lines
6.5 KiB
C++
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
|
/**
|
|
* Copyright (C) 2014 Named Data Networking Project
|
|
* See COPYING for copyright and distribution information.
|
|
*/
|
|
|
|
|
|
#include "mgmt/config-file.hpp"
|
|
|
|
#include <boost/test/unit_test.hpp>
|
|
|
|
namespace nfd {
|
|
|
|
NFD_LOG_INIT("ConfigFileTest");
|
|
|
|
BOOST_AUTO_TEST_SUITE(MgmtConfigFile)
|
|
|
|
// a
|
|
// {
|
|
// akey "avalue"
|
|
// }
|
|
// b
|
|
// {
|
|
// bkey "bvalue"
|
|
// }
|
|
|
|
const std::string CONFIG =
|
|
"a\n"
|
|
"{\n"
|
|
" akey \"avalue\"\n"
|
|
"}\n"
|
|
"b\n"
|
|
"{\n"
|
|
" bkey \"bvalue\"\n"
|
|
"}\n";
|
|
|
|
|
|
// a
|
|
// {
|
|
// akey "avalue"
|
|
// }
|
|
// b
|
|
//
|
|
// bkey "bvalue"
|
|
// }
|
|
|
|
const std::string MALFORMED_CONFIG =
|
|
"a\n"
|
|
"{\n"
|
|
" akey \"avalue\"\n"
|
|
"}\n"
|
|
"b\n"
|
|
"\n"
|
|
" bkey \"bvalue\"\n"
|
|
"}\n";
|
|
|
|
// counts of the respective section counts in config_example.info
|
|
|
|
const int CONFIG_N_A_SECTIONS = 1;
|
|
const int CONFIG_N_B_SECTIONS = 1;
|
|
|
|
class DummySubscriber
|
|
{
|
|
public:
|
|
|
|
DummySubscriber(ConfigFile& config,
|
|
int nASections,
|
|
int nBSections,
|
|
bool expectDryRun)
|
|
: m_nASections(nASections),
|
|
m_nBSections(nBSections),
|
|
m_nRemainingACallbacks(nASections),
|
|
m_nRemainingBCallbacks(nBSections),
|
|
m_expectDryRun(expectDryRun)
|
|
{
|
|
|
|
}
|
|
|
|
void
|
|
onA(const ConfigSection& section, bool isDryRun)
|
|
{
|
|
// NFD_LOG_DEBUG("a");
|
|
BOOST_CHECK_EQUAL(isDryRun, m_expectDryRun);
|
|
--m_nRemainingACallbacks;
|
|
}
|
|
|
|
|
|
void
|
|
onB(const ConfigSection& section, bool isDryRun)
|
|
{
|
|
// NFD_LOG_DEBUG("b");
|
|
BOOST_CHECK_EQUAL(isDryRun, m_expectDryRun);
|
|
--m_nRemainingBCallbacks;
|
|
}
|
|
|
|
bool
|
|
allCallbacksFired() const
|
|
{
|
|
return m_nRemainingACallbacks == 0 &&
|
|
m_nRemainingBCallbacks == 0;
|
|
}
|
|
|
|
bool
|
|
noCallbacksFired() const
|
|
{
|
|
return m_nRemainingACallbacks == m_nASections &&
|
|
m_nRemainingBCallbacks == m_nBSections;
|
|
}
|
|
|
|
virtual
|
|
~DummySubscriber()
|
|
{
|
|
|
|
}
|
|
|
|
private:
|
|
int m_nASections;
|
|
int m_nBSections;
|
|
int m_nRemainingACallbacks;
|
|
int m_nRemainingBCallbacks;
|
|
bool m_expectDryRun;
|
|
};
|
|
|
|
class DummyAllSubscriber : public DummySubscriber
|
|
{
|
|
public:
|
|
DummyAllSubscriber(ConfigFile& config, bool expectDryRun=false)
|
|
: DummySubscriber(config,
|
|
CONFIG_N_A_SECTIONS,
|
|
CONFIG_N_B_SECTIONS,
|
|
expectDryRun)
|
|
{
|
|
config.addSectionHandler("a", bind(&DummySubscriber::onA, this, _1, _2));
|
|
config.addSectionHandler("b", bind(&DummySubscriber::onB, this, _1, _2));
|
|
}
|
|
|
|
virtual
|
|
~DummyAllSubscriber()
|
|
{
|
|
|
|
}
|
|
};
|
|
|
|
class DummyOneSubscriber : public DummySubscriber
|
|
{
|
|
public:
|
|
DummyOneSubscriber(ConfigFile& config,
|
|
const std::string& sectionName,
|
|
bool expectDryRun=false)
|
|
: DummySubscriber(config,
|
|
(sectionName == "a"),
|
|
(sectionName == "b"),
|
|
expectDryRun)
|
|
{
|
|
if (sectionName == "a")
|
|
{
|
|
config.addSectionHandler(sectionName, bind(&DummySubscriber::onA, this, _1, _2));
|
|
}
|
|
else if (sectionName == "b")
|
|
{
|
|
config.addSectionHandler(sectionName, bind(&DummySubscriber::onB, this, _1, _2));
|
|
}
|
|
else
|
|
{
|
|
BOOST_FAIL("Test setup error: "
|
|
<< "Unexpected section name "
|
|
<<"\"" << sectionName << "\"");
|
|
}
|
|
|
|
}
|
|
|
|
virtual
|
|
~DummyOneSubscriber()
|
|
{
|
|
|
|
}
|
|
};
|
|
|
|
class DummyNoSubscriber : public DummySubscriber
|
|
{
|
|
public:
|
|
DummyNoSubscriber(ConfigFile& config, bool expectDryRun)
|
|
: DummySubscriber(config, 0, 0, expectDryRun)
|
|
{
|
|
|
|
}
|
|
|
|
virtual
|
|
~DummyNoSubscriber()
|
|
{
|
|
|
|
}
|
|
};
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigStream)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub(file);
|
|
std::ifstream input;
|
|
|
|
input.open("tests/mgmt/config_example.info");
|
|
BOOST_REQUIRE(input.is_open());
|
|
|
|
file.parse(input);
|
|
|
|
BOOST_CHECK(sub.allCallbacksFired());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigStreamEmptyStream)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub(file);
|
|
|
|
std::ifstream input;
|
|
|
|
BOOST_CHECK_THROW(file.parse(input), ConfigFile::Error);
|
|
BOOST_CHECK(sub.noCallbacksFired());
|
|
}
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigString)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub(file);
|
|
|
|
file.parse(CONFIG);
|
|
|
|
BOOST_CHECK(sub.allCallbacksFired());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigStringEmpty)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub(file);
|
|
|
|
BOOST_CHECK_THROW(file.parse(std::string()), ConfigFile::Error);
|
|
BOOST_CHECK(sub.noCallbacksFired());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigStringMalformed)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub(file);
|
|
|
|
BOOST_CHECK_THROW(file.parse(MALFORMED_CONFIG), ConfigFile::Error);
|
|
BOOST_CHECK(sub.noCallbacksFired());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigStringDryRun)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub(file, true);
|
|
|
|
file.parse(CONFIG, true);
|
|
|
|
BOOST_CHECK(sub.allCallbacksFired());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigFilename)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub(file);
|
|
|
|
file.parse("tests/mgmt/config_example.info");
|
|
|
|
BOOST_CHECK(sub.allCallbacksFired());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigFilenameNoFile)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub(file);
|
|
|
|
BOOST_CHECK_THROW(file.parse("i_made_this_up.info"), ConfigFile::Error);
|
|
|
|
BOOST_CHECK(sub.noCallbacksFired());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigFilenameMalformed)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub(file);
|
|
|
|
BOOST_CHECK_THROW(file.parse("tests/mgmt/config_malformed.info"), ConfigFile::Error);
|
|
|
|
BOOST_CHECK(sub.noCallbacksFired());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigStreamDryRun)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub(file, true);
|
|
std::ifstream input;
|
|
|
|
input.open("tests/mgmt/config_example.info");
|
|
BOOST_REQUIRE(input.is_open());
|
|
|
|
file.parse(input, true);
|
|
|
|
BOOST_CHECK(sub.allCallbacksFired());
|
|
|
|
input.close();
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigFilenameDryRun)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub(file, true);
|
|
|
|
file.parse("tests/mgmt/config_example.info", true);
|
|
BOOST_CHECK(sub.allCallbacksFired());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigReplaceSubscriber)
|
|
{
|
|
ConfigFile file;
|
|
DummyAllSubscriber sub1(file);
|
|
DummyAllSubscriber sub2(file);
|
|
|
|
file.parse(CONFIG);
|
|
|
|
BOOST_CHECK(sub1.noCallbacksFired());
|
|
BOOST_CHECK(sub2.allCallbacksFired());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigUncoveredSections)
|
|
{
|
|
ConfigFile file;
|
|
|
|
BOOST_CHECK_THROW(file.parse(CONFIG), ConfigFile::Error);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(OnConfigCoveredByPartialSubscribers)
|
|
{
|
|
ConfigFile file;
|
|
DummyOneSubscriber subA(file, "a");
|
|
DummyOneSubscriber subB(file, "b");
|
|
|
|
file.parse(CONFIG);
|
|
|
|
BOOST_CHECK(subA.allCallbacksFired());
|
|
BOOST_CHECK(subB.allCallbacksFired());
|
|
}
|
|
|
|
} // namespace nfd
|
|
|
|
BOOST_AUTO_TEST_SUITE_END()
|