[cpp-sp] branch main updated: Logging API adjustments and tests for config.
Scott Cantor
cantor.2 at osu.edu
Tue Nov 26 18:33:43 UTC 2024
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository cpp-sp.
View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=2bf4341d79c7030931e2c60c8aa5490cefc7baf1
The following commit(s) were added to refs/heads/main by this push:
new 2bf4341d Logging API adjustments and tests for config.
2bf4341d is described below
commit 2bf4341d79c7030931e2c60c8aa5490cefc7baf1
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Nov 26 13:33:32 2024 -0500
Logging API adjustments and tests for config.
---
shibsp/Makefile.am | 1 +
shibsp/SPConfig.cpp | 18 ----
shibsp/base.h | 14 +--
shibsp/impl/AgentConfig.cpp | 138 ++++++++++++-------------
shibsp/logging/LoggingService.h | 4 +-
shibsp/logging/impl/AbstractLoggingService.cpp | 18 +++-
shibsp/logging/impl/AbstractLoggingService.h | 6 +-
shibsp/logging/impl/Category.cpp | 6 +-
shibsp/logging/impl/ConsoleLoggingService.cpp | 16 ++-
shibsp/logging/impl/LoggingServiceSPI.h | 16 +--
shibsp/logging/impl/Priority.cpp | 12 ++-
shibsp/util/PathResolver.cpp | 2 +-
tests/AgentConfigTests.cpp | 87 ++++++++++++++++
tests/Makefile.am | 1 +
tests/data/dupproperty_shibboleth.ini | 3 +
tests/data/dupsection_shibboleth.ini | 5 +
tests/data/noequals_shibboleth.ini | 2 +
tests/data/nokey_shibboleth.ini | 2 +
tests/data/shibboleth.ini | 6 ++
tests/data/unmatched_shibboleth.ini | 1 +
20 files changed, 222 insertions(+), 136 deletions(-)
diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am
index 94057762..53d2fac2 100644
--- a/shibsp/Makefile.am
+++ b/shibsp/Makefile.am
@@ -111,6 +111,7 @@ libshibsp_la_SOURCES = \
handler/impl/SessionHandler.cpp \
handler/impl/SessionInitiator.cpp \
handler/impl/StatusHandler.cpp \
+ impl/AgentConfig.cpp \
impl/XMLAccessControl.cpp \
impl/ChainingAccessControl.cpp \
impl/StoredSession.cpp \
diff --git a/shibsp/SPConfig.cpp b/shibsp/SPConfig.cpp
index beb77e7e..7346d49a 100644
--- a/shibsp/SPConfig.cpp
+++ b/shibsp/SPConfig.cpp
@@ -139,24 +139,6 @@ bool SPConfig::init(const char* catalog_path, const char* inst_prefix)
++inst_prefix;
}
- const char* logconf = getenv("SHIBSP_LOGGING");
- if (!logconf || !*logconf) {
- if (isEnabled(SPConfig::Logging) && isEnabled(SPConfig::OutOfProcess) && !isEnabled(SPConfig::InProcess))
- logconf = SHIBSP_OUTOFPROC_LOGGING;
- else if (isEnabled(SPConfig::Logging) && isEnabled(SPConfig::InProcess) && !isEnabled(SPConfig::OutOfProcess))
- logconf = SHIBSP_INPROC_LOGGING;
- else
- logconf = SHIBSP_LOGGING;
- }
- PathResolver localpr;
- localpr.setDefaultPrefix(inst_prefix2.c_str());
- inst_prefix = getenv("SHIBSP_CFGDIR");
- if (!inst_prefix || !*inst_prefix)
- inst_prefix = SHIBSP_CFGDIR;
- localpr.setCfgDir(inst_prefix);
- std::string lc(logconf);
- XMLToolingConfig::getConfig().log_config(localpr.resolve(lc, PathResolver::XMLTOOLING_CFG_FILE, PACKAGE_NAME).c_str());
-
Category& log=Category::getInstance(SHIBSP_LOGCAT ".Config");
log.debug("%s library initialization started", PACKAGE_STRING);
diff --git a/shibsp/base.h b/shibsp/base.h
index 0b2c5215..560a172b 100644
--- a/shibsp/base.h
+++ b/shibsp/base.h
@@ -76,18 +76,6 @@
#define SHIBSP_EXCEPTIONAPI(api)
#endif
-/**
- * Controls default logging level of console tools and other situations
- * where fully-configured logging isn't used.
- */
-#define SHIBSP_LOGGING "console.logger"
-
-/** Default name of SP in-process logging config file. */
-#define SHIBSP_INPROC_LOGGING "native.logger"
-
-/** Default name of SP out-of-process logging config file. */
-#define SHIBSP_OUTOFPROC_LOGGING "shibd.logger"
-
/** Logging category for Service Provider functions. */
#define SHIBSP_LOGCAT "Shibboleth"
@@ -95,7 +83,7 @@
#define SHIBSP_TX_LOGCAT "Shibboleth-TRANSACTION"
/** Default name of configuration file. */
-# define SHIBSP_CONFIG "shibboleth2.xml"
+# define SHIBSP_CONFIG "shibboleth.ini"
#ifdef WIN32
diff --git a/shibsp/impl/AgentConfig.cpp b/shibsp/impl/AgentConfig.cpp
index 70885df9..2ac591d2 100644
--- a/shibsp/impl/AgentConfig.cpp
+++ b/shibsp/impl/AgentConfig.cpp
@@ -27,8 +27,10 @@
#include "util/PathResolver.h"
#include <ctime>
+#include <stdexcept>
#include <thread>
#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/ini_parser.hpp>
using namespace shibsp;
using namespace xmltooling;
@@ -56,20 +58,22 @@ namespace shibsp {
bool _init(const char* inst_prefix=nullptr, const char* config_file=nullptr, bool rethrow=false);
void _term();
+ bool initLogging();
+
unsigned int m_initCount;
mutex m_lock;
+ ptree m_config;
PathResolver m_pathResolver;
- unique_ptr<Agent> m_agent;
unique_ptr<LoggingService> m_logging;
- unique_ptr<ptree> m_config;
+ //unique_ptr<Agent> m_agent;
};
- AgentInternalConfig g_config;
+ static AgentInternalConfig g_agentConfig;
}
AgentConfig& AgentConfig::getConfig()
{
- return g_config;
+ return g_agentConfig;
}
AgentConfig::AgentConfig()
@@ -95,9 +99,9 @@ LoggingService& AgentInternalConfig::getLoggingService() const
Agent& AgentInternalConfig::getAgent() const
{
- if (m_agent) {
- return *m_agent;
- }
+// if (m_agent) {
+// return *m_agent;
+// }
throw logic_error("Agent not initialized.");
}
@@ -132,12 +136,13 @@ bool AgentInternalConfig::_init(const char* inst_prefix, const char* config_file
inst_prefix = getenv("SHIBSP_PREFIX");
if (!inst_prefix)
inst_prefix = SHIBSP_PREFIX;
- std::string inst_prefix2;
+ string inst_prefix2;
while (*inst_prefix) {
inst_prefix2.push_back((*inst_prefix=='\\') ? ('/') : (*inst_prefix));
++inst_prefix;
}
+ // Set up PathResolver component.
m_pathResolver.setDefaultPackageName(PACKAGE_NAME);
m_pathResolver.setDefaultPrefix(inst_prefix2.c_str());
m_pathResolver.setCfgDir(inst_prefix);
@@ -158,13 +163,43 @@ bool AgentInternalConfig::_init(const char* inst_prefix, const char* config_file
inst_prefix = SHIBSP_CACHEDIR;
m_pathResolver.setCacheDir(inst_prefix);
+ // Resolve primary config path and parse as INI file.
+ if (!config_file)
+ config_file = getenv("SHIBSP_CONFIG");
+ if (!config_file) {
+ config_file = SHIBSP_CONFIG;
+ }
+ string config_file_resolved(config_file);
+ m_pathResolver.resolve(config_file_resolved, PathResolver::SHIBSP_CFG_FILE);
+
+ try {
+ ini_parser::read_ini(config_file_resolved, m_config);
+ } catch (const ini_parser_error& e) {
+ if (rethrow) {
+ throw;
+ }
+ return false;
+ }
+
registerLoggingServices();
-/*
+ try {
+ if (!initLogging()) {
+ return false;
+ }
+ } catch (const std::exception& e) {
+ if (rethrow) {
+ throw;
+ }
+ return false;
+ }
+
+ // At this point, logging is active/usable.
- Category& log=Category::getInstance(SHIBSP_LOGCAT ".Config");
- log.debug("%s library initialization started", PACKAGE_STRING);
+ Category& log=Category::getInstance(SHIBSP_LOGCAT ".AgentConfig");
+ log.info("%s agent initialization underway", PACKAGE_STRING);
+ /*
XMLToolingConfig::getConfig().user_agent = string(PACKAGE_NAME) + '/' + PACKAGE_VERSION;
registerAttributeFactories();
@@ -197,63 +232,22 @@ bool AgentInternalConfig::_init(const char* inst_prefix, const char* config_file
return true;
}
- /*
-bool SPConfig::instantiate(const char* config, bool rethrow)
+bool AgentInternalConfig::initLogging()
{
- if (!config)
- config = getenv("SHIBSP_CONFIG");
- if (!config) {
- config = SHIBSP_CONFIG;
- }
- try {
- xercesc::DOMDocument* dummydoc;
- if (*config == '"' || *config == '\'') {
- throw ConfigurationException("The value of SHIBSP_CONFIG started with a quote.");
- }
- else if (*config != '<') {
- // Mock up some XML.
- string resolved(config);
- stringstream snippet;
- snippet
- << "<Dummy path='"
- << XMLToolingConfig::getConfig().getPathResolver()->resolve(resolved, PathResolver::XMLTOOLING_CFG_FILE)
- << "' validate='1'/>";
- dummydoc = XMLToolingConfig::getConfig().getParser().parse(snippet);
- XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);
- setServiceProvider(ServiceProviderManager.newPlugin(XML_SERVICE_PROVIDER, dummydoc->getDocumentElement(), true));
- if (m_configDoc)
- m_configDoc->release();
- m_configDoc = docjanitor.release();
- }
- else {
- stringstream snippet(config);
- dummydoc = XMLToolingConfig::getConfig().getParser().parse(snippet);
- XercesJanitor<xercesc::DOMDocument> docjanitor(dummydoc);
- static const XMLCh _type[] = UNICODE_LITERAL_4(t,y,p,e);
- auto_ptr_char type(dummydoc->getDocumentElement()->getAttributeNS(nullptr,_type));
- if (type.get() && *type.get())
- setServiceProvider(ServiceProviderManager.newPlugin(type.get(), dummydoc->getDocumentElement(), true));
- else
- throw ConfigurationException("The supplied XML bootstrapping configuration did not include a type attribute.");
- if (m_configDoc)
- m_configDoc->release();
- m_configDoc = docjanitor.release();
- }
-
- getServiceProvider()->init();
- return true;
- }
- catch (const std::exception& ex) {
- if (rethrow) {
- throw;
- }
- else {
- Category::getInstance(SHIBSP_LOGCAT ".Config").fatal("caught exception while loading configuration: %s", ex.what());
- }
+ // Config is loaded, look for logging section and type to instantiate.
+ string type = m_config.get(LoggingService::LOGGING_TYPE_PROP_PATH,
+#ifdef WIN32
+ WINDOWS_LOGGING_SERVICE
+#else
+ SYSLOG_LOGGING_SERVICE
+#endif
+ );
+ m_logging = unique_ptr<LoggingService>(LoggingServiceManager.newPlugin(type, m_config, false));
+ if (!m_logging->init()) {
+ return false;
}
- return false;
+ return true;
}
-*/
void AgentInternalConfig::term()
{
@@ -272,10 +266,16 @@ void AgentInternalConfig::term()
void AgentInternalConfig::_term()
{
- /*
- Category& log=Category::getInstance(SHIBSP_LOGCAT ".Config");
- log.info("%s library shutting down", PACKAGE_STRING);
+ Category& log=Category::getInstance(SHIBSP_LOGCAT ".AgentConfig");
+ log.info("%s agent shutting down", PACKAGE_STRING);
+ LoggingServiceManager.deregisterFactories();
+
+ log.info("%s agent shutdown complete", PACKAGE_STRING);
+
+ m_logging->term();
+
+ /*
setServiceProvider(nullptr);
if (m_configDoc)
m_configDoc->release();
@@ -302,7 +302,5 @@ void AgentInternalConfig::_term()
if (isEnabled(Caching))
SessionCacheManager.deregisterFactories();
-
- log.info("%s library shutdown complete", PACKAGE_STRING);
*/
}
diff --git a/shibsp/logging/LoggingService.h b/shibsp/logging/LoggingService.h
index cecef4f0..b03911e2 100644
--- a/shibsp/logging/LoggingService.h
+++ b/shibsp/logging/LoggingService.h
@@ -40,6 +40,8 @@ namespace shibsp {
public:
virtual ~LoggingService();
+ static const char LOGGING_TYPE_PROP_PATH[];
+
/**
* Initializes the designated logging service.
*/
@@ -48,7 +50,7 @@ namespace shibsp {
/**
* Terminates the designated logging service.
*/
- virtual bool term()=0;
+ virtual void term()=0;
/**
* Retrieves an instance of a logging Category of the specified name (empty is permitted).
diff --git a/shibsp/logging/impl/AbstractLoggingService.cpp b/shibsp/logging/impl/AbstractLoggingService.cpp
index dcf7115f..2c486a11 100644
--- a/shibsp/logging/impl/AbstractLoggingService.cpp
+++ b/shibsp/logging/impl/AbstractLoggingService.cpp
@@ -23,6 +23,8 @@
#include "AgentConfig.h"
#include "logging/impl/AbstractLoggingService.h"
+#include <stdexcept>
+
#include <boost/property_tree/ptree.hpp>
using namespace shibsp;
@@ -56,7 +58,7 @@ void SHIBSP_API shibsp::registerLoggingServices()
#endif
}
-const char AbstractLoggingService::LOGGING_SECTION_NAME[] = "logging";
+const char LoggingService::LOGGING_TYPE_PROP_PATH[] = "logging.type";
const char AbstractLoggingService::CATEGORIES_SECTION_NAME[] = "logging-categories";
const char AbstractLoggingService::DEFAULT_LEVEL_PROP_PATH[] = "logging.default-level";
@@ -70,18 +72,22 @@ LoggingServiceSPI::~LoggingServiceSPI() {}
AbstractLoggingService::~AbstractLoggingService() {}
-AbstractLoggingService::AbstractLoggingService(const ptree& pt)
+AbstractLoggingService::AbstractLoggingService(const ptree& pt) : m_config(pt)
+{
+}
+
+bool AbstractLoggingService::init()
{
// Processes property tree to create mappings from category name to logging level.
// If an invalid property token is seen, the default level is INFO.
try {
- m_defaultPriority = Priority::getPriorityValue(pt.get(DEFAULT_LEVEL_PROP_PATH, "INFO"));
+ m_defaultPriority = Priority::getPriorityValue(m_config.get(DEFAULT_LEVEL_PROP_PATH, "INFO"));
} catch (const invalid_argument& e) {
m_defaultPriority = Priority::PriorityLevel::SHIB_INFO;
}
- const boost::optional<const ptree&> categories = pt.get_child_optional(CATEGORIES_SECTION_NAME);
+ const boost::optional<const ptree&> categories = m_config.get_child_optional(CATEGORIES_SECTION_NAME);
if (categories) {
for (const auto& mapping : categories.get()) {
try {
@@ -91,8 +97,12 @@ AbstractLoggingService::AbstractLoggingService(const ptree& pt)
}
}
}
+
+ return true;
}
+void AbstractLoggingService::term() {}
+
Category& AbstractLoggingService::getCategory(const std::string& name)
{
lock_guard<mutex> locker(m_lock);
diff --git a/shibsp/logging/impl/AbstractLoggingService.h b/shibsp/logging/impl/AbstractLoggingService.h
index 57aaa60f..18f474ff 100644
--- a/shibsp/logging/impl/AbstractLoggingService.h
+++ b/shibsp/logging/impl/AbstractLoggingService.h
@@ -58,13 +58,17 @@ namespace shibsp {
public:
virtual ~AbstractLoggingService();
+ bool init();
+ void term();
+
Category& getCategory(const std::string& name);
- static const char LOGGING_SECTION_NAME[];
static const char CATEGORIES_SECTION_NAME[];
static const char DEFAULT_LEVEL_PROP_PATH[];
private:
+ const boost::property_tree::ptree& m_config;
+
// Default logging level.
Priority::Value m_defaultPriority;
diff --git a/shibsp/logging/impl/Category.cpp b/shibsp/logging/impl/Category.cpp
index 17b43027..b72f14b1 100644
--- a/shibsp/logging/impl/Category.cpp
+++ b/shibsp/logging/impl/Category.cpp
@@ -12,14 +12,16 @@
* limitations under the License.
*/
+#include "AgentConfig.h"
#include "logging/Category.h"
+#include "logging/LoggingService.h"
#include "logging/impl/LoggingServiceSPI.h"
#include "logging/impl/StringUtil.h"
using namespace shibsp;
Category& Category::getInstance(const std::string& name) {
- //return HierarchyMaintainer::getDefaultMaintainer().getInstance(name);
+ return AgentConfig::getConfig().getLoggingService().getCategory(name);
}
Category::Category(LoggingServiceSPI& spi, const std::string& name, Priority::Value priority)
@@ -42,7 +44,7 @@ void Category::_logUnconditionally(Priority::Value priority, const char* format,
}
void Category::_logUnconditionally2(Priority::Value priority, const std::string& message) throw() {
- m_spi.outputMessage(*this, message);
+ m_spi.outputMessage(*this, priority, message);
}
bool Category::isPriorityEnabled(Priority::Value priority) const {
diff --git a/shibsp/logging/impl/ConsoleLoggingService.cpp b/shibsp/logging/impl/ConsoleLoggingService.cpp
index 80c9347e..376cecbf 100644
--- a/shibsp/logging/impl/ConsoleLoggingService.cpp
+++ b/shibsp/logging/impl/ConsoleLoggingService.cpp
@@ -35,12 +35,10 @@ namespace shibsp {
public:
ConsoleLoggingService(const ptree& pt);
- bool init() {}
- bool term() {}
- void outputMessage(const Category& category, const string& message) {
- outputMessage(category, message.c_str());
+ void outputMessage(const Category& category, Priority::Value prio, const string& message) {
+ outputMessage(category, prio, message.c_str());
}
- void outputMessage(const Category& category, const char* message);
+ void outputMessage(const Category& category, Priority::Value prio, const char* message);
};
@@ -56,13 +54,13 @@ ConsoleLoggingService::ConsoleLoggingService(const ptree& pt) : AbstractLoggingS
// message formatting.
}
-void ConsoleLoggingService::outputMessage(const Category& category, const char* message)
+void ConsoleLoggingService::outputMessage(const Category& category, Priority::Value prio, const char* message)
{
auto now = chrono::system_clock::now();
- cerr << date::format("%FT%TZ", date::floor<chrono::milliseconds>(now)) << " - "
- << Priority::getPriorityName(category.getPriority())
- << ' [' << category.getName() << "] - "
+ cout << date::format("%FT%TZ", date::floor<chrono::milliseconds>(now)) << " - "
+ << Priority::getPriorityName(prio)
+ << " [" << category.getName() << "] - "
<< message
<< endl;
}
\ No newline at end of file
diff --git a/shibsp/logging/impl/LoggingServiceSPI.h b/shibsp/logging/impl/LoggingServiceSPI.h
index 9b3bf5b2..38e95534 100644
--- a/shibsp/logging/impl/LoggingServiceSPI.h
+++ b/shibsp/logging/impl/LoggingServiceSPI.h
@@ -39,31 +39,23 @@ namespace shibsp {
public:
virtual ~LoggingServiceSPI();
- /**
- * Initializes the designated logging service.
- */
- virtual bool init()=0;
-
- /**
- * Terminates the designated logging service.
- */
- virtual bool term()=0;
-
/**
* Outputs a logging message in whatever manner is defined by the underlying implementation.
*
* @param category logging category
+ * @param prio logging priority
* @param message logging message
*/
- virtual void outputMessage(const Category& category, const std::string& message)=0;
+ virtual void outputMessage(const Category& category, Priority::Value prio, const std::string& message)=0;
/**
* Outputs a logging message in whatever manner is defined by the underlying implementation.
*
* @param category logging category
+ * @param prio logging priority
* @param message logging message
*/
- virtual void outputMessage(const Category& category, const char* message)=0;
+ virtual void outputMessage(const Category& category, Priority::Value prio, const char* message)=0;
};
};
diff --git a/shibsp/logging/impl/Priority.cpp b/shibsp/logging/impl/Priority.cpp
index efc4b9ff..bebf60f5 100644
--- a/shibsp/logging/impl/Priority.cpp
+++ b/shibsp/logging/impl/Priority.cpp
@@ -15,23 +15,25 @@
#include <shibsp/logging/Priority.h>
#include <cstdlib>
+#include <stdexcept>
using namespace shibsp;
+using namespace std;
namespace {
- const std::string names[7] = {
+ const string names[7] = {
"CRIT", "ERROR", "WARN", "INFO", "DEBUG", "NOTSET", "UNKNOWN"
};
}
-const std::string& Priority::getPriorityName(int priority) throw() {
+const string& Priority::getPriorityName(int priority) throw() {
priority++;
priority /= 100;
return names[((priority < 0) || (priority > 5)) ? 5 : priority];
}
-Priority::Value Priority::getPriorityValue(const std::string& priorityName) {
+Priority::Value Priority::getPriorityValue(const string& priorityName) {
Priority::Value value = -1;
for (unsigned int i = 0; i < 7; i++) {
@@ -43,9 +45,9 @@ Priority::Value Priority::getPriorityValue(const std::string& priorityName) {
if (value == -1) {
char* endPointer;
- value = std::strtoul(priorityName.c_str(), &endPointer, 10);
+ value = strtoul(priorityName.c_str(), &endPointer, 10);
if (*endPointer != 0) {
- throw std::invalid_argument(std::string("unknown priority name: '") + priorityName + "'");
+ throw invalid_argument(string("unknown priority name: '") + priorityName + "'");
}
}
diff --git a/shibsp/util/PathResolver.cpp b/shibsp/util/PathResolver.cpp
index a1db5fd3..1e63c6f0 100644
--- a/shibsp/util/PathResolver.cpp
+++ b/shibsp/util/PathResolver.cpp
@@ -27,7 +27,7 @@
#include "internal.h"
#include "util/PathResolver.h"
-#include <exception>
+#include <stdexcept>
#ifdef WIN32
# include <Shlobj.h>
diff --git a/tests/AgentConfigTests.cpp b/tests/AgentConfigTests.cpp
new file mode 100644
index 00000000..e799069a
--- /dev/null
+++ b/tests/AgentConfigTests.cpp
@@ -0,0 +1,87 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * AgentConfigTests.cpp
+ *
+ * Unit tests for agent config machinery and logging.
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <boost/property_tree/ini_parser.hpp>
+
+#include "AgentConfig.h"
+
+using namespace boost::property_tree::ini_parser;
+using namespace shibsp;
+using namespace std;
+
+// The ./ bypasses the usual path resolution for relative paths.
+#define DATA_PATH "./data/"
+
+struct AC_Fixture {
+ AC_Fixture() : data_path(DATA_PATH) {}
+ string data_path;
+};
+
+class exceptionCheck {
+public:
+ exceptionCheck(const string& msg) : m_msg(msg) {}
+ bool check_message(const ini_parser_error& e) {
+ return e.message().compare(m_msg) == 0;
+ }
+private:
+ string m_msg;
+};
+
+BOOST_FIXTURE_TEST_CASE(AgentConfig_init_bad_path, AC_Fixture)
+{
+ // No throw.
+ BOOST_CHECK(!AgentConfig::getConfig().init(nullptr, (data_path + "missing.ini").c_str(), false));
+
+ exceptionCheck checker("cannot open file");
+
+ // Throw.
+ BOOST_CHECK_EXCEPTION(AgentConfig::getConfig().init(nullptr, (data_path + "missing.ini").c_str(), true),
+ ini_parser_error, checker.check_message);
+}
+
+BOOST_FIXTURE_TEST_CASE(AgentConfig_init_bad_format, AC_Fixture)
+{
+ exceptionCheck checker_unmatched("unmatched '['");
+ BOOST_CHECK_EXCEPTION(AgentConfig::getConfig().init(nullptr, (data_path + "unmatched_shibboleth.ini").c_str(), true),
+ ini_parser_error, checker_unmatched.check_message);
+
+ exceptionCheck checker_dupsection("duplicate section name");
+ BOOST_CHECK_EXCEPTION(AgentConfig::getConfig().init(nullptr, (data_path + "dupsection_shibboleth.ini").c_str(), true),
+ ini_parser_error, checker_dupsection.check_message);
+
+ exceptionCheck checker_noequals("'=' character not found in line");
+ BOOST_CHECK_EXCEPTION(AgentConfig::getConfig().init(nullptr, (data_path + "noequals_shibboleth.ini").c_str(), true),
+ ini_parser_error, checker_noequals.check_message);
+
+ exceptionCheck checker_dupproperty("duplicate key name");
+ BOOST_CHECK_EXCEPTION(AgentConfig::getConfig().init(nullptr, (data_path + "dupproperty_shibboleth.ini").c_str(), true),
+ ini_parser_error, checker_dupproperty.check_message);
+
+ exceptionCheck checker_nokey("key expected");
+ BOOST_CHECK_EXCEPTION(AgentConfig::getConfig().init(nullptr, (data_path + "nokey_shibboleth.ini").c_str(), true),
+ ini_parser_error, checker_nokey.check_message);
+}
+
+BOOST_FIXTURE_TEST_CASE(AgentConfig_init_success, AC_Fixture)
+{
+ BOOST_CHECK(AgentConfig::getConfig().init(nullptr, (data_path + "shibboleth.ini").c_str(), true));
+ AgentConfig::getConfig().term();
+}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index edf67c90..b6b61a25 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -11,6 +11,7 @@ shibsptest_CXXFLAGS = \
shibsptest_SOURCES = \
AgentTestSuite.cpp \
+ AgentConfigTests.cpp \
util/PropertyTreeTests.cpp \
util/BoostPropertySetTests.cpp
diff --git a/tests/data/dupproperty_shibboleth.ini b/tests/data/dupproperty_shibboleth.ini
new file mode 100644
index 00000000..b95a216f
--- /dev/null
+++ b/tests/data/dupproperty_shibboleth.ini
@@ -0,0 +1,3 @@
+[bar]
+foo = bar
+foo = bar
diff --git a/tests/data/dupsection_shibboleth.ini b/tests/data/dupsection_shibboleth.ini
new file mode 100644
index 00000000..68985037
--- /dev/null
+++ b/tests/data/dupsection_shibboleth.ini
@@ -0,0 +1,5 @@
+[foo]
+bar = baz
+
+[foo]
+baz = baf
diff --git a/tests/data/noequals_shibboleth.ini b/tests/data/noequals_shibboleth.ini
new file mode 100644
index 00000000..9bc83d60
--- /dev/null
+++ b/tests/data/noequals_shibboleth.ini
@@ -0,0 +1,2 @@
+[foo]
+bar
diff --git a/tests/data/nokey_shibboleth.ini b/tests/data/nokey_shibboleth.ini
new file mode 100644
index 00000000..ca45a379
--- /dev/null
+++ b/tests/data/nokey_shibboleth.ini
@@ -0,0 +1,2 @@
+[foo]
+=bar
diff --git a/tests/data/shibboleth.ini b/tests/data/shibboleth.ini
new file mode 100644
index 00000000..c8471aa8
--- /dev/null
+++ b/tests/data/shibboleth.ini
@@ -0,0 +1,6 @@
+[logging]
+type = console
+default-level = WARN
+
+[logging-categories]
+Shibboleth.AgentConfig = DEBUG
diff --git a/tests/data/unmatched_shibboleth.ini b/tests/data/unmatched_shibboleth.ini
new file mode 100644
index 00000000..3316e1e1
--- /dev/null
+++ b/tests/data/unmatched_shibboleth.ini
@@ -0,0 +1 @@
+[unmatched
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list