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/10/16 18:03:21 UTC

qpid-proton git commit: PROTON-1618: c++ provide separate test_port implementation

Repository: qpid-proton
Updated Branches:
  refs/heads/master a518b1ce9 -> b4e0edd2c


PROTON-1618: c++ provide separate test_port implementation

Break unwanted dependency between C++ and C test trees.


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/b4e0edd2
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/b4e0edd2
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/b4e0edd2

Branch: refs/heads/master
Commit: b4e0edd2cab25b95a6fa245d00c35928de01550e
Parents: a518b1c
Author: Alan Conway <ac...@redhat.com>
Authored: Mon Oct 16 18:11:52 2017 +0100
Committer: Alan Conway <ac...@redhat.com>
Committed: Mon Oct 16 18:33:02 2017 +0100

----------------------------------------------------------------------
 proton-c/bindings/cpp/src/container_test.cpp |  27 +----
 proton-c/bindings/cpp/src/test_port.hpp      | 129 ++++++++++++++++++++++
 proton-c/src/tests/test_port.h               |   4 +-
 3 files changed, 135 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e0edd2/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 c9657b9..fc368d0 100644
--- a/proton-c/bindings/cpp/src/container_test.cpp
+++ b/proton-c/bindings/cpp/src/container_test.cpp
@@ -19,9 +19,7 @@
 
 
 #include "test_bits.hpp"
-extern "C" {
-#include "../../../../src/tests/test_port.h"
-}
+#include "test_port.hpp"
 
 #include "proton/connection.hpp"
 #include "proton/connection_options.hpp"
