You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2017/11/15 21:05:25 UTC
[01/31] qpid-proton git commit: PROTON-1641: Windows proactor hang on
inbound connections
Repository: qpid-proton
Updated Branches:
refs/heads/go1 14f7ca56f -> 6c48527c1
PROTON-1641: Windows proactor hang on inbound connections
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/686a400c
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/686a400c
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/686a400c
Branch: refs/heads/go1
Commit: 686a400c907c5f03d9ce5ec542752ec9d1651812
Parents: 97815c3
Author: Clifford Jansen <cl...@apache.org>
Authored: Thu Oct 19 13:13:38 2017 -0700
Committer: Clifford Jansen <cl...@apache.org>
Committed: Thu Oct 19 13:13:38 2017 -0700
----------------------------------------------------------------------
proton-c/src/proactor/win_iocp.c | 1 +
1 file changed, 1 insertion(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/686a400c/proton-c/src/proactor/win_iocp.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proactor/win_iocp.c b/proton-c/src/proactor/win_iocp.c
index 09d39cf..51b4874 100644
--- a/proton-c/src/proactor/win_iocp.c
+++ b/proton-c/src/proactor/win_iocp.c
@@ -3185,6 +3185,7 @@ void pn_listener_accept(pn_listener_t *l, pn_connection_t *c) {
conn_iocpd->active_completer =&pc->psocket;
set_sock_names(pc);
pc->started = true;
+ csguard g(&pc->context.cslock);
pni_iocpdesc_start(conn_iocpd);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[24/31] qpid-proton git commit: PROTON-1663: [ruby] use cmake status
messages, not warnings if ruby deps not found
Posted by ac...@apache.org.
PROTON-1663: [ruby] use cmake status messages, not warnings if ruby deps not found
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/a1ceb2f1
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/a1ceb2f1
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/a1ceb2f1
Branch: refs/heads/go1
Commit: a1ceb2f15b0870ea6748fb9c9a2276c3c7d00722
Parents: 9cd879e
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 30 16:43:19 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 30 16:43:19 2017 -0400
----------------------------------------------------------------------
proton-c/bindings/ruby/CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a1ceb2f1/proton-c/bindings/ruby/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/CMakeLists.txt b/proton-c/bindings/ruby/CMakeLists.txt
index ff88ddd..5ceb7f0 100644
--- a/proton-c/bindings/ruby/CMakeLists.txt
+++ b/proton-c/bindings/ruby/CMakeLists.txt
@@ -119,7 +119,7 @@ if (result EQUAL 0) # Have minitest
endforeach()
else()
# No minitest
- message(WARNING "ruby tests will not run, minitest is not installed")
+ message(STATUS "Ruby tests will not run, minitest is not installed")
endif()
## Documentation
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[23/31] qpid-proton git commit: PROTON-1664: Ensure that C++ examples
build standalone
Posted by ac...@apache.org.
PROTON-1664: Ensure that C++ examples build standalone
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/9cd879eb
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/9cd879eb
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/9cd879eb
Branch: refs/heads/go1
Commit: 9cd879eba69e7bf4182d24f72b74110252a910ce
Parents: ae1f143
Author: Andrew Stitcher <as...@apache.org>
Authored: Mon Oct 30 15:56:34 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Mon Oct 30 15:56:34 2017 -0400
----------------------------------------------------------------------
examples/cpp/CMakeLists.txt | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9cd879eb/examples/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt
index 3967fc1..018a03e 100644
--- a/examples/cpp/CMakeLists.txt
+++ b/examples/cpp/CMakeLists.txt
@@ -21,6 +21,8 @@ cmake_minimum_required (VERSION 2.8.7)
enable_language(CXX)
find_package(ProtonCpp REQUIRED)
+set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
+find_package(Threads)
include_directories(${ProtonCpp_INCLUDE_DIRS})
link_libraries(${ProtonCpp_LIBRARIES})
@@ -68,12 +70,19 @@ if(HAS_CPP11)
# Examples that require C++11
foreach(example
scheduled_send
- service_bus
- multithreaded_client
- multithreaded_client_flow_control
- )
+ service_bus)
add_executable(${example} ${example}.cpp)
endforeach()
+
+ # Examples that use threads directly
+ if (Threads_FOUND)
+ foreach(example
+ multithreaded_client
+ multithreaded_client_flow_control)
+ add_executable(${example} ${example}.cpp)
+ target_link_libraries(${example} ${CMAKE_THREAD_LIBS_INIT})
+ endforeach()
+ endif()
endif()
# Add a test with the correct environment to find test executables and valgrind.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[21/31] qpid-proton git commit: PROTON-1650: Add extern "C" to
netaddr.h
Posted by ac...@apache.org.
PROTON-1650: Add extern "C" to netaddr.h
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/61808383
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/61808383
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/61808383
Branch: refs/heads/go1
Commit: 61808383e7cb50275653c990bc8450e1b97e7d3a
Parents: 705f835
Author: Andrew Stitcher <as...@apache.org>
Authored: Mon Oct 30 10:50:09 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Mon Oct 30 10:50:09 2017 -0400
----------------------------------------------------------------------
proton-c/include/proton/netaddr.h | 8 ++++++++
1 file changed, 8 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/61808383/proton-c/include/proton/netaddr.h
----------------------------------------------------------------------
diff --git a/proton-c/include/proton/netaddr.h b/proton-c/include/proton/netaddr.h
index bd2f9c1..7f21d93 100644
--- a/proton-c/include/proton/netaddr.h
+++ b/proton-c/include/proton/netaddr.h
@@ -23,6 +23,10 @@
#include <proton/import_export.h>
#include <proton/types.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/**
* @file
*
@@ -73,4 +77,8 @@ PNP_EXTERN size_t pn_netaddr_socklen(const pn_netaddr_t *na);
* @}
*/
+#ifdef __cplusplus
+}
+#endif
+
#endif /* PROTON_NETADDR_H */
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[03/31] qpid-proton git commit: PROTON-1639: epoll.c assert() on
immediate connect() failure
Posted by ac...@apache.org.
PROTON-1639: epoll.c assert() on immediate connect() failure
The epoll proactor was asserting if a connect() call failed immediately.
This doesn't show up in most tests because the connect() is non-blocking, and
most failures are deferred to epoll and handled correctly
However trying to connect() to an IPv6 address with IPv6 disabled does fail
immediately and causes an assert() failure.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/e479d4c0
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/e479d4c0
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/e479d4c0
Branch: refs/heads/go1
Commit: e479d4c0c65c8fe7aec60f6b34416c70d99e93fc
Parents: b94d7dd
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Oct 20 14:35:18 2017 +0100
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Oct 20 14:57:45 2017 +0100
----------------------------------------------------------------------
proton-c/src/proactor/epoll.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e479d4c0/proton-c/src/proactor/epoll.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proactor/epoll.c b/proton-c/src/proactor/epoll.c
index d5a323c..6234d4b 100644
--- a/proton-c/src/proactor/epoll.c
+++ b/proton-c/src/proactor/epoll.c
@@ -129,7 +129,7 @@ typedef struct epoll_extended_t {
pmutex barrier_mutex;
} epoll_extended_t;
-/* epoll_ctl()/epoll_wake() do not form a memory barrier, so cached memory
+/* epoll_ctl()/epoll_wait() do not form a memory barrier, so cached memory
writes to struct epoll_extended_t in the EPOLL_ADD thread might not be
visible to epoll_wait() thread. This function creates a memory barrier,
called before epoll_ctl() and after epoll_wait()
@@ -1267,7 +1267,7 @@ void pn_proactor_connect(pn_proactor_t *p, pn_connection_t *c, const char *addr)
pn_connection_open(pc->driver.connection); /* Auto-open */
pc->ai = pc->addrinfo;
pconnection_maybe_connect_lh(pc); /* Start connection attempts */
- notify = pc->disconnected;
+ if (pc->disconnected) notify = wake(&pc->context);
} else {
psocket_gai_error(&pc->psocket, gai_error, "connect to ");
notify = wake(&pc->context);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[04/31] qpid-proton git commit: PROTON-1639 proton.c ipv6 test does
not detect lack of ipv6 support
Posted by ac...@apache.org.
PROTON-1639 proton.c ipv6 test does not detect lack of ipv6 support
The test was checking for IPV6 by listening on "::" INADDR6_ANY.
On some IPV6-capable platforms with IPV6 disabled, this listen() succeeds even
though it not possible to connect to the listening port.
Modified the test to listen() on "::1" INADDR6_LOOPBACK. A host without ipv6
disabled should report this as an error as it will not have an IPV6 loopback
available.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/b94d7dd3
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/b94d7dd3
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/b94d7dd3
Branch: refs/heads/go1
Commit: b94d7dd3e72728ee002271d329c1be835b4fa161
Parents: 63b8528
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Oct 20 12:24:37 2017 +0100
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Oct 20 14:57:45 2017 +0100
----------------------------------------------------------------------
proton-c/src/tests/proactor.c | 57 +++++++++++++++++++++-----------------
1 file changed, 32 insertions(+), 25 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b94d7dd3/proton-c/src/tests/proactor.c
----------------------------------------------------------------------
diff --git a/proton-c/src/tests/proactor.c b/proton-c/src/tests/proactor.c
index a0b2a15..aecbd3e 100644
--- a/proton-c/src/tests/proactor.c
+++ b/proton-c/src/tests/proactor.c
@@ -142,10 +142,12 @@ typedef struct test_listener_t {
pn_listener_t *listener;
} test_listener_t;
+/* Return a listening test_listener_t, raise errors if not successful */
test_listener_t test_listen(test_proactor_t *tp, const char *host) {
test_listener_t l = { test_port(host), pn_listener() };
pn_proactor_listen(tp->proactor, l.listener, l.port.host_port, 4);
TEST_ETYPE_EQUAL(tp->handler.t, PN_LISTENER_OPEN, test_proactors_run(tp, 1));
+ TEST_COND_EMPTY(tp->handler.t, last_condition);
test_port_close(&l.port);
return l;
}
@@ -507,7 +509,8 @@ static void test_errors(test_t *t) {
TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));
pn_proactor_listen(server, pn_listener(), "127.0.0.1:xxx", 1);
- TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps));
+ TEST_PROACTORS_RUN(tps);
+ TEST_HANDLER_EXPECT(&tps[1].handler, PN_LISTENER_CLOSE, 0); /* CLOSE only, no OPEN */
TEST_COND_DESC(t, "xxx", last_condition);
TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));
@@ -518,8 +521,10 @@ static void test_errors(test_t *t) {
TEST_COND_DESC(t, "nosuch", last_condition);
TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));
+ test_handler_clear(&tps[1].handler, 0);
pn_proactor_listen(server, pn_listener(), "nosuch.example.com:", 1);
- TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps));
+ TEST_PROACTORS_RUN(tps);
+ TEST_HANDLER_EXPECT(&tps[1].handler, PN_LISTENER_CLOSE, 0); /* CLOSE only, no OPEN */
TEST_COND_DESC(t, "nosuch", last_condition);
TEST_ETYPE_EQUAL(t, PN_PROACTOR_INACTIVE, TEST_PROACTORS_RUN(tps));
@@ -528,8 +533,10 @@ static void test_errors(test_t *t) {
pn_listener_t *l = pn_listener();
pn_proactor_listen(server, l, port.host_port, 1);
TEST_ETYPE_EQUAL(t, PN_LISTENER_OPEN, TEST_PROACTORS_RUN(tps));
+ test_handler_clear(&tps[1].handler, 0);
pn_proactor_listen(server, pn_listener(), port.host_port, 1); /* Busy */
- TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps));
+ TEST_PROACTORS_RUN(tps);
+ TEST_HANDLER_EXPECT(&tps[1].handler, PN_LISTENER_CLOSE, 0); /* CLOSE only, no OPEN */
TEST_COND_NAME(t, "proton:io", last_condition);
pn_listener_close(l);
TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps));
@@ -580,26 +587,14 @@ static void test_proton_1586(test_t *t) {
/* Test that we can control listen/select on ipv6/v4 and listen on both by default */
static void test_ipv4_ipv6(test_t *t) {
test_proactor_t tps[] ={ test_proactor(t, open_close_handler), test_proactor(t, listen_handler) };
- pn_proactor_t *client = tps[0].proactor;
-
- /* Listen on all interfaces for IPv6 only. If this fails, skip IPv6 tests */
- test_listener_t l6 = test_listen(&tps[1], "::");
- pn_event_type_t e = TEST_PROACTORS_GET(tps);
- bool has_ipv6 = (e != PN_LISTENER_CLOSE);
- if (!has_ipv6) {
- TEST_LOGF(t, "skip IPv6 tests: %s", pn_condition_get_description(last_condition));
- }
- TEST_PROACTORS_DRAIN(tps);
+ pn_proactor_t *client = tps[0].proactor, *server = tps[1].proactor;
/* Listen on all interfaces for IPv4 only. */
test_listener_t l4 = test_listen(&tps[1], "0.0.0.0");
- TEST_CHECKF(t, TEST_PROACTORS_GET(tps) != PN_LISTENER_CLOSE, "listener error: %s", pn_condition_get_description(last_condition));
TEST_PROACTORS_DRAIN(tps);
/* Empty address listens on both IPv4 and IPv6 on all interfaces */
test_listener_t l = test_listen(&tps[1], "");
- e = TEST_PROACTORS_GET(tps);
- TEST_CHECKF(t, TEST_PROACTORS_GET(tps) != PN_LISTENER_CLOSE, "listener error: %s", pn_condition_get_description(last_condition));
TEST_PROACTORS_DRAIN(tps);
#define EXPECT_CONNECT(TP, HOST) do { \
@@ -622,25 +617,37 @@ static void test_ipv4_ipv6(test_t *t) {
EXPECT_CONNECT(l.port, "127.0.0.1"); /* v4->all */
EXPECT_CONNECT(l.port, ""); /* local->all */
- if (has_ipv6) {
+ /* Listen on ipv6 loopback, if it fails skip ipv6 tests.
+
+ NOTE: Don't use the unspecified address "::" here - ipv6-disabled platforms
+ may allow listening on "::" without complaining. However they won't have a
+ local ipv6 loopback configured, so "::1" will force an error.
+ */
+ TEST_PROACTORS_DRAIN(tps);
+ test_listener_t l6 = { test_port("::1"), pn_listener() };
+ pn_proactor_listen(server, l6.listener, l6.port.host_port, 4);
+ pn_event_type_t e = TEST_PROACTORS_RUN(tps);
+ if (e == PN_LISTENER_OPEN && !pn_condition_is_set(last_condition)) {
+ TEST_PROACTORS_DRAIN(tps);
+
EXPECT_CONNECT(l6.port, "::1"); /* v6->v6 */
- EXPECT_CONNECT(l6.port, ""); /* local->v6 */
- EXPECT_CONNECT(l.port, "::1"); /* v6->all */
+ EXPECT_CONNECT(l6.port, ""); /* local->v6 */
+ EXPECT_CONNECT(l.port, "::1"); /* v6->all */
EXPECT_FAIL(l6.port, "127.0.0.1"); /* fail v4->v6 */
EXPECT_FAIL(l4.port, "::1"); /* fail v6->v4 */
+
+ pn_listener_close(l6.listener);
+ } else {
+ const char *d = pn_condition_get_description(last_condition);
+ TEST_LOGF(t, "skip IPv6 tests: %s %s", pn_event_type_name(e), d ? d : "no condition");
}
- TEST_PROACTORS_DRAIN(tps);
+ TEST_PROACTORS_DRAIN(tps);
pn_listener_close(l.listener);
TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps));
pn_listener_close(l4.listener);
TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps));
- if (has_ipv6) {
- pn_listener_close(l6.listener);
- TEST_ETYPE_EQUAL(t, PN_LISTENER_CLOSE, TEST_PROACTORS_RUN(tps));
- }
-
TEST_PROACTORS_DESTROY(tps);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[06/31] qpid-proton git commit: PROTON-1611: Fix that meets the high
standards of aconway!
Posted by ac...@apache.org.
PROTON-1611: Fix that meets the high standards of aconway!
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/b9bb35b1
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/b9bb35b1
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/b9bb35b1
Branch: refs/heads/go1
Commit: b9bb35b1573cedc11f8734441d046b6e28934c9c
Parents: 79cc60f
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Oct 19 19:06:02 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Fri Oct 20 15:21:44 2017 -0400
----------------------------------------------------------------------
CMakeLists.txt | 13 ++++++++++---
appveyor.yml | 5 ++++-
proton-c/bindings/CMakeLists.txt | 7 +++----
3 files changed, 17 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b9bb35b1/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3bec2d1..75310bd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,8 +18,7 @@
#
cmake_minimum_required (VERSION 2.8.7)
-# project defaults to C and C++ languages
-project (Proton)
+project (Proton C)
# Enable testing
enable_testing()
@@ -28,13 +27,21 @@ include (CTest)
# Pull in local cmake modules
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/tools/cmake/Modules/")
+include (CheckLanguage)
+check_language(CXX)
+if (CMAKE_CXX_COMPILER)
+ enable_language(CXX)
+endif()
+
# TODO - Should change this test to take account of recent MSVC that does support C99
if (MSVC)
# No C99 capability, use C++
set(DEFAULT_BUILD_WITH_CXX ON)
endif (MSVC)
-option(BUILD_WITH_CXX "Compile Proton using C++" ${DEFAULT_BUILD_WITH_CXX})
+if (CMAKE_CXX_COMPILER)
+ option(BUILD_WITH_CXX "Compile Proton using C++" ${DEFAULT_BUILD_WITH_CXX})
+endif()
if (CMAKE_CONFIGURATION_TYPES)
# There is no single "build type"...
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b9bb35b1/appveyor.yml
----------------------------------------------------------------------
diff --git a/appveyor.yml b/appveyor.yml
index 0ee66ad..49f17ad 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,5 +1,7 @@
version: '{branch}.{build}'
configuration: RelWithDebInfo
+environment:
+ CMAKE_GENERATOR: Visual Studio 12
install:
- cinst -y swig
cache:
@@ -8,9 +10,10 @@ cache:
before_build:
- mkdir BLD
- cd BLD
-- cmake -G "Visual Studio 12" -DBUILD_PERL=no %QPID_PROTON_CMAKE_ARGS% ..
+- cmake -G "%CMAKE_GENERATOR%" -DBUILD_PERL=no %QPID_PROTON_CMAKE_ARGS% ..
- cd ..
build:
+ project: BLD/Proton.sln
parallel: true
verbosity: normal
test_script:
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b9bb35b1/proton-c/bindings/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/CMakeLists.txt b/proton-c/bindings/CMakeLists.txt
index 9a431d7..5362f92 100644
--- a/proton-c/bindings/CMakeLists.txt
+++ b/proton-c/bindings/CMakeLists.txt
@@ -31,10 +31,9 @@ if (EMSCRIPTEN_FOUND)
set (DEFAULT_JAVASCRIPT ON)
endif (EMSCRIPTEN_FOUND)
-# It is impossible to easily test for the presence of a C++ compiler! so set this on by default
-# That is because the OPTIONAL attribute to enable_language() does nothing (as of CMake 3.9.1)
-# so if C++ is not present the build will fail anyway!
-set (DEFAULT_CPP ON)
+if (CMAKE_CXX_COMPILER)
+ set (DEFAULT_CPP ON)
+endif()
# Prerequisites for Go
find_program(GO_EXE go)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[10/31] qpid-proton git commit: PROTON-1628: [cpp] Stopping container
in on_container_start will hang
Posted by ac...@apache.org.
PROTON-1628: [cpp] Stopping container in on_container_start will hang
Check if already stopping before entering the event loop in container::impl::thread()
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/e1708890
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/e1708890
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/e1708890
Branch: refs/heads/go1
Commit: e1708890cad88175f5465275a854bd279b7109bc
Parents: d09511f
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 23 17:24:10 2017 +0100
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 23 17:24:10 2017 +0100
----------------------------------------------------------------------
proton-c/bindings/cpp/src/container_test.cpp | 30 +++++++---
.../cpp/src/proactor_container_impl.cpp | 63 ++++++++++++--------
2 files changed, 59 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e1708890/proton-c/bindings/cpp/src/container_test.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/container_test.cpp b/proton-c/bindings/cpp/src/container_test.cpp
index fc368d0..c0a9734 100644
--- a/proton-c/bindings/cpp/src/container_test.cpp
+++ b/proton-c/bindings/cpp/src/container_test.cpp
@@ -245,17 +245,31 @@ int test_container_schedule_nohang() {
return 0;
}
+class immediate_stop_tester : public proton::messaging_handler {
+public:
+ void on_container_start(proton::container &c) PN_CPP_OVERRIDE {
+ c.stop();
+ }
+};
+
+int test_container_immediate_stop() {
+ immediate_stop_tester t;
+ proton::container(t).run(); // will hang
+ return 0;
}
-int main(int, char**) {
+} // namespace
+
+int main(int argc, char** argv) {
int failed = 0;
- RUN_TEST(failed, test_container_default_container_id());
- RUN_TEST(failed, test_container_vhost());
- RUN_TEST(failed, test_container_default_vhost());
- RUN_TEST(failed, test_container_no_vhost());
- RUN_TEST(failed, test_container_bad_address());
- RUN_TEST(failed, test_container_stop());
- RUN_TEST(failed, test_container_schedule_nohang());
+ RUN_ARGV_TEST(failed, test_container_default_container_id());
+ RUN_ARGV_TEST(failed, test_container_vhost());
+ RUN_ARGV_TEST(failed, test_container_default_vhost());
+ RUN_ARGV_TEST(failed, test_container_no_vhost());
+ RUN_ARGV_TEST(failed, test_container_bad_address());
+ RUN_ARGV_TEST(failed, test_container_stop());
+ RUN_ARGV_TEST(failed, test_container_schedule_nohang());
+ RUN_ARGV_TEST(failed, test_container_immediate_stop());
return failed;
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/e1708890/proton-c/bindings/cpp/src/proactor_container_impl.cpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/proactor_container_impl.cpp b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
index 0965391..427bb7c 100644
--- a/proton-c/bindings/cpp/src/proactor_container_impl.cpp
+++ b/proton-c/bindings/cpp/src/proactor_container_impl.cpp
@@ -455,6 +455,7 @@ void container::impl::run_timer_jobs() {
}
}
+// Return true if this thread is finished
bool container::impl::handle(pn_event_t* event) {
// If we have any pending connection work, do it now
@@ -620,32 +621,38 @@ bool container::impl::handle(pn_event_t* event) {
}
void container::impl::thread() {
+ bool finished;
{
GUARD(lock_);
++threads_;
+ finished = stopping_;
}
- bool finished = false;
- do {
- pn_event_batch_t *events = pn_proactor_wait(proactor_);
- pn_event_t *e;
- try {
- while ((e = pn_event_batch_next(events))) {
- finished = handle(e);
- if (finished) break;
+ while (!finished) {
+ pn_event_batch_t *events = pn_proactor_wait(proactor_);
+ pn_event_t *e;
+ const char *what = 0;
+ try {
+ while ((e = pn_event_batch_next(events))) {
+ finished = handle(e);
+ if (finished) break;
+ }
+ } catch (const std::exception& e) {
+ // If we caught an exception then shutdown the (other threads of the) container
+ what = e.what();
+ } catch (...) {
+ what = "container shut-down by unknown exception";
+ }
+ pn_proactor_done(proactor_, events);
+ if (what) {
+ finished = true;
+ error_condition error("exception", what);
+ {
+ GUARD(lock_);
+ disconnect_error_ = error;
+ }
+ stop(error);
}
- } catch (const std::exception& e) {
- // If we caught an exception then shutdown the (other threads of the) container
- disconnect_error_ = error_condition("exception", e.what());
- if (!stopping_) stop(disconnect_error_);
- finished = true;
- } catch (...) {
- // If we caught an exception then shutdown the (other threads of the) container
- disconnect_error_ = error_condition("exception", "container shut-down by unknown exception");
- if (!stopping_) stop(disconnect_error_);
- finished = true;
- }
- pn_proactor_done(proactor_, events);
- } while(!finished);
+ }
{
GUARD(lock_);
--threads_;
@@ -692,8 +699,9 @@ void container::impl::run(int threads) {
if (last) CALL_ONCE(stop_once_, &impl::stop_event, this);
// Throw an exception if we disconnected the proactor because of an exception
- if (!disconnect_error_.empty()) {
- throw proton::error(disconnect_error_.description());
+ {
+ GUARD(lock_);
+ if (!disconnect_error_.empty()) throw proton::error(disconnect_error_.description());
};
}
@@ -703,9 +711,12 @@ void container::impl::auto_stop(bool set) {
}
void container::impl::stop(const proton::error_condition& err) {
- GUARD(lock_);
- auto_stop_ = true;
- stopping_ = true;
+ {
+ GUARD(lock_);
+ if (stopping_) return; // Already stopping
+ auto_stop_ = true;
+ stopping_ = true;
+ }
pn_condition_t* error_condition = pn_condition();
set_error_condition(err, error_condition);
pn_proactor_disconnect(proactor_, error_condition);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[02/31] qpid-proton git commit: PROTON-1620: Windows schannel thread
safety for use with proactor
Posted by ac...@apache.org.
PROTON-1620: Windows schannel thread safety for use with proactor
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/63b85282
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/63b85282
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/63b85282
Branch: refs/heads/go1
Commit: 63b8528294d9431f46fc61b0b515c45b70645c4c
Parents: 686a400
Author: Clifford Jansen <cl...@apache.org>
Authored: Thu Oct 19 15:22:42 2017 -0700
Committer: Clifford Jansen <cl...@apache.org>
Committed: Thu Oct 19 15:22:42 2017 -0700
----------------------------------------------------------------------
proton-c/src/ssl/schannel.c | 144 ++++++++++++++++++++++++++++++---------
1 file changed, 110 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/63b85282/proton-c/src/ssl/schannel.c
----------------------------------------------------------------------
diff --git a/proton-c/src/ssl/schannel.c b/proton-c/src/ssl/schannel.c
index 763cae5..788b52d 100644
--- a/proton-c/src/ssl/schannel.c
+++ b/proton-c/src/ssl/schannel.c
@@ -61,6 +61,25 @@ static void ssl_log(pn_transport_t *transport, const char *fmt, ...);
static void ssl_log_error_status(HRESULT status, const char *fmt, ...);
static HCERTSTORE open_cert_db(const char *store_name, const char *passwd, int *error);
+// Thread support. Some SChannel objects are shared or ref-counted.
+// Consistent with the rest of Proton, we assume a connection (and
+// therefore its pn_ssl_t) will not be accessed concurrently by
+// multiple threads.
+class csguard {
+ public:
+ csguard(CRITICAL_SECTION *cs) : cs_(cs), set_(true) { EnterCriticalSection(cs_); }
+ ~csguard() { if (set_) LeaveCriticalSection(cs_); }
+ void release() {
+ if (set_) {
+ set_ = false;
+ LeaveCriticalSection(cs_);
+ }
+ }
+ private:
+ LPCRITICAL_SECTION cs_;
+ bool set_;
+};
+
/*
* win_credential_t: SChannel context that must accompany TLS connections.
*
@@ -73,6 +92,7 @@ static HCERTSTORE open_cert_db(const char *store_name, const char *passwd, int *
* Ref counted by parent ssl_domain_t and each derived connection.
*/
struct win_credential_t {
+ CRITICAL_SECTION cslock;
pn_ssl_mode_t mode;
PCCERT_CONTEXT cert_context; // Particulars of the certificate (if any)
CredHandle cred_handle; // Bound session parameters, certificate, CAs, verification_mode
@@ -88,6 +108,7 @@ struct win_credential_t {
static void win_credential_initialize(void *object)
{
win_credential_t *c = (win_credential_t *) object;
+ InitializeCriticalSectionAndSpinCount(&c->cslock, 4000);
SecInvalidateHandle(&c->cred_handle);
c->cert_context = 0;
c->trust_store = 0;
@@ -106,6 +127,7 @@ static void win_credential_finalize(void *object)
CertCloseStore(c->trust_store, 0);
if (c->server_CA_certs)
CertCloseStore(c->server_CA_certs, 0);
+ DeleteCriticalSection(&c->cslock);
free(c->trust_store_name);
}
@@ -115,9 +137,28 @@ static win_credential_t *win_credential(pn_ssl_mode_t m)
static const pn_class_t clazz = PN_CLASS(win_credential);
win_credential_t *c = (win_credential_t *) pn_class_new(&clazz, sizeof(win_credential_t));
c->mode = m;
+ csguard g(&c->cslock);
+ pn_incref(c); // See next comment regarding refcounting and locks
return c;
}
+// Hack strategy for Proton object refcounting. Just hold the lock for incref.
+// Use the next two functions for decref, one with, the other without the lock.
+// The refcount is artificially bumped by one in win_credential() so that we
+// can use refcount == 1 to actually delete (by calling decref one last time).
+static bool win_credential_decref(win_credential_t *c)
+{
+ // Call with lock held. Caller MUST call win_credential_delete if this returns true.
+ return pn_decref(c) == 1;
+}
+
+static void win_credential_delete(win_credential_t *c)
+{
+ // Call without lock held.
+ assert(pn_refcount(c) == 1);
+ pn_decref(c);
+}
+
static int win_credential_load_cert(win_credential_t *cred, const char *store_name, const char *cert_name, const char *passwd)
{
if (!store_name)
@@ -174,6 +215,7 @@ static int win_credential_load_cert(win_credential_t *cred, const char *store_na
}
+// call with win_credential lock held
static CredHandle win_credential_cred_handle(win_credential_t *cred, pn_ssl_verify_mode_t verify_mode,
const char *session_id, SECURITY_STATUS *status)
{
@@ -227,6 +269,7 @@ typedef enum { UNKNOWN_CONNECTION, SSL_CONNECTION, CLEAR_CONNECTION } connection
typedef struct pn_ssl_session_t pn_ssl_session_t;
struct pn_ssl_domain_t {
+ CRITICAL_SECTION cslock;
int ref_count;
pn_ssl_mode_t mode;
bool has_ca_db; // true when CA database configured
@@ -420,6 +463,8 @@ pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
pn_ssl_domain_t *domain = (pn_ssl_domain_t *) calloc(1, sizeof(pn_ssl_domain_t));
if (!domain) return NULL;
+ InitializeCriticalSectionAndSpinCount(&domain->cslock, 4000);
+ csguard(&domain->cslock);
domain->ref_count = 1;
domain->mode = mode;
switch(mode) {
@@ -436,14 +481,24 @@ pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
return domain;
}
+// call with no locks
void pn_ssl_domain_free( pn_ssl_domain_t *domain )
{
if (!domain) return;
-
- if (--domain->ref_count == 0) {
- pn_decref(domain->cred);
- free(domain);
+ {
+ csguard g(&domain->cslock);
+ if (--domain->ref_count)
+ return;
+ }
+ {
+ csguard g2(&domain->cred->cslock);
+ if (win_credential_decref(domain->cred)) {
+ g2.release();
+ win_credential_delete(domain->cred);
+ }
}
+ DeleteCriticalSection(&domain->cslock);
+ free(domain);
}
@@ -453,10 +508,15 @@ int pn_ssl_domain_set_credentials( pn_ssl_domain_t *domain,
const char *password)
{
if (!domain) return -1;
+ csguard g(&domain->cslock);
+ csguard g2(&domain->cred->cslock);
if (win_credential_has_certificate(domain->cred)) {
// Need a new win_credential_t to hold new certificate
- pn_decref(domain->cred);
+ if (win_credential_decref(domain->cred)) {
+ g2.release();
+ win_credential_delete(domain->cred);
+ }
domain->cred = win_credential(domain->mode);
if (!domain->cred)
return -1;
@@ -469,6 +529,7 @@ int pn_ssl_domain_set_trusted_ca_db(pn_ssl_domain_t *domain,
const char *certificate_db)
{
if (!domain || !certificate_db) return -1;
+ csguard g(&domain->cslock);
int ec = 0;
HCERTSTORE store = open_cert_db(certificate_db, NULL, &ec);
@@ -476,14 +537,21 @@ int pn_ssl_domain_set_trusted_ca_db(pn_ssl_domain_t *domain,
return ec;
if (domain->has_ca_db) {
+ csguard g2(&domain->cred->cslock);
win_credential_t *new_cred = win_credential(domain->mode);
- if (!new_cred)
+ if (!new_cred) {
+ CertCloseStore(store, 0);
return -1;
+ }
new_cred->cert_context = CertDuplicateCertificateContext(domain->cred->cert_context);
- pn_decref(domain->cred);
+ if (win_credential_decref(domain->cred)) {
+ g2.release();
+ win_credential_delete(domain->cred);
+ }
domain->cred = new_cred;
}
+ csguard g3(&domain->cred->cslock);
domain->cred->trust_store = store;
domain->cred->trust_store_name = pn_strdup(certificate_db);
domain->has_ca_db = true;
@@ -496,6 +564,9 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
const char *trusted_CAs)
{
if (!domain) return -1;
+ csguard g(&domain->cslock);
+ csguard g2(&domain->cred->cslock);
+
if (!domain->has_ca_db && (mode == PN_SSL_VERIFY_PEER || mode == PN_SSL_VERIFY_PEER_NAME)) {
ssl_log_error("Error: cannot verify peer without a trusted CA configured.\n"
" Use pn_ssl_domain_set_trusted_ca_db()\n");
@@ -520,29 +591,11 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
}
int ec = 0;
if (!strcmp(trusted_CAs, domain->cred->trust_store_name)) {
+ changed = true;
store = open_cert_db(trusted_CAs, NULL, &ec);
if (!store)
return ec;
- } else {
- store = CertDuplicateStore(domain->cred->trust_store);
- }
-
- if (domain->cred->server_CA_certs) {
- // Already have one
- changed = true;
- win_credential_t *new_cred = win_credential(domain->mode);
- if (!new_cred) {
- CertCloseStore(store, 0);
- return -1;
- }
- new_cred->cert_context = CertDuplicateCertificateContext(domain->cred->cert_context);
- new_cred->trust_store = CertDuplicateStore(domain->cred->trust_store);
- new_cred->trust_store_name = pn_strdup(domain->cred->trust_store_name);
- pn_decref(domain->cred);
- domain->cred = new_cred;
}
-
- domain->cred->server_CA_certs = store;
}
break;
@@ -557,18 +610,22 @@ int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
if (changed) {
win_credential_t *new_cred = win_credential(domain->mode);
if (!new_cred) {
- CertCloseStore(store, 0);
+ if (store)
+ CertCloseStore(store, 0);
return -1;
}
new_cred->cert_context = CertDuplicateCertificateContext(domain->cred->cert_context);
new_cred->trust_store = CertDuplicateStore(domain->cred->trust_store);
new_cred->trust_store_name = pn_strdup(domain->cred->trust_store_name);
- pn_decref(domain->cred);
+ if (win_credential_decref(domain->cred)) {
+ g2.release();
+ win_credential_delete(domain->cred);
+ }
domain->cred = new_cred;
+ domain->cred->server_CA_certs = store;
}
domain->verify_mode = mode;
- domain->cred->server_CA_certs = store;
return 0;
}
@@ -617,6 +674,8 @@ int pn_ssl_init(pn_ssl_t *ssl0, pn_ssl_domain_t *domain, const char *session_id)
if (!ssl || !domain || ssl->domain) return -1;
if (ssl->state != CREATED) return -1;
+ csguard g(&domain->cslock);
+ csguard g2(&domain->cred->cslock);
ssl->domain = domain;
domain->ref_count++;
if (session_id && domain->mode == PN_SSL_MODE_CLIENT)
@@ -719,6 +778,8 @@ void pn_ssl_free( pn_transport_t *transport)
if (!ssl) return;
ssl_log( transport, "SSL socket freed.\n" );
// clean up Windows per TLS session data before releasing the domain count
+ csguard g(&ssl->domain->cslock);
+ csguard g2(&ssl->cred->cslock);
if (SecIsValidHandle(&ssl->ctxt_handle))
DeleteSecurityContext(&ssl->ctxt_handle);
if (ssl->cred) {
@@ -727,10 +788,16 @@ void pn_ssl_free( pn_transport_t *transport)
if (SecIsValidHandle(&ssl->cred_handle))
FreeCredentialsHandle(&ssl->cred_handle);
}
- pn_decref(ssl->cred);
+ if (win_credential_decref(ssl->cred)) {
+ g2.release();
+ win_credential_delete(ssl->cred);
+ }
}
- if (ssl->domain) pn_ssl_domain_free(ssl->domain);
+ g2.release();
+ g.release();
+ pn_ssl_domain_free(ssl->domain);
+
if (ssl->session_id) free((void *)ssl->session_id);
if (ssl->peer_hostname) free((void *)ssl->peer_hostname);
if (ssl->sc_inbuf) free((void *)ssl->sc_inbuf);
@@ -998,6 +1065,7 @@ static void client_handshake_init(pn_transport_t *transport)
send_buff_desc.ulVersion = SECBUFFER_VERSION;
send_buff_desc.cBuffers = 2;
send_buff_desc.pBuffers = send_buffs;
+ csguard g(&ssl->cred->cslock);
SECURITY_STATUS status = InitializeSecurityContext(&ssl->cred_handle,
NULL, host, ctxt_requested, 0, 0, NULL, 0,
&ssl->ctxt_handle, &send_buff_desc,
@@ -1051,10 +1119,15 @@ static void client_handshake( pn_transport_t* transport) {
send_buff_desc.cBuffers = 2;
send_buff_desc.pBuffers = send_buffs;
- SECURITY_STATUS status = InitializeSecurityContext(&ssl->cred_handle,
+ SECURITY_STATUS status;
+ {
+ csguard g(&ssl->cred->cslock);
+ status = InitializeSecurityContext(&ssl->cred_handle,
&ssl->ctxt_handle, host, ctxt_requested, 0, 0,
&token_buff_desc, 0, NULL, &send_buff_desc,
&ctxt_attrs, NULL);
+ }
+
switch (status) {
case SEC_E_INCOMPLETE_MESSAGE:
// Not enough - get more data from the server then try again.
@@ -1210,10 +1283,13 @@ static void server_handshake(pn_transport_t* transport)
send_buff_desc.pBuffers = send_buffs;
PCtxtHandle ctxt_handle_ptr = (SecIsValidHandle(&ssl->ctxt_handle)) ? &ssl->ctxt_handle : 0;
- SECURITY_STATUS status = AcceptSecurityContext(&ssl->cred_handle, ctxt_handle_ptr,
+ SECURITY_STATUS status;
+ {
+ csguard g(&ssl->cred->cslock);
+ status = AcceptSecurityContext(&ssl->cred_handle, ctxt_handle_ptr,
&token_buff_desc, ctxt_requested, 0, &ssl->ctxt_handle,
&send_buff_desc, &ctxt_attrs, NULL);
-
+ }
bool outbound_token = false;
switch(status) {
case SEC_E_INCOMPLETE_MESSAGE:
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[08/31] qpid-proton git commit: PROTON-1597: Add
cmake_minimum_required() to examples which need to compile separately
Posted by ac...@apache.org.
PROTON-1597: Add cmake_minimum_required() to examples which need to compile separately
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/4c21712a
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/4c21712a
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/4c21712a
Branch: refs/heads/go1
Commit: 4c21712aa12d49ee9168656814cce2c9caff0997
Parents: b9bb35b
Author: Andrew Stitcher <as...@apache.org>
Authored: Fri Oct 20 16:11:57 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Fri Oct 20 16:11:57 2017 -0400
----------------------------------------------------------------------
examples/c/CMakeLists.txt | 1 +
examples/cpp/CMakeLists.txt | 2 ++
2 files changed, 3 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4c21712a/examples/c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt
index d2d0fcf..08a7a74 100644
--- a/examples/c/CMakeLists.txt
+++ b/examples/c/CMakeLists.txt
@@ -16,6 +16,7 @@
# specific language governing permissions and limitations
# under the License.
#
+cmake_minimum_required (VERSION 2.8.7)
find_package(Proton REQUIRED Core Proactor)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/4c21712a/examples/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt
index cf6b958..f00556c 100644
--- a/examples/cpp/CMakeLists.txt
+++ b/examples/cpp/CMakeLists.txt
@@ -16,6 +16,8 @@
# specific language governing permissions and limitations
# under the License.
#
+cmake_minimum_required (VERSION 2.8.7)
+
enable_language(CXX)
find_package(ProtonCpp REQUIRED)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[30/31] qpid-proton git commit: PROTON-1668: update versions for
0.18.1-rc1
Posted by ac...@apache.org.
PROTON-1668: update versions for 0.18.1-rc1
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/42f67b65
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/42f67b65
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/42f67b65
Branch: refs/heads/go1
Commit: 42f67b651ce127d84f2a319e1a0f496f6aaac10e
Parents: 2c07cc3
Author: Robbie Gemmell <ro...@apache.org>
Authored: Tue Oct 31 12:46:02 2017 +0000
Committer: Robbie Gemmell <ro...@apache.org>
Committed: Tue Oct 31 12:46:02 2017 +0000
----------------------------------------------------------------------
proton-c/bindings/python/docs/conf.py | 4 ++--
version.txt | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/42f67b65/proton-c/bindings/python/docs/conf.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/docs/conf.py b/proton-c/bindings/python/docs/conf.py
index 97d65c9..f311d80 100644
--- a/proton-c/bindings/python/docs/conf.py
+++ b/proton-c/bindings/python/docs/conf.py
@@ -48,9 +48,9 @@ copyright = u'2015, Apache Qpid'
# built documents.
#
# The short X.Y version.
-version = '0.19.0'
+version = '0.18.1'
# The full version, including alpha/beta/rc tags.
-release = '0.19.0-SNAPSHOT'
+release = '0.18.1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/42f67b65/version.txt
----------------------------------------------------------------------
diff --git a/version.txt b/version.txt
index aa2ab03..249afd5 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-0.19.0-SNAPSHOT
+0.18.1
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[12/31] qpid-proton git commit: PROTON-1176: Core dump if reactor
creation fails
Posted by ac...@apache.org.
PROTON-1176: Core dump if reactor creation fails
Fixed wrapper construct bug that leaves fields uninitialized if the reactor
fails to create. Added test to verify that BlockingConnection raises a
ProtonException if there are not enough FDs, and does not crash.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/da7f5056
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/da7f5056
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/da7f5056
Branch: refs/heads/go1
Commit: da7f5056a45528196be6733fc56a1f41bda58ded
Parents: bdfe982
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 23 19:57:07 2017 +0100
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 23 20:21:18 2017 +0100
----------------------------------------------------------------------
proton-c/bindings/python/proton/wrapper.py | 3 ++
tests/python/proton_tests/utils.py | 40 +++++++++++++++++++++----
2 files changed, 38 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/da7f5056/proton-c/bindings/python/proton/wrapper.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/wrapper.py b/proton-c/bindings/python/proton/wrapper.py
index 8519646..f009de5 100644
--- a/proton-c/bindings/python/proton/wrapper.py
+++ b/proton-c/bindings/python/proton/wrapper.py
@@ -39,6 +39,9 @@ class Wrapper(object):
# we are constructing a new object
impl = impl_or_constructor()
if impl is None:
+ self.__dict__["_impl"] = impl
+ self.__dict__["_attrs"] = EMPTY_ATTRS
+ self.__dict__["_record"] = None
from proton import ProtonException
raise ProtonException("Wrapper failed to create wrapped object. Check for file descriptor or memory exhaustion.")
init = True
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/da7f5056/tests/python/proton_tests/utils.py
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/utils.py b/tests/python/proton_tests/utils.py
index 52d0dc2..72711c7 100644
--- a/tests/python/proton_tests/utils.py
+++ b/tests/python/proton_tests/utils.py
@@ -22,7 +22,7 @@ from threading import Thread, Event
from unittest import TestCase
from proton_tests.common import Test, free_tcp_port
from copy import copy
-from proton import Message, Url, generate_uuid, Array, UNDESCRIBED, Data, symbol, ConnectionException
+from proton import Message, Url, generate_uuid, Array, UNDESCRIBED, Data, symbol, ConnectionException, ProtonException
from proton.handlers import MessagingHandler
from proton.reactor import Container
from proton.utils import SyncRequestResponse, BlockingConnection
@@ -53,7 +53,7 @@ class EchoServer(MessagingHandler, Thread):
self.acceptor = event.container.listen(self.url)
self.container = event.container
self.event.set()
-
+
def on_link_opening(self, event):
if event.link.is_sender:
if event.link.remote_source and event.link.remote_source.dynamic:
@@ -89,14 +89,14 @@ class ConnPropertiesServer(EchoServer):
def on_connection_opening(self, event):
conn = event.connection
-
+
if conn.remote_properties == CONNECTION_PROPERTIES:
self.properties_received = True
if conn.remote_offered_capabilities == OFFERED_CAPABILITIES:
self.offered_capabilities_received = True
if conn.remote_desired_capabilities == DESIRED_CAPABILITIES:
self.desired_capabilities_received = True
-
+
class SyncRequestResponseTest(Test):
"""Test SyncRequestResponse"""
@@ -135,7 +135,7 @@ class SyncRequestResponseTest(Test):
self.assertEquals(server.desired_capabilities_received, True)
def test_allowed_mechs_external(self):
- # All this test does it make sure that if we pass allowed_mechs to BlockingConnection, it is actually used.
+ # All this test does it make sure that if we pass allowed_mechs to BlockingConnection, it is actually used.
port = free_tcp_port()
server = ConnPropertiesServer(Url(host="127.0.0.1", port=port), timeout=self.timeout)
server.start()
@@ -162,3 +162,33 @@ class SyncRequestResponseTest(Test):
self.assertEquals(server.offered_capabilities_received, True)
self.assertEquals(server.desired_capabilities_received, True)
+class OutOfFdsTest(Test):
+
+ def test_out_of_fds(self):
+ """Create BlockingConnections until we run out of FDs, make sure we get an exception
+ and not a crash"""
+
+ server = EchoServer(Url(host="127.0.0.1", port=free_tcp_port()), self.timeout)
+ server.start()
+ server.wait()
+
+ # Use up all the FDs
+ dummy = os.tmpfile()
+ fds = []
+ try:
+ while True: fds.append(os.dup(dummy.fileno()));
+ except OSError, e:
+ pass
+
+ for i in [0, 1]: # Check the odd and even case
+ try:
+ BlockingConnection(server.url)
+ fail("Expected ProtonException")
+ except ProtonException, e:
+ pass
+ os.close(fds.pop())
+
+ for f in fds: os.close(f)
+ c = BlockingConnection(server.url, timeout=self.timeout)
+ c.close()
+ server.join(timeout=self.timeout)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[09/31] qpid-proton git commit: NO-JIRA: Rearrange example CMakes to
put test running stuff at end - Don't distract from the essential simplicity
of file
Posted by ac...@apache.org.
NO-JIRA: Rearrange example CMakes to put test running stuff at end
- Don't distract from the essential simplicity of file
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/d09511f1
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/d09511f1
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/d09511f1
Branch: refs/heads/go1
Commit: d09511f198b37310dc16de9a5fbd7c21e861901d
Parents: 4c21712
Author: Andrew Stitcher <as...@apache.org>
Authored: Fri Oct 20 16:30:35 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Fri Oct 20 17:03:06 2017 -0400
----------------------------------------------------------------------
examples/c/CMakeLists.txt | 24 +++++++++++++-----------
examples/cpp/CMakeLists.txt | 22 +++++++++++-----------
2 files changed, 24 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d09511f1/examples/c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt
index 08a7a74..d9f6550 100644
--- a/examples/c/CMakeLists.txt
+++ b/examples/c/CMakeLists.txt
@@ -22,18 +22,9 @@ find_package(Proton REQUIRED Core Proactor)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR})
-
include_directories(${Proton_INCLUDE_DIRS})
add_definitions(${Proton_DEFINITIONS})
-# Add a test with the correct environment to find test executables and valgrind.
-if(WIN32)
- set(test_path "$<TARGET_FILE_DIR:broker>;$<TARGET_FILE_DIR:qpid-proton>")
-else()
- set(test_path "${CMAKE_CURRENT_BINARY_DIR}:$ENV{PATH}")
-endif()
-
foreach (name broker send receive direct send-abort send-ssl)
add_executable(c-${name} ${name}.c)
target_link_libraries(c-${name} ${Proton_Proactor_LIBRARIES} ${Proton_Core_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
@@ -41,9 +32,20 @@ foreach (name broker send receive direct send-abort send-ssl)
OUTPUT_NAME ${name})
endforeach()
-set(run_env ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/proton-c/env.py ${EXAMPLE_ENV} "PATH=${test_path}" ${VALGRIND_ENV})
+
+# Add a test to run all examples
# windows exclusion only for 0.18 beta
if(NOT WIN32)
-add_test(c-example-tests ${run_env} -- ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v)
+
+# Make correct environment to find test executables and valgrind.
+if(WIN32)
+ set(test_path "$<TARGET_FILE_DIR:c-broker>;$<TARGET_FILE_DIR:qpid-proton-core>;$<TARGET_FILE_DIR:qpid-proton-proactor>")
+else()
+ set(test_path "$<TARGET_FILE_DIR:c-broker>:$ENV{PATH}")
+endif()
+set(run_env ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/proton-c/env.py ${EXAMPLE_ENV} "PATH=${test_path}" ${VALGRIND_ENV})
+
+add_test(NAME c-example-tests COMMAND ${run_env} -- ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v)
+
endif()
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/d09511f1/examples/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt
index f00556c..3967fc1 100644
--- a/examples/cpp/CMakeLists.txt
+++ b/examples/cpp/CMakeLists.txt
@@ -39,17 +39,6 @@ if (DEFINED CMAKE_CXX_COMPILE_FEATURES)
set(CMAKE_CXX_EXTENSIONS OFF)
endif()
-# Add a test with the correct environment to find test executables and valgrind.
-macro(add_cpp_test name)
- if(WIN32)
- set(test_path "$<TARGET_FILE_DIR:broker>;$<TARGET_FILE_DIR:qpid-proton>;$<TARGET_FILE_DIR:qpid-proton-cpp>")
- else(WIN32)
- set(test_path "$<TARGET_FILE_DIR:broker>:$ENV{PATH}")
- endif(WIN32)
- set(run_env ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/proton-c/env.py ${EXAMPLE_ENV})
- add_test(NAME ${name} COMMAND ${run_env} "PATH=${test_path}" ${VALGRIND_ENV} -- ${ARGN})
-endmacro()
-
# Single-threaded examples that work on C++03
foreach(example
broker
@@ -87,6 +76,17 @@ if(HAS_CPP11)
endforeach()
endif()
+# Add a test with the correct environment to find test executables and valgrind.
+macro(add_cpp_test name)
+ if(WIN32)
+ set(test_path "$<TARGET_FILE_DIR:broker>;$<TARGET_FILE_DIR:qpid-proton>;$<TARGET_FILE_DIR:qpid-proton-cpp>")
+ else(WIN32)
+ set(test_path "$<TARGET_FILE_DIR:broker>:$ENV{PATH}")
+ endif(WIN32)
+ set(run_env ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/proton-c/env.py ${EXAMPLE_ENV})
+ add_test(NAME ${name} COMMAND ${run_env} "PATH=${test_path}" ${VALGRIND_ENV} -- ${ARGN})
+endmacro()
+
add_cpp_test(cpp-example-container ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v ContainerExampleTest)
if (NOT SSL_IMPL STREQUAL none)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[15/31] qpid-proton git commit: PROTON-1622: Add instructions for
coverage reporting to DEVELOPERS.md
Posted by ac...@apache.org.
PROTON-1622: Add instructions for coverage reporting to DEVELOPERS.md
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/540ef366
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/540ef366
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/540ef366
Branch: refs/heads/go1
Commit: 540ef366f3a124b4dc3ec595504a6fd309fb45bf
Parents: 415a1f7
Author: Chuck Rolke <cr...@redhat.com>
Authored: Tue Oct 24 15:32:43 2017 -0400
Committer: Chuck Rolke <cr...@redhat.com>
Committed: Tue Oct 24 15:32:43 2017 -0400
----------------------------------------------------------------------
DEVELOPERS.md | 9 +++++++++
1 file changed, 9 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/540ef366/DEVELOPERS.md
----------------------------------------------------------------------
diff --git a/DEVELOPERS.md b/DEVELOPERS.md
index d195083..5eaa235 100644
--- a/DEVELOPERS.md
+++ b/DEVELOPERS.md
@@ -76,6 +76,15 @@ Additional packages required for testing the language bindings:
# alternatively ruby depedencies on non-RPM based systems
$ gem install minitest
+To run coverage reporting:
+
+ # install coverage tools
+ $ dnf install lcov
+ $ pip install coverage
+
+ $ cmake -DCMAKE_BUILD_TYPE=Coverage && make && ctest && make coverage
+ # Then browse to {CMAKE_BUILD_DIR}/coverage_results/html/index.html
+
Mailing list
------------
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[05/31] qpid-proton git commit: NO-JIRA: [go] disable go with
sanitizer flags, example fixes
Posted by ac...@apache.org.
NO-JIRA: [go] disable go with sanitizer flags, example fixes
- disable go by default if sanitizer flags are enabled
- restore error handling in client_server example
- use ipv4 in example to avoid problems on ipv6-disabled platforms
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/affa7cbf
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/affa7cbf
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/affa7cbf
Branch: refs/heads/go1
Commit: affa7cbf63771829c6fea1404cce8bf4917e51d8
Parents: e479d4c
Author: Alan Conway <ac...@redhat.com>
Authored: Fri Oct 20 16:58:16 2017 +0100
Committer: Alan Conway <ac...@redhat.com>
Committed: Fri Oct 20 17:12:00 2017 +0100
----------------------------------------------------------------------
CMakeLists.txt | 2 +-
.../qpid.apache.org/electron/electron_test.go | 2 +-
.../electron/example_client_server_test.go | 24 +++++++++++++++-----
3 files changed, 20 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/affa7cbf/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 36b1b34..3bec2d1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -174,7 +174,7 @@ endif (ENABLE_VALGRIND)
option(ENABLE_SANITIZERS "Compile with sanitizers (ASan, UBSan, TSan); incompatible with Valgrind" OFF)
option(ENABLE_TSAN "Compile with Thread Sanitizer (TSan); incompatible with Valgrind" OFF)
if (ENABLE_SANITIZERS OR ENABLE_TSAN)
- set(DISABLE ENABLE_VALGRIND ENABLE_UNDEFINED_ERROR)
+ set(DISABLE ENABLE_VALGRIND ENABLE_UNDEFINED_ERROR BUILD_GO)
message(STATUS "Building with sanitizers; disables ${DISABLE}")
foreach(d ${DISABLE})
set(${d} OFF CACHE BOOL "Disabled to run sanitizers" FORCE)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/affa7cbf/proton-c/bindings/go/src/qpid.apache.org/electron/electron_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/electron_test.go b/proton-c/bindings/go/src/qpid.apache.org/electron/electron_test.go
index 294e952..4cd8453 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/electron_test.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/electron_test.go
@@ -59,7 +59,7 @@ func checkEqual(want interface{}, got interface{}) error {
// Start a server, return listening addr and channel for incoming Connections.
func newServer(t *testing.T, cont Container, opts ...ConnectionOption) (net.Addr, <-chan Connection) {
- listener, err := net.Listen("tcp", "")
+ listener, err := net.Listen("tcp4", "") // For systems with ipv6 disabled
fatalIf(t, err)
addr := listener.Addr()
ch := make(chan Connection)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/affa7cbf/proton-c/bindings/go/src/qpid.apache.org/electron/example_client_server_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/example_client_server_test.go b/proton-c/bindings/go/src/qpid.apache.org/electron/example_client_server_test.go
index 3aa5892..385c865 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/example_client_server_test.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/example_client_server_test.go
@@ -2,6 +2,7 @@ package electron_test
import (
"fmt"
+ "log"
"net"
"qpid.apache.org/amqp"
"qpid.apache.org/electron"
@@ -12,8 +13,11 @@ import (
// and prints messages received until the link closes.
func Server(l net.Listener) {
cont := electron.NewContainer("server")
- c, _ := cont.Accept(l) // Ignoring error handling
- l.Close() // This server only accepts one connection
+ c, err := cont.Accept(l)
+ if err != nil {
+ log.Fatal(err)
+ }
+ l.Close() // This server only accepts one connection
// Process incoming endpoints till we get a Receiver link
var r electron.Receiver
for r == nil {
@@ -51,8 +55,10 @@ func Server(l net.Listener) {
// https://github.com/apache/qpid-proton/blob/master/examples/go/README.md
//
func Example_clientServer() {
- // NOTE: We ignoring error handling in this example
- l, _ := net.Listen("tcp", "") // Open a listening port for server, client connect to this port
+ l, err := net.Listen("tcp", "127.0.0.1:0") // tcp4 so example will work on ipv6-disabled platforms
+ if err != nil {
+ log.Fatal(err)
+ }
// SERVER: start the server running in a separate goroutine
var waitServer sync.WaitGroup // We will wait for the server goroutine to finish before exiting
@@ -64,8 +70,14 @@ func Example_clientServer() {
// CLIENT: Send messages to the server
addr := l.Addr()
- c, _ := electron.Dial(addr.Network(), addr.String())
- s, _ := c.Sender()
+ c, err := electron.Dial(addr.Network(), addr.String())
+ if err != nil {
+ log.Fatal(err)
+ }
+ s, err := c.Sender()
+ if err != nil {
+ log.Fatal(err)
+ }
for i := 0; i < 3; i++ {
msg := fmt.Sprintf("hello %v", i)
// Send and wait for the Outcome from the server.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[31/31] qpid-proton git commit: Updated to 0.18.1 release
Posted by ac...@apache.org.
Updated to 0.18.1 release
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/6c48527c
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/6c48527c
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/6c48527c
Branch: refs/heads/go1
Commit: 6c48527c1514dfd5add06353eb0b9e43b3b8938e
Parents: 14f7ca5 42f67b6
Author: Alan Conway <ac...@redhat.com>
Authored: Wed Nov 15 16:04:15 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Wed Nov 15 16:04:15 2017 -0500
----------------------------------------------------------------------
electron/auth_test.go | 9 +++++++++
electron/connection.go | 8 ++++++++
electron/electron_test.go | 2 +-
electron/example_client_server_test.go | 24 ++++++++++++++++++------
proton/wrappers.go | 10 ++++++++++
5 files changed, 46 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6c48527c/electron/auth_test.go
----------------------------------------------------------------------
diff --cc electron/auth_test.go
index 73a9299,0000000..9eb48c0
mode 100644,000000..100644
--- a/electron/auth_test.go
+++ b/electron/auth_test.go
@@@ -1,124 -1,0 +1,133 @@@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+*/
+
+package electron
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+func testAuthClientServer(t *testing.T, copts []ConnectionOption, sopts []ConnectionOption) (got connectionSettings, err error) {
+ client, server := newClientServerOpts(t, copts, sopts)
+ defer closeClientServer(client, server)
+
+ go func() {
+ for in := range server.Incoming() {
+ switch in := in.(type) {
+ case *IncomingConnection:
+ got = connectionSettings{user: in.User(), virtualHost: in.VirtualHost()}
+ }
+ in.Accept()
+ }
+ }()
+
+ err = client.Sync()
+ return
+}
+
+func TestAuthAnonymous(t *testing.T) {
+ fatalIf(t, configureSASL())
+ got, err := testAuthClientServer(t,
+ []ConnectionOption{User("fred"), VirtualHost("vhost"), SASLAllowInsecure(true)},
+ []ConnectionOption{SASLAllowedMechs("ANONYMOUS"), SASLAllowInsecure(true)})
+ fatalIf(t, err)
+ errorIf(t, checkEqual(connectionSettings{user: "anonymous", virtualHost: "vhost"}, got))
+}
+
+func TestAuthPlain(t *testing.T) {
++ if !SASLExtended() {
++ t.Skip()
++ }
+ fatalIf(t, configureSASL())
+ got, err := testAuthClientServer(t,
+ []ConnectionOption{SASLAllowInsecure(true), SASLAllowedMechs("PLAIN"), User("fred@proton"), Password([]byte("xxx"))},
+ []ConnectionOption{SASLAllowInsecure(true), SASLAllowedMechs("PLAIN")})
+ fatalIf(t, err)
+ errorIf(t, checkEqual(connectionSettings{user: "fred@proton"}, got))
+}
+
+func TestAuthBadPass(t *testing.T) {
++ if !SASLExtended() {
++ t.Skip()
++ }
+ fatalIf(t, configureSASL())
+ _, err := testAuthClientServer(t,
+ []ConnectionOption{SASLAllowInsecure(true), SASLAllowedMechs("PLAIN"), User("fred@proton"), Password([]byte("yyy"))},
+ []ConnectionOption{SASLAllowInsecure(true), SASLAllowedMechs("PLAIN")})
+ if err == nil {
+ t.Error("Expected auth failure for bad pass")
+ }
+}
+
+func TestAuthBadUser(t *testing.T) {
++ if !SASLExtended() {
++ t.Skip()
++ }
+ fatalIf(t, configureSASL())
+ _, err := testAuthClientServer(t,
+ []ConnectionOption{SASLAllowInsecure(true), SASLAllowedMechs("PLAIN"), User("foo@bar"), Password([]byte("yyy"))},
+ []ConnectionOption{SASLAllowInsecure(true), SASLAllowedMechs("PLAIN")})
+ if err == nil {
+ t.Error("Expected auth failure for bad user")
+ }
+}
+
+var confDir string
+var confErr error
+
+func configureSASL() error {
+ if confDir != "" || confErr != nil {
+ return confErr
+ }
+ confDir, confErr = ioutil.TempDir("", "")
+ if confErr != nil {
+ return confErr
+ }
+
+ GlobalSASLConfigDir(confDir)
+ GlobalSASLConfigName("test")
+ conf := filepath.Join(confDir, "test.conf")
+
+ db := filepath.Join(confDir, "proton.sasldb")
+ cmd := exec.Command("saslpasswd2", "-c", "-p", "-f", db, "-u", "proton", "fred")
+ cmd.Stdin = strings.NewReader("xxx") // Password
+ if out, err := cmd.CombinedOutput(); err != nil {
+ confErr = fmt.Errorf("saslpasswd2 failed: %s\n%s", err, out)
+ return confErr
+ }
+ confStr := "sasldb_path: " + db + "\nmech_list: EXTERNAL DIGEST-MD5 SCRAM-SHA-1 CRAM-MD5 PLAIN ANONYMOUS\n"
+ if err := ioutil.WriteFile(conf, []byte(confStr), os.ModePerm); err != nil {
+ confErr = fmt.Errorf("write conf file %s failed: %s", conf, err)
+ }
+ return confErr
+}
+
+func TestMain(m *testing.M) {
+ status := m.Run()
+ if confDir != "" {
+ _ = os.RemoveAll(confDir)
+ }
+ os.Exit(status)
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6c48527c/electron/connection.go
----------------------------------------------------------------------
diff --cc electron/connection.go
index 267ee1e,0000000..2749b2b
mode 100644,000000..100644
--- a/electron/connection.go
+++ b/electron/connection.go
@@@ -1,413 -1,0 +1,421 @@@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+*/
+
+package electron
+
+// #include <proton/disposition.h>
+import "C"
+
+import (
+ "net"
+ "qpid.apache.org/proton"
+ "sync"
+ "time"
+)
+
+// Settings associated with a Connection.
+type ConnectionSettings interface {
+ // Authenticated user name associated with the connection.
+ User() string
+
+ // The AMQP virtual host name for the connection.
+ //
+ // Optional, useful when the server has multiple names and provides different
+ // service based on the name the client uses to connect.
+ //
+ // By default it is set to the DNS host name that the client uses to connect,
+ // but it can be set to something different at the client side with the
+ // VirtualHost() option.
+ //
+ // Returns error if the connection fails to authenticate.
+ VirtualHost() string
+
+ // Heartbeat is the maximum delay between sending frames that the remote peer
+ // has requested of us. If the interval expires an empty "heartbeat" frame
+ // will be sent automatically to keep the connection open.
+ Heartbeat() time.Duration
+}
+
+// Connection is an AMQP connection, created by a Container.
+type Connection interface {
+ Endpoint
+ ConnectionSettings
+
+ // Sender opens a new sender on the DefaultSession.
+ Sender(...LinkOption) (Sender, error)
+
+ // Receiver opens a new Receiver on the DefaultSession().
+ Receiver(...LinkOption) (Receiver, error)
+
+ // DefaultSession() returns a default session for the connection. It is opened
+ // on the first call to DefaultSession and returned on subsequent calls.
+ DefaultSession() (Session, error)
+
+ // Session opens a new session.
+ Session(...SessionOption) (Session, error)
+
+ // Container for the connection.
+ Container() Container
+
+ // Disconnect the connection abruptly with an error.
+ Disconnect(error)
+
+ // Wait waits for the connection to be disconnected.
+ Wait() error
+
+ // WaitTimeout is like Wait but returns Timeout if the timeout expires.
+ WaitTimeout(time.Duration) error
+
+ // Incoming returns a channel for incoming endpoints opened by the remote peer.
+ // See the Incoming interface for more detail.
+ //
+ // Note: this channel will first return an *IncomingConnection for the
+ // connection itself which allows you to look at security information and
+ // decide whether to Accept() or Reject() the connection. Then it will return
+ // *IncomingSession, *IncomingSender and *IncomingReceiver as they are opened
+ // by the remote end.
+ //
+ // Note 2: you must receiving from Incoming() and call Accept/Reject to avoid
+ // blocking electron event loop. Normally you would run a loop in a goroutine
+ // to handle incoming types that interest and Accept() those that don't.
+ Incoming() <-chan Incoming
+}
+
+type connectionSettings struct {
+ user, virtualHost string
+ heartbeat time.Duration
+}
+
+func (c connectionSettings) User() string { return c.user }
+func (c connectionSettings) VirtualHost() string { return c.virtualHost }
+func (c connectionSettings) Heartbeat() time.Duration { return c.heartbeat }
+
+// ConnectionOption can be passed when creating a connection to configure various options
+type ConnectionOption func(*connection)
+
+// User returns a ConnectionOption sets the user name for a connection
+func User(user string) ConnectionOption {
+ return func(c *connection) {
+ c.user = user
+ c.pConnection.SetUser(user)
+ }
+}
+
+// VirtualHost returns a ConnectionOption to set the AMQP virtual host for the connection.
+// Only applies to outbound client connection.
+func VirtualHost(virtualHost string) ConnectionOption {
+ return func(c *connection) {
+ c.virtualHost = virtualHost
+ c.pConnection.SetHostname(virtualHost)
+ }
+}
+
+// Password returns a ConnectionOption to set the password used to establish a
+// connection. Only applies to outbound client connection.
+//
+// The connection will erase its copy of the password from memory as soon as it
+// has been used to authenticate. If you are concerned about paswords staying in
+// memory you should never store them as strings, and should overwrite your
+// copy as soon as you are done with it.
+//
+func Password(password []byte) ConnectionOption {
+ return func(c *connection) { c.pConnection.SetPassword(password) }
+}
+
+// Server returns a ConnectionOption to put the connection in server mode for incoming connections.
+//
+// A server connection will do protocol negotiation to accept a incoming AMQP
+// connection. Normally you would call this for a connection created by
+// net.Listener.Accept()
+//
+func Server() ConnectionOption {
+ return func(c *connection) { c.engine.Server(); c.server = true; AllowIncoming()(c) }
+}
+
+// AllowIncoming returns a ConnectionOption to enable incoming endpoints, see
+// Connection.Incoming() This is automatically set for Server() connections.
+func AllowIncoming() ConnectionOption {
+ return func(c *connection) { c.incoming = make(chan Incoming) }
+}
+
+// Parent returns a ConnectionOption that associates the Connection with it's Container
+// If not set a connection will create its own default container.
+func Parent(cont Container) ConnectionOption {
+ return func(c *connection) { c.container = cont.(*container) }
+}
+
+type connection struct {
+ endpoint
+ connectionSettings
+
+ defaultSessionOnce, closeOnce sync.Once
+
+ container *container
+ conn net.Conn
+ server bool
+ incoming chan Incoming
+ handler *handler
+ engine *proton.Engine
+ pConnection proton.Connection
+
+ defaultSession Session
+}
+
+// NewConnection creates a connection with the given options.
+func NewConnection(conn net.Conn, opts ...ConnectionOption) (*connection, error) {
+ c := &connection{
+ conn: conn,
+ }
+ c.handler = newHandler(c)
+ var err error
+ c.engine, err = proton.NewEngine(c.conn, c.handler.delegator)
+ if err != nil {
+ return nil, err
+ }
+ c.pConnection = c.engine.Connection()
+ for _, set := range opts {
+ set(c)
+ }
+ if c.container == nil {
+ c.container = NewContainer("").(*container)
+ }
+ c.pConnection.SetContainer(c.container.Id())
+ globalSASLInit(c.engine)
+
+ c.endpoint.init(c.engine.String())
+ go c.run()
+ return c, nil
+}
+
+func (c *connection) run() {
+ if !c.server {
+ c.pConnection.Open()
+ }
+ _ = c.engine.Run()
+ if c.incoming != nil {
+ close(c.incoming)
+ }
+ _ = c.closed(Closed)
+}
+
+func (c *connection) Close(err error) {
+ c.err.Set(err)
+ c.engine.Close(err)
+}
+
+func (c *connection) Disconnect(err error) {
+ c.err.Set(err)
+ c.engine.Disconnect(err)
+}
+
+func (c *connection) Session(opts ...SessionOption) (Session, error) {
+ var s Session
+ err := c.engine.InjectWait(func() error {
+ if c.Error() != nil {
+ return c.Error()
+ }
+ pSession, err := c.engine.Connection().Session()
+ if err == nil {
+ pSession.Open()
+ if err == nil {
+ s = newSession(c, pSession, opts...)
+ }
+ }
+ return err
+ })
+ return s, err
+}
+
+func (c *connection) Container() Container { return c.container }
+
+func (c *connection) DefaultSession() (s Session, err error) {
+ c.defaultSessionOnce.Do(func() {
+ c.defaultSession, err = c.Session()
+ })
+ if err == nil {
+ err = c.Error()
+ }
+ return c.defaultSession, err
+}
+
+func (c *connection) Sender(opts ...LinkOption) (Sender, error) {
+ if s, err := c.DefaultSession(); err == nil {
+ return s.Sender(opts...)
+ } else {
+ return nil, err
+ }
+}
+
+func (c *connection) Receiver(opts ...LinkOption) (Receiver, error) {
+ if s, err := c.DefaultSession(); err == nil {
+ return s.Receiver(opts...)
+ } else {
+ return nil, err
+ }
+}
+
+func (c *connection) Connection() Connection { return c }
+
+func (c *connection) Wait() error { return c.WaitTimeout(Forever) }
+func (c *connection) WaitTimeout(timeout time.Duration) error {
+ _, err := timedReceive(c.done, timeout)
+ if err == Timeout {
+ return Timeout
+ }
+ return c.Error()
+}
+
+func (c *connection) Incoming() <-chan Incoming {
+ assert(c.incoming != nil, "Incoming() is only allowed for a Connection created with the Server() option: %s", c)
+ return c.incoming
+}
+
+type IncomingConnection struct {
+ incoming
+ connectionSettings
+ c *connection
+}
+
+func newIncomingConnection(c *connection) *IncomingConnection {
+ c.user = c.pConnection.Transport().User()
+ c.virtualHost = c.pConnection.RemoteHostname()
+ return &IncomingConnection{
+ incoming: makeIncoming(c.pConnection),
+ connectionSettings: c.connectionSettings,
+ c: c}
+}
+
+// AcceptConnection is like Accept() but takes ConnectionOption s
+// For example you can set the Heartbeat() for the accepted connection.
+func (in *IncomingConnection) AcceptConnection(opts ...ConnectionOption) Connection {
+ return in.accept(func() Endpoint {
+ for _, opt := range opts {
+ opt(in.c)
+ }
+ in.c.pConnection.Open()
+ return in.c
+ }).(Connection)
+}
+
+func (in *IncomingConnection) Accept() Endpoint {
+ return in.AcceptConnection()
+}
+
+func sasl(c *connection) proton.SASL { return c.engine.Transport().SASL() }
+
+// SASLEnable returns a ConnectionOption that enables SASL authentication.
+// Only required if you don't set any other SASL options.
+func SASLEnable() ConnectionOption { return func(c *connection) { sasl(c) } }
+
+// SASLAllowedMechs returns a ConnectionOption to set the list of allowed SASL
+// mechanisms.
+//
+// Can be used on the client or the server to restrict the SASL for a connection.
+// mechs is a space-separated list of mechanism names.
+//
+func SASLAllowedMechs(mechs string) ConnectionOption {
+ return func(c *connection) { sasl(c).AllowedMechs(mechs) }
+}
+
+// SASLAllowInsecure returns a ConnectionOption that allows or disallows clear
+// text SASL authentication mechanisms
+//
+// By default the SASL layer is configured not to allow mechanisms that disclose
+// the clear text of the password over an unencrypted AMQP connection. This specifically
+// will disallow the use of the PLAIN mechanism without using SSL encryption.
+//
+// This default is to avoid disclosing password information accidentally over an
+// insecure network.
+//
+func SASLAllowInsecure(b bool) ConnectionOption {
+ return func(c *connection) { sasl(c).SetAllowInsecureMechs(b) }
+}
+
+// Heartbeat returns a ConnectionOption that requests the maximum delay
+// between sending frames for the remote peer. If we don't receive any frames
+// within 2*delay we will close the connection.
+//
+func Heartbeat(delay time.Duration) ConnectionOption {
+ // Proton-C divides the idle-timeout by 2 before sending, so compensate.
+ return func(c *connection) { c.engine.Transport().SetIdleTimeout(2 * delay) }
+}
+
+// GlobalSASLConfigDir sets the SASL configuration directory for every
+// Connection created in this process. If not called, the default is determined
+// by your SASL installation.
+//
+// You can set SASLAllowInsecure and SASLAllowedMechs on individual connections.
+//
+func GlobalSASLConfigDir(dir string) { globalSASLConfigDir = dir }
+
+// GlobalSASLConfigName sets the SASL configuration name for every Connection
+// created in this process. If not called the default is "proton-server".
+//
+// The complete configuration file name is
+// <sasl-config-dir>/<sasl-config-name>.conf
+//
+// You can set SASLAllowInsecure and SASLAllowedMechs on individual connections.
+//
+func GlobalSASLConfigName(dir string) { globalSASLConfigName = dir }
+
++// Do we support extended SASL negotiation?
++// All implementations of Proton support ANONYMOUS and EXTERNAL on both
++// client and server sides and PLAIN on the client side.
++//
++// Extended SASL implememtations use an external library (Cyrus SASL)
++// to support other mechanisms beyond these basic ones.
++func SASLExtended() bool { return proton.SASLExtended() }
++
+var (
+ globalSASLConfigName string
+ globalSASLConfigDir string
+)
+
+// TODO aconway 2016-09-15: Current pn_sasl C impl config is broken, so all we
+// can realistically offer is global configuration. Later if/when the pn_sasl C
+// impl is fixed we can offer per connection over-rides.
+func globalSASLInit(eng *proton.Engine) {
+ sasl := eng.Transport().SASL()
+ if globalSASLConfigName != "" {
+ sasl.ConfigName(globalSASLConfigName)
+ }
+ if globalSASLConfigDir != "" {
+ sasl.ConfigPath(globalSASLConfigDir)
+ }
+}
+
+// Dial is shorthand for using net.Dial() then NewConnection()
+// See net.Dial() for the meaning of the network, address arguments.
+func Dial(network, address string, opts ...ConnectionOption) (c Connection, err error) {
+ conn, err := net.Dial(network, address)
+ if err == nil {
+ c, err = NewConnection(conn, opts...)
+ }
+ return
+}
+
+// DialWithDialer is shorthand for using dialer.Dial() then NewConnection()
+// See net.Dial() for the meaning of the network, address arguments.
+func DialWithDialer(dialer *net.Dialer, network, address string, opts ...ConnectionOption) (c Connection, err error) {
+ conn, err := dialer.Dial(network, address)
+ if err == nil {
+ c, err = NewConnection(conn, opts...)
+ }
+ return
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6c48527c/electron/electron_test.go
----------------------------------------------------------------------
diff --cc electron/electron_test.go
index 294e952,0000000..4cd8453
mode 100644,000000..100644
--- a/electron/electron_test.go
+++ b/electron/electron_test.go
@@@ -1,546 -1,0 +1,546 @@@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+*/
+
+package electron
+
+import (
+ "fmt"
+ "net"
+ "path"
+ "qpid.apache.org/amqp"
+ "reflect"
+ "runtime"
+ "testing"
+ "time"
+)
+
+func fatalIf(t *testing.T, err error) {
+ if err != nil {
+ _, file, line, ok := runtime.Caller(1) // annotate with location of caller.
+ if ok {
+ _, file = path.Split(file)
+ }
+ t.Fatalf("(from %s:%d) %v", file, line, err)
+ }
+}
+
+func errorIf(t *testing.T, err error) {
+ if err != nil {
+ _, file, line, ok := runtime.Caller(1) // annotate with location of caller.
+ if ok {
+ _, file = path.Split(file)
+ }
+ t.Errorf("(from %s:%d) %v", file, line, err)
+ }
+}
+
+func checkEqual(want interface{}, got interface{}) error {
+ if !reflect.DeepEqual(want, got) {
+ return fmt.Errorf("%#v != %#v", want, got)
+ }
+ return nil
+}
+
+// Start a server, return listening addr and channel for incoming Connections.
+func newServer(t *testing.T, cont Container, opts ...ConnectionOption) (net.Addr, <-chan Connection) {
- listener, err := net.Listen("tcp", "")
++ listener, err := net.Listen("tcp4", "") // For systems with ipv6 disabled
+ fatalIf(t, err)
+ addr := listener.Addr()
+ ch := make(chan Connection)
+ go func() {
+ conn, err := listener.Accept()
+ c, err := cont.Connection(conn, append([]ConnectionOption{Server()}, opts...)...)
+ fatalIf(t, err)
+ ch <- c
+ }()
+ return addr, ch
+}
+
+// Open a client connection and session, return the session.
+func newClient(t *testing.T, cont Container, addr net.Addr, opts ...ConnectionOption) Session {
+ conn, err := net.Dial(addr.Network(), addr.String())
+ fatalIf(t, err)
+ c, err := cont.Connection(conn, opts...)
+ fatalIf(t, err)
+ sn, err := c.Session()
+ fatalIf(t, err)
+ return sn
+}
+
+// Return client and server ends of the same connection.
+func newClientServerOpts(t *testing.T, copts []ConnectionOption, sopts []ConnectionOption) (client Session, server Connection) {
+ addr, ch := newServer(t, NewContainer("test-server"), sopts...)
+ client = newClient(t, NewContainer("test-client"), addr, copts...)
+ return client, <-ch
+}
+
+// Return client and server ends of the same connection.
+func newClientServer(t *testing.T) (client Session, server Connection) {
+ return newClientServerOpts(t, nil, nil)
+}
+
+// Close client and server
+func closeClientServer(client Session, server Connection) {
+ client.Connection().Close(nil)
+ server.Close(nil)
+}
+
+// Send a message one way with a client sender and server receiver, verify ack.
+func TestClientSendServerReceive(t *testing.T) {
+ nLinks := 3
+ nMessages := 3
+
+ rchan := make(chan Receiver, nLinks)
+ client, server := newClientServer(t)
+ go func() {
+ for in := range server.Incoming() {
+ switch in := in.(type) {
+ case *IncomingReceiver:
+ in.SetCapacity(1)
+ in.SetPrefetch(false)
+ rchan <- in.Accept().(Receiver)
+ default:
+ in.Accept()
+ }
+ }
+ }()
+
+ defer func() { closeClientServer(client, server) }()
+
+ s := make([]Sender, nLinks)
+ for i := 0; i < nLinks; i++ {
+ var err error
+ s[i], err = client.Sender(Target(fmt.Sprintf("foo%d", i)))
+ if err != nil {
+ t.Fatal(err)
+ }
+ }
+ r := make([]Receiver, nLinks)
+ for i := 0; i < nLinks; i++ {
+ r[i] = <-rchan
+ }
+
+ for i := 0; i < nLinks; i++ {
+ for j := 0; j < nMessages; j++ {
+ // Client send
+ ack := make(chan Outcome, 1)
+ sendDone := make(chan struct{})
+ go func() {
+ defer close(sendDone)
+ m := amqp.NewMessageWith(fmt.Sprintf("foobar%v-%v", i, j))
+ var err error
+ s[i].SendAsync(m, ack, "testing")
+ if err != nil {
+ t.Fatal(err)
+ }
+ }()
+
+ // Server recieve
+ rm, err := r[i].Receive()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if want, got := interface{}(fmt.Sprintf("foobar%v-%v", i, j)), rm.Message.Body(); want != got {
+ t.Errorf("%#v != %#v", want, got)
+ }
+
+ // Should not be acknowledged on client yet
+ <-sendDone
+ select {
+ case <-ack:
+ t.Errorf("unexpected ack")
+ default:
+ }
+
+ // Server send ack
+ if err := rm.Reject(); err != nil {
+ t.Error(err)
+ }
+ // Client get ack.
+ if a := <-ack; a.Value != "testing" || a.Error != nil || a.Status != Rejected {
+ t.Error("unexpected ack: ", a.Status, a.Error, a.Value)
+ }
+ }
+ }
+}
+
+func TestClientReceiver(t *testing.T) {
+ nMessages := 3
+ client, server := newClientServer(t)
+ go func() {
+ for in := range server.Incoming() {
+ switch in := in.(type) {
+ case *IncomingSender:
+ s := in.Accept().(Sender)
+ go func() {
+ for i := int32(0); i < int32(nMessages); i++ {
+ out := s.SendSync(amqp.NewMessageWith(i))
+ if out.Error != nil {
+ t.Error(out.Error)
+ return
+ }
+ }
+ s.Close(nil)
+ }()
+ default:
+ in.Accept()
+ }
+ }
+ }()
+
+ r, err := client.Receiver(Source("foo"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ for i := int32(0); i < int32(nMessages); i++ {
+ rm, err := r.Receive()
+ if err != nil {
+ if err != Closed {
+ t.Error(err)
+ }
+ break
+ }
+ if err := rm.Accept(); err != nil {
+ t.Error(err)
+ }
+ if b, ok := rm.Message.Body().(int32); !ok || b != i {
+ t.Errorf("want %v, true got %v, %v", i, b, ok)
+ }
+ }
+ server.Close(nil)
+ client.Connection().Close(nil)
+}
+
+// Test timeout versions of waiting functions.
+func TestTimeouts(t *testing.T) {
+ var err error
+ rchan := make(chan Receiver, 1)
+ client, server := newClientServer(t)
+ go func() {
+ for i := range server.Incoming() {
+ switch i := i.(type) {
+ case *IncomingReceiver:
+ i.SetCapacity(1)
+ i.SetPrefetch(false)
+ rchan <- i.Accept().(Receiver) // Issue credit only on receive
+ default:
+ i.Accept()
+ }
+ }
+ }()
+ defer func() { closeClientServer(client, server) }()
+
+ // Open client sender
+ snd, err := client.Sender(Target("test"))
+ if err != nil {
+ t.Fatal(err)
+ }
+ rcv := <-rchan
+
+ // Test send with timeout
+ short := time.Millisecond
+ long := time.Second
+ m := amqp.NewMessage()
+ if err := snd.SendSyncTimeout(m, 0).Error; err != Timeout { // No credit, expect timeout.
+ t.Error("want Timeout got", err)
+ }
+ if err := snd.SendSyncTimeout(m, short).Error; err != Timeout { // No credit, expect timeout.
+ t.Error("want Timeout got", err)
+ }
+ // Test receive with timeout
+ if _, err = rcv.ReceiveTimeout(0); err != Timeout { // No credit, expect timeout.
+ t.Error("want Timeout got", err)
+ }
+ // Test receive with timeout
+ if _, err = rcv.ReceiveTimeout(short); err != Timeout { // No credit, expect timeout.
+ t.Error("want Timeout got", err)
+ }
+ // There is now a credit on the link due to receive
+ ack := make(chan Outcome)
+ snd.SendAsyncTimeout(m, ack, nil, short)
+ // Disposition should timeout
+ select {
+ case <-ack:
+ t.Errorf("want Timeout got %#v", ack)
+ case <-time.After(short):
+ }
+
+ // Receive and accept
+ rm, err := rcv.ReceiveTimeout(long)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := rm.Accept(); err != nil {
+ t.Fatal(err)
+ }
+ // Sender get ack
+ if a := <-ack; a.Status != Accepted || a.Error != nil {
+ t.Errorf("want (accepted, nil) got %#v", a)
+ }
+}
+
+// A server that returns the opposite end of each client link via channels.
+type pairs struct {
+ t *testing.T
+ client Session
+ server Connection
+ rchan chan Receiver
+ schan chan Sender
+ capacity int
+ prefetch bool
+}
+
+func newPairs(t *testing.T, capacity int, prefetch bool) *pairs {
+ p := &pairs{t: t, rchan: make(chan Receiver, 1), schan: make(chan Sender, 1)}
+ p.client, p.server = newClientServer(t)
+ go func() {
+ for i := range p.server.Incoming() {
+ switch i := i.(type) {
+ case *IncomingReceiver:
+ i.SetCapacity(capacity)
+ i.SetPrefetch(prefetch)
+ p.rchan <- i.Accept().(Receiver)
+ case *IncomingSender:
+ p.schan <- i.Accept().(Sender)
+ default:
+ i.Accept()
+ }
+ }
+ }()
+ return p
+}
+
+func (p *pairs) close() {
+ closeClientServer(p.client, p.server)
+}
+
+// Return a client sender and server receiver
+func (p *pairs) senderReceiver() (Sender, Receiver) {
+ snd, err := p.client.Sender()
+ fatalIf(p.t, err)
+ rcv := <-p.rchan
+ return snd, rcv
+}
+
+// Return a client receiver and server sender
+func (p *pairs) receiverSender() (Receiver, Sender) {
+ rcv, err := p.client.Receiver()
+ fatalIf(p.t, err)
+ snd := <-p.schan
+ return rcv, snd
+}
+
+type result struct {
+ label string
+ err error
+ value interface{}
+}
+
+func (r result) String() string { return fmt.Sprintf("%v(%v)", r.err, r.label) }
+
+func doSend(snd Sender, results chan result) {
+ err := snd.SendSync(amqp.NewMessage()).Error
+ results <- result{"send", err, nil}
+}
+
+func doReceive(rcv Receiver, results chan result) {
+ msg, err := rcv.Receive()
+ results <- result{"receive", err, msg}
+}
+
+func doDisposition(ack <-chan Outcome, results chan result) {
+ results <- result{"disposition", (<-ack).Error, nil}
+}
+
+// Senders get credit immediately if receivers have prefetch set
+func TestSendReceivePrefetch(t *testing.T) {
+ pairs := newPairs(t, 1, true)
+ s, r := pairs.senderReceiver()
+ s.SendAsyncTimeout(amqp.NewMessage(), nil, nil, time.Second) // Should not block for credit.
+ if _, err := r.Receive(); err != nil {
+ t.Error(err)
+ }
+}
+
+// Senders do not get credit till Receive() if receivers don't have prefetch
+func TestSendReceiveNoPrefetch(t *testing.T) {
+ pairs := newPairs(t, 1, false)
+ s, r := pairs.senderReceiver()
+ done := make(chan struct{}, 1)
+ go func() {
+ s.SendAsyncTimeout(amqp.NewMessage(), nil, nil, time.Second) // Should block for credit.
+ close(done)
+ }()
+ select {
+ case <-done:
+ t.Errorf("send should be blocked on credit")
+ default:
+ if _, err := r.Receive(); err != nil {
+ t.Error(err)
+ } else {
+ <-done
+ } // Should be unblocked now
+ }
+}
+
+// Test that closing Links interrupts blocked link functions.
+func TestLinkCloseInterrupt(t *testing.T) {
+ want := amqp.Error{Name: "x", Description: "all bad"}
+ pairs := newPairs(t, 1, false)
+ results := make(chan result) // Collect expected errors
+
+ // Note closing the link does not interrupt Send() calls, the AMQP spec says
+ // that deliveries can be settled after the link is closed.
+
+ // Receiver.Close() interrupts Receive()
+ snd, rcv := pairs.senderReceiver()
+ go doReceive(rcv, results)
+ rcv.Close(want)
+ if r := <-results; want != r.err {
+ t.Errorf("want %#v got %#v", want, r)
+ }
+
+ // Remote Sender.Close() interrupts Receive()
+ snd, rcv = pairs.senderReceiver()
+ go doReceive(rcv, results)
+ snd.Close(want)
+ if r := <-results; want != r.err {
+ t.Errorf("want %#v got %#v", want, r)
+ }
+}
+
+// Test closing the server end of a connection.
+func TestConnectionCloseInterrupt1(t *testing.T) {
+ want := amqp.Error{Name: "x", Description: "bad"}
+ pairs := newPairs(t, 1, true)
+ results := make(chan result) // Collect expected errors
+
+ // Connection.Close() interrupts Send, Receive, Disposition.
+ snd, rcv := pairs.senderReceiver()
+ go doSend(snd, results)
+
+ if _, err := rcv.Receive(); err != nil {
+ t.Error("receive", err)
+ }
+ rcv, snd = pairs.receiverSender()
+ go doReceive(rcv, results)
+
+ snd, rcv = pairs.senderReceiver()
+ ack := snd.SendWaitable(amqp.NewMessage())
+ if _, err := rcv.Receive(); err != nil {
+ t.Error("receive", err)
+ }
+ go doDisposition(ack, results)
+
+ pairs.server.Close(want)
+ for i := 0; i < 3; i++ {
+ if r := <-results; want != r.err {
+ t.Errorf("want %v got %v", want, r)
+ }
+ }
+}
+
+// Test closing the client end of the connection.
+func TestConnectionCloseInterrupt2(t *testing.T) {
+ want := amqp.Error{Name: "x", Description: "bad"}
+ pairs := newPairs(t, 1, true)
+ results := make(chan result) // Collect expected errors
+
+ // Connection.Close() interrupts Send, Receive, Disposition.
+ snd, rcv := pairs.senderReceiver()
+ go doSend(snd, results)
+ if _, err := rcv.Receive(); err != nil {
+ t.Error("receive", err)
+ }
+
+ rcv, snd = pairs.receiverSender()
+ go doReceive(rcv, results)
+
+ snd, rcv = pairs.senderReceiver()
+ ack := snd.SendWaitable(amqp.NewMessage())
+ go doDisposition(ack, results)
+
+ pairs.client.Connection().Close(want)
+ for i := 0; i < 3; i++ {
+ if r := <-results; want != r.err {
+ t.Errorf("want %v got %v", want, r.err)
+ }
+ }
+}
+
+func heartbeat(c Connection) time.Duration {
+ return c.(*connection).engine.Transport().RemoteIdleTimeout()
+}
+
+func TestHeartbeat(t *testing.T) {
+ client, server := newClientServerOpts(t,
+ []ConnectionOption{Heartbeat(102 * time.Millisecond)},
+ nil)
+ defer closeClientServer(client, server)
+
+ var serverHeartbeat time.Duration
+
+ go func() {
+ for in := range server.Incoming() {
+ switch in := in.(type) {
+ case *IncomingConnection:
+ serverHeartbeat = in.Heartbeat()
+ in.AcceptConnection(Heartbeat(101 * time.Millisecond))
+ default:
+ in.Accept()
+ }
+ }
+ }()
+
+ // Freeze the server to stop it sending heartbeats.
+ unfreeze := make(chan bool)
+ defer close(unfreeze)
+ freeze := func() error { return server.(*connection).engine.Inject(func() { <-unfreeze }) }
+
+ fatalIf(t, client.Sync())
+ errorIf(t, checkEqual(101*time.Millisecond, heartbeat(client.Connection())))
+ errorIf(t, checkEqual(102*time.Millisecond, serverHeartbeat))
+ errorIf(t, client.Connection().Error())
+
+ // Freeze the server for less than a heartbeat
+ fatalIf(t, freeze())
+ time.Sleep(50 * time.Millisecond)
+ unfreeze <- true
+ // Make sure server is still responding.
+ s, err := client.Sender()
+ errorIf(t, err)
+ errorIf(t, s.Sync())
+
+ // Freeze the server till the client times out the connection
+ fatalIf(t, freeze())
+ select {
+ case <-client.Done():
+ if amqp.ResourceLimitExceeded != client.Error().(amqp.Error).Name {
+ t.Error("bad timeout error:", client.Error())
+ }
+ case <-time.After(400 * time.Millisecond):
+ t.Error("connection failed to time out")
+ }
+
+ unfreeze <- true // Unfreeze the server
+ <-server.Done()
+ if amqp.ResourceLimitExceeded != server.Error().(amqp.Error).Name {
+ t.Error("bad timeout error:", server.Error())
+ }
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6c48527c/electron/example_client_server_test.go
----------------------------------------------------------------------
diff --cc electron/example_client_server_test.go
index 3aa5892,0000000..385c865
mode 100644,000000..100644
--- a/electron/example_client_server_test.go
+++ b/electron/example_client_server_test.go
@@@ -1,85 -1,0 +1,97 @@@
+package electron_test
+
+import (
+ "fmt"
++ "log"
+ "net"
+ "qpid.apache.org/amqp"
+ "qpid.apache.org/electron"
+ "sync"
+)
+
+// Example Server that accepts a single Connection, Session and Receiver link
+// and prints messages received until the link closes.
+func Server(l net.Listener) {
+ cont := electron.NewContainer("server")
- c, _ := cont.Accept(l) // Ignoring error handling
- l.Close() // This server only accepts one connection
++ c, err := cont.Accept(l)
++ if err != nil {
++ log.Fatal(err)
++ }
++ l.Close() // This server only accepts one connection
+ // Process incoming endpoints till we get a Receiver link
+ var r electron.Receiver
+ for r == nil {
+ in := <-c.Incoming()
+ switch in := in.(type) {
+ case *electron.IncomingSession, *electron.IncomingConnection:
+ in.Accept() // Accept the incoming connection and session for the receiver
+ case *electron.IncomingReceiver:
+ in.SetCapacity(10)
+ in.SetPrefetch(true) // Automatic flow control for a buffer of 10 messages.
+ r = in.Accept().(electron.Receiver)
+ case nil:
+ return // Connection is closed
+ default:
+ in.Reject(amqp.Errorf("example-server", "unexpected endpoint %v", in))
+ }
+ }
+ go func() { // Reject any further incoming endpoints
+ for in := range c.Incoming() {
+ in.Reject(amqp.Errorf("example-server", "unexpected endpoint %v", in))
+ }
+ }()
+ // Receive messages till the Receiver closes
+ rm, err := r.Receive()
+ for ; err == nil; rm, err = r.Receive() {
+ fmt.Printf("server received: %q\n", rm.Message.Body())
+ rm.Accept() // Signal to the client that the message was accepted
+ }
+ fmt.Printf("server receiver closed: %v\n", err)
+}
+
+// Example client sending messages to a server running in a goroutine.
+//
+// Normally client and server would be separate processes. For more realistic and detailed examples:
+// https://github.com/apache/qpid-proton/blob/master/examples/go/README.md
+//
+func Example_clientServer() {
- // NOTE: We ignoring error handling in this example
- l, _ := net.Listen("tcp", "") // Open a listening port for server, client connect to this port
++ l, err := net.Listen("tcp", "127.0.0.1:0") // tcp4 so example will work on ipv6-disabled platforms
++ if err != nil {
++ log.Fatal(err)
++ }
+
+ // SERVER: start the server running in a separate goroutine
+ var waitServer sync.WaitGroup // We will wait for the server goroutine to finish before exiting
+ waitServer.Add(1)
+ go func() { // Run the server in the background
+ defer waitServer.Done()
+ Server(l)
+ }()
+
+ // CLIENT: Send messages to the server
+ addr := l.Addr()
- c, _ := electron.Dial(addr.Network(), addr.String())
- s, _ := c.Sender()
++ c, err := electron.Dial(addr.Network(), addr.String())
++ if err != nil {
++ log.Fatal(err)
++ }
++ s, err := c.Sender()
++ if err != nil {
++ log.Fatal(err)
++ }
+ for i := 0; i < 3; i++ {
+ msg := fmt.Sprintf("hello %v", i)
+ // Send and wait for the Outcome from the server.
+ // Note: For higher throughput, use SendAsync() to send a stream of messages
+ // and process the returning stream of Outcomes concurrently.
+ s.SendSync(amqp.NewMessageWith(msg))
+ }
+ c.Close(nil) // Closing the connection will stop the server
+
+ waitServer.Wait() // Let the server finish
+
+ // Output:
+ // server received: "hello 0"
+ // server received: "hello 1"
+ // server received: "hello 2"
+ // server receiver closed: EOF
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/6c48527c/proton/wrappers.go
----------------------------------------------------------------------
diff --cc proton/wrappers.go
index 879ad53,0000000..09f3e65
mode 100644,000000..100644
--- a/proton/wrappers.go
+++ b/proton/wrappers.go
@@@ -1,450 -1,0 +1,460 @@@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+*/
+
+// This file contains special-case wrapper functions or wrappers that don't follow
+// the pattern of genwrap.go.
+
+package proton
+
+//#include <proton/codec.h>
+//#include <proton/connection.h>
+//#include <proton/delivery.h>
+//#include <proton/event.h>
+//#include <proton/link.h>
+//#include <proton/link.h>
+//#include <proton/object.h>
+//#include <proton/sasl.h>
+//#include <proton/session.h>
+//#include <proton/transport.h>
+//#include <stdlib.h>
+import "C"
+
+import (
+ "fmt"
+ "qpid.apache.org/amqp"
+ "reflect"
+ "time"
+ "unsafe"
+)
+
+// TODO aconway 2015-05-05: Documentation for generated types.
+
+// CHandle holds an unsafe.Pointer to a proton C struct, the C type depends on the
+// Go type implementing this interface. For low level, at-your-own-risk use only.
+type CHandle interface {
+ // CPtr returns the unsafe C pointer, equivalent to a C void*.
+ CPtr() unsafe.Pointer
+}
+
+// Incref increases the refcount of a proton value, which prevents the
+// underlying C struct being freed until you call Decref().
+//
+// It can be useful to "pin" a proton value in memory while it is in use by
+// goroutines other than the event loop goroutine. For example if you Incref() a
+// Link, the underlying object is not freed when the link is closed, so means
+// other goroutines can continue to safely use it as an index in a map or inject
+// it into the event loop goroutine. There will of course be an error if you try
+// to use a link after it is closed, but not a segmentation fault.
+func Incref(c CHandle) {
+ if p := c.CPtr(); p != nil {
+ C.pn_incref(p)
+ }
+}
+
+// Decref decreases the refcount of a proton value, freeing the underlying C
+// struct if this is the last reference. Only call this if you previously
+// called Incref() for this value.
+func Decref(c CHandle) {
+ if p := c.CPtr(); p != nil {
+ C.pn_decref(p)
+ }
+}
+
+// Event is an AMQP protocol event.
+type Event struct {
+ pn *C.pn_event_t
+ eventType EventType
+ connection Connection
+ transport Transport
+ session Session
+ link Link
+ delivery Delivery
+ injecter Injecter
+}
+
+func makeEvent(pn *C.pn_event_t, injecter Injecter) Event {
+ return Event{
+ pn: pn,
+ eventType: EventType(C.pn_event_type(pn)),
+ connection: Connection{C.pn_event_connection(pn)},
+ transport: Transport{C.pn_event_transport(pn)},
+ session: Session{C.pn_event_session(pn)},
+ link: Link{C.pn_event_link(pn)},
+ delivery: Delivery{C.pn_event_delivery(pn)},
+ injecter: injecter,
+ }
+}
+func (e Event) IsNil() bool { return e.eventType == EventType(0) }
+func (e Event) Type() EventType { return e.eventType }
+func (e Event) Connection() Connection { return e.connection }
+func (e Event) Transport() Transport { return e.transport }
+func (e Event) Session() Session { return e.session }
+func (e Event) Link() Link { return e.link }
+func (e Event) Delivery() Delivery { return e.delivery }
+func (e Event) String() string { return e.Type().String() }
+
+// Injecter should not be used in a handler function, but it can be passed to
+// other goroutines (via a channel or to a goroutine started by handler
+// functions) to let them inject functions back into the handlers goroutine.
+func (e Event) Injecter() Injecter { return e.injecter }
+
+// Data is an intermediate form of decoded AMQP data.
+type Data struct{ pn *C.pn_data_t }
+
+func (d Data) Free() { C.pn_data_free(d.pn) }
+func (d Data) CPtr() unsafe.Pointer { return unsafe.Pointer(d.pn) }
+func (d Data) Clear() { C.pn_data_clear(d.pn) }
+func (d Data) Rewind() { C.pn_data_rewind(d.pn) }
+func (d Data) Next() { C.pn_data_next(d.pn) }
+func (d Data) Error() error { return PnError(C.pn_data_error(d.pn)) }
+func (d Data) Empty() bool { return C.pn_data_size(d.pn) == 0 }
+
+func (d Data) String() string {
+ str := C.pn_string(C.CString(""))
+ defer C.pn_free(unsafe.Pointer(str))
+ C.pn_inspect(unsafe.Pointer(d.pn), str)
+ return C.GoString(C.pn_string_get(str))
+}
+
+// Unmarshal the value of d into value pointed at by ptr, see amqp.Unmarshal() for details
+func (d Data) Unmarshal(ptr interface{}) error {
+ d.Rewind()
+ d.Next()
+ err := amqp.UnmarshalUnsafe(d.CPtr(), ptr)
+ return err
+}
+
+// Marshal the value v into d, see amqp.Marshal() for details
+func (d Data) Marshal(v interface{}) error {
+ d.Clear()
+ return amqp.MarshalUnsafe(v, d.CPtr())
+}
+
+// State holds the state flags for an AMQP endpoint.
+type State byte
+
+const (
+ SLocalUninit State = C.PN_LOCAL_UNINIT
+ SLocalActive = C.PN_LOCAL_ACTIVE
+ SLocalClosed = C.PN_LOCAL_CLOSED
+ SRemoteUninit = C.PN_REMOTE_UNINIT
+ SRemoteActive = C.PN_REMOTE_ACTIVE
+ SRemoteClosed = C.PN_REMOTE_CLOSED
+)
+
+// Has is True if bits & state is non 0.
+func (s State) Has(bits State) bool { return s&bits != 0 }
+
+func (s State) LocalUninit() bool { return s.Has(SLocalUninit) }
+func (s State) LocalActive() bool { return s.Has(SLocalActive) }
+func (s State) LocalClosed() bool { return s.Has(SLocalClosed) }
+func (s State) RemoteUninit() bool { return s.Has(SRemoteUninit) }
+func (s State) RemoteActive() bool { return s.Has(SRemoteActive) }
+func (s State) RemoteClosed() bool { return s.Has(SRemoteClosed) }
+
+// Return a State containig just the local flags
+func (s State) Local() State { return State(s & C.PN_LOCAL_MASK) }
+
+// Return a State containig just the remote flags
+func (s State) Remote() State { return State(s & C.PN_REMOTE_MASK) }
+
+// Endpoint is the common interface for Connection, Link and Session.
+type Endpoint interface {
+ // State is the open/closed state.
+ State() State
+ // Open an endpoint.
+ Open()
+ // Close an endpoint.
+ Close()
+ // Condition holds a local error condition.
+ Condition() Condition
+ // RemoteCondition holds a remote error condition.
+ RemoteCondition() Condition
+ // Human readable name
+ String() string
+ // Human readable endpoint type "sender-link", "session" etc.
+ Type() string
+}
+
+// CloseError sets an error condition (if err != nil) on an endpoint and closes
+// the endpoint if not already closed
+func CloseError(e Endpoint, err error) {
+ if err != nil && !e.Condition().IsSet() {
+ e.Condition().SetError(err)
+ }
+ e.Close()
+}
+
+// EndpointError returns the remote error if there is one, the local error if not
+// nil if there is no error.
+func EndpointError(e Endpoint) error {
+ err := e.RemoteCondition().Error()
+ if err == nil {
+ err = e.Condition().Error()
+ }
+ return err
+}
+
+const (
+ Received uint64 = C.PN_RECEIVED
+ Accepted = C.PN_ACCEPTED
+ Rejected = C.PN_REJECTED
+ Released = C.PN_RELEASED
+ Modified = C.PN_MODIFIED
+)
+
+// SettleAs is equivalent to d.Update(disposition); d.Settle()
+func (d Delivery) SettleAs(disposition uint64) {
+ d.Update(disposition)
+ d.Settle()
+}
+
+// Accept accepts and settles a delivery.
+func (d Delivery) Accept() { d.SettleAs(Accepted) }
+
+// Reject rejects and settles a delivery
+func (d Delivery) Reject() { d.SettleAs(Rejected) }
+
+// Release releases and settles a delivery
+// If delivered is true the delivery count for the message will be increased.
+func (d Delivery) Release(delivered bool) {
+ if delivered {
+ d.SettleAs(Modified)
+ } else {
+ d.SettleAs(Released)
+ }
+}
+
+type DeliveryTag struct{ pn C.pn_delivery_tag_t }
+
+func (t DeliveryTag) String() string { return C.GoStringN(t.pn.start, C.int(t.pn.size)) }
+
+func (l Link) Recv(buf []byte) int {
+ if len(buf) == 0 {
+ return 0
+ }
+ return int(C.pn_link_recv(l.pn, (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(len(buf))))
+}
+
+func (l Link) SendBytes(bytes []byte) int {
+ return int(C.pn_link_send(l.pn, cPtr(bytes), cLen(bytes)))
+}
+
+func pnTag(tag string) C.pn_delivery_tag_t {
+ bytes := []byte(tag)
+ return C.pn_dtag(cPtr(bytes), cLen(bytes))
+}
+
+func (l Link) Delivery(tag string) Delivery {
+ return Delivery{C.pn_delivery(l.pn, pnTag(tag))}
+}
+
+func (l Link) Connection() Connection { return l.Session().Connection() }
+
+// Human-readable link description including name, source, target and direction.
+func (l Link) String() string {
+ switch {
+ case l.IsNil():
+ return fmt.Sprintf("<nil-link>")
+ case l.IsSender():
+ return fmt.Sprintf("%s(%s->%s)", l.Name(), l.Source().Address(), l.Target().Address())
+ default:
+ return fmt.Sprintf("%s(%s<-%s)", l.Name(), l.Target().Address(), l.Source().Address())
+ }
+}
+
+func (l Link) Type() string {
+ if l.IsSender() {
+ return "sender-link"
+ } else {
+ return "receiver-link"
+ }
+}
+
+// IsDrain calls pn_link_get_drain(), it conflicts with pn_link_drain() under the normal mapping.
+func (l Link) IsDrain() bool {
+ return bool(C.pn_link_get_drain(l.pn))
+}
+
+func cPtr(b []byte) *C.char {
+ if len(b) == 0 {
+ return nil
+ }
+ return (*C.char)(unsafe.Pointer(&b[0]))
+}
+
+func cLen(b []byte) C.size_t {
+ return C.size_t(len(b))
+}
+
+func (s Session) Sender(name string) Link {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ return Link{C.pn_sender(s.pn, cname)}
+}
+
+func (s Session) Receiver(name string) Link {
+ cname := C.CString(name)
+ defer C.free(unsafe.Pointer(cname))
+ return Link{C.pn_receiver(s.pn, cname)}
+}
+
+func (t Transport) String() string {
+ return fmt.Sprintf("(Transport)(%p)", t.CPtr())
+}
+
+// Unique (per process) string identifier for a connection, useful for debugging.
+func (c Connection) String() string {
+ // Use the transport address to match the default transport logs from PN_TRACE.
+ return fmt.Sprintf("(Connection)(%p)", c.Transport().CPtr())
+}
+
+func (c Connection) Type() string {
+ return "connection"
+}
+
+// Head functions don't follow the normal naming conventions so missed by the generator.
+
+func (c Connection) LinkHead(s State) Link {
+ return Link{C.pn_link_head(c.pn, C.pn_state_t(s))}
+}
+
+func (c Connection) SessionHead(s State) Session {
+ return Session{C.pn_session_head(c.pn, C.pn_state_t(s))}
+}
+
+func (c Connection) Links(state State) (links []Link) {
+ for l := c.LinkHead(state); !l.IsNil(); l = l.Next(state) {
+ links = append(links, l)
+ }
+ return
+}
+
+func (c Connection) Sessions(state State) (sessions []Session) {
+ for s := c.SessionHead(state); !s.IsNil(); s = s.Next(state) {
+ sessions = append(sessions, s)
+ }
+ return
+}
+
+// SetPassword takes []byte not string because it is impossible to erase a string
+// from memory reliably. Proton will not keep the password in memory longer than
+// needed, the caller should overwrite their copy on return.
+//
+// The password must not contain embedded nul characters, a trailing nul is ignored.
+func (c Connection) SetPassword(password []byte) {
+ if len(password) == 0 || password[len(password)-1] != 0 {
+ password = append(password, 0) // Proton requires a terminating null.
+ }
+ C.pn_connection_set_password(c.pn, (*C.char)(unsafe.Pointer(&password[0])))
+}
+
+func (s Session) String() string {
+ return fmt.Sprintf("(Session)(%p)", s.pn) // TODO aconway 2016-09-12: should print channel number.
+}
+
+func (s Session) Type() string { return "session" }
+
+// Error returns an instance of amqp.Error or nil.
+func (c Condition) Error() error {
+ if c.IsNil() || !c.IsSet() {
+ return nil
+ }
+ return amqp.Error{Name: c.Name(), Description: c.Description()}
+}
+
+// Set a Go error into a condition.
+// If it is not an amqp.Condition use the error type as name, error string as description.
+func (c Condition) SetError(err error) {
+ if err != nil {
+ if cond, ok := err.(amqp.Error); ok {
+ c.SetName(cond.Name)
+ c.SetDescription(cond.Description)
+ } else {
+ c.SetName(reflect.TypeOf(err).Name())
+ c.SetDescription(err.Error())
+ }
+ }
+}
+
+func (c Connection) Session() (Session, error) {
+ s := Session{C.pn_session(c.pn)}
+ if s.IsNil() {
+ return s, Connection(c).Error()
+ }
+ return s, nil
+}
+
+// pnTime converts Go time.Time to Proton millisecond Unix time.
+//
+// Note: t.isZero() is converted to C.pn_timestamp_t(0) and vice-versa. These
+// are used as "not set" sentinel values by the Go and Proton APIs, so it is
+// better to conserve the "zeroness" even though they don't represent the same
+// time instant.
+//
+func pnTime(t time.Time) (pnt C.pn_timestamp_t) {
+ if !t.IsZero() {
+ pnt = C.pn_timestamp_t(t.Unix()*1000 + int64(t.Nanosecond())/int64(time.Millisecond))
+ }
+ return
+}
+
+// goTime converts a pn_timestamp_t to a Go time.Time.
+//
+// Note: C.pn_timestamp_t(0) is converted to a zero time.Time and
+// vice-versa. These are used as "not set" sentinel values by the Go and Proton
+// APIs, so it is better to conserve the "zeroness" even though they don't
+// represent the same time instant.
+//
+func goTime(pnt C.pn_timestamp_t) (t time.Time) {
+ if pnt != 0 {
+ t = time.Unix(int64(pnt/1000), int64(pnt%1000)*int64(time.Millisecond))
+ }
+ return
+}
+
+// Special treatment for Transport.Head, return value is unsafe.Pointer not string
+func (t Transport) Head() unsafe.Pointer {
+ return unsafe.Pointer(C.pn_transport_head(t.pn))
+}
+
+// Special treatment for Transport.Tail, return value is unsafe.Pointer not string
+func (t Transport) Tail() unsafe.Pointer {
+ return unsafe.Pointer(C.pn_transport_tail(t.pn))
+}
+
+// Special treatment for Transport.Push, takes []byte instead of char*, size
+func (t Transport) Push(bytes []byte) int {
+ return int(C.pn_transport_push(t.pn, (*C.char)(unsafe.Pointer(&bytes[0])), C.size_t(len(bytes))))
+}
+
+// Get the SASL object for the transport.
+func (t Transport) SASL() SASL {
+ return SASL{C.pn_sasl(t.pn)}
+}
++
++// Do we support extended SASL negotiation?
++// All implementations of Proton support ANONYMOUS and EXTERNAL on both
++// client and server sides and PLAIN on the client side.
++//
++// Extended SASL implememtations use an external library (Cyrus SASL)
++// to support other mechanisms beyond these basic ones.
++func SASLExtended() bool {
++ return bool(C.pn_sasl_extended())
++}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[22/31] qpid-proton git commit: PROTON-1660: [ruby] remove broken
dependency "json ~> 0"
Posted by ac...@apache.org.
PROTON-1660: [ruby] remove broken dependency "json ~> 0"
Removed this dependency entirely, proton no longer depends on the json module.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/ae1f143d
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/ae1f143d
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/ae1f143d
Branch: refs/heads/go1
Commit: ae1f143d2dcce6689785224d50e91cd144e7643e
Parents: 6180838
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 30 12:02:08 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 30 12:02:08 2017 -0400
----------------------------------------------------------------------
proton-c/bindings/ruby/qpid_proton.gemspec.in | 1 -
1 file changed, 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/ae1f143d/proton-c/bindings/ruby/qpid_proton.gemspec.in
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/qpid_proton.gemspec.in b/proton-c/bindings/ruby/qpid_proton.gemspec.in
index 8dbcee6..cb25199 100644
--- a/proton-c/bindings/ruby/qpid_proton.gemspec.in
+++ b/proton-c/bindings/ruby/qpid_proton.gemspec.in
@@ -28,5 +28,4 @@ EOF
"lib/**/*.rb",
]
s.require_path = 'lib'
- s.add_runtime_dependency "json", "~> 0"
end
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[19/31] qpid-proton git commit: PROTON-1652: Fix tests to run on
Windows - run test in correct directory - some extra broker output flushing -
treat empty ssl cert_name like no cert_name
Posted by ac...@apache.org.
PROTON-1652: Fix tests to run on Windows
- run test in correct directory
- some extra broker output flushing
- treat empty ssl cert_name like no cert_name
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/23601872
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/23601872
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/23601872
Branch: refs/heads/go1
Commit: 236018722ab8fcb7aa947c319c5e2ec95c235f1d
Parents: fb352ce
Author: Andrew Stitcher <as...@apache.org>
Authored: Fri Oct 27 13:49:14 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Fri Oct 27 13:49:14 2017 -0400
----------------------------------------------------------------------
examples/c/CMakeLists.txt | 5 ++++-
examples/c/broker.c | 1 +
examples/c/direct.c | 1 +
examples/c/send-ssl.c | 1 +
proton-c/src/ssl/schannel.c | 2 +-
5 files changed, 8 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/23601872/examples/c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt
index bdb1c7d..894f1d8 100644
--- a/examples/c/CMakeLists.txt
+++ b/examples/c/CMakeLists.txt
@@ -43,4 +43,7 @@ else()
endif()
set(run_env ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/proton-c/env.py ${EXAMPLE_ENV})
-add_test(NAME c-example-tests COMMAND ${run_env} "PATH=${test_path}" ${VALGRIND_ENV} -- ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v)
+add_test(
+ NAME c-example-tests
+ COMMAND ${run_env} "PATH=${test_path}" ${VALGRIND_ENV} -- ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/23601872/examples/c/broker.c
----------------------------------------------------------------------
diff --git a/examples/c/broker.c b/examples/c/broker.c
index 541fbff..ceb9e96 100644
--- a/examples/c/broker.c
+++ b/examples/c/broker.c
@@ -365,6 +365,7 @@ static void handle(broker_t* b, pn_event_t* e) {
recv = pn_link_recv(l, m->start, m->size);
if (recv == PN_ABORTED) { /* */
fprintf(stderr, "Message aborted\n");
+ fflush(stderr);
m->size = 0; /* Forget the data we accumulated */
pn_delivery_settle(d); /* Free the delivery so we can receive the next message */
pn_link_flow(l, WINDOW - pn_link_credit(l)); /* Replace credit for the aborted message */
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/23601872/examples/c/direct.c
----------------------------------------------------------------------
diff --git a/examples/c/direct.c b/examples/c/direct.c
index fb737a1..219cd60 100644
--- a/examples/c/direct.c
+++ b/examples/c/direct.c
@@ -150,6 +150,7 @@ static void handle_receive(app_data_t *app, pn_event_t* event) {
recv = pn_link_recv(l, m->start, m->size);
if (recv == PN_ABORTED) {
fprintf(stderr, "Message aborted\n");
+ fflush(stderr);
m->size = 0; /* Forget the data we accumulated */
pn_delivery_settle(d); /* Free the delivery so we can receive the next message */
pn_link_flow(l, 1); /* Replace credit for aborted message */
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/23601872/examples/c/send-ssl.c
----------------------------------------------------------------------
diff --git a/examples/c/send-ssl.c b/examples/c/send-ssl.c
index 8e0722e..83a3ab3 100644
--- a/examples/c/send-ssl.c
+++ b/examples/c/send-ssl.c
@@ -153,6 +153,7 @@ static bool handle(app_data_t* app, pn_event_t* event) {
if (pn_delivery_remote_state(d) == PN_ACCEPTED) {
if (++app->acknowledged == app->message_count) {
printf("%d messages sent and acknowledged\n", app->acknowledged);
+ fflush(stdout);
pn_connection_close(pn_event_connection(event));
/* Continue handling events till we receive TRANSPORT_CLOSED */
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/23601872/proton-c/src/ssl/schannel.c
----------------------------------------------------------------------
diff --git a/proton-c/src/ssl/schannel.c b/proton-c/src/ssl/schannel.c
index 788b52d..054683c 100644
--- a/proton-c/src/ssl/schannel.c
+++ b/proton-c/src/ssl/schannel.c
@@ -177,7 +177,7 @@ static int win_credential_load_cert(win_credential_t *cred, const char *store_na
char *fn = name_len ? (char *) malloc(name_len + 1) : 0;
while (tmpctx = CertEnumCertificatesInStore(cert_store, tmpctx)) {
cert_count++;
- if (cert_name) {
+ if (cert_name && *cert_name) {
DWORD len = CertGetNameString(tmpctx, CERT_NAME_FRIENDLY_DISPLAY_TYPE,
0, NULL, NULL, 0);
if (len != name_len + 1)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[25/31] qpid-proton git commit: PROTON-1655: [go] TestAuthPlain fails
when SASL_IMPL is none
Posted by ac...@apache.org.
PROTON-1655: [go] TestAuthPlain fails when SASL_IMPL is none
Added electron.SASLExtended() check for extended SASL support.
Skip tests that can't be run without extended support when it is not available.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/91195b58
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/91195b58
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/91195b58
Branch: refs/heads/go1
Commit: 91195b58019a1be801e4fc9d8fd0a3f7ab433f3e
Parents: a1ceb2f
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 30 17:14:26 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 30 17:14:26 2017 -0400
----------------------------------------------------------------------
.../bindings/go/src/qpid.apache.org/electron/auth_test.go | 9 +++++++++
.../go/src/qpid.apache.org/electron/connection.go | 8 ++++++++
.../bindings/go/src/qpid.apache.org/proton/wrappers.go | 10 ++++++++++
3 files changed, 27 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/91195b58/proton-c/bindings/go/src/qpid.apache.org/electron/auth_test.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/auth_test.go b/proton-c/bindings/go/src/qpid.apache.org/electron/auth_test.go
index 73a9299..9eb48c0 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/auth_test.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/auth_test.go
@@ -57,6 +57,9 @@ func TestAuthAnonymous(t *testing.T) {
}
func TestAuthPlain(t *testing.T) {
+ if !SASLExtended() {
+ t.Skip()
+ }
fatalIf(t, configureSASL())
got, err := testAuthClientServer(t,
[]ConnectionOption{SASLAllowInsecure(true), SASLAllowedMechs("PLAIN"), User("fred@proton"), Password([]byte("xxx"))},
@@ -66,6 +69,9 @@ func TestAuthPlain(t *testing.T) {
}
func TestAuthBadPass(t *testing.T) {
+ if !SASLExtended() {
+ t.Skip()
+ }
fatalIf(t, configureSASL())
_, err := testAuthClientServer(t,
[]ConnectionOption{SASLAllowInsecure(true), SASLAllowedMechs("PLAIN"), User("fred@proton"), Password([]byte("yyy"))},
@@ -76,6 +82,9 @@ func TestAuthBadPass(t *testing.T) {
}
func TestAuthBadUser(t *testing.T) {
+ if !SASLExtended() {
+ t.Skip()
+ }
fatalIf(t, configureSASL())
_, err := testAuthClientServer(t,
[]ConnectionOption{SASLAllowInsecure(true), SASLAllowedMechs("PLAIN"), User("foo@bar"), Password([]byte("yyy"))},
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/91195b58/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go b/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
index 267ee1e..2749b2b 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/electron/connection.go
@@ -374,6 +374,14 @@ func GlobalSASLConfigDir(dir string) { globalSASLConfigDir = dir }
//
func GlobalSASLConfigName(dir string) { globalSASLConfigName = dir }
+// Do we support extended SASL negotiation?
+// All implementations of Proton support ANONYMOUS and EXTERNAL on both
+// client and server sides and PLAIN on the client side.
+//
+// Extended SASL implememtations use an external library (Cyrus SASL)
+// to support other mechanisms beyond these basic ones.
+func SASLExtended() bool { return proton.SASLExtended() }
+
var (
globalSASLConfigName string
globalSASLConfigDir string
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/91195b58/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
----------------------------------------------------------------------
diff --git a/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go b/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
index 879ad53..09f3e65 100644
--- a/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
+++ b/proton-c/bindings/go/src/qpid.apache.org/proton/wrappers.go
@@ -448,3 +448,13 @@ func (t Transport) Push(bytes []byte) int {
func (t Transport) SASL() SASL {
return SASL{C.pn_sasl(t.pn)}
}
+
+// Do we support extended SASL negotiation?
+// All implementations of Proton support ANONYMOUS and EXTERNAL on both
+// client and server sides and PLAIN on the client side.
+//
+// Extended SASL implememtations use an external library (Cyrus SASL)
+// to support other mechanisms beyond these basic ones.
+func SASLExtended() bool {
+ return bool(C.pn_sasl_extended())
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[28/31] qpid-proton git commit: PROTON-1667: Fix more coverity issues
Posted by ac...@apache.org.
PROTON-1667: Fix more coverity issues
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/41003e64
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/41003e64
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/41003e64
Branch: refs/heads/go1
Commit: 41003e64a9f99e1e4905cbc893cf6dd2013a87bd
Parents: de3fd61
Author: Andrew Stitcher <as...@apache.org>
Authored: Tue Oct 31 01:12:13 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Tue Oct 31 01:12:13 2017 -0400
----------------------------------------------------------------------
examples/cpp/scheduled_send.cpp | 1 +
proton-c/src/proactor/epoll.c | 35 +++++++++++++++--------------
proton-c/src/tests/connection_driver.c | 1 +
3 files changed, 20 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/41003e64/examples/cpp/scheduled_send.cpp
----------------------------------------------------------------------
diff --git a/examples/cpp/scheduled_send.cpp b/examples/cpp/scheduled_send.cpp
index 867b0df..3244540 100644
--- a/examples/cpp/scheduled_send.cpp
+++ b/examples/cpp/scheduled_send.cpp
@@ -48,6 +48,7 @@ class scheduled_sender : public proton::messaging_handler {
url(s),
interval(int(d*proton::duration::SECOND.milliseconds())), // Send interval.
timeout(int(t*proton::duration::SECOND.milliseconds())), // Cancel after timeout.
+ work_queue(0),
ready(true), // Ready to send.
canceled(false) // Canceled.
{}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/41003e64/proton-c/src/proactor/epoll.c
----------------------------------------------------------------------
diff --git a/proton-c/src/proactor/epoll.c b/proton-c/src/proactor/epoll.c
index 6234d4b..69e6d0f 100644
--- a/proton-c/src/proactor/epoll.c
+++ b/proton-c/src/proactor/epoll.c
@@ -1382,23 +1382,24 @@ void pn_proactor_listen(pn_proactor_t *p, pn_listener_t *l, const char *addr, in
for (struct addrinfo *ai = addrinfo; ai; ai = ai->ai_next) {
int fd = socket(ai->ai_family, SOCK_STREAM, ai->ai_protocol);
static int on = 1;
- if ((fd >= 0) &&
- !setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) &&
- /* We listen to v4/v6 on separate sockets, don't let v6 listen for v4 */
- (ai->ai_family != AF_INET6 ||
- !setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on))) &&
- !bind(fd, ai->ai_addr, ai->ai_addrlen) &&
- !listen(fd, backlog))
- {
- psocket_t *ps = &l->psockets[l->psockets_size++];
- psocket_init(ps, p, l, addr);
- ps->sockfd = fd;
- ps->epoll_io.fd = fd;
- ps->epoll_io.wanted = EPOLLIN;
- ps->epoll_io.polling = false;
- start_polling(&ps->epoll_io, ps->proactor->epollfd); // TODO: check for error
- } else {
- close(fd);
+ if (fd >= 0) {
+ if (!setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) &&
+ /* We listen to v4/v6 on separate sockets, don't let v6 listen for v4 */
+ (ai->ai_family != AF_INET6 ||
+ !setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on))) &&
+ !bind(fd, ai->ai_addr, ai->ai_addrlen) &&
+ !listen(fd, backlog))
+ {
+ psocket_t *ps = &l->psockets[l->psockets_size++];
+ psocket_init(ps, p, l, addr);
+ ps->sockfd = fd;
+ ps->epoll_io.fd = fd;
+ ps->epoll_io.wanted = EPOLLIN;
+ ps->epoll_io.polling = false;
+ start_polling(&ps->epoll_io, ps->proactor->epollfd); // TODO: check for error
+ } else {
+ close(fd);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/41003e64/proton-c/src/tests/connection_driver.c
----------------------------------------------------------------------
diff --git a/proton-c/src/tests/connection_driver.c b/proton-c/src/tests/connection_driver.c
index fbcefc3..f152e89 100644
--- a/proton-c/src/tests/connection_driver.c
+++ b/proton-c/src/tests/connection_driver.c
@@ -291,6 +291,7 @@ int send_receive_message(test_t *t, const char* tag,
int errors = t->errors;
char data[100] = {0}; /* Dummy data to send. */
strncpy(data, tag, sizeof(data));
+ data[99] = 0; /* Ensure terminated as we strcmp this later*/
if (!TEST_CHECK(t, pn_link_credit(src->handler.link))) return 1;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[07/31] qpid-proton git commit: PROTON-1633: Much neater way to allow
the examples to work with the sanitizers
Posted by ac...@apache.org.
PROTON-1633: Much neater way to allow the examples to work with the sanitizers
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/79cc60fc
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/79cc60fc
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/79cc60fc
Branch: refs/heads/go1
Commit: 79cc60fcfecb5ba73956465c379415c125bcbce9
Parents: affa7cb
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Oct 19 18:57:20 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Fri Oct 20 15:21:44 2017 -0400
----------------------------------------------------------------------
examples/ProtonConfig.cmake | 9 ++++++---
examples/ProtonCppConfig.cmake | 3 ++-
examples/c/CMakeLists.txt | 10 ++++------
examples/cpp/CMakeLists.txt | 4 +---
4 files changed, 13 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/79cc60fc/examples/ProtonConfig.cmake
----------------------------------------------------------------------
diff --git a/examples/ProtonConfig.cmake b/examples/ProtonConfig.cmake
index e0a2ff8..29c1fb5 100644
--- a/examples/ProtonConfig.cmake
+++ b/examples/ProtonConfig.cmake
@@ -30,16 +30,19 @@
set (Proton_VERSION ${PN_VERSION})
set (Proton_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/proton-c/include)
-set (Proton_LIBRARIES qpid-proton)
+set (Proton_LIBRARIES ${C_EXAMPLE_LINK_FLAGS} qpid-proton)
+set (Proton_DEFINITIONS ${C_EXAMPLE_FLAGS})
set (Proton_FOUND True)
set (Proton_Core_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/proton-c/include)
-set (Proton_Core_LIBRARIES qpid-proton-core)
+set (Proton_Core_LIBRARIES ${C_EXAMPLE_LINK_FLAGS} qpid-proton-core)
+set (Proton_Core_DEFINITIONS ${C_EXAMPLE_FLAGS})
set (Proton_Core_FOUND True)
if (${HAS_PROACTOR})
set (Proton_Proactor_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/proton-c/include)
- set (Proton_Proactor_LIBRARIES qpid-proton-proactor)
+ set (Proton_Proactor_LIBRARIES ${C_EXAMPLE_LINK_FLAGS} qpid-proton-proactor)
+ set (Proton_Proactor_DEFINITIONS ${C_EXAMPLE_FLAGS})
set (Proton_Proactor_FOUND True)
endif()
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/79cc60fc/examples/ProtonCppConfig.cmake
----------------------------------------------------------------------
diff --git a/examples/ProtonCppConfig.cmake b/examples/ProtonCppConfig.cmake
index e23d134..9709163 100644
--- a/examples/ProtonCppConfig.cmake
+++ b/examples/ProtonCppConfig.cmake
@@ -29,5 +29,6 @@
set (ProtonCpp_VERSION ${PN_VERSION})
set (ProtonCpp_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/proton-c/include ${CMAKE_SOURCE_DIR}/proton-c/bindings/cpp/include)
-set (ProtonCpp_LIBRARIES qpid-proton-cpp)
+set (ProtonCpp_LIBRARIES ${C_EXAMPLE_LINK_FLAGS} qpid-proton-cpp)
+set (ProtonCpp_DEFINITIONS ${CXX_EXAMPLE_FLAGS})
set (ProtonCpp_FOUND True)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/79cc60fc/examples/c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt
index dd1feb4..d2d0fcf 100644
--- a/examples/c/CMakeLists.txt
+++ b/examples/c/CMakeLists.txt
@@ -21,11 +21,10 @@ find_package(Proton REQUIRED Core Proactor)
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
-include(CheckCCompilerFlag)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${Proton_INCLUDE_DIRS})
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR})
-add_definitions(${C_EXAMPLE_FLAGS})
+include_directories(${Proton_INCLUDE_DIRS})
+add_definitions(${Proton_DEFINITIONS})
# Add a test with the correct environment to find test executables and valgrind.
if(WIN32)
@@ -38,8 +37,7 @@ foreach (name broker send receive direct send-abort send-ssl)
add_executable(c-${name} ${name}.c)
target_link_libraries(c-${name} ${Proton_Proactor_LIBRARIES} ${Proton_Core_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
set_target_properties(c-${name} PROPERTIES
- OUTPUT_NAME ${name}
- LINK_FLAGS "${C_EXAMPLE_LINK_FLAGS}")
+ OUTPUT_NAME ${name})
endforeach()
set(run_env ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/proton-c/env.py ${EXAMPLE_ENV} "PATH=${test_path}" ${VALGRIND_ENV})
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/79cc60fc/examples/cpp/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt
index 037285d..cf6b958 100644
--- a/examples/cpp/CMakeLists.txt
+++ b/examples/cpp/CMakeLists.txt
@@ -22,7 +22,7 @@ find_package(ProtonCpp REQUIRED)
include_directories(${ProtonCpp_INCLUDE_DIRS})
link_libraries(${ProtonCpp_LIBRARIES})
-add_definitions(${CXX_EXAMPLE_FLAGS})
+add_definitions(${ProtonCpp_DEFINITIONS})
set (BUILD_CPP_03 OFF CACHE BOOL "Compile as C++03 even when C++11 is available")
# This effectively checks for cmake version 3.1 or later
@@ -71,7 +71,6 @@ foreach(example
ssl_client_cert
encode_decode)
add_executable(${example} ${example}.cpp)
- set_target_properties(${example} PROPERTIES LINK_FLAGS "${CXX_EXAMPLE_LINK_FLAGS}")
endforeach()
if(HAS_CPP11)
@@ -83,7 +82,6 @@ if(HAS_CPP11)
multithreaded_client_flow_control
)
add_executable(${example} ${example}.cpp)
- set_target_properties(${example} PROPERTIES LINK_FLAGS "${CXX_EXAMPLE_LINK_FLAGS}")
endforeach()
endif()
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[14/31] qpid-proton git commit: PROTON-1176: [python] remove
unreliable file descriptors test
Posted by ac...@apache.org.
PROTON-1176: [python] remove unreliable file descriptors test
Removed a FD overflow test that is not reliable under both linux and windows.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/415a1f7a
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/415a1f7a
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/415a1f7a
Branch: refs/heads/go1
Commit: 415a1f7ab6c76414a98b26883fe2d6c3ba26addd
Parents: 9f80e57
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Oct 24 16:23:58 2017 +0100
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Oct 24 16:51:16 2017 +0100
----------------------------------------------------------------------
tests/python/proton_tests/utils.py | 31 -------------------------------
1 file changed, 31 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/415a1f7a/tests/python/proton_tests/utils.py
----------------------------------------------------------------------
diff --git a/tests/python/proton_tests/utils.py b/tests/python/proton_tests/utils.py
index 72711c7..1f20bba 100644
--- a/tests/python/proton_tests/utils.py
+++ b/tests/python/proton_tests/utils.py
@@ -161,34 +161,3 @@ class SyncRequestResponseTest(Test):
self.assertEquals(server.properties_received, True)
self.assertEquals(server.offered_capabilities_received, True)
self.assertEquals(server.desired_capabilities_received, True)
-
-class OutOfFdsTest(Test):
-
- def test_out_of_fds(self):
- """Create BlockingConnections until we run out of FDs, make sure we get an exception
- and not a crash"""
-
- server = EchoServer(Url(host="127.0.0.1", port=free_tcp_port()), self.timeout)
- server.start()
- server.wait()
-
- # Use up all the FDs
- dummy = os.tmpfile()
- fds = []
- try:
- while True: fds.append(os.dup(dummy.fileno()));
- except OSError, e:
- pass
-
- for i in [0, 1]: # Check the odd and even case
- try:
- BlockingConnection(server.url)
- fail("Expected ProtonException")
- except ProtonException, e:
- pass
- os.close(fds.pop())
-
- for f in fds: os.close(f)
- c = BlockingConnection(server.url, timeout=self.timeout)
- c.close()
- server.join(timeout=self.timeout)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[18/31] qpid-proton git commit: PROTON-1659: Fix test to run with
python 3
Posted by ac...@apache.org.
PROTON-1659: Fix test to run with python 3
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/fb352ceb
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/fb352ceb
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/fb352ceb
Branch: refs/heads/go1
Commit: fb352ceb4d6d668ba7132d182772c66ed9f12e4c
Parents: 7781204
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Oct 26 22:42:01 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Oct 26 22:42:01 2017 -0400
----------------------------------------------------------------------
examples/c/example_test.py | 2 +-
proton-c/src/tests/fdlimit.py | 5 +++--
tools/py/proctest.py | 11 ++++++-----
3 files changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fb352ceb/examples/c/example_test.py
----------------------------------------------------------------------
diff --git a/examples/c/example_test.py b/examples/c/example_test.py
index 31d941f..5c97e46 100644
--- a/examples/c/example_test.py
+++ b/examples/c/example_test.py
@@ -28,7 +28,7 @@ def python_cmd(name):
MESSAGES=10
-def receive_expect_messages(n=MESSAGES): return ''.join(['{"sequence"=%s}\n'%i for i in xrange(1, n+1)])
+def receive_expect_messages(n=MESSAGES): return ''.join(['{"sequence"=%s}\n'%i for i in range(1, n+1)])
def receive_expect_total(n=MESSAGES): return "%s messages received\n"%n
def receive_expect(n=MESSAGES): return receive_expect_messages(n)+receive_expect_total(n)
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fb352ceb/proton-c/src/tests/fdlimit.py
----------------------------------------------------------------------
diff --git a/proton-c/src/tests/fdlimit.py b/proton-c/src/tests/fdlimit.py
index c41d14a..53751cb 100644
--- a/proton-c/src/tests/fdlimit.py
+++ b/proton-c/src/tests/fdlimit.py
@@ -16,6 +16,7 @@
# specific language governing permissions and limitations
# under the License
#
+from __future__ import print_function
from proctest import *
@@ -42,7 +43,7 @@ class LimitedBroker(object):
try:
Proc(["prlimit"]).wait_exit()
except:
- print "Skipping test: prlimit not available"
+ print("Skipping test: prlimit not available")
sys.exit(0)
class FdLimitTest(ProcTestCase):
@@ -58,7 +59,7 @@ class FdLimitTest(ProcTestCase):
with LimitedBroker(self, fdlimit) as b:
receivers = []
# Start enough receivers to use all FDs, make sure the broker logs an error
- for i in xrange(fdlimit+1):
+ for i in range(fdlimit+1):
receivers.append(self.proc(["receive", "", b.port, str(i)]))
# Note: libuv silently swallows EMFILE/ENFILE errors so there is no error reporting.
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/fb352ceb/tools/py/proctest.py
----------------------------------------------------------------------
diff --git a/tools/py/proctest.py b/tools/py/proctest.py
index 947e7a5..8e3c473 100644
--- a/tools/py/proctest.py
+++ b/tools/py/proctest.py
@@ -79,14 +79,13 @@ class Proc(Popen):
@property
def out(self):
self._out.seek(0)
- # Normalize line endings, os.tmpfile() opens in binary mode.
- return self._out.read().replace('\r\n','\n').replace('\r','\n')
+ return self._out.read()
def __init__(self, args, valgrind=True, helgrind=False, **kwargs):
"""Start an example process"""
self.args = list(args)
self.kwargs = kwargs
- self._out = tempfile.TemporaryFile()
+ self._out = tempfile.TemporaryFile(mode='w+')
valgrind_exe = valgrind and os.getenv("VALGRIND")
if valgrind_exe:
# run valgrind for speed, not for detailed information
@@ -100,11 +99,11 @@ class Proc(Popen):
sys.stderr.write("\n== running == "+" ".join(self.args)+"\n")
try:
Popen.__init__(self, self.args, stdout=self._out, stderr=STDOUT, **kwargs)
- except OSError, e:
+ except OSError as e:
if e.errno == errno.ENOENT:
raise NotFoundError(self, str(e))
raise ProcError(self, str(e))
- except Exception, e:
+ except Exception as e:
raise ProcError(self, str(e))
def kill(self):
@@ -213,6 +212,8 @@ class ProcTestCase(unittest.TestCase):
def assertMultiLineEqual(self, a, b):
self.assertEqual(a, b)
+from functools import reduce
+
def find_file(filename, path):
"""
Find filename in path. Path is a list of directory names or OS path strings
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[13/31] qpid-proton git commit: NO-JIRA: [ruby] fix cmake parallel
build dependency
Posted by ac...@apache.org.
NO-JIRA: [ruby] fix cmake parallel build dependency
Make ruby-gem depend on cproton-ruby to fix problems with parallel builds.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/9f80e575
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/9f80e575
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/9f80e575
Branch: refs/heads/go1
Commit: 9f80e57537f3037902b86aac1a3da2b3ccbddc08
Parents: da7f505
Author: Alan Conway <ac...@redhat.com>
Authored: Tue Oct 24 13:37:34 2017 +0100
Committer: Alan Conway <ac...@redhat.com>
Committed: Tue Oct 24 13:37:34 2017 +0100
----------------------------------------------------------------------
proton-c/bindings/ruby/CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/9f80e575/proton-c/bindings/ruby/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/CMakeLists.txt b/proton-c/bindings/ruby/CMakeLists.txt
index 24e16d5..ff88ddd 100644
--- a/proton-c/bindings/ruby/CMakeLists.txt
+++ b/proton-c/bindings/ruby/CMakeLists.txt
@@ -57,7 +57,7 @@ if (GEM_EXE)
COMMAND ${CMAKE_COMMAND} -E copy_directory ${src} ${bin}
COMMAND ${CMAKE_COMMAND} -E copy ${bin}/rubyRUBY_wrap.c ${bin}/ext/cproton/cproton.c
COMMAND ${GEM_EXE} build qpid_proton.gemspec
- DEPENDS ${RUBY_SRC} ${src}/LICENSE ${src}/TODO ${src}/ChangeLog ${bin}/rubyRUBY_wrap.c
+ DEPENDS ${RUBY_SRC} ${src}/LICENSE ${src}/TODO ${src}/ChangeLog cproton-ruby
WORKING_DIRECTORY ${bin})
add_custom_target(ruby-gem ALL DEPENDS ${bin}/qpid_proton-${PN_VERSION}.gem )
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[29/31] qpid-proton git commit: PROTON-1668: update release helper
script, use version rather than tag name for archive filename
Posted by ac...@apache.org.
PROTON-1668: update release helper script, use version rather than tag name for archive filename
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/2c07cc30
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/2c07cc30
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/2c07cc30
Branch: refs/heads/go1
Commit: 2c07cc30064bacf4f315ea60f2973ba213379bbc
Parents: 41003e6
Author: Robbie Gemmell <ro...@apache.org>
Authored: Tue Oct 31 12:43:33 2017 +0000
Committer: Robbie Gemmell <ro...@apache.org>
Committed: Tue Oct 31 12:44:58 2017 +0000
----------------------------------------------------------------------
bin/export.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/2c07cc30/bin/export.sh
----------------------------------------------------------------------
diff --git a/bin/export.sh b/bin/export.sh
index 4bad515..ee2c23c 100755
--- a/bin/export.sh
+++ b/bin/export.sh
@@ -66,8 +66,8 @@ WORKDIR=$(mktemp -d)
(
cd ${SRC}
MTIME=$(date -d @`git log -1 --pretty=format:%ct tags/${TAG}` '+%Y-%m-%d %H:%M:%S')
- ARCHIVE=$DIR/qpid-proton-${TAG}.tar.gz
VERSION=$(git show tags/${TAG}:version.txt)
+ ARCHIVE=$DIR/qpid-proton-${VERSION}.tar.gz
PREFIX=qpid-proton-${VERSION}
[ -d ${WORKDIR} ] || mkdir -p ${WORKDIR}
git archive --format=tar --prefix=${PREFIX}/ tags/${TAG} \
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[17/31] qpid-proton git commit: NO-JIRA: Change Travis build to use
"matrix" builds for coverage - Note don't actually need to run "make
coverage" as codecov.io does all that processing itself.
Posted by ac...@apache.org.
NO-JIRA: Change Travis build to use "matrix" builds for coverage
- Note don't actually need to run "make coverage" as codecov.io
does all that processing itself.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/7781204e
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/7781204e
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/7781204e
Branch: refs/heads/go1
Commit: 7781204e58b238c40faf8a35c3206d2634ce161d
Parents: 0790bb9
Author: Andrew Stitcher <as...@apache.org>
Authored: Thu Oct 26 16:00:06 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Thu Oct 26 17:39:06 2017 -0400
----------------------------------------------------------------------
.travis.yml | 15 ++++++++-------
bin/record-coverage.sh | 2 +-
2 files changed, 9 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/7781204e/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index f8694b0..f162dcb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -23,7 +23,13 @@ language: cpp
compiler:
- gcc
- clang
-
+env:
+- QPID_PROTON_CMAKE_ARGS=
+- QPID_PROTON_CMAKE_ARGS=-DCMAKE_BUILD_TYPE=Coverage
+matrix:
+ exclude:
+ - compiler: clang
+ env: QPID_PROTON_CMAKE_ARGS=-DCMAKE_BUILD_TYPE=Coverage
addons:
apt:
packages:
@@ -56,11 +62,6 @@ script:
after_success:
- |
- if [[ ${CC} = gcc ]]; then
- mkdir ../build_coverage
- cd ../build_coverage
- cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/install -DCMAKE_BUILD_TYPE=Coverage ${QPID_PROTON_CMAKE_ARGS}
- cmake --build . --target install && ctest -V ${QPID_PROTON_CTEST_ARGS}
- make coverage
+ if [[ -d coverage_results ]]; then
bash <(curl -s https://codecov.io/bash)
fi
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/7781204e/bin/record-coverage.sh
----------------------------------------------------------------------
diff --git a/bin/record-coverage.sh b/bin/record-coverage.sh
index edc903d..f161e6d 100755
--- a/bin/record-coverage.sh
+++ b/bin/record-coverage.sh
@@ -1,4 +1,4 @@
-# /usr/bin/bash
+#! /usr/bin/env bash
# This script collates coverage data already present from running instrumented code.
#
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[26/31] qpid-proton git commit: PROTON-1658: [ruby] simpler,
more portable port allocation for tests
Posted by ac...@apache.org.
PROTON-1658: [ruby] simpler, more portable port allocation for tests
The SO_REUSEADDR trick that works on Linux does not work on OSX or Windows.
Use a simpler approach of listen(0), close socket, do real listen. This is
potentially race-prone but works well in practice
The correct solution is to allow the container to listen using a pre-existing socket,
this is coming with PROTON-1064.
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/738c1980
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/738c1980
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/738c1980
Branch: refs/heads/go1
Commit: 738c1980eff65051163e53ba2f1a64a0ce2672dd
Parents: 91195b5
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 30 19:27:18 2017 -0400
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 30 19:27:18 2017 -0400
----------------------------------------------------------------------
examples/ruby/example_test.rb | 18 ++++++++-----
proton-c/bindings/ruby/tests/test_tools.rb | 35 ++++---------------------
2 files changed, 17 insertions(+), 36 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/738c1980/examples/ruby/example_test.rb
----------------------------------------------------------------------
diff --git a/examples/ruby/example_test.rb b/examples/ruby/example_test.rb
index e14aef7..86890ce 100755
--- a/examples/ruby/example_test.rb
+++ b/examples/ruby/example_test.rb
@@ -18,9 +18,9 @@
# under the License.
#
+require 'minitest/autorun'
require 'qpid_proton'
require 'socket'
-require 'test_tools'
class ExampleTest < MiniTest::Test
@@ -66,11 +66,17 @@ EOS
end
end
-# Start the broker before all tests
-TestPort.new do |tp|
- $port = tp.port
- $broker = spawn("#{RbConfig.ruby} reactor/broker.rb -a :#{$port}")
- wait_port($port)
+# Start the broker before all tests.
+$port = TCPServer.open(0) do |s| s.addr[1]; end # find an unused port
+$broker = spawn("#{RbConfig.ruby} reactor/broker.rb -a :#{$port}")
+
+# Wait for the broker to be listening
+deadline = Time.now + 5
+begin
+ TCPSocket.open("", $port).close
+rescue Errno::ECONNREFUSED
+ retry if Time.now < deadline
+ raise
end
# Kill the broker after all tests
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/738c1980/proton-c/bindings/ruby/tests/test_tools.rb
----------------------------------------------------------------------
diff --git a/proton-c/bindings/ruby/tests/test_tools.rb b/proton-c/bindings/ruby/tests/test_tools.rb
index e9045ee..22a9040 100644
--- a/proton-c/bindings/ruby/tests/test_tools.rb
+++ b/proton-c/bindings/ruby/tests/test_tools.rb
@@ -27,31 +27,6 @@ require 'socket'
Container = Qpid::Proton::Reactor::Container
MessagingHandler = Qpid::Proton::Handler::MessagingHandler
-# Bind an unused local port using bind(0) and SO_REUSEADDR and hold it till close()
-# Provides #host, #port and #addr ("host:port") as strings
-class TestPort
- attr_reader :host, :port, :addr
-
- # With block, execute block passing self then close
- # Note host must be the local host, but you can pass '::1' instead for ipv6
- def initialize(host='127.0.0.1')
- @sock = Socket.new(:INET, :STREAM)
- @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
- @sock.bind(Socket.sockaddr_in(0, host))
- @host, @port = @sock.connect_address.ip_unpack
- @addr = "#{@host}:#{@port}"
- if block_given?
- begin
- yield self
- ensure
- close
- end
- end
- end
-
- def close() @sock.close(); end
-end
-
class TestError < Exception; end
def wait_port(port, timeout=5)
@@ -134,16 +109,16 @@ class TestHandler < MessagingHandler
end
end
-# A TestHandler that listens on a TestPort
+# A TestHandler that listens on a random port
class TestServer < TestHandler
def initialize
super
- @tp = TestPort.new
+ @port = TCPServer.open(0) do |s| s.addr[1]; end # find an unused port
end
- def host() @tp.host; end
- def port() @tp.port; end
- def addr() @tp.addr; end
+ def host() ""; end
+ def port() @port; end
+ def addr() "#{host}:#{port}"; end
def on_start(e)
super
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[27/31] qpid-proton git commit: PROTON-1616: Revert erroneous fix for
coverity false positive
Posted by ac...@apache.org.
PROTON-1616: Revert erroneous fix for coverity false positive
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/de3fd617
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/de3fd617
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/de3fd617
Branch: refs/heads/go1
Commit: de3fd617210b5d5a2f2c3e384c33905dbf75ad58
Parents: 738c198
Author: Andrew Stitcher <as...@apache.org>
Authored: Tue Oct 31 00:29:33 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Tue Oct 31 00:29:33 2017 -0400
----------------------------------------------------------------------
proton-c/src/sasl/default_sasl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/de3fd617/proton-c/src/sasl/default_sasl.c
----------------------------------------------------------------------
diff --git a/proton-c/src/sasl/default_sasl.c b/proton-c/src/sasl/default_sasl.c
index 64ffd3a..66dd318 100644
--- a/proton-c/src/sasl/default_sasl.c
+++ b/proton-c/src/sasl/default_sasl.c
@@ -159,7 +159,7 @@ bool default_sasl_process_mechanisms(pn_transport_t *transport, const char *mech
pnx_sasl_is_included_mech(transport, pn_bytes(9, found))) {
pnx_sasl_set_selected_mechanism(transport, ANONYMOUS);
if (username) {
- size_t size = strlen(username+1);
+ size_t size = strlen(username);
char *iresp = (char *) malloc(size);
if (!iresp) return false;
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[20/31] qpid-proton git commit: PROTON-1662: Make sure we link with
pthreads for both openssl and cyrus sasl plugins
Posted by ac...@apache.org.
PROTON-1662: Make sure we link with pthreads for both openssl and cyrus sasl plugins
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/705f8355
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/705f8355
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/705f8355
Branch: refs/heads/go1
Commit: 705f83550f9e143db25d1725170bc8837220a92b
Parents: 2360187
Author: Andrew Stitcher <as...@apache.org>
Authored: Mon Oct 30 09:05:57 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Mon Oct 30 09:05:57 2017 -0400
----------------------------------------------------------------------
proton-c/CMakeLists.txt | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/705f8355/proton-c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt
index c420649..b6ce4a7 100644
--- a/proton-c/CMakeLists.txt
+++ b/proton-c/CMakeLists.txt
@@ -27,6 +27,8 @@ add_custom_target(doc DEPENDS docs)
# Set the default SSL/TLS implementation
find_package(OpenSSL)
+set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
+find_package(Threads)
find_package(PythonInterp REQUIRED)
find_package(SWIG)
# FindSwig.cmake "forgets" make its outputs advanced like a good citizen
@@ -52,15 +54,15 @@ if(PN_WINAPI)
set(ssl_impl schannel)
set(ssl_providers "'none','schannel','openssl'")
else(PN_WINAPI)
- if (OPENSSL_FOUND)
+ if (OPENSSL_FOUND AND Threads_FOUND)
set(ssl_impl openssl)
- endif (OPENSSL_FOUND)
+ endif ()
set(ssl_providers "'none','openssl'")
endif(PN_WINAPI)
set(SSL_IMPL ${ssl_impl} CACHE STRING "Library to use for SSL/TLS support. Valid values: ${ssl_providers}")
set(sasl_providers cyrus none)
-if (CYRUSSASL_FOUND)
+if (CYRUSSASL_FOUND AND Threads_FOUND)
set (sasl_impl cyrus)
else ()
set (sasl_impl none)
@@ -109,7 +111,7 @@ endif(PN_WINAPI)
if (SASL_IMPL STREQUAL cyrus)
set(pn_sasl_impl src/sasl/sasl.c src/sasl/default_sasl.c src/sasl/cyrus_sasl.c)
include_directories (${CYRUS_SASL_INCLUDE_DIR})
- set(SASL_LIB ${CYRUS_SASL_LIBRARY} -lpthread)
+ set(SASL_LIB ${CYRUS_SASL_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
elseif (SASL_IMPL STREQUAL none)
set(pn_sasl_impl src/sasl/sasl.c src/sasl/default_sasl.c src/sasl/cyrus_stub.c)
endif ()
@@ -127,7 +129,7 @@ endif()
if (SSL_IMPL STREQUAL openssl)
set (pn_ssl_impl src/ssl/openssl.c)
include_directories (${OPENSSL_INCLUDE_DIR})
- set (SSL_LIB ${OPENSSL_LIBRARIES})
+ set (SSL_LIB ${OPENSSL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
elseif (SSL_IMPL STREQUAL schannel)
set (pn_ssl_impl src/ssl/schannel.c)
set (SSL_LIB Crypt32.lib Secur32.lib)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[16/31] qpid-proton git commit: NO-JIRA: Re enable Windows C example
testing
Posted by ac...@apache.org.
NO-JIRA: Re enable Windows C example testing
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/0790bb99
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/0790bb99
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/0790bb99
Branch: refs/heads/go1
Commit: 0790bb99fabc4a6d7c1c12fb09c0ff76a3594f5a
Parents: 540ef36
Author: Andrew Stitcher <as...@apache.org>
Authored: Mon Oct 23 14:01:24 2017 -0400
Committer: Andrew Stitcher <as...@apache.org>
Committed: Wed Oct 25 13:20:04 2017 -0400
----------------------------------------------------------------------
examples/c/CMakeLists.txt | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/0790bb99/examples/c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt
index d9f6550..bdb1c7d 100644
--- a/examples/c/CMakeLists.txt
+++ b/examples/c/CMakeLists.txt
@@ -35,17 +35,12 @@ endforeach()
# Add a test to run all examples
-# windows exclusion only for 0.18 beta
-if(NOT WIN32)
-
# Make correct environment to find test executables and valgrind.
if(WIN32)
set(test_path "$<TARGET_FILE_DIR:c-broker>;$<TARGET_FILE_DIR:qpid-proton-core>;$<TARGET_FILE_DIR:qpid-proton-proactor>")
else()
set(test_path "$<TARGET_FILE_DIR:c-broker>:$ENV{PATH}")
endif()
-set(run_env ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/proton-c/env.py ${EXAMPLE_ENV} "PATH=${test_path}" ${VALGRIND_ENV})
-
-add_test(NAME c-example-tests COMMAND ${run_env} -- ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v)
-endif()
+set(run_env ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/proton-c/env.py ${EXAMPLE_ENV})
+add_test(NAME c-example-tests COMMAND ${run_env} "PATH=${test_path}" ${VALGRIND_ENV} -- ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/example_test.py -v)
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org
[11/31] qpid-proton git commit: PROTON-1622 Add coverage reporting to
CMake build
Posted by ac...@apache.org.
PROTON-1622 Add coverage reporting to CMake build
cmake -DCMAKE_BUILD_TYPE=Coverage && make && ctest && make coverage
Then browse ${CMAKE_BUILD_DIR}/coverage_results/html/index.html
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/bdfe982f
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/bdfe982f
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/bdfe982f
Branch: refs/heads/go1
Commit: bdfe982f5f2dd8b9735288623fbc8eabe4a5371f
Parents: e170889
Author: Jiri Danek <jd...@redhat.com>
Authored: Tue Oct 10 21:57:30 2017 +0200
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 23 17:37:33 2017 +0100
----------------------------------------------------------------------
.travis.yml | 14 +++++++++++++-
CMakeLists.txt | 2 +-
proton-c/CMakeLists.txt | 6 +++++-
3 files changed, 19 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bdfe982f/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index f7a8d77..f8694b0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -39,10 +39,11 @@ addons:
- python3-dev
- php5
- golang
+ - lcov
install:
- pip install --user --upgrade pip
-- pip install --user tox
+- pip install --user coverage tox
- gem install minitest
before_script:
@@ -52,3 +53,14 @@ before_script:
script:
- cmake --build . --target install && ctest -V ${QPID_PROTON_CTEST_ARGS}
+
+after_success:
+- |
+ if [[ ${CC} = gcc ]]; then
+ mkdir ../build_coverage
+ cd ../build_coverage
+ cmake .. -DCMAKE_INSTALL_PREFIX=$PWD/install -DCMAKE_BUILD_TYPE=Coverage ${QPID_PROTON_CMAKE_ARGS}
+ cmake --build . --target install && ctest -V ${QPID_PROTON_CTEST_ARGS}
+ make coverage
+ bash <(curl -s https://codecov.io/bash)
+ fi
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bdfe982f/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 75310bd..9f81cbb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -78,7 +78,7 @@ if (CMAKE_BUILD_TYPE MATCHES "Coverage")
make_directory(coverage_results)
add_custom_target(coverage
WORKING_DIRECTORY ./coverage_results
- CgOMMAND ${CMAKE_SOURCE_DIR}/bin/record-coverage.sh ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
+ COMMAND ${CMAKE_SOURCE_DIR}/bin/record-coverage.sh ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
endif()
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/bdfe982f/proton-c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/CMakeLists.txt b/proton-c/CMakeLists.txt
index 4cd4bd5..c420649 100644
--- a/proton-c/CMakeLists.txt
+++ b/proton-c/CMakeLists.txt
@@ -744,13 +744,17 @@ if (BUILD_PYTHON)
to_native_path ("${py_pythonpath}" py_pythonpath)
to_native_path ("${py_path}" py_path)
+ if (CMAKE_BUILD_TYPE MATCHES "Coverage")
+ set (python_coverage_options -m coverage run)
+ endif(CMAKE_BUILD_TYPE MATCHES "Coverage")
+
add_test (NAME python-test
COMMAND ${env_py}
"PATH=${py_path}" "PYTHONPATH=${py_pythonpath}"
"CLASSPATH=${CMAKE_BINARY_DIR}/proton-j/proton-j.jar"
"SASLPASSWD=${SASLPASSWD_EXE}"
${VALGRIND_ENV}
- ${PYTHON_EXECUTABLE} "${py_root}/proton-test")
+ ${PYTHON_EXECUTABLE} -- ${python_coverage_options} "${py_root}/proton-test")
set_tests_properties(python-test PROPERTIES PASS_REGULAR_EXPRESSION "Totals: .* 0 failed")
# Eventually, we'll get rid of this check when other
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org