PROTON-1974: [cpp] modify to work with older jsoncpp (1.7.4) - add jsoncpp to travis packages for CI testing - fix string conversions - rules changed between 1.7.4 and 1.8 - better error handling/reporting
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/aa85a1fe Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/aa85a1fe Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/aa85a1fe Branch: refs/heads/go1 Commit: aa85a1fe86827656501fe01f5695cd7ff4a842f3 Parents: ab82a8b Author: Alan Conway <acon...@redhat.com> Authored: Tue Oct 2 11:40:16 2018 -0400 Committer: Alan Conway <acon...@redhat.com> Committed: Tue Oct 2 13:53:11 2018 -0400 ---------------------------------------------------------------------- .travis.yml | 1 + cpp/CMakeLists.txt | 23 ++++++++++++++------- cpp/src/connect_config.cpp | 39 ++++++++++++++++++++++++------------ cpp/src/connect_config_test.cpp | 12 ++++++----- 4 files changed, 50 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/aa85a1fe/.travis.yml ---------------------------------------------------------------------- diff --git a/.travis.yml b/.travis.yml index d3fd7c9..6a8aa2e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -72,6 +72,7 @@ addons: - python3-dev - golang - lcov + - libjsoncpp-dev install: - python -m pip install --user --upgrade pip http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/aa85a1fe/cpp/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index f3c93fb..794fcbe 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -247,7 +247,22 @@ install (FILES DESTINATION ${LIB_INSTALL_DIR}/cmake/ProtonCpp) set(testdata "${CMAKE_CURRENT_BINARY_DIR}/testdata") -set(test_env "PN_SASL_CONFIG_PATH=${testdata}/sasl-conf") + +# SASL configuration for tests +if(CyrusSASL_Saslpasswd_EXECUTABLE) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/testdata/sasl-conf/proton-server.conf.in" + "${testdata}/sasl-conf/proton-server.conf") + execute_process( + COMMAND echo password + COMMAND ${CyrusSASL_Saslpasswd_EXECUTABLE} -c -p -f "${testdata}/sasl-conf/proton.sasldb" -u proton user + RESULT_VARIABLE ret) + if(ret) + message(WARNING "${CyrusSASL_Saslpasswd_EXECUTABLE}: error ${ret} - some SASL tests will be skipped") + else() + set(test_env ${test_env} "PN_SASL_CONFIG_PATH=${testdata}/sasl-conf") + endif() +endif() + if (CMAKE_SYSTEM_NAME STREQUAL Windows) set(test_env ${test_env} "PATH=$<TARGET_FILE_DIR:qpid-proton>") endif() @@ -276,10 +291,4 @@ if (ENABLE_JSONCPP) set_tests_properties(cpp-connect_config_test PROPERTIES WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") # Test data and output directories for connect_config_test file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/testdata" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") - if(CyrusSASL_Saslpasswd_EXECUTABLE) - configure_file("${CMAKE_CURRENT_SOURCE_DIR}/testdata/sasl-conf/proton-server.conf.in" - "${testdata}/sasl-conf/proton-server.conf") - execute_process(COMMAND echo password - COMMAND ${CyrusSASL_Saslpasswd_EXECUTABLE} -c -p -f "${testdata}/sasl-conf/proton.sasldb" -u proton user) - endif() endif() http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/aa85a1fe/cpp/src/connect_config.cpp ---------------------------------------------------------------------- diff --git a/cpp/src/connect_config.cpp b/cpp/src/connect_config.cpp index 2bcbfc2..d157d67 100644 --- a/cpp/src/connect_config.cpp +++ b/cpp/src/connect_config.cpp @@ -27,9 +27,11 @@ #include <json/value.h> #include <json/reader.h> +#include <json/writer.h> #include <cstdlib> #include <fstream> +#include <sstream> using namespace Json; using std::string; @@ -71,7 +73,7 @@ Value validate(ValueType t, const Value& v, const string& name) { Value get(ValueType t, const Value& obj, const char *key, const Value& dflt=Value()) { Value v = obj.get(key, dflt); - return v.type() == nullValue ? dflt : validate(t, v, key); + return v.isNull() ? dflt : validate(t, v, key); } bool get_bool(const Value& obj, const char *key, bool dflt) { @@ -94,7 +96,7 @@ void parse_sasl(Value root, connection_options& opts) { Value sasl = get(objectValue, root, "sasl"); opts.sasl_enabled(get_bool(sasl, "enable", true)); opts.sasl_allow_insecure_mechs(get_bool(sasl, "allow_insecure", false)); - if (sasl.type() != nullValue) { + if (!sasl.isNull()) { Value mechs = sasl.get("mechanisms", Value()); switch (mechs.type()) { case nullValue: @@ -106,9 +108,7 @@ void parse_sasl(Value root, connection_options& opts) { std::ostringstream s; for (ArrayIndex i= 0; i < mechs.size(); ++i) { Value v = mechs.get(i, Value()); - if (v.type() != stringValue) { - throw err(msg() << "'sasl/mechanisms' expect string elements, found " << v.type()); - } + validate(stringValue, v, "sasl/mechanisms"); if (i > 0) s << " "; s << v.asString(); } @@ -137,7 +137,7 @@ void parse_tls(const string& scheme, Value root, connection_options& opts) { ssl_opts = ssl_client_options(ca, mode); } opts.ssl_client_options(ssl_opts); - } else if (tls.type() != nullValue) { + } else if (!tls.isNull()) { throw err(msg() << "'tls' object not allowed unless scheme is \"amqps\""); } } @@ -146,8 +146,11 @@ void parse_tls(const string& scheme, Value root, connection_options& opts) { std::string parse(std::istream& is, connection_options& opts) { try { + std::ostringstream addr; + Value root; is >> root; + validate(objectValue, root, "configuration"); string scheme = get_string(root, "scheme", "amqps"); if (scheme != "amqp" && scheme != "amqps") { @@ -156,20 +159,28 @@ std::string parse(std::istream& is, connection_options& opts) { string host = get_string(root, "host", "localhost"); opts.virtual_host(host.c_str()); + addr << host << ":"; Value port = root.get("port", scheme); - if (!port.isIntegral() && !port.isString()) { - throw err(msg() << "'port' expected string or integer, found " << port.type()); + switch (port.type()) { + case stringValue: + addr << port.asString(); break; + case intValue: + case uintValue: + addr << port.asUInt(); break; + default: + throw err(msg() << "'port' expected string or uint, found " << port.type()); } Value user = get(stringValue, root, "user"); - if (user.type() != nullValue) opts.user(user.asString()); + if (!user.isNull()) opts.user(user.asString()); Value password = get(stringValue, root, "password"); - if (password.type() != nullValue) opts.password(password.asString()); + if (!password.isNull()) opts.password(password.asString()); parse_sasl(root, opts); parse_tls(scheme, root, opts); - return host + ":" + port.asString(); + + return addr.str(); } catch (const std::exception& e) { throw err(e.what()); } catch (...) { @@ -203,17 +214,19 @@ string parse_default(connection_options& opts) { string name = default_file(); std::ifstream f; try { - f.exceptions(~std::ifstream::goodbit); + f.exceptions(std::ifstream::badbit|std::ifstream::failbit); f.open(name.c_str()); } catch (const std::exception& e) { throw err(msg() << "error opening '" << name << "': " << e.what()); } try { return parse(f, opts); + } catch (const std::ifstream::failure& e) { + throw err(msg() << "io error parsing '" << name << "': " << e.what()); } catch (const std::exception& e) { throw err(msg() << "error parsing '" << name << "': " << e.what()); } catch (...) { - throw err(msg() << "error parsing '" << name); + throw err(msg() << "error parsing '" << name << "'"); } } http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/aa85a1fe/cpp/src/connect_config_test.cpp ---------------------------------------------------------------------- diff --git a/cpp/src/connect_config_test.cpp b/cpp/src/connect_config_test.cpp index 0573f8f..8a17bba 100644 --- a/cpp/src/connect_config_test.cpp +++ b/cpp/src/connect_config_test.cpp @@ -38,8 +38,6 @@ #include <fstream> #include <cstdio> -#include <stdlib.h> - namespace { using namespace std; @@ -80,7 +78,7 @@ void test_addr() { ASSERT_THROWS_MSG(error, "'scheme' must be", configure(opts, "{\"scheme\":\"bad\"}")); ASSERT_THROWS_MSG(error, "'scheme' expected string, found boolean", configure(opts, "{\"scheme\":true}")); - ASSERT_THROWS_MSG(error, "'port' expected string or integer, found boolean", configure(opts, "{\"port\":true}")); + ASSERT_THROWS_MSG(error, "'port' expected string or uint, found boolean", configure(opts, "{\"port\":true}")); ASSERT_THROWS_MSG(error, "'host' expected string, found boolean", configure(opts, "{\"host\":true}")); } @@ -270,14 +268,18 @@ int main(int argc, char** argv) { RUN_ARGV_TEST(failed, test_addr()); RUN_ARGV_TEST(failed, test_invalid()); RUN_ARGV_TEST(failed, test_default_connect().run()); - RUN_ARGV_TEST(failed, test_host_user_pass().run()); + bool have_sasl = pn_sasl_extended() && getenv("PN_SASL_CONFIG_PATH"); pn_ssl_domain_t *have_ssl = pn_ssl_domain(PN_SSL_MODE_SERVER); + + if (have_sasl) { + RUN_ARGV_TEST(failed, test_host_user_pass().run()); + } if (have_ssl) { pn_ssl_domain_free(have_ssl); RUN_ARGV_TEST(failed, test_tls().run()); RUN_ARGV_TEST(failed, test_tls_external().run()); - if (pn_sasl_extended()) { + if (have_sasl) { RUN_ARGV_TEST(failed, test_tls_plain().run()); } } else { --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org For additional commands, e-mail: commits-h...@qpid.apache.org