@@ -39,23 +37,6 @@ extern "C" {
 
 namespace {
 
-std::string make_url(const std::string& host, int port) {
-    std::ostringstream url;
-    url << "amqp://" << host << ":" << port;
-    return url.str();
-}
-
-// C++ Wrapper for C test port.
-// Binds to a port with REUSEADDR set so that the port is protected from
-// other processes and can safely be used for listening.
-class listen_port {
-    ::test_port_t tp;
-  public:
-    listen_port() { tp = ::test_port(""); } // NOTE: assign tp, don't initialize - Windows.
-    ~listen_port() { ::test_port_close(&tp); }
-    int port() const { return tp.port; }
-    std::string url(const std::string& host="") const { return make_url(host, tp.port); }
-};
 
 struct test_listen_handler : public proton::listen_handler {
     bool on_open_, on_accept_, on_close_;
@@ -91,7 +72,7 @@ class test_handler : public proton::messaging_handler {
 
     std::string peer_vhost;
     std::string peer_container_id;
-    listen_port port;
+    test_port port;
     proton::listener listener;
     test_listen_handler listen_handler;
 
@@ -183,7 +164,7 @@ int test_container_bad_address() {
 }
 
 class stop_tester : public proton::messaging_handler {
-    listen_port port;
+    test_port port;
     proton::listener listener;
 
     // Set up a listener which would block forever
@@ -232,7 +213,7 @@ int test_container_stop() {
 
 struct hang_tester : public proton::messaging_handler {
     proton::listener listener;
-    listen_port port;
+    test_port port;
     bool done;
 
     hang_tester() : done(false) {}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e0edd2/proton-c/bindings/cpp/src/test_port.hpp
----------------------------------------------------------------------
diff --git a/proton-c/bindings/cpp/src/test_port.hpp b/proton-c/bindings/cpp/src/test_port.hpp
new file mode 100644
index 0000000..eb94e84
--- /dev/null
+++ b/proton-c/bindings/cpp/src/test_port.hpp
@@ -0,0 +1,129 @@
+#ifndef TEST_PORT_HPP
+#define TEST_PORT_HPP
+
+/*
+ * 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.
+ */
+
+#include <cstring>
+#include <cerrno>
+
+/* Some simple platform-secifics to acquire an unused socket */
+
+#if defined(_WIN32)
+
+extern "C" {
+# include <winsock2.h>
+# include <ws2tcpip.h>
+}
+
+typedef SOCKET sock_t;
+
+void check_err(int ret, const char *what) {
+  if (ret) {
+    char buf[512];
+    FormatMessage(
+      FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+      NULL, WSAGetLastError(), NULL, buf, sizeof(buf), NULL);
+    fprintf(stderr, "%s: %s\n", what, buf);
+    throw std::runtime_error(buf);
+  }
+}
+
+class test_socket {
+  public:
+    SOCKET sock_;
+    test_socket() {
+        WORD wsa_ver = MAKEWORD(2, 2);
+        WSADATA unused;
+        check_err(WSAStartup(wsa_ver, &unused), "WSAStartup");
+        sock_ = socket(AF_INET, SOCK_STREAM, 0);
+        check_err(sock_ < 0, "socket");
+    }
+    ~test_socket() { WSACleanup(); }
+    void close_early()  { closesocket(sock_); } // Windows won't allow two sockets on a port
+};
+
+#else  /* POSIX */
+
+extern "C" {
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <unistd.h>
+# include <netdb.h>
+}
+
+void check_err(int ret, const std::string& what) {
+    if (ret) throw std::runtime_error(what + ": " + std::strerror(errno));
+}
+
+class test_socket {
+  public:
+    int sock_;
+    test_socket() : sock_(socket(AF_INET, SOCK_STREAM, 0)) {
+        check_err(sock_ < 0, "socket");
+        int on = 1;
+        check_err(setsockopt(sock_, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)),
+                  "setsockop");
+    }
+    ~test_socket() { close(sock_); }
+    void close_early() {}   // Don't close early on POSIX, keep the port safe
+};
+
+#endif
+
+#define TEST_PORT_MAX_STR 1060
+
+/* Acquire a port suitable for listening */
+class test_port {
+    test_socket sock_;
+    int port_;
+
+  public:
+
+    /* Acquire a port suitable for listening */
+    test_port() : port_(0) {
+        /* Create a socket and bind(INADDR_LOOPBACK:0) to get a free port.
+           Set socket options so the port can be bound and used for listen() within this process,
+           even though it is bound to the test_port socket.
+           Use host to create the host_port address string.
+        */
+        struct sockaddr_in addr = {0};
+        addr.sin_family = AF_INET;    /* set the type of connection to TCP/IP */
+        addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+        addr.sin_port = 0;            /* bind to port 0 */
+        check_err(bind(sock_.sock_, (struct sockaddr*)&addr, sizeof(addr)), "bind");
+        socklen_t len = sizeof(addr);
+        check_err(getsockname(sock_.sock_, (struct sockaddr*)&addr, &len), "getsockname");
+        port_ = ntohs(addr.sin_port);
+        sock_.close_early();
+    }
+
+    int port() const { return port_; }
+
+    std::string url(const std::string& host="") const {
+        std::ostringstream url;
+        url << "amp://" << host << ":" << port_;
+        return url.str();
+    }
+};
+
+
+
+#endif // TEST_PORT_HPP

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/b4e0edd2/proton-c/src/tests/test_port.h
----------------------------------------------------------------------
diff --git a/proton-c/src/tests/test_port.h b/proton-c/src/tests/test_port.h
index 85a3fd7..0569c44 100644
--- a/proton-c/src/tests/test_port.h
+++ b/proton-c/src/tests/test_port.h
@@ -104,9 +104,9 @@ test_port_t test_port(const char* host) {
   test_port_t tp = {0};
   tp.sock = socket(AF_INET, SOCK_STREAM, 0);
   check_err(tp.sock < 0, "socket");
-  int on = 1;
 #ifndef _WIN32
-  check_err(setsockopt(tp.sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)), "setsockopt");
+  int on = 1;
+  check_err(setsockopt(tp.sock, SOL_SOCKET, SO_REUSEADDR, (const char*)&on, sizeof(on)), "setsockopt");;;
 #endif
   struct sockaddr_in addr = {0};
   addr.sin_family = AF_INET;    /* set the type of connection to TCP/IP */


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org