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