From 4a7d59681178d18064daef217fc6f376f4cb4b9c Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 25 Jun 2021 13:38:16 -0400 Subject: [PATCH 01/39] try a windows build --- .github/workflows/win.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/win.yml diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml new file mode 100644 index 0000000..d26b7ae --- /dev/null +++ b/.github/workflows/win.yml @@ -0,0 +1,20 @@ +name: Windows + +on: [push, pull_request] +jobs: + windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - name: dependencies + run: | + choco install make cmake + - name: build + shell: bash + run: | + cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_SANITIZERS=On + make all + - name: test + shell: bash + run: | + make test From 79eb865043d8a1cc61404b511ca37a9053048101 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 25 Jun 2021 14:19:50 -0400 Subject: [PATCH 02/39] try another target --- .github/workflows/win.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index d26b7ae..8f8e64d 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -13,8 +13,8 @@ jobs: shell: bash run: | cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_SANITIZERS=On - make all + make - name: test shell: bash run: | - make test + make check From db7debd616e6a7eed9f82e675955b6de50e1449f Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 25 Jun 2021 14:31:21 -0400 Subject: [PATCH 03/39] leave out the build options --- .github/workflows/win.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index 8f8e64d..7070581 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -12,9 +12,9 @@ jobs: - name: build shell: bash run: | - cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_SANITIZERS=On - make + cmake . + make all - name: test shell: bash run: | - make check + make test From 8c85eee0a43303165e8610e0c08cfa1e4b3e1a54 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 25 Jun 2021 14:48:20 -0400 Subject: [PATCH 04/39] Update win.yml --- .github/workflows/win.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index 7070581..1b877da 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -13,7 +13,7 @@ jobs: shell: bash run: | cmake . - make all + make - name: test shell: bash run: | From 5a6fa2bc8308245284b1dc8397215bc33c50c42f Mon Sep 17 00:00:00 2001 From: Rahul Sheth Date: Wed, 14 Oct 2020 14:17:04 -0400 Subject: [PATCH 05/39] Initial Hunterization --- CMakeLists.txt | 33 ++++++++++++++++--------- cmake/Config.cmake.in | 18 ++++++++++++++ include/cpp-statsd-client/UDPSender.hpp | 11 ++++++--- 3 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 cmake/Config.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 0173a78..ae5e2d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,14 @@ project(cpp-statsd-client LANGUAGES CXX DESCRIPTION "A header-only StatsD client implemented in C++" HOMEPAGE_URL "https://github.com/vthiery/cpp-statsd-client") -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_EXTENSIONS OFF) + +option(BUILD_TESTS "Build tests" OFF) +option(HUNTER_ENABLED "Use the Hunter package manager" OFF) + +if(NOT HUNTER_ENABLED) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_EXTENSIONS OFF) +endif() include(GNUInstallDirs) include(CMakePackageConfigHelpers) find_package(Threads) @@ -18,6 +24,9 @@ target_include_directories( INTERFACE $ $) target_link_libraries(${PROJECT_NAME} INTERFACE Threads::Threads) +if(WIN32) + target_link_libraries(${PROJECT_NAME} INTERFACE ws2_32) +endif() # The installation and pkg-config-like cmake config install(TARGETS ${PROJECT_NAME} @@ -42,13 +51,15 @@ install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake) install(DIRECTORY ${PROJECT_SOURCE_DIR}/include DESTINATION include) -# The test targets -add_executable(testStatsdClient ${CMAKE_CURRENT_SOURCE_DIR}/tests/testStatsdClient.cpp) -target_compile_options(testStatsdClient PRIVATE -Wall -Wextra -pedantic -Werror) -target_include_directories(testStatsdClient PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests) -target_link_libraries(testStatsdClient ${PROJECT_NAME}) +if(BUILD_TESTS) + # The test targets + add_executable(testStatsdClient ${CMAKE_CURRENT_SOURCE_DIR}/tests/testStatsdClient.cpp) + target_compile_options(testStatsdClient PRIVATE -Wall -Wextra -pedantic -Werror) + target_include_directories(testStatsdClient PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests) + target_link_libraries(testStatsdClient ${PROJECT_NAME}) -# The test suite -enable_testing() -add_test(ctestTestStatsdClient testStatsdClient) -add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS testStatsdClient) + # The test suite + enable_testing() + add_test(ctestTestStatsdClient testStatsdClient) + add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS testStatsdClient) +endif() diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in new file mode 100644 index 0000000..25a2902 --- /dev/null +++ b/cmake/Config.cmake.in @@ -0,0 +1,18 @@ +# Copyright (c) 2016, Ruslan Baratov +# +# Licensed under the MIT License (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# http://opensource.org/licenses/MIT +# +# 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_INIT@ + +find_package(Threads REQUIRED) + +include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/include/cpp-statsd-client/UDPSender.hpp b/include/cpp-statsd-client/UDPSender.hpp index d511960..9965d94 100644 --- a/include/cpp-statsd-client/UDPSender.hpp +++ b/include/cpp-statsd-client/UDPSender.hpp @@ -1,12 +1,17 @@ #ifndef UDP_SENDER_HPP #define UDP_SENDER_HPP +#if _WIN32 +#include +#include +#include +#else #include -#include #include -#include +#include #include #include +#endif #include #include #include @@ -210,7 +215,7 @@ inline bool UDPSender::initialize() noexcept { m_server.sin_family = AF_INET; m_server.sin_port = htons(m_port); - if (inet_aton(m_host.c_str(), &m_server.sin_addr) == 0) { + if (inet_pton(AF_INET, m_host.c_str(), &m_server.sin_addr) == 0) { // An error code has been returned by inet_aton // Specify the criteria for selecting the socket address structure From f153eeebb114a3e38dba7006c237ac74a6c77b07 Mon Sep 17 00:00:00 2001 From: Rahul Sheth Date: Fri, 25 Jun 2021 14:14:32 -0400 Subject: [PATCH 06/39] Windows fixes --- include/cpp-statsd-client/UDPSender.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/cpp-statsd-client/UDPSender.hpp b/include/cpp-statsd-client/UDPSender.hpp index 9965d94..c4d21c7 100644 --- a/include/cpp-statsd-client/UDPSender.hpp +++ b/include/cpp-statsd-client/UDPSender.hpp @@ -171,7 +171,11 @@ inline UDPSender::~UDPSender() { m_batchingThread.join(); } +#if _WIN32 + closesocket(m_socket); +#else close(m_socket); +#endif } inline void UDPSender::send(const std::string& message) noexcept { @@ -229,7 +233,11 @@ inline bool UDPSender::initialize() noexcept { const int ret{getaddrinfo(m_host.c_str(), nullptr, &hints, &results)}; if (ret != 0) { // An error code has been returned by getaddrinfo +#if _WIN32 + closesocket(m_socket); +#else close(m_socket); +#endif m_socket = k_invalidFd; m_errorMessage = "getaddrinfo failed: err=" + std::to_string(ret) + ", msg=" + gai_strerror(ret); return false; From ebce2a8c1f029fc562bbacb11bdf3327d5d26318 Mon Sep 17 00:00:00 2001 From: Rahul Sheth Date: Fri, 25 Jun 2021 14:19:07 -0400 Subject: [PATCH 07/39] Include fixup --- include/cpp-statsd-client/UDPSender.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/cpp-statsd-client/UDPSender.hpp b/include/cpp-statsd-client/UDPSender.hpp index c4d21c7..a568f2f 100644 --- a/include/cpp-statsd-client/UDPSender.hpp +++ b/include/cpp-statsd-client/UDPSender.hpp @@ -7,11 +7,12 @@ #include #else #include -#include #include +#include #include #include #endif +#include #include #include #include From 5518121b81f98938f3e431026ac56af7d9219751 Mon Sep 17 00:00:00 2001 From: Rahul Sheth Date: Fri, 25 Jun 2021 14:26:10 -0400 Subject: [PATCH 08/39] test fixes --- CMakeLists.txt | 2 +- include/cpp-statsd-client/UDPSender.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae5e2d5..a092f6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project(cpp-statsd-client DESCRIPTION "A header-only StatsD client implemented in C++" HOMEPAGE_URL "https://github.com/vthiery/cpp-statsd-client") -option(BUILD_TESTS "Build tests" OFF) +option(BUILD_TESTS "Build tests" ON) option(HUNTER_ENABLED "Use the Hunter package manager" OFF) if(NOT HUNTER_ENABLED) diff --git a/include/cpp-statsd-client/UDPSender.hpp b/include/cpp-statsd-client/UDPSender.hpp index a568f2f..1bccf8e 100644 --- a/include/cpp-statsd-client/UDPSender.hpp +++ b/include/cpp-statsd-client/UDPSender.hpp @@ -2,9 +2,9 @@ #define UDP_SENDER_HPP #if _WIN32 +#include #include #include -#include #else #include #include From beadc097b1fac6ec4d21269c534e568be05fd6a1 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Tue, 29 Jun 2021 09:03:24 -0400 Subject: [PATCH 09/39] add ifdefs to mock server --- include/cpp-statsd-client/UDPSender.hpp | 11 ++++++----- tests/StatsdServer.hpp | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/include/cpp-statsd-client/UDPSender.hpp b/include/cpp-statsd-client/UDPSender.hpp index 1bccf8e..9f4a8db 100644 --- a/include/cpp-statsd-client/UDPSender.hpp +++ b/include/cpp-statsd-client/UDPSender.hpp @@ -1,7 +1,7 @@ #ifndef UDP_SENDER_HPP #define UDP_SENDER_HPP -#if _WIN32 +#ifdef _WIN32 #include #include #include @@ -10,10 +10,11 @@ #include #include #include -#include #endif -#include + +#include #include +#include #include #include #include @@ -172,7 +173,7 @@ inline UDPSender::~UDPSender() { m_batchingThread.join(); } -#if _WIN32 +#ifdef _WIN32 closesocket(m_socket); #else close(m_socket); @@ -234,7 +235,7 @@ inline bool UDPSender::initialize() noexcept { const int ret{getaddrinfo(m_host.c_str(), nullptr, &hints, &results)}; if (ret != 0) { // An error code has been returned by getaddrinfo -#if _WIN32 +#ifdef _WIN32 closesocket(m_socket); #else close(m_socket); diff --git a/tests/StatsdServer.hpp b/tests/StatsdServer.hpp index 5f1e87e..786c991 100644 --- a/tests/StatsdServer.hpp +++ b/tests/StatsdServer.hpp @@ -1,9 +1,15 @@ #ifndef STATSD_SERVER_HPP #define STATSD_SERVER_HPP +#ifdef _WIN32 +#include +#include +#include +#else #include #include #include +#endif #include namespace Statsd { @@ -25,7 +31,11 @@ class StatsdServer { // Try to bind if (bind(m_fd, reinterpret_cast(&address), sizeof(address)) != 0) { +#ifdef _WIN32 + closesocket(m_fd); +#else close(m_fd); +#endif m_fd = k_invalidFd; m_errorMessage = "Could not bind to address and port"; } @@ -33,7 +43,11 @@ class StatsdServer { ~StatsdServer() { if (isValidFd(m_fd)) { +#ifdef _WIN32 + closesocket(m_fd); +#else close(m_fd); +#endif } } From 652c0027b817576ae2a015b92b41a64cfa6471cf Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Tue, 29 Jun 2021 09:16:36 -0400 Subject: [PATCH 10/39] build within the build dir --- .github/workflows/win.yml | 8 ++++---- CMakeLists.txt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index 1b877da..b8120dc 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -10,11 +10,11 @@ jobs: run: | choco install make cmake - name: build - shell: bash run: | - cmake . + mkdir build + cd build + cmake .. -DCOVERAGE_ENABLED=Off make - name: test - shell: bash run: | - make test + make -C test diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d0505d..6ed80a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,13 +8,13 @@ project(cpp-statsd-client option(BUILD_TESTS "Build tests" ON) option(HUNTER_ENABLED "Use the Hunter package manager" OFF) +option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF) if(NOT HUNTER_ENABLED) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_EXTENSIONS OFF) endif() -option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF) include(GNUInstallDirs) include(CMakePackageConfigHelpers) find_package(Threads) From 3d029e29914397a09c92b4bac7148c4a6b888096 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Tue, 29 Jun 2021 09:23:51 -0400 Subject: [PATCH 11/39] coverage is disabled by default --- .github/workflows/win.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index b8120dc..b42bca9 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -13,7 +13,7 @@ jobs: run: | mkdir build cd build - cmake .. -DCOVERAGE_ENABLED=Off + cmake .. make - name: test run: | From 2b74325235070ba84eec2a9caafc1b47616ce88e Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 2 Jul 2021 11:43:03 -0400 Subject: [PATCH 12/39] Update .github/workflows/win.yml Co-authored-by: Rahul Sheth --- .github/workflows/win.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index b42bca9..45487ce 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -11,10 +11,8 @@ jobs: choco install make cmake - name: build run: | - mkdir build - cd build - cmake .. - make + cmake -H . -B build -G "Visual Studio 15 2017" -A x64 + cmake --build build --target ALL_BUILD --config Release - name: test run: | make -C test From 29e9efbadf04e63e59de2938dcb518e9aaac2b34 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 2 Jul 2021 11:43:08 -0400 Subject: [PATCH 13/39] Update .github/workflows/win.yml Co-authored-by: Rahul Sheth --- .github/workflows/win.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index 45487ce..221bce4 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -15,4 +15,4 @@ jobs: cmake --build build --target ALL_BUILD --config Release - name: test run: | - make -C test + cmake --build build --target RUN_TESTS --config Release From a38092c6898ad14b4c7016429bb21e4c7025b2d3 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 2 Jul 2021 11:43:12 -0400 Subject: [PATCH 14/39] Update .github/workflows/win.yml Co-authored-by: Rahul Sheth --- .github/workflows/win.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index 221bce4..78cb529 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -8,7 +8,7 @@ jobs: - uses: actions/checkout@v2 - name: dependencies run: | - choco install make cmake + choco install cmake - name: build run: | cmake -H . -B build -G "Visual Studio 15 2017" -A x64 From 6fcc092af826da62be22cc5e707c40353420fbcb Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 2 Jul 2021 11:48:19 -0400 Subject: [PATCH 15/39] Update .github/workflows/win.yml Co-authored-by: Rahul Sheth --- .github/workflows/win.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index 78cb529..ba261ea 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -11,7 +11,7 @@ jobs: choco install cmake - name: build run: | - cmake -H . -B build -G "Visual Studio 15 2017" -A x64 + cmake -H. -Bbuild -G "Visual Studio 15 2017" -A x64 cmake --build build --target ALL_BUILD --config Release - name: test run: | From ff215d611c5371254800ba5cf407ca1a994f1beb Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 2 Jul 2021 11:53:15 -0400 Subject: [PATCH 16/39] Update .github/workflows/win.yml Co-authored-by: Rahul Sheth --- .github/workflows/win.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index ba261ea..4f75a1e 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -11,7 +11,7 @@ jobs: choco install cmake - name: build run: | - cmake -H. -Bbuild -G "Visual Studio 15 2017" -A x64 + cmake -S . -B build -G "Visual Studio 15 2017" -A x64 cmake --build build --target ALL_BUILD --config Release - name: test run: | From 74889d3d80584533a588acc71e3405278f4fe076 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 2 Jul 2021 11:59:09 -0400 Subject: [PATCH 17/39] Update .github/workflows/win.yml Co-authored-by: Rahul Sheth --- .github/workflows/win.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index 4f75a1e..3b86400 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -11,7 +11,7 @@ jobs: choco install cmake - name: build run: | - cmake -S . -B build -G "Visual Studio 15 2017" -A x64 + cmake -S . -B build -G "Visual Studio 16 2019" -A x64 cmake --build build --target ALL_BUILD --config Release - name: test run: | From 0483d3ce6b83ca2000378a9312b67232614ff65a Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 2 Jul 2021 21:35:50 -0400 Subject: [PATCH 18/39] set warning flags differently for msvc --- CMakeLists.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ed80a8..67990a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ project(cpp-statsd-client DESCRIPTION "A header-only StatsD client implemented in C++" HOMEPAGE_URL "https://github.com/vthiery/cpp-statsd-client") -option(BUILD_TESTS "Build tests" ON) +option(ENABLE_TESTS "Build tests" ON) option(HUNTER_ENABLED "Use the Hunter package manager" OFF) option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF) @@ -64,10 +64,14 @@ install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${PROJECT_NAME}/cmake) install(DIRECTORY ${PROJECT_SOURCE_DIR}/include DESTINATION include) -if(BUILD_TESTS) +if(ENABLE_TESTS) # The test targets add_executable(testStatsdClient ${CMAKE_CURRENT_SOURCE_DIR}/tests/testStatsdClient.cpp) - target_compile_options(testStatsdClient PRIVATE -Wall -Wextra -pedantic -Werror) + if(WIN32) + target_compile_options(testStatsdClient PRIVATE -Wall -WX) + else() + target_compile_options(testStatsdClient PRIVATE -Wall -Wextra -pedantic -Werror) + endif() target_include_directories(testStatsdClient PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests) target_link_libraries(testStatsdClient ${PROJECT_NAME}) From a0c069536f1780f1be30b9c5fd6423070d4d21a2 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Fri, 2 Jul 2021 21:55:56 -0400 Subject: [PATCH 19/39] try suppressing the warnings from external includes --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 67990a8..80a3e6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,7 @@ if(ENABLE_TESTS) # The test targets add_executable(testStatsdClient ${CMAKE_CURRENT_SOURCE_DIR}/tests/testStatsdClient.cpp) if(WIN32) - target_compile_options(testStatsdClient PRIVATE -Wall -WX) + target_compile_options(testStatsdClient PRIVATE -Wall -WX /external:W0) else() target_compile_options(testStatsdClient PRIVATE -Wall -Wextra -pedantic -Werror) endif() From e62520373566528a1682fe4ac9458b5a51a82ca9 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Sat, 3 Jul 2021 08:41:29 -0400 Subject: [PATCH 20/39] fix some warnings in test server --- tests/StatsdServer.hpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/StatsdServer.hpp b/tests/StatsdServer.hpp index 786c991..d990cc0 100644 --- a/tests/StatsdServer.hpp +++ b/tests/StatsdServer.hpp @@ -5,11 +5,19 @@ #include #include #include + +using SOCKET_TYPE = SOCKET; +constexpr SOCKET_TYPE k_invalidFd{INVALID_SOCKET}; #else #include #include #include + +using SOCKET_TYPE = int; +constexpr SOCKET_TYPE k_invalidFd{-1}; #endif + +#include #include namespace Statsd { @@ -63,8 +71,8 @@ class StatsdServer { // Try to receive (this is blocking) std::string buffer(256, '\0'); - int string_len = -1; - if ((string_len = recv(m_fd, &buffer[0], buffer.size(), 0)) < 1) { + int string_len; + if ((string_len = recv(m_fd, &buffer[0], static_cast(buffer.size()), 0)) < 1) { m_errorMessage = "Could not recv on the socket file descriptor"; return ""; } @@ -76,13 +84,12 @@ class StatsdServer { } private: - static inline bool isValidFd(const int fd) { + static inline bool isValidFd(const SOCKET_TYPE fd) { return fd != k_invalidFd; } - int m_fd; + SOCKET_TYPE m_fd; std::string m_errorMessage; - static constexpr int k_invalidFd{-1}; }; } // namespace Statsd From 17db245bf5a57b14e5c643f98652931cc0464638 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Sun, 4 Jul 2021 13:35:55 -0400 Subject: [PATCH 21/39] undefine windows built in min/max macros --- tests/StatsdServer.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/StatsdServer.hpp b/tests/StatsdServer.hpp index d990cc0..13da58e 100644 --- a/tests/StatsdServer.hpp +++ b/tests/StatsdServer.hpp @@ -2,6 +2,8 @@ #define STATSD_SERVER_HPP #ifdef _WIN32 +#define NOMINMAX + #include #include #include From ab42b1363d88a832de2d2b57bff05a2a4e3dbd41 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Sun, 4 Jul 2021 13:41:28 -0400 Subject: [PATCH 22/39] no more warnings in test server --- tests/StatsdServer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/StatsdServer.hpp b/tests/StatsdServer.hpp index 13da58e..9d8da39 100644 --- a/tests/StatsdServer.hpp +++ b/tests/StatsdServer.hpp @@ -81,7 +81,7 @@ class StatsdServer { // No error return the trimmed result m_errorMessage.clear(); - buffer.resize(std::min(string_len, static_cast(buffer.size()))); + buffer.resize(std::min(static_cast(string_len), buffer.size())); return buffer; } From 8b86d461d2c3c960227c0c5aaedea84c24061d3d Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Mon, 5 Jul 2021 22:02:23 -0400 Subject: [PATCH 23/39] move all socket defines and operations to udpsender and use from there --- include/cpp-statsd-client/UDPSender.hpp | 25 ++++++++++---- tests/StatsdServer.hpp | 46 ++++++++----------------- 2 files changed, 32 insertions(+), 39 deletions(-) diff --git a/include/cpp-statsd-client/UDPSender.hpp b/include/cpp-statsd-client/UDPSender.hpp index 608aec0..45e7320 100644 --- a/include/cpp-statsd-client/UDPSender.hpp +++ b/include/cpp-statsd-client/UDPSender.hpp @@ -2,6 +2,7 @@ #define UDP_SENDER_HPP #ifdef _WIN32 +#define NOMINMAX #include #include #include @@ -22,6 +23,15 @@ #include namespace Statsd { + +#ifdef _WIN32 +using SOCKET_TYPE = SOCKET; +constexpr SOCKET_TYPE k_invalidSocket{INVALID_SOCKET}; +#else +using SOCKET_TYPE = int; +constexpr SOCKET_TYPE k_invalidSocket{-1}; +#endif + /*! * * UDP sender @@ -99,7 +109,7 @@ class UDPSender final { struct sockaddr_in m_server; //! The socket to be used - int m_socket{-1}; + SOCKET_TYPE m_socket = k_invalidSocket; //!@} @@ -125,11 +135,12 @@ class UDPSender final { //! Error message (optional string) std::string m_errorMessage; - - //! Bad file descriptor - static constexpr int k_invalidFd{-1}; }; +inline bool isValidSocket(const SOCKET_TYPE socket) { + return socket != k_invalidSocket; +} + inline UDPSender::UDPSender(const std::string& host, const uint16_t port, const uint64_t batchsize, @@ -220,7 +231,7 @@ inline const std::string& UDPSender::errorMessage() const noexcept { inline bool UDPSender::initialize() noexcept { // Connect the socket m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (m_socket == k_invalidFd) { + if (!isValidSocket(m_socket)) { m_errorMessage = std::string("socket creation failed: err=") + std::strerror(errno); return false; } @@ -248,7 +259,7 @@ inline bool UDPSender::initialize() noexcept { #else close(m_socket); #endif - m_socket = k_invalidFd; + m_socket = k_invalidSocket; m_errorMessage = "getaddrinfo failed: err=" + std::to_string(ret) + ", msg=" + gai_strerror(ret); return false; } @@ -275,7 +286,7 @@ inline void UDPSender::sendToDaemon(const std::string& message) noexcept { } inline bool UDPSender::initialized() const noexcept { - return m_socket != k_invalidFd; + return m_socket != k_invalidSocket; } inline void UDPSender::flush() noexcept { diff --git a/tests/StatsdServer.hpp b/tests/StatsdServer.hpp index 9d8da39..9c16dac 100644 --- a/tests/StatsdServer.hpp +++ b/tests/StatsdServer.hpp @@ -1,23 +1,9 @@ #ifndef STATSD_SERVER_HPP #define STATSD_SERVER_HPP -#ifdef _WIN32 -#define NOMINMAX - -#include -#include -#include - -using SOCKET_TYPE = SOCKET; -constexpr SOCKET_TYPE k_invalidFd{INVALID_SOCKET}; -#else -#include -#include -#include - -using SOCKET_TYPE = int; -constexpr SOCKET_TYPE k_invalidFd{-1}; -#endif +// It might make sense to include this test class in the UDPSender header +// it includes most of the cross platform defines etc that we need for socket io +#include "cpp-statsd-client/UDPSender.hpp" #include #include @@ -28,7 +14,7 @@ class StatsdServer { public: StatsdServer(unsigned short port = 8125) noexcept { // Create the fd - if (!isValidFd(m_fd = socket(AF_INET, SOCK_DGRAM, 0))) { + if (!isValidSocket(m_socket = socket(AF_INET, SOCK_DGRAM, 0))) { m_errorMessage = "Could not create socket file descriptor"; return; } @@ -40,23 +26,23 @@ class StatsdServer { address.sin_addr.s_addr = INADDR_ANY; // Try to bind - if (bind(m_fd, reinterpret_cast(&address), sizeof(address)) != 0) { + if (bind(m_socket, reinterpret_cast(&address), sizeof(address)) != 0) { #ifdef _WIN32 - closesocket(m_fd); + closesocket(m_socket); #else - close(m_fd); + close(m_socket); #endif - m_fd = k_invalidFd; + m_socket = k_invalidSocket; m_errorMessage = "Could not bind to address and port"; } } ~StatsdServer() { - if (isValidFd(m_fd)) { + if (isValidSocket(m_socket)) { #ifdef _WIN32 - closesocket(m_fd); + closesocket(m_socket); #else - close(m_fd); + close(m_socket); #endif } } @@ -67,14 +53,14 @@ class StatsdServer { std::string receive() noexcept { // If uninitialized then bail - if (!isValidFd(m_fd)) { + if (!isValidSocket(m_socket)) { return ""; } // Try to receive (this is blocking) std::string buffer(256, '\0'); int string_len; - if ((string_len = recv(m_fd, &buffer[0], static_cast(buffer.size()), 0)) < 1) { + if ((string_len = recv(m_socket, &buffer[0], static_cast(buffer.size()), 0)) < 1) { m_errorMessage = "Could not recv on the socket file descriptor"; return ""; } @@ -86,11 +72,7 @@ class StatsdServer { } private: - static inline bool isValidFd(const SOCKET_TYPE fd) { - return fd != k_invalidFd; - } - - SOCKET_TYPE m_fd; + SOCKET_TYPE m_socket; std::string m_errorMessage; }; From 295026fb0e68defc961a55d2237bde5eb9c3e938 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Mon, 5 Jul 2021 22:47:43 -0400 Subject: [PATCH 24/39] avoid thread safety issues and annoyingly complex strerror --- include/cpp-statsd-client/StatsdClient.hpp | 3 ++- include/cpp-statsd-client/UDPSender.hpp | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/cpp-statsd-client/StatsdClient.hpp b/include/cpp-statsd-client/StatsdClient.hpp index 4b91de4..0b590d3 100644 --- a/include/cpp-statsd-client/StatsdClient.hpp +++ b/include/cpp-statsd-client/StatsdClient.hpp @@ -55,7 +55,7 @@ namespace Statsd { */ class StatsdClient { public: - //!@name Constructor and destructor + //!@name Constructor and destructor, non-copyable //!@{ //! Constructor @@ -67,6 +67,7 @@ class StatsdClient { StatsdClient(const StatsdClient&) = delete; StatsdClient& operator=(const StatsdClient&) = delete; + StatsdClient(StatsdClient&&) = default; //!@} diff --git a/include/cpp-statsd-client/UDPSender.hpp b/include/cpp-statsd-client/UDPSender.hpp index 45e7320..aa7dd67 100644 --- a/include/cpp-statsd-client/UDPSender.hpp +++ b/include/cpp-statsd-client/UDPSender.hpp @@ -41,7 +41,7 @@ constexpr SOCKET_TYPE k_invalidSocket{-1}; */ class UDPSender final { public: - //!@name Constructor and destructor + //!@name Constructor and destructor, non-copyable //!@{ //! Constructor @@ -53,6 +53,10 @@ class UDPSender final { //! Destructor ~UDPSender(); + UDPSender(const UDPSender&) = delete; + UDPSender& operator=(const UDPSender&) = delete; + UDPSender(UDPSender&&) = delete; + //!@} //!@name Methods @@ -232,7 +236,7 @@ inline bool UDPSender::initialize() noexcept { // Connect the socket m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (!isValidSocket(m_socket)) { - m_errorMessage = std::string("socket creation failed: err=") + std::strerror(errno); + m_errorMessage = "socket creation failed: errno=" + std::to_string(errno); return false; } @@ -281,7 +285,7 @@ inline void UDPSender::sendToDaemon(const std::string& message) noexcept { sendto(m_socket, message.data(), message.size(), 0, (struct sockaddr*)&m_server, sizeof(m_server))}; if (ret == -1) { m_errorMessage = - "sendto server failed: host=" + m_host + ":" + std::to_string(m_port) + ", err=" + std::strerror(errno); + "sendto server failed: host=" + m_host + ":" + std::to_string(m_port) + ", err=" + std::to_string(errno); } } From 63c6370fa0667fe8d15a316a4ca314326ec1ae0e Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Mon, 5 Jul 2021 22:57:48 -0400 Subject: [PATCH 25/39] try removing more warnings and also lower the warning level to ignore pedantic stuff --- CMakeLists.txt | 2 +- include/cpp-statsd-client/UDPSender.hpp | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80a3e6f..5ae08b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,7 @@ if(ENABLE_TESTS) # The test targets add_executable(testStatsdClient ${CMAKE_CURRENT_SOURCE_DIR}/tests/testStatsdClient.cpp) if(WIN32) - target_compile_options(testStatsdClient PRIVATE -Wall -WX /external:W0) + target_compile_options(testStatsdClient PRIVATE -W4 -WX /external:W0) else() target_compile_options(testStatsdClient PRIVATE -Wall -Wextra -pedantic -Werror) endif() diff --git a/include/cpp-statsd-client/UDPSender.hpp b/include/cpp-statsd-client/UDPSender.hpp index aa7dd67..68a80a4 100644 --- a/include/cpp-statsd-client/UDPSender.hpp +++ b/include/cpp-statsd-client/UDPSender.hpp @@ -281,8 +281,16 @@ inline bool UDPSender::initialize() noexcept { inline void UDPSender::sendToDaemon(const std::string& message) noexcept { // Try sending the message - const long int ret{ - sendto(m_socket, message.data(), message.size(), 0, (struct sockaddr*)&m_server, sizeof(m_server))}; + const auto ret = sendto(m_socket, + message.data(), +#ifdef _WIN32 + static_cast(message.size()), +#else + static_cast(message.size()), +#endif + 0, + (struct sockaddr*)&m_server, + sizeof(m_server)); if (ret == -1) { m_errorMessage = "sendto server failed: host=" + m_host + ":" + std::to_string(m_port) + ", err=" + std::to_string(errno); From 342336b4d2abda60a4572877d40001f990f73389 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Tue, 6 Jul 2021 12:56:53 -0400 Subject: [PATCH 26/39] remove final warning --- tests/testStatsdClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testStatsdClient.cpp b/tests/testStatsdClient.cpp index c58107d..0ff68a9 100644 --- a/tests/testStatsdClient.cpp +++ b/tests/testStatsdClient.cpp @@ -15,7 +15,7 @@ void mock(StatsdServer& server, std::vector& messages) { auto recvd = server.receive(); // Split the messages on '\n' - std::string::size_type start = -1; + auto start = std::string::npos; do { // Keep this message auto end = recvd.find('\n', ++start); From 7834b8e0b264f5fa0c597fea2d82558c4c96561b Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Wed, 7 Jul 2021 09:07:51 -0400 Subject: [PATCH 27/39] revert hunter for now, make library easier to vendor, print exact test failure --- CMakeLists.txt | 14 +++++++------- tests/testStatsdClient.cpp | 25 +++++++++++++++---------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ae08b8..1695421 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,15 +6,15 @@ project(cpp-statsd-client DESCRIPTION "A header-only StatsD client implemented in C++" HOMEPAGE_URL "https://github.com/vthiery/cpp-statsd-client") -option(ENABLE_TESTS "Build tests" ON) -option(HUNTER_ENABLED "Use the Hunter package manager" OFF) -option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF) - -if(NOT HUNTER_ENABLED) - set(CMAKE_CXX_STANDARD 11) - set(CMAKE_CXX_EXTENSIONS OFF) +option(CPP_STATSD_STANDALONE "Allows configuration of targets for verifying library functionality" ON) +if(${CPP_STATSD_STANDALONE}) + option(ENABLE_TESTS "Build tests" ON) + option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF) endif() +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_EXTENSIONS OFF) + include(GNUInstallDirs) include(CMakePackageConfigHelpers) find_package(Threads) diff --git a/tests/testStatsdClient.cpp b/tests/testStatsdClient.cpp index 0ff68a9..fa7c32b 100644 --- a/tests/testStatsdClient.cpp +++ b/tests/testStatsdClient.cpp @@ -162,16 +162,21 @@ void testSendRecv(uint64_t batchSize, uint64_t sendInterval) { int main() { // If any of these tests fail they throw an exception, not catching makes for a nonzero return code - // general things that should be errors - testErrorConditions(); - // reconfiguring how you are sending - testReconfigure(); - // no batching - testSendRecv(0, 0); - // background batching - testSendRecv(32, 1000); - // manual flushing of batches - testSendRecv(16, 0); + try { + // general things that should be errors + testErrorConditions(); + // reconfiguring how you are sending + testReconfigure(); + // no batching + testSendRecv(0, 0); + // background batching + testSendRecv(32, 1000); + // manual flushing of batches + testSendRecv(16, 0); + } catch (const std::exception& e) { + std::cerr << e.what(); + return EXIT_FAILURE; + } return EXIT_SUCCESS; } From 50d0ea9fe8ed3290d4736bcdb76891f9c1b70a83 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Wed, 7 Jul 2021 09:14:08 -0400 Subject: [PATCH 28/39] try for more output in CI --- .github/workflows/win.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index 3b86400..53fdf41 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -15,4 +15,4 @@ jobs: cmake --build build --target ALL_BUILD --config Release - name: test run: | - cmake --build build --target RUN_TESTS --config Release + build\testStatsdClient #cmake --build build --target RUN_TESTS --config Release From 133781729f1aa8de0c725cd3ef35965e51ca0585 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Wed, 7 Jul 2021 09:18:44 -0400 Subject: [PATCH 29/39] try more more output --- .github/workflows/win.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index 53fdf41..cde40b5 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -15,4 +15,4 @@ jobs: cmake --build build --target ALL_BUILD --config Release - name: test run: | - build\testStatsdClient #cmake --build build --target RUN_TESTS --config Release + ctest --test-dir build --verbose #cmake --build build --target RUN_TESTS --config Release From 193065c7dc77ddec6d28c1668ca9f8b2072ed9bc Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Wed, 7 Jul 2021 09:25:22 -0400 Subject: [PATCH 30/39] just want to see programs output.. --- .github/workflows/win.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index cde40b5..77f4d93 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -15,4 +15,4 @@ jobs: cmake --build build --target ALL_BUILD --config Release - name: test run: | - ctest --test-dir build --verbose #cmake --build build --target RUN_TESTS --config Release + ctest --output-on-failure --test-dir build --verbose #cmake --build build --target RUN_TESTS --config Release From 2998b4aad5b90de108b4fbcb9ff5e1064546b90a Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Wed, 7 Jul 2021 09:38:49 -0400 Subject: [PATCH 31/39] more logging of failure info --- tests/testStatsdClient.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/testStatsdClient.cpp b/tests/testStatsdClient.cpp index fa7c32b..0eaca14 100644 --- a/tests/testStatsdClient.cpp +++ b/tests/testStatsdClient.cpp @@ -38,6 +38,14 @@ void throwOnError(const StatsdClient& client, bool expectEmpty = true, const std } } +void throwOnWrongMessage(StatsdServer& server, const std::string& expected) { + auto actual = server.receive(); + if (actual != expected) { + std::cerr << "Expected: " << expected << " but got: " << actual << std::endl; + throw std::runtime_error("Incorrect stat received"); + } +} + void testErrorConditions() { // Resolve a rubbish ip and make sure initialization failed StatsdClient client{"256.256.256.256", 8125, "myPrefix", 20}; @@ -49,26 +57,18 @@ void testReconfigure() { StatsdClient client("localhost", 8125, "first."); client.increment("foo"); - if (server.receive() != "first.foo:1|c") { - throw std::runtime_error("Incorrect stat received"); - } + throwOnWrongMessage(server, "first.foo:1|c"); client.setConfig("localhost", 8125, "second"); client.increment("bar"); - if (server.receive() != "second.bar:1|c") { - throw std::runtime_error("Incorrect stat received"); - } + throwOnWrongMessage(server, "second.bar:1|c"); client.setConfig("localhost", 8125, ""); client.increment("third.baz"); - if (server.receive() != "third.baz:1|c") { - throw std::runtime_error("Incorrect stat received"); - } + throwOnWrongMessage(server, "third.baz:1|c"); client.increment(""); - if (server.receive() != ":1|c") { - throw std::runtime_error("Incorrect stat received"); - } + throwOnWrongMessage(server, ":1|c"); // TODO: test what happens with the batching after resolving the question about incomplete // batches being dropped vs sent on reconfiguring @@ -174,7 +174,7 @@ int main() { // manual flushing of batches testSendRecv(16, 0); } catch (const std::exception& e) { - std::cerr << e.what(); + std::cerr << e.what() << std::endl; return EXIT_FAILURE; } From 28ea211502081ff858c1adb5508fbae8cac5b140 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Wed, 7 Jul 2021 09:44:50 -0400 Subject: [PATCH 32/39] check if the test server binds properly --- tests/testStatsdClient.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/testStatsdClient.cpp b/tests/testStatsdClient.cpp index 0eaca14..90d34bb 100644 --- a/tests/testStatsdClient.cpp +++ b/tests/testStatsdClient.cpp @@ -31,10 +31,11 @@ void mock(StatsdServer& server, std::vector& messages) { } while (server.errorMessage().empty() && !messages.back().empty()); } -void throwOnError(const StatsdClient& client, bool expectEmpty = true, const std::string& extraMessage = "") { - if (client.errorMessage().empty() != expectEmpty) { - std::cerr << (expectEmpty ? client.errorMessage() : extraMessage) << std::endl; - throw std::runtime_error(expectEmpty ? client.errorMessage() : extraMessage); +template +void throwOnError(const SocketWrapper& wrapped, bool expectEmpty = true, const std::string& extraMessage = "") { + if (wrapped.errorMessage().empty() != expectEmpty) { + std::cerr << (expectEmpty ? wrapped.errorMessage() : extraMessage) << std::endl; + throw std::runtime_error(expectEmpty ? wrapped.errorMessage() : extraMessage); } } @@ -54,6 +55,7 @@ void testErrorConditions() { void testReconfigure() { StatsdServer server; + throwOnError(server); StatsdClient client("localhost", 8125, "first."); client.increment("foo"); From fa1f68e4e941bfb4542c762c46ecef8d0fa39c11 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Wed, 7 Jul 2021 11:14:27 -0400 Subject: [PATCH 33/39] debugging windows socket recv --- tests/StatsdServer.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/StatsdServer.hpp b/tests/StatsdServer.hpp index 9c16dac..b6675e2 100644 --- a/tests/StatsdServer.hpp +++ b/tests/StatsdServer.hpp @@ -14,8 +14,9 @@ class StatsdServer { public: StatsdServer(unsigned short port = 8125) noexcept { // Create the fd - if (!isValidSocket(m_socket = socket(AF_INET, SOCK_DGRAM, 0))) { - m_errorMessage = "Could not create socket file descriptor"; + m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (!isValidSocket(m_socket)) { + m_errorMessage = "Could not create socket"; return; } From 312cc1450e1497f900b82b841f59a7e7a38d4c15 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Wed, 7 Jul 2021 11:18:19 -0400 Subject: [PATCH 34/39] get the error number --- tests/StatsdServer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/StatsdServer.hpp b/tests/StatsdServer.hpp index b6675e2..92f0618 100644 --- a/tests/StatsdServer.hpp +++ b/tests/StatsdServer.hpp @@ -16,7 +16,7 @@ class StatsdServer { // Create the fd m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (!isValidSocket(m_socket)) { - m_errorMessage = "Could not create socket"; + m_errorMessage = "socket creation failed: errno=" + std::to_string(errno); return; } From c15f5d2bc28324f7eb863e4c43a8ce91e1fc4275 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Wed, 7 Jul 2021 11:19:20 -0400 Subject: [PATCH 35/39] check binding as well --- tests/StatsdServer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/StatsdServer.hpp b/tests/StatsdServer.hpp index 92f0618..33dc69b 100644 --- a/tests/StatsdServer.hpp +++ b/tests/StatsdServer.hpp @@ -34,7 +34,7 @@ class StatsdServer { close(m_socket); #endif m_socket = k_invalidSocket; - m_errorMessage = "Could not bind to address and port"; + m_errorMessage = "bind failed: errno=" + std::to_string(errno); } } From 1e5a73834edfc6756fbf4340a94928a3056c3933 Mon Sep 17 00:00:00 2001 From: kevinkreiser Date: Wed, 7 Jul 2021 19:29:12 +0200 Subject: [PATCH 36/39] get tests working on windows build --- include/cpp-statsd-client/UDPSender.hpp | 42 ++++++++++++++++++++++--- tests/StatsdServer.hpp | 10 ++++-- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/include/cpp-statsd-client/UDPSender.hpp b/include/cpp-statsd-client/UDPSender.hpp index 68a80a4..c9937ac 100644 --- a/include/cpp-statsd-client/UDPSender.hpp +++ b/include/cpp-statsd-client/UDPSender.hpp @@ -27,9 +27,11 @@ namespace Statsd { #ifdef _WIN32 using SOCKET_TYPE = SOCKET; constexpr SOCKET_TYPE k_invalidSocket{INVALID_SOCKET}; +#define SOCKET_ERRNO WSAGetLastError() #else using SOCKET_TYPE = int; constexpr SOCKET_TYPE k_invalidSocket{-1}; +#define SOCKET_ERRNO errno #endif /*! @@ -141,6 +143,30 @@ class UDPSender final { std::string m_errorMessage; }; +#ifdef _WIN32 +namespace detail { +struct WinSockSingleton { + inline static const WinSockSingleton& getInstance() { + static const WinSockSingleton instance; + return instance; + } + inline bool ok() const { + return m_ok; + } + ~WinSockSingleton() { + WSACleanup(); + } + +private: + WinSockSingleton() { + WSADATA wsa; + m_ok = WSAStartup(MAKEWORD(2, 2), &wsa) == 0; + } + bool m_ok; +}; +} // namespace detail +#endif + inline bool isValidSocket(const SOCKET_TYPE socket) { return socket != k_invalidSocket; } @@ -160,7 +186,7 @@ inline UDPSender::UDPSender(const std::string& host, // Define the batching thread m_batchingThread = std::thread([this] { // TODO: this will drop unsent stats, should we send all the unsent stats before we exit? - while (!m_mustExit.load(std::memory_order_acq_rel)) { + while (!m_mustExit.load(std::memory_order_acquire)) { std::deque stagedMessageQueue; std::unique_lock batchingLock(m_batchingMutex); @@ -187,7 +213,7 @@ inline UDPSender::~UDPSender() { // If we're running a background thread tell it to stop if (m_batchingThread.joinable()) { - m_mustExit.store(true, std::memory_order_acq_rel); + m_mustExit.store(true, std::memory_order_release); m_batchingThread.join(); } @@ -233,10 +259,16 @@ inline const std::string& UDPSender::errorMessage() const noexcept { } inline bool UDPSender::initialize() noexcept { +#ifdef _WIN32 + if (!detail::WinSockSingleton::getInstance().ok()) { + m_errorMessage = "WSAStartup failed: errno=" + std::to_string(SOCKET_ERRNO); + } +#endif + // Connect the socket m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (!isValidSocket(m_socket)) { - m_errorMessage = "socket creation failed: errno=" + std::to_string(errno); + m_errorMessage = "socket creation failed: errno=" + std::to_string(SOCKET_ERRNO); return false; } @@ -292,8 +324,8 @@ inline void UDPSender::sendToDaemon(const std::string& message) noexcept { (struct sockaddr*)&m_server, sizeof(m_server)); if (ret == -1) { - m_errorMessage = - "sendto server failed: host=" + m_host + ":" + std::to_string(m_port) + ", err=" + std::to_string(errno); + m_errorMessage = "sendto server failed: host=" + m_host + ":" + std::to_string(m_port) + + ", err=" + std::to_string(SOCKET_ERRNO); } } diff --git a/tests/StatsdServer.hpp b/tests/StatsdServer.hpp index 33dc69b..73ba12f 100644 --- a/tests/StatsdServer.hpp +++ b/tests/StatsdServer.hpp @@ -13,10 +13,16 @@ namespace Statsd { class StatsdServer { public: StatsdServer(unsigned short port = 8125) noexcept { +#ifdef _WIN32 + if (!detail::WinSockSingleton::getInstance().ok()) { + m_errorMessage = "WSAStartup failed: errno=" + std::to_string(SOCKET_ERRNO); + } +#endif + // Create the fd m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (!isValidSocket(m_socket)) { - m_errorMessage = "socket creation failed: errno=" + std::to_string(errno); + m_errorMessage = "socket creation failed: errno=" + std::to_string(SOCKET_ERRNO); return; } @@ -34,7 +40,7 @@ class StatsdServer { close(m_socket); #endif m_socket = k_invalidSocket; - m_errorMessage = "bind failed: errno=" + std::to_string(errno); + m_errorMessage = "bind failed: errno=" + std::to_string(SOCKET_ERRNO); } } From 58456a4a4599de30f2ca20d488a888226d7af24e Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Wed, 7 Jul 2021 14:07:45 -0400 Subject: [PATCH 37/39] clean up pr for review --- .github/workflows/win.yml | 2 +- include/cpp-statsd-client/UDPSender.hpp | 30 +++++++++++-------------- tests/StatsdServer.hpp | 20 +++++------------ tests/testStatsdClient.cpp | 25 +++++++++------------ 4 files changed, 30 insertions(+), 47 deletions(-) diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml index 77f4d93..3b86400 100644 --- a/.github/workflows/win.yml +++ b/.github/workflows/win.yml @@ -15,4 +15,4 @@ jobs: cmake --build build --target ALL_BUILD --config Release - name: test run: | - ctest --output-on-failure --test-dir build --verbose #cmake --build build --target RUN_TESTS --config Release + cmake --build build --target RUN_TESTS --config Release diff --git a/include/cpp-statsd-client/UDPSender.hpp b/include/cpp-statsd-client/UDPSender.hpp index c9937ac..c7d667a 100644 --- a/include/cpp-statsd-client/UDPSender.hpp +++ b/include/cpp-statsd-client/UDPSender.hpp @@ -28,10 +28,12 @@ namespace Statsd { using SOCKET_TYPE = SOCKET; constexpr SOCKET_TYPE k_invalidSocket{INVALID_SOCKET}; #define SOCKET_ERRNO WSAGetLastError() +#define SOCKET_CLOSE closesocket #else using SOCKET_TYPE = int; constexpr SOCKET_TYPE k_invalidSocket{-1}; #define SOCKET_ERRNO errno +#define SOCKET_CLOSE close #endif /*! @@ -143,8 +145,13 @@ class UDPSender final { std::string m_errorMessage; }; -#ifdef _WIN32 namespace detail { + +inline bool isValidSocket(const SOCKET_TYPE socket) { + return socket != k_invalidSocket; +} + +#ifdef _WIN32 struct WinSockSingleton { inline static const WinSockSingleton& getInstance() { static const WinSockSingleton instance; @@ -164,12 +171,9 @@ struct WinSockSingleton { } bool m_ok; }; -} // namespace detail #endif -inline bool isValidSocket(const SOCKET_TYPE socket) { - return socket != k_invalidSocket; -} +} // namespace detail inline UDPSender::UDPSender(const std::string& host, const uint16_t port, @@ -218,11 +222,7 @@ inline UDPSender::~UDPSender() { } // Cleanup the socket -#ifdef _WIN32 - closesocket(m_socket); -#else - close(m_socket); -#endif + SOCKET_CLOSE(m_socket); } inline void UDPSender::send(const std::string& message) noexcept { @@ -267,7 +267,7 @@ inline bool UDPSender::initialize() noexcept { // Connect the socket m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (!isValidSocket(m_socket)) { + if (!detail::isValidSocket(m_socket)) { m_errorMessage = "socket creation failed: errno=" + std::to_string(SOCKET_ERRNO); return false; } @@ -290,11 +290,7 @@ inline bool UDPSender::initialize() noexcept { const int ret{getaddrinfo(m_host.c_str(), nullptr, &hints, &results)}; if (ret != 0) { // An error code has been returned by getaddrinfo -#ifdef _WIN32 - closesocket(m_socket); -#else - close(m_socket); -#endif + SOCKET_CLOSE(m_socket); m_socket = k_invalidSocket; m_errorMessage = "getaddrinfo failed: err=" + std::to_string(ret) + ", msg=" + gai_strerror(ret); return false; @@ -318,7 +314,7 @@ inline void UDPSender::sendToDaemon(const std::string& message) noexcept { #ifdef _WIN32 static_cast(message.size()), #else - static_cast(message.size()), + message.size(), #endif 0, (struct sockaddr*)&m_server, diff --git a/tests/StatsdServer.hpp b/tests/StatsdServer.hpp index 73ba12f..e87fe59 100644 --- a/tests/StatsdServer.hpp +++ b/tests/StatsdServer.hpp @@ -19,9 +19,9 @@ class StatsdServer { } #endif - // Create the fd + // Create the socket m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (!isValidSocket(m_socket)) { + if (!detail::isValidSocket(m_socket)) { m_errorMessage = "socket creation failed: errno=" + std::to_string(SOCKET_ERRNO); return; } @@ -34,23 +34,15 @@ class StatsdServer { // Try to bind if (bind(m_socket, reinterpret_cast(&address), sizeof(address)) != 0) { -#ifdef _WIN32 - closesocket(m_socket); -#else - close(m_socket); -#endif + SOCKET_CLOSE(m_socket); m_socket = k_invalidSocket; m_errorMessage = "bind failed: errno=" + std::to_string(SOCKET_ERRNO); } } ~StatsdServer() { - if (isValidSocket(m_socket)) { -#ifdef _WIN32 - closesocket(m_socket); -#else - close(m_socket); -#endif + if (detail::isValidSocket(m_socket)) { + SOCKET_CLOSE(m_socket); } } @@ -60,7 +52,7 @@ class StatsdServer { std::string receive() noexcept { // If uninitialized then bail - if (!isValidSocket(m_socket)) { + if (!detail::isValidSocket(m_socket)) { return ""; } diff --git a/tests/testStatsdClient.cpp b/tests/testStatsdClient.cpp index 90d34bb..cda8038 100644 --- a/tests/testStatsdClient.cpp +++ b/tests/testStatsdClient.cpp @@ -164,21 +164,16 @@ void testSendRecv(uint64_t batchSize, uint64_t sendInterval) { int main() { // If any of these tests fail they throw an exception, not catching makes for a nonzero return code - try { - // general things that should be errors - testErrorConditions(); - // reconfiguring how you are sending - testReconfigure(); - // no batching - testSendRecv(0, 0); - // background batching - testSendRecv(32, 1000); - // manual flushing of batches - testSendRecv(16, 0); - } catch (const std::exception& e) { - std::cerr << e.what() << std::endl; - return EXIT_FAILURE; - } + // general things that should be errors + testErrorConditions(); + // reconfiguring how you are sending + testReconfigure(); + // no batching + testSendRecv(0, 0); + // background batching + testSendRecv(32, 1000); + // manual flushing of batches + testSendRecv(16, 0); return EXIT_SUCCESS; } From 21a9767e10b1cc514a9d35133bb2ce865861e6d6 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Wed, 7 Jul 2021 14:22:00 -0400 Subject: [PATCH 38/39] disable the options if not standalone mode --- CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1695421..38287d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,9 +7,12 @@ project(cpp-statsd-client HOMEPAGE_URL "https://github.com/vthiery/cpp-statsd-client") option(CPP_STATSD_STANDALONE "Allows configuration of targets for verifying library functionality" ON) -if(${CPP_STATSD_STANDALONE}) - option(ENABLE_TESTS "Build tests" ON) - option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF) +option(ENABLE_TESTS "Build tests" ON) +option(ENABLE_COVERAGE "Build with coverage instrumentalisation" OFF) + +if(NOT CPP_STATSD_STANDALONE) + set(ENABLE_TESTS OFF) + set(ENABLE_COVERAGE OFF) endif() set(CMAKE_CXX_STANDARD 11) From b1ea5968831a34073f66f31ec15ebc4f0fade8b8 Mon Sep 17 00:00:00 2001 From: Kevin Kreiser Date: Mon, 12 Jul 2021 09:16:50 -0400 Subject: [PATCH 39/39] didnt need to fix this warning --- include/cpp-statsd-client/StatsdClient.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/cpp-statsd-client/StatsdClient.hpp b/include/cpp-statsd-client/StatsdClient.hpp index 0b590d3..7a5d22a 100644 --- a/include/cpp-statsd-client/StatsdClient.hpp +++ b/include/cpp-statsd-client/StatsdClient.hpp @@ -67,7 +67,6 @@ class StatsdClient { StatsdClient(const StatsdClient&) = delete; StatsdClient& operator=(const StatsdClient&) = delete; - StatsdClient(StatsdClient&&) = default; //!@}