diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml deleted file mode 100644 index 64fd89ce..00000000 --- a/.github/workflows/build_cmake.yml +++ /dev/null @@ -1,85 +0,0 @@ -# Note differences between Unix variants and Windows shell when invoking -# multiple commands on one line - bash uses double ampersand, powershell -# uses semi-colon -# -# Currently there is duplication, specially for the dependency management, -# this should be refactored in the future -# -name: CMake Build Matrix - -on: - push: - branches: - - master - - develop - -jobs: - - build-unixes: - - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest, macos-latest] - - steps: - - name: checkout - uses: actions/checkout@v2 - with: - path: main - - name: checkout-utility-rack - uses: actions/checkout@v2 - with: - repository: connectivecpp/utility-rack - path: utility-rack - - name: checkout-catch - uses: actions/checkout@v2 - with: - repository: catchorg/Catch2 - ref: master - path: Catch2 - - name: checkout-asio - uses: actions/checkout@v2 - with: - repository: chriskohlhoff/asio - ref: master - path: asio - - name: configure-cmake - run: mkdir build && cd build && cmake ../main - - name: build - run: cd build && cmake --build . - - name: unit-test - run: cd build && ctest - - build-windows: - - runs-on: windows-latest - - steps: - - name: checkout - uses: actions/checkout@v2 - with: - path: main - - name: checkout-utility-rack - uses: actions/checkout@v2 - with: - repository: connectivecpp/utility-rack - path: utility-rack - - name: checkout-catch - uses: actions/checkout@v2 - with: - repository: catchorg/Catch2 - ref: master - path: Catch2 - - name: checkout-asio - uses: actions/checkout@v2 - with: - repository: chriskohlhoff/asio - ref: master - path: asio - - name: configure-cmake - run: mkdir build; cd build; cmake ../main - - name: build - run: cd build; cmake --build . - - name: unit-test - run: cd build; ctest -C "Debug" diff --git a/.github/workflows/build_run_unit_test_cmake.yml b/.github/workflows/build_run_unit_test_cmake.yml new file mode 100644 index 00000000..a1c9af72 --- /dev/null +++ b/.github/workflows/build_run_unit_test_cmake.yml @@ -0,0 +1,31 @@ +# Build, run unit tests +name: CMake build and run unit test matrix + +on: + push: + branches: + - main + - develop +env: + BUILD_TYPE: Release +jobs: + build_matrix: + strategy: + matrix: + # os: [ubuntu-latest, windows-latest, macos-15] + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + steps: + - name: checkout + uses: actions/checkout@v4 + - name: create-build-dir + run: mkdir build + - name: configure-cmake + run: cd build && cmake -D CHOPS_NET_IP_BUILD_TESTS:BOOL=ON -D CHOPS_NET_IP_BUILD_EXAMPLES:BOOL=ON .. + - name: build + run: cd build && cmake --build . --config $BUILD_TYPE + - name: run-unit-test + run: cd build && ctest -C $BUILD_TYPE diff --git a/.github/workflows/gen_docs.yml b/.github/workflows/gen_docs.yml new file mode 100644 index 00000000..bab0fc8a --- /dev/null +++ b/.github/workflows/gen_docs.yml @@ -0,0 +1,28 @@ +# Build, run unit tests +name: Generate documentation + +on: + push: + branches: + - main +jobs: + build_matrix: + strategy: + matrix: + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + steps: + - name: checkout + uses: actions/checkout@v4 + - name: run-doxygen + uses: mattnotmitt/doxygen-action@v1.12.0 + with: + working-directory: doc + - name: deploy-pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./doc/doc_output/html diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 6195b778..00000000 --- a/.travis.yml +++ /dev/null @@ -1,153 +0,0 @@ - -dist: bionic -language: cpp -cache: ccache - -common_sources: &all_sources -- ubuntu-toolchain-r-test -- llvm-toolchain-trusty -- llvm-toolchain-trusty-3.9 -- llvm-toolchain-trusty-4.0 -- llvm-toolchain-xenial-5.0 -- llvm-toolchain-xenial-6.0 - -matrix: - include: - - # 1/ Linux Clang Builds - - - os: linux - compiler: clang - addons: - apt: - sources: *all_sources - packages: ['clang-3.9'] - env: COMPILER='clang++-3.9' - - - os: linux - compiler: clang - addons: - apt: - sources: *all_sources - packages: ['clang-4.0'] - env: COMPILER='clang++-4.0' - - - os: linux - dist: bionic - compiler: clang - addons: - apt: - sources: *all_sources - packages: ['clang-5.0'] - env: COMPILER='clang++-5.0' - - - os: linux - dist: bionic - compiler: clang - addons: - apt: - sources: *all_sources - packages: ['clang-6.0'] - env: COMPILER='clang++-6.0' - - # 2/ Linux GCC Builds - - os: linux - compiler: gcc - addons: - apt: - sources: *all_sources - packages: ['g++-5'] - env: COMPILER='g++-5' - - - os: linux - compiler: gcc - addons: &gcc6 - apt: - sources: *all_sources - packages: ['g++-6'] - env: COMPILER='g++-6' - - - os: linux - compiler: gcc - addons: &gcc7 - apt: - sources: *all_sources - packages: ['g++-7'] - env: COMPILER='g++-7' - - - os: linux - compiler: gcc - addons: &gcc8 - apt: - sources: *all_sources - packages: ['g++-8'] - env: COMPILER='g++-8' - - # 3b/ Linux C++14 Clang builds - # Note that we need newer libstdc++ for C++14 support - - os: linux - compiler: clang - addons: - apt: - sources: *all_sources - packages: ['clang-3.9', 'libstdc++-6-dev'] - env: COMPILER='clang++-3.9' CPP17=1 - - - os: linux - compiler: clang - addons: - apt: - sources: *all_sources - packages: ['clang-4.0', 'libstdc++-6-dev'] - env: COMPILER='clang++-4.0' CPP17=1 - - - os: linux - dist: bionic - compiler: clang - addons: - apt: - sources: *all_sources - packages: ['clang-5.0', 'libstdc++-6-dev'] - env: COMPILER='clang++-5.0' CPP17=1 - - - os: linux - dist: bionic - compiler: clang - addons: - apt: - sources: *all_sources - packages: ['clang-6.0', 'libstdc++-6-dev'] - env: COMPILER='clang++-6.0' CPP17=1 - - - # 4a/ Linux C++14 GCC builds - - os: linux - compiler: gcc - addons: *gcc6 - env: COMPILER='g++-6' - - - os: linux - compiler: gcc - addons: *gcc7 - env: COMPILER='g++-7' - - - os: linux - compiler: gcc - addons: *gcc8 - env: COMPILER='g++-8' - -before install: - -install: - -before_script: -- cd .. -- wget https://github.com/connectivecpp/utility-rack/archive/develop.tar.gz && mkdir utility-rack && tar -zxvf develop.tar.gz -C utility-rack --strip-components=1 -- wget https://github.com/chriskohlhoff/asio/archive/asio-1-14-0.tar.gz && mkdir asio && tar -zxvf asio-1-14-0.tar.gz -C asio --strip-components=1 -- wget https://github.com/catchorg/Catch2/archive/v2.10.2.tar.gz && mkdir Catch2 && tar -zxvf v2.10.2.tar.gz -C Catch2 --strip-components=1 -- mkdir build && cd build -- cmake ../chops-net-ip/ - -script: -- make all -j2 -- make test diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a159d36..fd9554de 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,53 +1,63 @@ -# Copyright 2019-2020 by Cliff Green +# Copyright (c) 2019-2025 by Cliff Green # # https://github.com/connectivecpp/chops-net-ip # +# I'm still learning CMake, so improvement suggestions are always welcome. +# +# The Asio CMake code is taken from CPM.cmake examples/asio-standalone. +# # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -# CMake 3.8 required for cxx_std_17 target_compile_features +cmake_minimum_required ( VERSION 3.14 FATAL_ERROR ) -cmake_minimum_required ( VERSION 3.12 ) +project ( chops_net_ip + LANGUAGES CXX + DESCRIPTION "An asynchronous networking library based on Asio" + HOMEPAGE_URL "https://github.com/connectivecpp/chops-net-ip/" ) -option ( CHOPS_NET_IP_OPT_BUILD_TESTS "Build and perform chops-net-ip tests" ON ) -option ( CHOPS_NET_IP_OPT_BUILD_EXAMPLES "Build and perform chops-net-ip examples" ON ) -option ( CHOPS_NET_IP_OPT_BUILD_DOCS "Build doxygen documentation" OFF ) +option ( CHOPS_NET_IP_BUILD_TESTS "Build unit tests" OFF ) +option ( CHOPS_NET_IP_BUILD_EXAMPLES "Build examples" OFF ) +option ( CHOPS_NET_IP_INSTALL "Install header only library" OFF ) -set ( OPTIONS "" ) -set ( DEFINITIONS "" ) +# add library targets -project ( chops-net-ip VERSION 1.0 LANGUAGES CXX ) +add_library ( chops_net_ip INTERFACE ) +add_library ( chops::chops_net_ip ALIAS chops_net_ip ) -set ( package_name "chops-net-ip" ) +# thread support specified in Asio download -set ( include_source_dir "${CMAKE_SOURCE_DIR}/include" ) -set ( utility_rack_dir "${CMAKE_SOURCE_DIR}/../utility-rack" ) -set ( utility_rack_include_source_dir "${utility_rack_dir}/include" ) -set ( third_party_include_source_dir "${utility_rack_dir}/third_party" ) -set ( cmake_include_dir "${CMAKE_SOURCE_DIR}/cmake" ) -set ( cmake_all_repos_include_dir "${utility_rack_dir}/cmake/all_repos" ) +# dependencies needed for main library +include ( cmake/download_cpm.cmake ) +CPMAddPackage ( "gh:connectivecpp/shared-buffer@1.0.4" ) +CPMAddPackage ( "gh:martinmoene/expected-lite@0.8.0" ) -# Interface library: +include ( cmake/download_asio_cpm.cmake ) -add_library ( ${package_name} INTERFACE ) +# configure library target -target_include_directories ( ${package_name} INTERFACE ${include_source_dir} ) -target_include_directories ( ${package_name} INTERFACE ${third_party_include_source_dir} ) -target_compile_features ( ${package_name} INTERFACE cxx_std_17) +target_include_directories ( chops_net_ip INTERFACE + $ + $ ) +target_compile_features ( chops_net_ip INTERFACE cxx_std_20 ) -if ( CHOPS_NET_IP_OPT_BUILD_TESTS ) +# check to build unit tests +if ( ${CHOPS_NET_IP_BUILD_TESTS} ) enable_testing() add_subdirectory ( test ) -endif() +endif () -if ( CHOPS_NET_IP_OPT_BUILD_EXAMPLES ) +# check to build example code +if ( ${CHOPS_NET_IP_BUILD_EXAMPLES} ) add_subdirectory ( example ) -endif() +endif () -if ( CHOPS_NET_IP_OPT_BUILD_DOCS ) - add_subdirectory ( doc ) -endif() +# check to install +if ( ${CHOPS_NET_IP_INSTALL} ) + set ( CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt ) + include ( CPack ) +endif () # end of file diff --git a/README.md b/README.md index 78702617..3f989265 100644 --- a/README.md +++ b/README.md @@ -1,124 +1,81 @@ # Chops Net IP - Connective Handcrafted Openwork Software for Asynchronous IP Networking -Chops Net IP is a C++ library that makes asynchronous networking programming fun. Or at least if not fun, it makes network programming easier and safer, without significantly sacrificing performance. Chops Net IP handles Internet Protocol (IP) communications including TCP, UDP, and UDP multicast. It is written using modern C++ design idioms and the latest (2017) C++ standard. +Chops Net IP is a C++ library that makes asynchronous networking programming fun. Or at least if not fun, it makes network programming easier and safer, without significantly sacrificing performance. Chops Net IP handles Internet Protocol (IP) communications including TCP, UDP, and UDP multicast. It is written using modern C++ design idioms and a recent (2020) C++ standard. Chops Net IP is not like any other high-level, general purpose C++ socket library. Chops Net IP is layered on top of the Asio asynchronous networking library, taking advantage of the portability and functionality that Asio provides. However, it simplifies network programming compared to coding against the Asio API, while providing easy scalability through the asynchronous facilities. -# Build and Release Status, License Info +Chops Net IP: -**Travis CI Build Status:** +1. Asio gotchas +2. Simplifies many use cases +3. API between TCP and UDP is similar, allowing shared code +4. Provides callback points -*Master Branch* | [![Build Status](https://travis-ci.org/connectivecpp/chops-net-ip.svg?branch=master)](https://travis-ci.org/connectivecpp/chops-net-ip) -*Develop Branch* | [![Build Status](https://travis-ci.org/connectivecpp/chops-net-ip.svg?branch=develop)](https://travis-ci.org/connectivecpp/chops-net-ip) +#### Unit Test and Documentation Generation Workflow Status -**GitHub Actions CI Build Status:** +![GH Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/connectivecpp/chops-net-ip/build_run_unit_test_cmake.yml?branch=main&label=GH%20Actions%20build,%20unit%20tests%20on%20main) -![CMake Build Matrix](https://github.com/connectivecpp/chops-net-ip/workflows/CMake%20Build%20Matrix/badge.svg) +![GH Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/connectivecpp/chops-net-ip/build_run_unit_test_cmake.yml?branch=develop&label=GH%20Actions%20build,%20unit%20tests%20on%20develop) -**Latest tag:** ![Latest Tag](https://img.shields.io/github/v/tag/connectivecpp/chops-net-ip) +![GH Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/connectivecpp/chops-net-ip/gen_docs.yml?branch=main&label=GH%20Actions%20generate%20docs) -Release 1.0 is under development as of January 2020, awaiting CMake enhancements, a comprehensive tutorial, and additional testing under multiple compilers and platforms. +![GH Tag](https://img.shields.io/github/v/tag/connectivecpp/chops-net-ip?label=GH%20tag) -Release notes and upcoming development plans are [available here](doc/release.md). +## Overview -This project is distributed under the [Boost Software License](LICENSE.txt): [![Licence](https://img.shields.io/badge/license-boost-4480cc.svg)](http://www.boost.org/LICENSE_1_0.txt) +(fill in) -# Overview +## Generated Documentation -For many software developers, asynchronous network programming in C++ is not easy. It is complex, has many pitfalls, and requires designing C++ code in a way that is not natural, even for those with years of experience. Chops Net IP ("C"onnective "H"andcrafted "Op"enwork "S"oftware, Networking over Internet Protocol) simplifies asynchronous network programming and provides useful (and tasty!) abstractions for many types of communication patterns. +The generated Doxygen documentation for `chops_net_ip` is [here](https://connectivecpp.github.io/chops-net-ip/). -Chops Net IP is layered on top of Chris Kohlhoff's Asio library (see [References](https://connectivecpp.github.io/doc/references.html)) allowing it to be portable across many compilers and platforms. When the C++ Networking TS is standardized (possibly C++ 23 but more likely C++ 26) Chops Net IP will directly use the networking facilities of the C++ standard library. +## Library Dependencies -Chops Net IP simplifies application code that processes data on multiple simultaneous TCP connections or UDP endpoints. All Chops Net IP operations (from the application viewpoint) are no-wait (i.e. there are no blocking methods) and all network processing operations are performed asynchronously. +The stand-alone Asio library is a dependency for Chops Net IP. Specific version (or branch) specs for the Asio dependency is in [`cmake/download_asio_cpm.cmake`](cmake/download_asio_cpm.cmake). -## Tasty Bites +The [`shared_buffer`](https://github.com/connectivecpp/shared-buffer) library from Connective C++ is a dependency, providing reference counted `std::byte` buffers. -Chops Net IP functionality: +[`expected_lite`](https://github.com/martinmoene/expected-lite) from Martin Moene is a dependency, providing `std::expected` functionality for C++ 20 code baselines. Chops Net IP uses `nonstd::expected` in the codebase per Martin's library and will transition to `std::expected` when C++ 23 becomes the baseline. -- simplifies the creation of various IP (Internet Protocol) networking entities including TCP acceptors and connectors, UDP senders and receivers, and UDP multicast senders and receivers. -- simplifies the resolution of network names to IP addresses (i.e. domain name system lookups). -- abstracts message concepts in TCP (Transmission Control Protocol) and provides customization points in two areas: - 1. message framing, which is the code and logic that determines the begin and end of a message within the TCP byte stream. - 2. message processing, which is the code and logic that processes a message when the framing determines a complete message has arrived. -- provides buffer lifetime management for outgoing data. -- provides customization points for state changes in the networking entities, including: - - a TCP connection has become active and is ready for input and output. - - a UDP endpoint has been created and is ready for input and output. - - a TCP connection has been destroyed or a UDP socket has closed. -- implements the "plumbing" for asynchronous processing on multiple simultaneous connections. -- abstracts many differences between network protocols (TCP, UDP, UDP multicast), allowing easier application transitioning between protocol types. -- allows the application to control threading (no threads are created or managed inside Chops Net IP). -- is agnostic with respect to data marshalling or serialization or "wire protocols" (application code provides any and all data marshalling and endian logic). -- does not impose any structure on network message content. +## C++ Standard -Chops Net IP is designed to make it easy and efficient for an application to create hundreds (or thousands) of network connections and handle them simultaneously. In particular, there are no threads or thread pools within Chops Net IP, and it works well with only one application thread invoking the event loop (an executor, in current C++ terminology). +`chops_net_ip` is built under C++ 20, using features such as `std::span`. In the future `concepts` / `requires` will be added. -## Tasty Uses +## Supported Compilers -Example environments where Chops Net IP is a good fit: +Continuous integration workflows build and unit test on g++ (through Ubuntu), MSVC (through Windows), and clang (through macOS). -- Applications that are event driven or highly asynchronous in nature. -- Applications where data is generated and handled in a non-symmetric manner. For example, data may be generated on the TCP acceptor side, or may be generated on a TCP connector side, or on both sides depending on the use case. Similarly, applications where the data flow is bi-directional and sends or receives are data-driven versus pattern-driven work well with this library. -- Applications interacting with multiple (many) connections (e.g. handling multiple sensors or inputs or outputs), each with low to moderate throughput needs (i.e. IoT environments, chat networks, gaming networks). -- Small footprint or embedded environments, where all network processing is run inside a single thread. In particular, environments where a JVM (or similar run-time support) is too costly in terms of system resources, but have a relatively rich operating environment (e.g. Linux running on a small chip) are a very good fit. (Currently the main constraint is small system support in the Asio library implementation.) -- Applications with relatively simple network processing that need an easy-to-use and quick-for-development networking library. -- Applications with configuration driven networks that may need to switch (for example) between TCP connect versus TCP accept for a given connection, or between TCP and UDP for a given communication path. -- Peer-to-peer applications where the application doesn't care which side connects or accepts. -- Frameworks or groups of applications where abstracting wire-protocol logic from message processing logic makes sense. +## Unit Test Dependencies -## Examples +The unit test code uses [Catch2](https://github.com/catchorg/Catch2). If the `CHOPS_NET_IP_BUILD_TESTS` flag is provided to Cmake (see commands below) the Cmake configure / generate will download the Catch2 library as appropriate using the [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake) dependency manager. If Catch2 (v3 or greater) is already installed using a different package manager (such as Conan or vcpkg), the `CPM_USE_LOCAL_PACKAGES` variable can be set which results in `find_package` being attempted. Note that v3 (or later) of Catch2 is required. -Example demo programs are in the [`/example`](https://github.com/connectivecpp/chops-net-ip) directory. +Specific version (or branch) specs for the Catch2 dependency is in the [test/CMakeLists.txt](test/CMakeLists.txt) file, look for the `CPMAddPackage` command. -The `simple_chat_demo.cpp` program has a listing of the multiple steps to set up working example. +## Example Dependencies -## Want More? +(Fill in). -A detailed overview, a C++ socket library comparison, and a FAQ is [available here](doc/overview.md). +## Build and Run Unit Tests -# C++ Language Requirements and Alternatives +To build and run the unit test programs: -C++ 17 is the primary baseline for this repository. Additional notes on possible alternatives are [available here](https://connectivecpp.github.io/). +First clone the `chops-net-ip` repository, then create a build directory in parallel to the `chops-net-ip` directory (this is called "out of source" builds, which is recommended), then `cd` (change directory) into the build directory. The CMake commands: -# External Dependencies +``` +cmake -D CHOPS_NET_IP_BUILD_TESTS:BOOL=ON ../chops-net-ip -Production external dependencies: +cmake --build . -- Version 1.13 (or later) of Chris Kohlhoff's [`asio`](https://github.com/chriskohlhoff/asio) library is required. Note that it is the stand-alone Asio library, not the Boost Asio version. -- The [`utility-rack`](https://github.com/connectivecpp/utility-rack) library, which is a repository in the same GitHub account as Chops Net IP. +ctest +``` -Test external dependencies: +For additional test output, run the unit test individually, for example: -- Version 2.8.0 (or later) of Phil Nash's [`Catch2`](https://github.com/catchorg/Catch2) library is required for all test scenarios. +``` +test/net_ip/basic_io_output_test -s +``` -There are single file headers that have been copied into the `third_party` directory of the `utility-rack` repository from various GitHub repositories and do not require any external dependency management. These are: - -- Martin Moene's [`expected-lite`](https://github.com/martinmoene/expected-lite) library. - -See [References](https://connectivecpp.github.io/doc/references.html) for additional details. - -# Supported Compilers and Platforms - -Chops Net IP has been compiled and tests run on: - -- g++ 7.2, g++ 7.3, Linux (Ubuntu 17.10 - kernel 4.13, Ubuntu 18.04 - kernel 4.15) -- (TBD, will include at least clang on linux and vc++ on Windows) - -Follow the CI links for additional build environments. - -# Installation - -Chops Net IP is header-only, so installation consists of downloading or cloning and setting compiler include paths appropriately. No compile time configuration macros are defined. - -# References - -See [References](https://connectivecpp.github.io/doc/references.html) for details on dependencies and inspirations for Chops Net IP. - -# About - -Team member information is [available here](https://connectivecpp.github.io/). - -A few "Cliff Notes" are [available here](doc/cliff_notes.md). +The examples can be built by adding `-D CHOPS_NET_IP_BUILD_EXAMPLES:BOOL=ON` to the CMake configure / generate step. diff --git a/cmake/add_target_dependencies.cmake b/cmake/add_target_dependencies.cmake deleted file mode 100644 index 7863a9bf..00000000 --- a/cmake/add_target_dependencies.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2020 by Cliff Green -# -# https://github.com/connectivecpp/utility-rack -# -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -# Still learning find_package and related ways to bring in third party dependent include directories, -# so don't judge, instead please help. - -set ( catch2_include_dir "${CMAKE_SOURCE_DIR}/../Catch2/single_include" ) -if ( NOT $ENV{CATCH2_INCLUDE_DIR} STREQUAL "" ) - set ( catch2_include_dir $ENV{CATCH2_INCLUDE_DIR}} ) -endif() -set ( asio_include_dir "${CMAKE_SOURCE_DIR}/../asio/asio/include" ) -if ( NOT $ENV{ASIO_INCLUDE_DIR} STREQUAL "" ) - set ( asio_include_dir $ENV{ASIO_INCLUDE_DIR}} ) -endif() - -function ( add_target_dependencies target ) -# find_package ( Catch2 REQUIRED ) -# target_include_directories ( ${target} PRIVATE ${Catch2_INCLUDE_DIRS} ) - target_include_directories ( ${target} PRIVATE ${catch2_include_dir} ) -# find_package ( asio REQUIRED ) -# target_include_directories ( ${target} PRIVATE ${asio_INCLUDE_DIRS} ) - target_include_directories ( ${target} PRIVATE ${asio_include_dir} ) -endfunction() - -# end of file - diff --git a/cmake/download_asio_cpm.cmake b/cmake/download_asio_cpm.cmake new file mode 100644 index 00000000..93df15b3 --- /dev/null +++ b/cmake/download_asio_cpm.cmake @@ -0,0 +1,63 @@ +# This Asio CMake code is taken from CPM.cmake examples/asio-standalone. +# +# This code assumes it is run from a top-level CMakeLists.txt file, +# with a download_cpm.cmake file in a parallel cmake directory. +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +set ( CMAKE_THREAD_PREFER_PTHREAD TRUE ) +set ( THREADS_PREFER_PTHREAD_FLAG TRUE ) +find_package ( Threads REQUIRED ) + +CPMAddPackage ( "gh:chriskohlhoff/asio#asio-1-34-0@1.34.0" ) + +# ASIO doesn't use CMake, we have to configure it manually. Extra notes for using on Windows: +# +# 1) If _WIN32_WINNT is not set, ASIO assumes _WIN32_WINNT=0x0501, i.e. Windows XP target, which is +# definitely not the platform which most users target. +# +# 2) WIN32_LEAN_AND_MEAN is defined to make Winsock2 work. + +if(asio_ADDED) + add_library(asio INTERFACE) + + target_include_directories(asio SYSTEM INTERFACE ${asio_SOURCE_DIR}/asio/include) + + target_compile_definitions(asio INTERFACE ASIO_STANDALONE ASIO_NO_DEPRECATED) + + target_link_libraries(asio INTERFACE Threads::Threads) + + if(WIN32) + # macro see @ https://stackoverflow.com/a/40217291/1746503 + macro(get_win32_winnt version) + if(CMAKE_SYSTEM_VERSION) + set(ver ${CMAKE_SYSTEM_VERSION}) + string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver}) + string(REGEX MATCH "^([0-9]+)" verMajor ${ver}) + # Check for Windows 10, b/c we'll need to convert to hex 'A'. + if("${verMajor}" MATCHES "10") + set(verMajor "A") + string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver}) + endif("${verMajor}" MATCHES "10") + # Remove all remaining '.' characters. + string(REPLACE "." "" ver ${ver}) + # Prepend each digit with a zero. + string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver}) + set(${version} "0x${ver}") + endif() + endmacro() + + if(NOT DEFINED _WIN32_WINNT) + get_win32_winnt(ver) + set(_WIN32_WINNT ${ver}) + endif() + + message(STATUS "Set _WIN32_WINNET=${_WIN32_WINNT}") + + target_compile_definitions(asio INTERFACE _WIN32_WINNT=${_WIN32_WINNT} WIN32_LEAN_AND_MEAN) + endif() +endif() + +# end of file + diff --git a/cmake/download_cpm.cmake b/cmake/download_cpm.cmake new file mode 100644 index 00000000..dd69ebe3 --- /dev/null +++ b/cmake/download_cpm.cmake @@ -0,0 +1,10 @@ + +# copied from CPM.cmake GitHub site +# download CPM.cmake + +file( + DOWNLOAD + https://github.com/cpm-cmake/CPM.cmake/releases/download/v0.40.0/CPM.cmake + ${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake +) +include(${CMAKE_CURRENT_BINARY_DIR}/cmake/CPM.cmake) diff --git a/cmake/example_app_creation.cmake b/cmake/example_app_creation.cmake new file mode 100644 index 00000000..2160ed8f --- /dev/null +++ b/cmake/example_app_creation.cmake @@ -0,0 +1,16 @@ +# Copyright (c) 2024-2025 by Cliff Green +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +# add example executable +foreach ( example_app_name IN LISTS example_app_names ) + message ( "Creating example executable: ${example_app_name}" ) + add_executable ( ${example_app_name} ${example_app_name}.cpp ) + target_compile_features ( ${example_app_name} PRIVATE cxx_std_20 ) + target_link_libraries ( ${example_app_name} PRIVATE + Threads::Threads + chops_net_ip asio expected-lite shared_buffer + utility_rack wait_queue binary_serialize ) +endforeach() + diff --git a/cmake/header_dirs_var.cmake b/cmake/header_dirs_var.cmake deleted file mode 100644 index f574bc04..00000000 --- a/cmake/header_dirs_var.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2020 by Cliff Green -# -# https://github.com/connectivecpp/utility-rack -# -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -set ( header_dirs - "${include_source_dir}" - "${utility_rack_include_source_dir}" - "${third_party_include_source_dir}" - ) - -# end of file - diff --git a/cmake/test_app_creation.cmake b/cmake/test_app_creation.cmake new file mode 100644 index 00000000..c6375bd1 --- /dev/null +++ b/cmake/test_app_creation.cmake @@ -0,0 +1,19 @@ +# Copyright (c) 2024-2025 by Cliff Green +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +# add unit test executable +foreach ( test_app_name IN LISTS test_app_names ) + message ( "Creating test executable: ${test_app_name}" ) + add_executable ( ${test_app_name} ${test_app_name}.cpp ) + target_compile_features ( ${test_app_name} PRIVATE cxx_std_20 ) + target_include_directories ( ${test_app_name} PRIVATE + ${CMAKE_SOURCE_DIR}/test/ ) + target_link_libraries ( ${test_app_name} PRIVATE + Threads::Threads + chops_net_ip asio expected-lite shared_buffer + utility_rack wait_queue binary_serialize + Catch2::Catch2WithMain ) +endforeach() + diff --git a/cmake/test_creation.cmake b/cmake/test_creation.cmake new file mode 100644 index 00000000..88cf67ce --- /dev/null +++ b/cmake/test_creation.cmake @@ -0,0 +1,14 @@ +# Copyright (c) 2024-2025 by Cliff Green +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +# add test to test suite +foreach ( test_app_name IN LISTS test_app_names ) + message ( "Creating test: run_${test_app_name}" ) + add_test ( NAME run_${test_app_name} COMMAND ${test_app_name} ) + set_tests_properties ( run_${test_app_name} + PROPERTIES PASS_REGULAR_EXPRESSION "All tests passed" + ) +endforeach() + diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 77ed67c7..5c270986 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,37 +1,21 @@ -# Copyright 2019-2020 by Cliff Green +# Copyright 2019-2025 by Cliff Green # # https://github.com/connectivecpp/chops-net-ip # # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -cmake_minimum_required ( VERSION 3.12 ) +cmake_minimum_required ( VERSION 3.14 FATAL_ERROR ) -project ( chops-net-ip-example VERSION 1.0 LANGUAGES CXX ) +project ( chops-net-ip-example LANGUAGES CXX ) -set ( example_source_dir "${CMAKE_SOURCE_DIR}/example" ) +set ( example_app_names local_echo_demo + chat_server_demo + simple_chat_demo + echo_binary_text_server_demo + echo_binary_text_client_demo +# udp_broadcast_demo + udp_receiver_demo ) -include ( "${cmake_include_dir}/header_dirs_var.cmake" ) - -set ( example_sources - "${example_source_dir}/local_echo_demo.cpp" - "${example_source_dir}/chat_server_demo.cpp" - "${example_source_dir}/simple_chat_demo.cpp" - "${example_source_dir}/echo_binary_text_server_demo.cpp" - "${example_source_dir}/echo_binary_text_client_demo.cpp" - "${example_source_dir}/udp_broadcast_demo.cpp" - "${example_source_dir}/udp_receiver_demo.cpp" ) - -include ( "${cmake_include_dir}/add_target_dependencies.cmake" ) - -include ( "${cmake_all_repos_include_dir}/add_target_info_func.cmake" ) -include ( "${cmake_all_repos_include_dir}/target_exe_func.cmake" ) - -foreach ( example_src IN LISTS example_sources ) - get_filename_component ( targ ${example_src} NAME_WE ) - message ( "Calling target_exe for: ${targ}" ) - target_exe ( ${targ} ${example_src} ) -endforeach() - -# end of file +include ( ../cmake/example_app_creation.cmake ) diff --git a/example/chat_server_demo.cpp b/example/chat_server_demo.cpp index 4f6a7585..defbb1e6 100644 --- a/example/chat_server_demo.cpp +++ b/example/chat_server_demo.cpp @@ -8,6 +8,8 @@ * * Copyright (c) 2019 Thurman Gillespy * 2019-10-28 + * + * Updated 2025-04-23 by Cliff Green for library dependency changes * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -35,7 +37,6 @@ chat_server_demo.cpp -lpthread -o chat_server #include "net_ip/net_entity.hpp" #include "net_ip_component/worker.hpp" #include "net_ip_component/send_to_all.hpp" -#include "marshall/extract_append.hpp" #include "net_ip/io_type_decls.hpp" using io_context = asio::io_context; diff --git a/example/echo_binary_text_client_demo.cpp b/example/echo_binary_text_client_demo.cpp index 56c99670..ee3e5b90 100644 --- a/example/echo_binary_text_client_demo.cpp +++ b/example/echo_binary_text_client_demo.cpp @@ -10,6 +10,8 @@ * * Copyright (c) Thurman Gillespy * 2019-10-21 + * + * Updated 2025-04-23 by Cliff Green for library dependency changes * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -38,7 +40,7 @@ echo_binary_text_client_demo.cpp -lpthread -o echo_client #include "net_ip/net_ip.hpp" #include "net_ip/net_entity.hpp" #include "net_ip_component/worker.hpp" -#include "marshall/extract_append.hpp" +#include "serialize/extract_append.hpp" #include "net_ip/io_type_decls.hpp" using io_context = asio::io_context; @@ -127,7 +129,7 @@ int main(int argc, char* argv[]) { hdr_processed = true; // 1st 2 bytes is message size // endian correct data marshalling - std::uint16_t size = chops::extract_val + std::uint16_t size = chops::extract_val (chops::cast_ptr_to(buf.data())); return size; @@ -201,7 +203,7 @@ int main(int argc, char* argv[]) { // endian correct data marshalling std::byte tbuf[HDR_SIZE]; // temp buffer to hold the header // write those 2 bytes to the temp buffer - std::size_t result = chops::append_val(tbuf, size_val); + std::size_t result = chops::append_val(tbuf, size_val); assert(result == HDR_SIZE); // now append our header and string data to the output buffer buf_out.append(tbuf, sizeof(tbuf)); // write the header diff --git a/example/echo_binary_text_server_demo.cpp b/example/echo_binary_text_server_demo.cpp index d3c039d6..dccaa7e0 100644 --- a/example/echo_binary_text_server_demo.cpp +++ b/example/echo_binary_text_server_demo.cpp @@ -10,6 +10,8 @@ * * Copyright (c) Thurman Gillespy * 2019-10-21 + * + * Updated 2025-04-23 by Cliff Green for library dependency changes * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -35,7 +37,7 @@ echo_binary_text_server_demo.cpp -lpthread -o echo_server #include "net_ip/net_ip.hpp" #include "net_ip/net_entity.hpp" #include "net_ip_component/worker.hpp" -#include "marshall/extract_append.hpp" +#include "serialize/extract_append.hpp" #include "net_ip/io_type_decls.hpp" using io_context = asio::io_context; @@ -107,7 +109,7 @@ int main(int argc, char* argv[]) { // endian correct data marshalling std::byte tbuf[HDR_SIZE]; // temp buffer to hold the header // write those 2 bytes to the temp buffer - std::size_t result = chops::append_val(tbuf, size_val); + std::size_t result = chops::append_val(tbuf, size_val); assert(result == HDR_SIZE); // now append our header and string data to the output buffer buf_out.append(tbuf, sizeof(tbuf)); // write the header @@ -131,7 +133,7 @@ int main(int argc, char* argv[]) { hdr_processed = true; // 1st 2 bytes is message size // endian correct data marshalling - uint16_t size = chops::extract_val + uint16_t size = chops::extract_val (static_cast (buf.data())); return size; // return the size of the text data (obtained from header) diff --git a/example/udp_broadcast_demo.cpp b/example/udp_broadcast_demo.cpp index f67d3b2b..7d16c734 100644 --- a/example/udp_broadcast_demo.cpp +++ b/example/udp_broadcast_demo.cpp @@ -36,6 +36,7 @@ udp_broadcast_demo.cpp -lpthread -o udp_broad #include "net_ip/net_entity.hpp" #include "net_ip_component/worker.hpp" #include "net_ip/io_type_decls.hpp" +#include "asio/ip/network_v4.hpp" using io_output = chops::net::udp_io_output; @@ -68,7 +69,7 @@ bool process_args(int argc, char* argv[], bool& print_errors, std::string& ip_ad int offset = 0; - using addr4 = asio::ip::address_v4; + using addr4 = asio::ip::network_v4; if (argc == 1 || argv[1] == HELP_PRM) { print_useage(); diff --git a/include/net_ip/basic_io_interface.hpp b/include/net_ip/basic_io_interface.hpp index 8eb14f60..313a4d9e 100644 --- a/include/net_ip/basic_io_interface.hpp +++ b/include/net_ip/basic_io_interface.hpp @@ -8,7 +8,7 @@ * * @author Cliff Green * - * Copyright (c) 2017-2019 by Cliff Green + * Copyright (c) 2017-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/net_ip/basic_io_output.hpp b/include/net_ip/basic_io_output.hpp index 0be8ee06..e27d1a38 100644 --- a/include/net_ip/basic_io_output.hpp +++ b/include/net_ip/basic_io_output.hpp @@ -7,7 +7,7 @@ * * @author Cliff Green * - * Copyright (c) 2019 by Cliff Green + * Copyright (c) 2019-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -24,7 +24,7 @@ #include "nonstd/expected.hpp" -#include "marshall/shared_buffer.hpp" +#include "buffer/shared_buffer.hpp" #include "net_ip/queue_stats.hpp" #include "net_ip/detail/wp_access.hpp" diff --git a/include/net_ip/detail/net_entity_common.hpp b/include/net_ip/detail/net_entity_common.hpp index 68ec1f6c..f93ca0f0 100644 --- a/include/net_ip/detail/net_entity_common.hpp +++ b/include/net_ip/detail/net_entity_common.hpp @@ -17,7 +17,7 @@ * * @author Cliff Green * - * Copyright (c) 2017-2019 by Cliff Green + * Copyright (c) 2017-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -27,7 +27,7 @@ #ifndef NET_ENTITY_COMMON_HPP_INCLUDED #define NET_ENTITY_COMMON_HPP_INCLUDED -#include "asio/executor.hpp" +#include "asio/any_io_executor.hpp" #include "asio/post.hpp" #include @@ -75,7 +75,7 @@ class net_entity_common { template std::error_code start(F1&& io_state_chg_func, F2&& err_func, - const asio::executor& exec, + const asio::any_io_executor& exec, SF&& start_func) { int expected = 0; if (!m_started.compare_exchange_strong(expected, 1)) { @@ -95,7 +95,7 @@ class net_entity_common { template - std::error_code stop(const asio::executor& exec, + std::error_code stop(const asio::any_io_executor& exec, SF&& stop_func) { int expected = 1; if (!m_started.compare_exchange_strong(expected, 2)) { diff --git a/include/net_ip/detail/output_queue.hpp b/include/net_ip/detail/output_queue.hpp index e7f4ac5f..4aa71cef 100644 --- a/include/net_ip/detail/output_queue.hpp +++ b/include/net_ip/detail/output_queue.hpp @@ -7,14 +7,14 @@ * Concurrency protection is needed at a higher level to enforce data structure and flag * consistency for data sending, as well as to ensure that only one write is in process at * a time. There are multiple ways to accomplish this goal, whether with locks (mutex or - * spin-lock or semaphore, etc), or by posting all write operations through the Asio + * spin-lock or semaphore, etc), or by posting all write operations through the @c asio * executor. * * @note For internal use only. * * @author Cliff Green * - * Copyright (c) 2017-2019 by Cliff Green + * Copyright (c) 2017-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/net_ip/detail/tcp_acceptor.hpp b/include/net_ip/detail/tcp_acceptor.hpp index ed96c13f..cea1f1ba 100644 --- a/include/net_ip/detail/tcp_acceptor.hpp +++ b/include/net_ip/detail/tcp_acceptor.hpp @@ -8,7 +8,7 @@ * * @author Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green + * Copyright (c) 2018-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -39,8 +39,6 @@ #include "net_ip/basic_io_output.hpp" -#include "utility/erase_where.hpp" - namespace chops { namespace net { namespace detail { @@ -231,7 +229,7 @@ class tcp_acceptor : public std::enable_shared_from_this { // this code invoked via a posted function object, allowing the TCP IO handler // to completely shut down void notify_me(std::error_code err, tcp_io_shared_ptr iop) { - chops::erase_where(m_io_handlers, iop); + std::erase_if (m_io_handlers, [iop] (auto sp) { return iop == sp; } ); m_entity_common.call_error_cb(iop, err); m_entity_common.call_io_state_chg_cb(iop, m_io_handlers.size(), false); } diff --git a/include/net_ip/detail/tcp_connector.hpp b/include/net_ip/detail/tcp_connector.hpp index 57e4ef7c..a806c769 100644 --- a/include/net_ip/detail/tcp_connector.hpp +++ b/include/net_ip/detail/tcp_connector.hpp @@ -8,7 +8,7 @@ * * @author Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green + * Copyright (c) 2018-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/include/net_ip/detail/tcp_io.hpp b/include/net_ip/detail/tcp_io.hpp index f3639e4e..26bbf4f3 100644 --- a/include/net_ip/detail/tcp_io.hpp +++ b/include/net_ip/detail/tcp_io.hpp @@ -8,7 +8,7 @@ * * @author Cliff Green * - * Copyright (c) 2017-2019 by Cliff Green + * Copyright (c) 2017-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -19,7 +19,7 @@ #define TCP_IO_HPP_INCLUDED #include "asio/io_context.hpp" -#include "asio/executor.hpp" +#include "asio/any_io_executor.hpp" #include "asio/read.hpp" #include "asio/read_until.hpp" #include "asio/write.hpp" @@ -42,7 +42,7 @@ #include "net_ip/basic_io_output.hpp" #include "net_ip/simple_variable_len_msg_frame.hpp" -#include "marshall/shared_buffer.hpp" +#include "buffer/shared_buffer.hpp" namespace chops { namespace net { diff --git a/include/net_ip/detail/udp_entity_io.hpp b/include/net_ip/detail/udp_entity_io.hpp index 88c7995b..08cf540f 100644 --- a/include/net_ip/detail/udp_entity_io.hpp +++ b/include/net_ip/detail/udp_entity_io.hpp @@ -8,7 +8,7 @@ * * @author Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green + * Copyright (c) 2018-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -40,7 +40,7 @@ #include "net_ip/basic_io_output.hpp" #include "net_ip/endpoints_resolver.hpp" -#include "marshall/shared_buffer.hpp" +#include "buffer/shared_buffer.hpp" ////// // #include diff --git a/include/net_ip/net_entity.hpp b/include/net_ip/net_entity.hpp index caf71263..18cae038 100644 --- a/include/net_ip/net_entity.hpp +++ b/include/net_ip/net_entity.hpp @@ -6,7 +6,7 @@ * * @author Cliff Green * - * Copyright (c) 2017-2019 by Cliff Green + * Copyright (c) 2017-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -37,16 +37,15 @@ #include "net_ip/io_type_decls.hpp" -#include "utility/overloaded.hpp" - namespace chops { namespace net { -// Cliff note: when C++ 20 lambda templates are available much of this code can be simplified, -// since most of it is generic (just doesn't have the specific type parameter available as -// needed in the right place). Stating it another way, there is waaaaaaay too much boilerplate -// code (it may be possible to simplify with C++17 techniques that I don't know yet). - +namespace detail { +// std::visit utility taken directly from cppreference + template + struct overloaded : Ts... { using Ts::operator()...; }; +} + /** * @brief The @c net_entity class provides the primary application interface * into the TCP acceptor, TCP connector, and UDP entity functionality. @@ -137,7 +136,7 @@ class net_entity { */ auto is_started() const -> nonstd::expected { - return std::visit(chops::overloaded { + return std::visit(detail::overloaded { [] (const udp_wp& wp) -> nonstd::expected { return detail::wp_access(wp, [] (detail::udp_entity_io_shared_ptr sp) { return sp->is_started(); } ); @@ -169,13 +168,14 @@ class net_entity { * Within the function object socket options can be queried or modified or any valid * socket method called. * - * @return @c nonstd::expected - socket has been visited on success; on error (if no + * @return @c nonstd::expected - @c bool socket has been visited; on error (if no * associated IO handler), a @c std::error_code is returned. */ + template auto visit_socket(F&& func) const -> nonstd::expected { - return std::visit(chops::overloaded { + return std::visit(detail::overloaded { [&func] (const udp_wp& wp) -> nonstd::expected { if constexpr (std::is_invocable_v) { return detail::wp_access_void(wp, @@ -225,7 +225,7 @@ class net_entity { template auto visit_io_output(F&& func) const -> nonstd::expected { - return std::visit(chops::overloaded { + return std::visit(detail::overloaded { [&func] (const udp_wp& wp)-> nonstd::expected { if constexpr (std::is_invocable_v) { return detail::wp_access(wp, @@ -343,7 +343,7 @@ class net_entity { template auto start(F1&& io_state_chg_func, F2&& err_func) -> nonstd::expected { - return std::visit(chops::overloaded { + return std::visit(detail::overloaded { [&io_state_chg_func, &err_func] (const udp_wp& wp)->nonstd::expected { if constexpr (std::is_invocable_v && std::is_invocable_v) { @@ -389,7 +389,7 @@ class net_entity { */ auto stop() -> nonstd::expected { - return std::visit(chops::overloaded { + return std::visit(detail::overloaded { [] (const udp_wp& wp)->nonstd::expected { return detail::wp_access_void(wp, [] (detail::udp_entity_io_shared_ptr sp) { return sp->stop(); } ); @@ -414,7 +414,7 @@ class net_entity { * */ std::string_view stream_out() const noexcept { - return std::visit(chops::overloaded { + return std::visit(detail::overloaded { [] (const udp_wp& wp) { return "[UDP network entity]"; }, [] (const acc_wp& wp) { return "[TCP acceptor network entity]"; }, [] (const conn_wp& wp) { return "[TCP connector network entity]"; }, @@ -442,7 +442,7 @@ class net_entity { */ inline bool operator==(const net_entity& lhs, const net_entity& rhs) noexcept { - return std::visit(chops::overloaded { + return std::visit(detail::overloaded { [] (const net_entity::udp_wp& lwp, const net_entity::udp_wp& rwp) { return lwp.lock() == rwp.lock(); }, @@ -487,7 +487,7 @@ inline bool operator==(const net_entity& lhs, const net_entity& rhs) noexcept { * @return As described in the comments. */ inline bool operator<(const net_entity& lhs, const net_entity& rhs) noexcept { - return std::visit(chops::overloaded { + return std::visit(detail::overloaded { [] (const net_entity::udp_wp& lwp, const net_entity::udp_wp& rwp) { return lwp.lock() < rwp.lock(); }, diff --git a/include/net_ip/net_ip.hpp b/include/net_ip/net_ip.hpp index 4e42e018..d5a937c0 100644 --- a/include/net_ip/net_ip.hpp +++ b/include/net_ip/net_ip.hpp @@ -8,7 +8,7 @@ * * @author Cliff Green * - * Copyright (c) 2017-2019 by Cliff Green + * Copyright (c) 2017-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -26,7 +26,7 @@ #include // std::visit #include // std::enable_if -#include +#include // std::scoped_lock, std::mutex #include "asio/io_context.hpp" #include "asio/ip/tcp.hpp" @@ -41,9 +41,6 @@ #include "net_ip/tcp_connector_timeout.hpp" -#include "utility/erase_where.hpp" -#include "utility/overloaded.hpp" - namespace chops { namespace net { @@ -97,7 +94,10 @@ namespace net { * other words, no event loop or @c run methods are available. Instead, the * @c net_ip class takes an @c asio @c io_context as a constructor parameter and * application code will use the @c asio executor methods for invoking - * the underlying asynchronous operations. + * the underlying asynchronous operations. The most current (as of early 2025) + * @c asio executor class, matching the C++ 26 standard executor, is the @c asio + * @c any_io_executor class. + * * * For convenience, a class named @c worker in the @c net_ip_component directory * combines an executor with a work guard and creates a thread to invoke the asynchronous @@ -130,7 +130,7 @@ class net_ip { std::vector m_udp_entities; private: - using lg = std::lock_guard; + using lg = std::scoped_lock; public: @@ -391,10 +391,17 @@ class net_ip { */ void remove(net_entity ent) { lg g(m_mutex); - std::visit (chops::overloaded { - [this] (detail::tcp_acceptor_weak_ptr p) { chops::erase_where(m_acceptors, p.lock()); }, - [this] (detail::tcp_connector_weak_ptr p) { chops::erase_where(m_connectors, p.lock()); }, - [this] (detail::udp_entity_io_weak_ptr p) { chops::erase_where(m_udp_entities, p.lock()); }, +// overloaded utility brought in from net_entity.hpp + std::visit (detail::overloaded { + [this] (detail::tcp_acceptor_weak_ptr p) { + std::erase_if(m_acceptors, [p] (detail::tcp_acceptor_shared_ptr sp) { return sp == p.lock(); } ); + }, + [this] (detail::tcp_connector_weak_ptr p) { + std::erase_if(m_connectors, [p] (detail::tcp_connector_shared_ptr sp) { return sp == p.lock(); } ); + }, + [this] (detail::udp_entity_io_weak_ptr p) { + std::erase_if(m_udp_entities, [p] (detail::udp_entity_io_shared_ptr sp) { return sp == p.lock(); } ); + } }, ent.m_wptr); } diff --git a/include/net_ip/simple_variable_len_msg_frame.hpp b/include/net_ip/simple_variable_len_msg_frame.hpp index 2ad15fa5..fa0b0a94 100644 --- a/include/net_ip/simple_variable_len_msg_frame.hpp +++ b/include/net_ip/simple_variable_len_msg_frame.hpp @@ -21,8 +21,6 @@ #include // std::size_t, std::byte -#include "utility/cast_ptr_to.hpp" - namespace chops { namespace net { @@ -68,7 +66,7 @@ class simple_variable_len_msg_frame { std::size_t operator() (asio::mutable_buffer buf) noexcept { if (!m_hdr_processed) { - auto sz = m_hdr_decoder_func(cast_ptr_to(buf.data()), buf.size()); + auto sz = m_hdr_decoder_func(static_cast(buf.data()), buf.size()); m_hdr_processed = (sz != 0u); return sz; } diff --git a/include/net_ip_component/send_to_all.hpp b/include/net_ip_component/send_to_all.hpp index c966b7e7..ef3d8d12 100644 --- a/include/net_ip_component/send_to_all.hpp +++ b/include/net_ip_component/send_to_all.hpp @@ -10,7 +10,7 @@ * * The "send to all but one" functionality added by Thurman in Oct, 2019. * - * Copyright (c) 2019 by Cliff Green, Thurman Gillespy + * Copyright (c) 2019-2025 by Cliff Green, Thurman Gillespy * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -31,8 +31,7 @@ #include "net_ip_component/output_queue_stats.hpp" -#include "utility/erase_where.hpp" -#include "marshall/shared_buffer.hpp" +#include "buffer/shared_buffer.hpp" namespace chops { namespace net { @@ -64,7 +63,7 @@ namespace net { template class send_to_all { private: - using lock_guard = std::lock_guard; + using lock_guard = std::scoped_lock; using io_out = chops::net::basic_io_output; using io_outs = std::vector; using io_interface = chops::net::basic_io_interface; @@ -91,7 +90,7 @@ class send_to_all { */ void remove_io_output(io_out io) { lock_guard gd { m_mutex }; - chops::erase_where(m_io_outs, io); + std::erase_if (m_io_outs, [io] (auto out) { return io == out; } ); } /** diff --git a/include/net_ip_component/worker.hpp b/include/net_ip_component/worker.hpp index 9800f5f9..c28f1f63 100644 --- a/include/net_ip_component/worker.hpp +++ b/include/net_ip_component/worker.hpp @@ -9,7 +9,7 @@ * * @author Cliff Green * - * Copyright (c) 2018 by Cliff Green + * Copyright (c) 2018-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -25,7 +25,7 @@ #include #include "asio/io_context.hpp" -#include "asio/executor.hpp" +#include "asio/any_io_executor.hpp" #include "asio/executor_work_guard.hpp" namespace chops { diff --git a/oldCMakeLists.txt b/oldCMakeLists.txt new file mode 100644 index 00000000..9a159d36 --- /dev/null +++ b/oldCMakeLists.txt @@ -0,0 +1,53 @@ +# Copyright 2019-2020 by Cliff Green +# +# https://github.com/connectivecpp/chops-net-ip +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# CMake 3.8 required for cxx_std_17 target_compile_features + +cmake_minimum_required ( VERSION 3.12 ) + +option ( CHOPS_NET_IP_OPT_BUILD_TESTS "Build and perform chops-net-ip tests" ON ) +option ( CHOPS_NET_IP_OPT_BUILD_EXAMPLES "Build and perform chops-net-ip examples" ON ) +option ( CHOPS_NET_IP_OPT_BUILD_DOCS "Build doxygen documentation" OFF ) + +set ( OPTIONS "" ) +set ( DEFINITIONS "" ) + +project ( chops-net-ip VERSION 1.0 LANGUAGES CXX ) + +set ( package_name "chops-net-ip" ) + +set ( include_source_dir "${CMAKE_SOURCE_DIR}/include" ) +set ( utility_rack_dir "${CMAKE_SOURCE_DIR}/../utility-rack" ) +set ( utility_rack_include_source_dir "${utility_rack_dir}/include" ) +set ( third_party_include_source_dir "${utility_rack_dir}/third_party" ) +set ( cmake_include_dir "${CMAKE_SOURCE_DIR}/cmake" ) +set ( cmake_all_repos_include_dir "${utility_rack_dir}/cmake/all_repos" ) + + +# Interface library: + +add_library ( ${package_name} INTERFACE ) + +target_include_directories ( ${package_name} INTERFACE ${include_source_dir} ) +target_include_directories ( ${package_name} INTERFACE ${third_party_include_source_dir} ) +target_compile_features ( ${package_name} INTERFACE cxx_std_17) + +if ( CHOPS_NET_IP_OPT_BUILD_TESTS ) + enable_testing() + add_subdirectory ( test ) +endif() + +if ( CHOPS_NET_IP_OPT_BUILD_EXAMPLES ) + add_subdirectory ( example ) +endif() + +if ( CHOPS_NET_IP_OPT_BUILD_DOCS ) + add_subdirectory ( doc ) +endif() + +# end of file + diff --git a/oldReadme.md b/oldReadme.md new file mode 100644 index 00000000..78702617 --- /dev/null +++ b/oldReadme.md @@ -0,0 +1,124 @@ +# Chops Net IP - Connective Handcrafted Openwork Software for Asynchronous IP Networking + +Chops Net IP is a C++ library that makes asynchronous networking programming fun. Or at least if not fun, it makes network programming easier and safer, without significantly sacrificing performance. Chops Net IP handles Internet Protocol (IP) communications including TCP, UDP, and UDP multicast. It is written using modern C++ design idioms and the latest (2017) C++ standard. + +Chops Net IP is not like any other high-level, general purpose C++ socket library. + +Chops Net IP is layered on top of the Asio asynchronous networking library, taking advantage of the portability and functionality that Asio provides. However, it simplifies network programming compared to coding against the Asio API, while providing easy scalability through the asynchronous facilities. + +# Build and Release Status, License Info + +**Travis CI Build Status:** + +*Master Branch* | [![Build Status](https://travis-ci.org/connectivecpp/chops-net-ip.svg?branch=master)](https://travis-ci.org/connectivecpp/chops-net-ip) +*Develop Branch* | [![Build Status](https://travis-ci.org/connectivecpp/chops-net-ip.svg?branch=develop)](https://travis-ci.org/connectivecpp/chops-net-ip) + +**GitHub Actions CI Build Status:** + +![CMake Build Matrix](https://github.com/connectivecpp/chops-net-ip/workflows/CMake%20Build%20Matrix/badge.svg) + +**Latest tag:** ![Latest Tag](https://img.shields.io/github/v/tag/connectivecpp/chops-net-ip) + +Release 1.0 is under development as of January 2020, awaiting CMake enhancements, a comprehensive tutorial, and additional testing under multiple compilers and platforms. + +Release notes and upcoming development plans are [available here](doc/release.md). + +This project is distributed under the [Boost Software License](LICENSE.txt): [![Licence](https://img.shields.io/badge/license-boost-4480cc.svg)](http://www.boost.org/LICENSE_1_0.txt) + +# Overview + +For many software developers, asynchronous network programming in C++ is not easy. It is complex, has many pitfalls, and requires designing C++ code in a way that is not natural, even for those with years of experience. Chops Net IP ("C"onnective "H"andcrafted "Op"enwork "S"oftware, Networking over Internet Protocol) simplifies asynchronous network programming and provides useful (and tasty!) abstractions for many types of communication patterns. + +Chops Net IP is layered on top of Chris Kohlhoff's Asio library (see [References](https://connectivecpp.github.io/doc/references.html)) allowing it to be portable across many compilers and platforms. When the C++ Networking TS is standardized (possibly C++ 23 but more likely C++ 26) Chops Net IP will directly use the networking facilities of the C++ standard library. + +Chops Net IP simplifies application code that processes data on multiple simultaneous TCP connections or UDP endpoints. All Chops Net IP operations (from the application viewpoint) are no-wait (i.e. there are no blocking methods) and all network processing operations are performed asynchronously. + +## Tasty Bites + +Chops Net IP functionality: + +- simplifies the creation of various IP (Internet Protocol) networking entities including TCP acceptors and connectors, UDP senders and receivers, and UDP multicast senders and receivers. +- simplifies the resolution of network names to IP addresses (i.e. domain name system lookups). +- abstracts message concepts in TCP (Transmission Control Protocol) and provides customization points in two areas: + 1. message framing, which is the code and logic that determines the begin and end of a message within the TCP byte stream. + 2. message processing, which is the code and logic that processes a message when the framing determines a complete message has arrived. +- provides buffer lifetime management for outgoing data. +- provides customization points for state changes in the networking entities, including: + - a TCP connection has become active and is ready for input and output. + - a UDP endpoint has been created and is ready for input and output. + - a TCP connection has been destroyed or a UDP socket has closed. +- implements the "plumbing" for asynchronous processing on multiple simultaneous connections. +- abstracts many differences between network protocols (TCP, UDP, UDP multicast), allowing easier application transitioning between protocol types. +- allows the application to control threading (no threads are created or managed inside Chops Net IP). +- is agnostic with respect to data marshalling or serialization or "wire protocols" (application code provides any and all data marshalling and endian logic). +- does not impose any structure on network message content. + +Chops Net IP is designed to make it easy and efficient for an application to create hundreds (or thousands) of network connections and handle them simultaneously. In particular, there are no threads or thread pools within Chops Net IP, and it works well with only one application thread invoking the event loop (an executor, in current C++ terminology). + +## Tasty Uses + +Example environments where Chops Net IP is a good fit: + +- Applications that are event driven or highly asynchronous in nature. +- Applications where data is generated and handled in a non-symmetric manner. For example, data may be generated on the TCP acceptor side, or may be generated on a TCP connector side, or on both sides depending on the use case. Similarly, applications where the data flow is bi-directional and sends or receives are data-driven versus pattern-driven work well with this library. +- Applications interacting with multiple (many) connections (e.g. handling multiple sensors or inputs or outputs), each with low to moderate throughput needs (i.e. IoT environments, chat networks, gaming networks). +- Small footprint or embedded environments, where all network processing is run inside a single thread. In particular, environments where a JVM (or similar run-time support) is too costly in terms of system resources, but have a relatively rich operating environment (e.g. Linux running on a small chip) are a very good fit. (Currently the main constraint is small system support in the Asio library implementation.) +- Applications with relatively simple network processing that need an easy-to-use and quick-for-development networking library. +- Applications with configuration driven networks that may need to switch (for example) between TCP connect versus TCP accept for a given connection, or between TCP and UDP for a given communication path. +- Peer-to-peer applications where the application doesn't care which side connects or accepts. +- Frameworks or groups of applications where abstracting wire-protocol logic from message processing logic makes sense. + +## Examples + +Example demo programs are in the [`/example`](https://github.com/connectivecpp/chops-net-ip) directory. + +The `simple_chat_demo.cpp` program has a listing of the multiple steps to set up working example. + +## Want More? + +A detailed overview, a C++ socket library comparison, and a FAQ is [available here](doc/overview.md). + +# C++ Language Requirements and Alternatives + +C++ 17 is the primary baseline for this repository. Additional notes on possible alternatives are [available here](https://connectivecpp.github.io/). + +# External Dependencies + +Production external dependencies: + +- Version 1.13 (or later) of Chris Kohlhoff's [`asio`](https://github.com/chriskohlhoff/asio) library is required. Note that it is the stand-alone Asio library, not the Boost Asio version. +- The [`utility-rack`](https://github.com/connectivecpp/utility-rack) library, which is a repository in the same GitHub account as Chops Net IP. + +Test external dependencies: + +- Version 2.8.0 (or later) of Phil Nash's [`Catch2`](https://github.com/catchorg/Catch2) library is required for all test scenarios. + +There are single file headers that have been copied into the `third_party` directory of the `utility-rack` repository from various GitHub repositories and do not require any external dependency management. These are: + +- Martin Moene's [`expected-lite`](https://github.com/martinmoene/expected-lite) library. + +See [References](https://connectivecpp.github.io/doc/references.html) for additional details. + +# Supported Compilers and Platforms + +Chops Net IP has been compiled and tests run on: + +- g++ 7.2, g++ 7.3, Linux (Ubuntu 17.10 - kernel 4.13, Ubuntu 18.04 - kernel 4.15) +- (TBD, will include at least clang on linux and vc++ on Windows) + +Follow the CI links for additional build environments. + +# Installation + +Chops Net IP is header-only, so installation consists of downloading or cloning and setting compiler include paths appropriately. No compile time configuration macros are defined. + +# References + +See [References](https://connectivecpp.github.io/doc/references.html) for details on dependencies and inspirations for Chops Net IP. + +# About + +Team member information is [available here](https://connectivecpp.github.io/). + +A few "Cliff Notes" are [available here](doc/cliff_notes.md). + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ee73cf10..eb4e1707 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,59 +1,24 @@ -# Copyright 2019-2020 by Cliff Green -# -# https://github.com/connectivecpp/chops-net-ip +# Copyright (c) 2019-2025 by Cliff Green # # Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -cmake_minimum_required ( VERSION 3.12 ) - -project ( chops-net-ip-test VERSION 1.0 LANGUAGES CXX ) +# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt) -include ( "${cmake_all_repos_include_dir}/unit_test_vars.cmake" ) +cmake_minimum_required ( VERSION 3.14 FATAL_ERROR ) -include ( "${cmake_include_dir}/header_dirs_var.cmake" ) -# the following will allow shared_test headers to be picked up by test code -set (header_dirs ${header_dirs} "${CMAKE_SOURCE_DIR}/test" ) +# create project +project ( chops_net_ip_test LANGUAGES CXX ) -set ( test_sources - "${test_source_dir}/shared_test/mock_classes_test.cpp" - "${test_source_dir}/shared_test/msg_handling_test.cpp" - "${test_source_dir}/shared_test/msg_handling_start_funcs_test.cpp" - "${test_source_dir}/shared_test/io_buf_test.cpp" - "${test_source_dir}/net_ip/detail/io_common_test.cpp" - "${test_source_dir}/net_ip/detail/net_entity_common_test.cpp" - "${test_source_dir}/net_ip/detail/output_queue_test.cpp" - "${test_source_dir}/net_ip/detail/tcp_acceptor_test.cpp" - "${test_source_dir}/net_ip/detail/tcp_connector_test.cpp" - "${test_source_dir}/net_ip/detail/tcp_io_test.cpp" - "${test_source_dir}/net_ip/detail/udp_entity_io_test.cpp" - "${test_source_dir}/net_ip/detail/wp_access_test.cpp" - "${test_source_dir}/net_ip_component/error_delivery_test.cpp" - "${test_source_dir}/net_ip_component/io_output_delivery_test.cpp" - "${test_source_dir}/net_ip_component/output_queue_stats_test.cpp" - "${test_source_dir}/net_ip_component/send_to_all_test.cpp" - "${test_source_dir}/net_ip/basic_io_interface_test.cpp" - "${test_source_dir}/net_ip/basic_io_output_test.cpp" - "${test_source_dir}/net_ip/endpoints_resolver_test.cpp" - "${test_source_dir}/net_ip/net_entity_test.cpp" - "${test_source_dir}/net_ip/net_ip_error_test.cpp" - "${test_source_dir}/net_ip/simple_variable_len_msg_frame_test.cpp" - "${test_source_dir}/net_ip/tcp_connector_timeout_test.cpp" - "${test_source_dir}/net_ip/net_ip_test.cpp" ) +# dependencies, Catch2 and Connective C++ +CPMAddPackage ( "gh:connectivecpp/utility-rack@1.0.4" ) +CPMAddPackage ( "gh:connectivecpp/wait-queue@1.2.3" ) +CPMAddPackage ( "gh:connectivecpp/binary-serialize@1.0.4" ) -include ( "${cmake_include_dir}/add_target_dependencies.cmake" ) +CPMAddPackage ( "gh:catchorg/Catch2@3.8.0" ) -include ( "${cmake_all_repos_include_dir}/add_target_info_func.cmake" ) -include ( "${cmake_all_repos_include_dir}/unit_test_main_lib.cmake" ) -include ( "${cmake_all_repos_include_dir}/target_exe_func.cmake" ) +add_subdirectory ( net_ip ) +add_subdirectory ( net_ip_component ) +add_subdirectory ( shared_test ) +add_subdirectory ( test_data_blaster ) enable_testing() -foreach ( test_src IN LISTS test_sources ) - get_filename_component ( targ ${test_src} NAME_WE ) - message ( "Calling unit_test_target_exe for: ${targ}" ) - unit_test_target_exe ( ${targ} ${test_src} ) -endforeach() - -# end of file - diff --git a/test/main_test.cpp b/test/main_test.cpp deleted file mode 100644 index 268b44e9..00000000 --- a/test/main_test.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/** @file - * - * @defgroup test_module Unit tests for the various Chops components. - * - * @ingroup test_module - * - * @brief Source file for combining (i.e. linking) all Chops tests together. - * - * @author Cliff Green - * - * Copyright (c) 2017-2019 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - * - */ - -#define CATCH_CONFIG_MAIN - -#include "catch2/catch.hpp" - diff --git a/test/net_ip/CMakeLists.txt b/test/net_ip/CMakeLists.txt new file mode 100644 index 00000000..6e1c5f72 --- /dev/null +++ b/test/net_ip/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (c) 2024-2025 by Cliff Green +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +cmake_minimum_required ( VERSION 3.14 FATAL_ERROR ) + +# create project +project ( net_ip_test LANGUAGES CXX ) + +add_subdirectory ( detail ) + +set ( test_app_names basic_io_interface_test + basic_io_output_test + endpoints_resolver_test + net_entity_test + net_ip_error_test + net_ip_test + simple_variable_len_msg_frame_test + tcp_connector_timeout_test ) + +include ( ../../cmake/test_app_creation.cmake ) + +enable_testing() + +include ( ../../cmake/test_creation.cmake ) + diff --git a/test/net_ip/basic_io_interface_test.cpp b/test/net_ip/basic_io_interface_test.cpp index 9367f0a5..77ba91ee 100644 --- a/test/net_ip/basic_io_interface_test.cpp +++ b/test/net_ip/basic_io_interface_test.cpp @@ -1,19 +1,17 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c basic_io_interface class template. * - * @brief Test scenarios for @c basic_io_interface class template. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2017-2025 by Cliff Green * - * Copyright (c) 2017-2018 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include // std::shared_ptr #include @@ -194,7 +192,7 @@ void basic_io_interface_test_compare() { } TEST_CASE ( "Basic io interface test, io_handler_mock used for IO handler type", - "[basic_io_interface] [io_handler_mock]" ) { + "[basic_io_interface] [io_handler_mock]" ) { basic_io_interface_test_default_constructed(); basic_io_interface_test_all_start_io(); basic_io_interface_test_other_methods(); diff --git a/test/net_ip/basic_io_output_test.cpp b/test/net_ip/basic_io_output_test.cpp index 0d393e66..7c3377f5 100644 --- a/test/net_ip/basic_io_output_test.cpp +++ b/test/net_ip/basic_io_output_test.cpp @@ -1,30 +1,29 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c basic_io_output class template. * - * @brief Test scenarios for @c basic_io_output class template. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2018-2025 by Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include // std::shared_ptr #include #include // std::size_t +#include #include "net_ip/queue_stats.hpp" #include "net_ip/basic_io_interface.hpp" #include "net_ip/basic_io_output.hpp" -#include "marshall/shared_buffer.hpp" -#include "utility/make_byte_array.hpp" +#include "buffer/shared_buffer.hpp" +#include "utility/byte_array.hpp" #include "shared_test/mock_classes.hpp" @@ -58,7 +57,8 @@ void basic_io_output_test_sends() { REQUIRE ((*s).output_queue_size == chops::test::io_handler_mock::qs_base); REQUIRE ((*s).bytes_in_output_queue == (chops::test::io_handler_mock::qs_base + 1)); - chops::const_shared_buffer buf(nullptr, 0); + std::byte b { 0x0 }; + chops::const_shared_buffer buf(std::span(&b, 0u)); using endp_t = typename IOT::endpoint_type; REQUIRE (io_out.is_valid()); diff --git a/test/net_ip/detail/CMakeLists.txt b/test/net_ip/detail/CMakeLists.txt new file mode 100644 index 00000000..2a505ee7 --- /dev/null +++ b/test/net_ip/detail/CMakeLists.txt @@ -0,0 +1,25 @@ +# Copyright (c) 2024-2025 by Cliff Green +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +cmake_minimum_required ( VERSION 3.14 FATAL_ERROR ) + +# create project +project ( net_ip_detail_test LANGUAGES CXX ) + +set ( test_app_names io_common_test + net_entity_common_test + output_queue_test + tcp_acceptor_test + tcp_connector_test + tcp_io_test + udp_entity_io_test + wp_access_test ) + +include ( ../../../cmake/test_app_creation.cmake ) + +enable_testing() + +include ( ../../../cmake/test_creation.cmake ) + diff --git a/test/net_ip/detail/io_common_test.cpp b/test/net_ip/detail/io_common_test.cpp index 1c35850f..f6b0c54c 100644 --- a/test/net_ip/detail/io_common_test.cpp +++ b/test/net_ip/detail/io_common_test.cpp @@ -1,19 +1,17 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c io_common detail class. * - * @brief Test scenarios for @c io_common detail class. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2017-2025 by Cliff Green * - * Copyright (c) 2017-2019 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include #include @@ -23,12 +21,11 @@ #include #include // std::cref, std::ref #include // std::size_t +#include // std::views::iota #include "net_ip/detail/io_common.hpp" -#include "marshall/shared_buffer.hpp" - -#include "utility/repeat.hpp" +#include "buffer/shared_buffer.hpp" #include "shared_test/io_buf.hpp" @@ -107,14 +104,14 @@ template std::size_t start_writes(const std::vector& data_vec, chops::net::detail::io_common& io_comm, int multiplier, int wait_offset) { - chops::repeat(multiplier, [&data_vec, &io_comm, wait_offset] { - for (const auto& e : data_vec) { - auto r = io_comm.start_write(e, empty_write_func); - assert (r != chops::net::detail::io_common::write_status::io_stopped); - } - std::this_thread::sleep_for(std::chrono::milliseconds(Wait+wait_offset)); - assert (io_comm.is_io_started()); - } ); + for (int i : std::views::iota(0, multiplier)) { + for (const auto& e : data_vec) { + auto r = io_comm.start_write(e, empty_write_func); + assert (r != chops::net::detail::io_common::write_status::io_stopped); + } + std::this_thread::sleep_for(std::chrono::milliseconds(Wait+wait_offset)); + assert (io_comm.is_io_started()); + } return data_vec.size() * multiplier; } @@ -136,11 +133,11 @@ void io_common_stress_test(const std::vector& data_vec, int multiplier, int n std::vector> futs; - chops::repeat(num_thrs, [&iocommon, multiplier, &data_vec, &futs] (int i) { + for (int i : std::views::iota(0, num_thrs)) { futs.push_back(std::async(std::launch::async, start_writes, std::cref(data_vec), std::ref(iocommon), multiplier, 2*i)); - } ); + } std::size_t tot = 0u; for (auto& fut : futs) { @@ -153,10 +150,10 @@ void io_common_stress_test(const std::vector& data_vec, int multiplier, int n futs.clear(); - chops::repeat(num_thrs, [&iocommon, &data_vec, &futs] { + for (int i : std::views::iota(0, num_thrs)) { futs.push_back(std::async(std::launch::async, write_next_elems, std::cref(data_vec), std::ref(iocommon))); - } ); + } for (auto& fut : futs) { tot += fut.get(); // join threads diff --git a/test/net_ip/detail/net_entity_common_test.cpp b/test/net_ip/detail/net_entity_common_test.cpp index 8787faf8..d846ed59 100644 --- a/test/net_ip/detail/net_entity_common_test.cpp +++ b/test/net_ip/detail/net_entity_common_test.cpp @@ -1,19 +1,17 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c net_entity_common detail class. * - * @brief Test scenarios for @c net_entity_common detail class. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2018-2025 by Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include // std::shared_ptr #include // std::error_code diff --git a/test/net_ip/detail/output_queue_test.cpp b/test/net_ip/detail/output_queue_test.cpp index 22bacae6..a42444f1 100644 --- a/test/net_ip/detail/output_queue_test.cpp +++ b/test/net_ip/detail/output_queue_test.cpp @@ -1,28 +1,25 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c output_queue detail class. * - * @brief Test scenarios for @c output_queue detail class. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2017-2025 by Cliff Green * - * Copyright (c) 2017-2018 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include #include +#include // std::views::iota #include "net_ip/detail/output_queue.hpp" -#include "marshall/shared_buffer.hpp" - -#include "utility/repeat.hpp" +#include "buffer/shared_buffer.hpp" #include "shared_test/io_buf.hpp" @@ -30,11 +27,11 @@ template std::size_t add_to_q(const std::vector& data_vec, chops::net::detail::output_queue& outq, int multiplier) { - chops::repeat(multiplier, [&data_vec, &outq] { - for (const auto& i : data_vec) { - outq.add_element(i); - } - } ); + for (int i : std::views::iota(0, multiplier)) { + for (const auto& j : data_vec) { + outq.add_element(j); + } + } return data_vec.size() * multiplier; } @@ -50,12 +47,11 @@ void output_queue_test(const std::vector& data_vec, int multiplier) { REQUIRE (qs.output_queue_size == tot); REQUIRE (qs.bytes_in_output_queue == chops::test::accum_io_buf_size(data_vec) * multiplier); - chops::repeat(static_cast(tot), [&outq] { - auto e = outq.get_next_element(); -// REQUIRE (e); - assert (e); - } - ); + for (int i : std::views::iota(0, static_cast(tot))) { + auto e = outq.get_next_element(); +// REQUIRE (e); + assert (e); + } auto e = outq.get_next_element(); // should be empty optional REQUIRE_FALSE (e); // no element val available qs = outq.get_queue_stats(); diff --git a/test/net_ip/detail/tcp_acceptor_test.cpp b/test/net_ip/detail/tcp_acceptor_test.cpp index f36cefa1..c8dedd3a 100644 --- a/test/net_ip/detail/tcp_acceptor_test.cpp +++ b/test/net_ip/detail/tcp_acceptor_test.cpp @@ -1,24 +1,21 @@ -/** @file +/* + * @brief Test scenarios for @c tcp_acceptor detail class. * - * @ingroup test_module + * This test is similar to the tcp_io_test code, with a little bit less + * internal plumbing, and allowing multiple connector threads to be started. + * The TCP acceptor is the Chops Net IP class, but the connector threads are + * using blocking Asio connects and io. * - * @brief Test scenarios for @c tcp_acceptor detail class. + * @author Cliff Green * - * This test is similar to the tcp_io_test code, with a little bit less - * internal plumbing, and allowing multiple connector threads to be started. - * The TCP acceptor is the Chops Net IP class, but the connector threads are - * using blocking Asio connects and io. + * @copyright (c) 2018-2025 by Cliff Green * - * @author Cliff Green - * - * Copyright (c) 2018-2019 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include "asio/ip/tcp.hpp" #include "asio/write.hpp" @@ -37,6 +34,7 @@ #include // std::ref, std::cref #include #include +#include // std::views::iota #include @@ -51,8 +49,7 @@ #include "shared_test/msg_handling.hpp" #include "shared_test/msg_handling_start_funcs.hpp" -#include "marshall/shared_buffer.hpp" -#include "utility/repeat.hpp" +#include "buffer/shared_buffer.hpp" // #include @@ -86,10 +83,9 @@ std::error_code read_only_func(asio::io_context& ioc) { void start_read_only_funcs (asio::io_context& ioc, int num_conns) { std::vector> conn_futs; - chops::repeat(num_conns, [&ioc, &conn_futs] () { - conn_futs.emplace_back(std::async(std::launch::async, read_only_func, std::ref(ioc))); - } - ); + for (int i : std::views::iota(0, num_conns)) { + conn_futs.emplace_back(std::async(std::launch::async, read_only_func, std::ref(ioc))); + } for (auto& fut : conn_futs) { auto e = fut.get(); // wait for connectors to finish std::cerr << "Read only future popped, err code: " << e.message() << std::endl; @@ -122,11 +118,9 @@ std::size_t start_fixed_data_funcs (asio::io_context& ioc, int num_conns) { std::size_t conn_cnt = 0; std::vector> conn_futs; - chops::repeat(num_conns, [&ioc, &conn_futs] () { - conn_futs.emplace_back(std::async(std::launch::async, fixed_data_func, std::ref(ioc))); - - } - ); + for (int i : std::views::iota(0, num_conns)) { + conn_futs.emplace_back(std::async(std::launch::async, fixed_data_func, std::ref(ioc))); + } for (auto& fut : conn_futs) { conn_cnt += fut.get(); // wait for connectors to finish } @@ -162,12 +156,11 @@ std::size_t start_var_data_funcs (const vec_buf& var_msg_vec, asio::io_context& std::size_t conn_cnt = 0; std::vector> conn_futs; - chops::repeat(num_conns, [&] () { - conn_futs.emplace_back(std::async(std::launch::async, var_data_func, std::cref(var_msg_vec), - std::ref(ioc), reply, interval, empty_msg)); + for (int i : std::views::iota(0, num_conns)) { + conn_futs.emplace_back(std::async(std::launch::async, var_data_func, std::cref(var_msg_vec), + std::ref(ioc), reply, interval, empty_msg)); - } - ); + } for (auto& fut : conn_futs) { conn_cnt += fut.get(); // wait for connectors to finish } @@ -312,7 +305,7 @@ void acceptor_test (const vec_buf& var_msg_vec, const vec_buf& fixed_msg_vec, while (!err_wq.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - err_wq.close(); + err_wq.request_stop(); auto cnt = err_fut.get(); INFO ("Number of messages passed thru error queue: " << cnt); diff --git a/test/net_ip/detail/tcp_connector_test.cpp b/test/net_ip/detail/tcp_connector_test.cpp index d8a4d971..50a7b8fa 100644 --- a/test/net_ip/detail/tcp_connector_test.cpp +++ b/test/net_ip/detail/tcp_connector_test.cpp @@ -9,14 +9,14 @@ * * @author Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green + * Copyright (c) 2018-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include "asio/ip/tcp.hpp" #include "asio/buffer.hpp" @@ -33,6 +33,7 @@ #include #include #include +#include // std::views::iota #include @@ -50,8 +51,7 @@ #include "shared_test/msg_handling.hpp" #include "shared_test/msg_handling_start_funcs.hpp" -#include "marshall/shared_buffer.hpp" -#include "utility/repeat.hpp" +#include "buffer/shared_buffer.hpp" #include "queue/wait_queue.hpp" #include // std::cerr for error sink @@ -81,29 +81,28 @@ std::size_t start_fixed_connectors(int num_conns, std::size_t expected_cnt, std::vector connectors; std::vector> conn_futs; - chops::repeat(num_conns, [&connectors, &conn_futs, &conn_cnt, &err_wq, &ioc, expected_cnt] () { - auto conn_ptr = std::make_shared(ioc, - std::string_view(test_port_fixed), std::string_view(test_host), - chops::net::simple_timeout(tout), false); - - connectors.push_back(conn_ptr); - // promise needs to be copyable since io state chg is stored in std::function - auto prom_ptr = std::make_shared(); - conn_futs.push_back(std::move(prom_ptr->get_future())); - - auto r = conn_ptr->start( [&conn_cnt, expected_cnt, &err_wq, prom_ptr] - (chops::net::tcp_io_interface io, std::size_t num, bool starting) { - if (starting) { - auto r = io.start_io(fixed_size_buf_size, - tcp_fixed_size_msg_hdlr(std::move(*prom_ptr), expected_cnt, conn_cnt)); - assert(r); - } - }, - chops::net::make_error_func_with_wait_queue(err_wq) - ); - assert (!r); - } - ); + for (int i : std::views::iota(0, num_conns)) { + auto conn_ptr = std::make_shared(ioc, + std::string_view(test_port_fixed), std::string_view(test_host), + chops::net::simple_timeout(tout), false); + + connectors.push_back(conn_ptr); + // promise needs to be copyable since io state chg is stored in std::function + auto prom_ptr = std::make_shared(); + conn_futs.push_back(std::move(prom_ptr->get_future())); + + auto r = conn_ptr->start( [&conn_cnt, expected_cnt, &err_wq, prom_ptr] + (chops::net::tcp_io_interface io, std::size_t num, bool starting) { + if (starting) { + auto r = io.start_io(fixed_size_buf_size, + tcp_fixed_size_msg_hdlr(std::move(*prom_ptr), expected_cnt, conn_cnt)); + assert(r); + } + }, + chops::net::make_error_func_with_wait_queue(err_wq) + ); + assert (!r); + } // wait for futures to pop for (auto& fut : conn_futs) { @@ -154,40 +153,37 @@ std::size_t start_var_connectors(const vec_buf& in_msg_vec, { std::vector connectors; - chops::repeat(num_conns, [&connectors, &start_io_wq, &stop_io_wq, - delim, &conn_cnt, &err_wq, &ioc] () { - auto conn_ptr = std::make_shared(ioc, - std::string_view(test_port_var), std::string_view(test_host), - chops::net::simple_timeout(tout), false); - - connectors.push_back(conn_ptr); - - auto r = conn_ptr->start( [&start_io_wq, &stop_io_wq, delim, &conn_cnt, &err_wq] - (chops::net::tcp_io_interface io, std::size_t num, bool starting ) { - if (starting) { - auto r = tcp_start_io(io, false, delim, conn_cnt); - assert(r); - start_io_wq.emplace_push(*(io.make_io_output()), num, starting); - } - else { - stop_io_wq.emplace_push(*(io.make_io_output()), num, starting); - } - }, - chops::net::make_error_func_with_wait_queue(err_wq) - ); - assert (!r); - } - ); + for (int i : std::views::iota(0, num_conns)) { + auto conn_ptr = std::make_shared(ioc, + std::string_view(test_port_var), std::string_view(test_host), + chops::net::simple_timeout(tout), false); + + connectors.push_back(conn_ptr); + + auto r = conn_ptr->start( [&start_io_wq, &stop_io_wq, delim, &conn_cnt, &err_wq] + (chops::net::tcp_io_interface io, std::size_t num, bool starting ) { + if (starting) { + auto r = tcp_start_io(io, false, delim, conn_cnt); + assert(r); + start_io_wq.emplace_push(*(io.make_io_output()), num, starting); + } + else { + stop_io_wq.emplace_push(*(io.make_io_output()), num, starting); + } + }, + chops::net::make_error_func_with_wait_queue(err_wq) + ); + assert (!r); + } // get all of the starting io_output objects std::vector io_outs; - chops::repeat(num_conns, [&start_io_wq, &io_outs] () { - // will hang if num io_outputs popped doesn't match num pushed - auto d = *(start_io_wq.wait_and_pop()); - assert (d.starting); - assert (d.num_handlers == 1u); - io_outs.push_back(d.io_out); - } - ); + for (int i : std::views::iota(0, num_conns)) { + // will hang if num io_outputs popped doesn't match num pushed + auto d = *(start_io_wq.wait_and_pop()); + assert (d.starting); + assert (d.num_handlers == 1u); + io_outs.push_back(d.io_out); + } // send messages through all the connectors for (const auto& buf : in_msg_vec) { for (auto& io : io_outs) { @@ -206,12 +202,11 @@ std::size_t start_var_connectors(const vec_buf& in_msg_vec, poll_output_queue_cond(200, std::cerr)); // wait for disconnect indications - chops::repeat(num_conns, [&stop_io_wq] () { - auto d = *(stop_io_wq.wait_and_pop()); - assert (!d.starting); - assert (d.num_handlers == 0u); - } - ); + for (int i : std::views::iota(0, num_conns)) { + auto d = *(stop_io_wq.wait_and_pop()); + assert (!d.starting); + assert (d.num_handlers == 0u); + } // stop all connectors for (auto& conn : connectors) { conn->stop(); @@ -332,7 +327,7 @@ void perform_test (const vec_buf& in_msg_vec, const vec_buf& fixed_msg_vec, while (!err_wq.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - err_wq.close(); + err_wq.request_stop(); auto err_cnt = err_fut.get(); INFO ("Num err messages passed thru error queue: " << err_cnt); diff --git a/test/net_ip/detail/tcp_io_test.cpp b/test/net_ip/detail/tcp_io_test.cpp index d09a071f..cc17b2d2 100644 --- a/test/net_ip/detail/tcp_io_test.cpp +++ b/test/net_ip/detail/tcp_io_test.cpp @@ -1,19 +1,17 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c tcp_io detail class. * - * @brief Test scenarios for @c tcp_io detail class. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2017-2025 by Cliff Green * - * Copyright (c) 2017-2018 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include "asio/ip/tcp.hpp" #include "asio/connect.hpp" @@ -40,7 +38,7 @@ #include "net_ip/endpoints_resolver.hpp" -#include "marshall/shared_buffer.hpp" +#include "buffer/shared_buffer.hpp" #include diff --git a/test/net_ip/detail/udp_entity_io_test.cpp b/test/net_ip/detail/udp_entity_io_test.cpp index 9ad780b4..c4e7e69c 100644 --- a/test/net_ip/detail/udp_entity_io_test.cpp +++ b/test/net_ip/detail/udp_entity_io_test.cpp @@ -1,24 +1,22 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c udp_entity_io detail class. * - * @brief Test scenarios for @c udp_entity_io detail class. + * This test design is different in a few respects from the tcp_io, tcp_acceptor, + * and tcp_connector tests. In particular, multiple UDP senders are sending to one + * UDP receiver, so an empty message shutdown sequence won't work the same as with + * TCP connections (which are always one-to-one). * - * This test design is different in a few respects from the tcp_io, tcp_acceptor, - * and tcp_connector tests. In particular, multiple UDP senders are sending to one - * UDP receiver, so an empty message shutdown sequence won't work the same as with - * TCP connections (which are always one-to-one). + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2018-2025 by Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include "asio/ip/udp.hpp" #include "asio/io_context.hpp" @@ -34,6 +32,7 @@ #include // std::ref, std::cref #include // std::transform #include // std::back_inserter +#include // std::views::iota #include @@ -49,10 +48,9 @@ #include "shared_test/msg_handling.hpp" #include "shared_test/msg_handling_start_funcs.hpp" -#include "marshall/shared_buffer.hpp" +#include "buffer/shared_buffer.hpp" -#include "utility/repeat.hpp" -#include "utility/make_byte_array.hpp" +#include "utility/byte_array.hpp" #include // std::err for error sink @@ -108,20 +106,19 @@ void start_var_udp_senders(const vec_buf& in_msg_vec, bool reply, int interval, std::vector senders; - chops::repeat(num_senders, [&ioc, &senders, &send_cnt, &err_wq] (int i) { - std::string port_num = std::to_string(test_port_base + i + 1); - auto send_ptr = std::make_shared(ioc, port_num, test_addr); - senders.push_back(send_ptr); - send_ptr->start([&send_cnt] (chops::net::udp_io_interface io, std::size_t, bool starting) { - if (starting) { - auto r = udp_start_io(io, false, send_cnt); - assert (r); - } - }, - chops::net::make_error_func_with_wait_queue(err_wq) - ); - } - ); + for (int i : std::views::iota(0, num_senders)) { + std::string port_num = std::to_string(test_port_base + i + 1); + auto send_ptr = std::make_shared(ioc, port_num, test_addr); + senders.push_back(send_ptr); + send_ptr->start([&send_cnt] (chops::net::udp_io_interface io, std::size_t, bool starting) { + if (starting) { + auto r = udp_start_io(io, false, send_cnt); + assert (r); + } + }, + chops::net::make_error_func_with_wait_queue(err_wq) + ); + } send_data (in_msg_vec, interval, recv_endp, senders, false); } @@ -234,7 +231,7 @@ void udp_test (const vec_buf& in_msg_vec, const vec_buf& fixed_msg_vec, while (!err_wq.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - err_wq.close(); + err_wq.request_stop(); auto cnt = err_fut.get(); INFO ("Number of messages passed thru error queue: " << cnt); diff --git a/test/net_ip/detail/wp_access_test.cpp b/test/net_ip/detail/wp_access_test.cpp index 6f8580d0..fb692dbc 100644 --- a/test/net_ip/detail/wp_access_test.cpp +++ b/test/net_ip/detail/wp_access_test.cpp @@ -1,19 +1,17 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c wp_access and @c wp_access_void function templates. * - * @brief Test scenarios for @c wp_access and @c wp_access_void function templates. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2019-2025 by Cliff Green * - * Copyright (c) 2019 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include // std::shared_ptr, std::weak_ptr #include // std::size_t @@ -24,71 +22,62 @@ #include "net_ip/detail/wp_access.hpp" -SCENARIO ( "Weak pointer access utility functions testing", - "[wp_access]" ) { +using ne_wp = std::weak_ptr; +using ne_sp = std::shared_ptr; - using ne_wp = std::weak_ptr; - using ne_sp = std::shared_ptr; +TEST_CASE ( "Weak pointer access utility functions, empty weak ptr", + "[wp_access]" ) { ne_wp empty_wp; - GIVEN ("An empty weak pointer") { - WHEN ("is_started is called, returning bool") { - THEN ("the return value contains an error") { - auto r = chops::net::detail::wp_access(empty_wp, [] (ne_sp nesp) { return nesp->is_started(); } ); - REQUIRE_FALSE (r); - INFO("Error code: " << r.error()); - } - } - AND_WHEN ("the wp_access_void function is called") { - THEN ("the return value contains an error") { - auto r = chops::net::detail::wp_access_void(empty_wp, [] (ne_sp) { return std::error_code(); } ); - REQUIRE_FALSE (r); - INFO("Error code: " << r.error()); - } - } - } // end given + SECTION ("Check for false when is_started is called on empty weak ptr") { + auto r = chops::net::detail::wp_access(empty_wp, [] (ne_sp nesp) { return nesp->is_started(); } ); + REQUIRE_FALSE (r); + INFO("Error code: " << r.error()); + } + + SECTION ("Check for error code return on wp_access_void") { + auto r = chops::net::detail::wp_access_void(empty_wp, [] (ne_sp) { return std::error_code(); } ); + REQUIRE_FALSE (r); + INFO("Error code: " << r.error()); + } +} +TEST_CASE ("Weak pointer pointing to default constructed net_entity_mock") { auto sp = std::make_shared(); ne_wp wp(sp); - GIVEN ("A weak pointer to a default constructed net_entity_mock") { - WHEN ("is_started is called") { - THEN ("the return value is false") { - auto r = chops::net::detail::wp_access(wp, [] (ne_sp nesp) { return nesp->is_started(); } ); - REQUIRE (r); - REQUIRE_FALSE (*r); - } - } - AND_WHEN ("start is called followed by is_started followed by stop") { - THEN ("all calls succeed") { - auto r1 = chops::net::detail::wp_access_void(wp, - [] (ne_sp nesp) { return nesp->start(chops::test::io_state_chg_mock, chops::test::err_func_mock ); } - ); - REQUIRE (r1); - auto r2 = chops::net::detail::wp_access(wp, [] (ne_sp nesp) { return nesp->is_started(); } ); - REQUIRE (r2); - REQUIRE(*r2); - auto r3 = chops::net::detail::wp_access_void(wp, [] (ne_sp nesp) { return nesp->stop(); } ); - REQUIRE (r3); - auto r4 = chops::net::detail::wp_access(wp, [] (ne_sp nesp) { return nesp->is_started(); } ); - REQUIRE (r4); - REQUIRE_FALSE(*r4); - } - } - AND_WHEN ("visit_io_output is called") { - THEN ("the call succeeds with the correct return value") { - auto r = chops::net::detail::wp_access(wp, - [] (ne_sp nesp) { return nesp->visit_io_output( - [] (chops::net::basic_io_output) { } ); - } - ); - REQUIRE (r); - REQUIRE (*r == 1u); - } - } - } // end given + SECTION ("Calling is_started on mock object should return false") { + auto r = chops::net::detail::wp_access(wp, [] (ne_sp nesp) { return nesp->is_started(); } ); + REQUIRE (r); + REQUIRE_FALSE (*r); + } + SECTION ("Calling start followed by stop should return false for is_started") { + auto r1 = chops::net::detail::wp_access_void(wp, + [] (ne_sp nesp) { return nesp->start(chops::test::io_state_chg_mock, chops::test::err_func_mock ); } + ); + REQUIRE (r1); + auto r2 = chops::net::detail::wp_access(wp, [] (ne_sp nesp) { return nesp->is_started(); } ); + REQUIRE (r2); + REQUIRE(*r2); + auto r3 = chops::net::detail::wp_access_void(wp, [] (ne_sp nesp) { return nesp->stop(); } ); + REQUIRE (r3); + auto r4 = chops::net::detail::wp_access(wp, [] (ne_sp nesp) { return nesp->is_started(); } ); + REQUIRE (r4); + REQUIRE_FALSE(*r4); + } + + SECTION ("When visit_io_output the correct return value should be returned") { + auto r = chops::net::detail::wp_access(wp, + [] (ne_sp nesp) { return nesp->visit_io_output( + [] (chops::net::basic_io_output) { } ); + } + ); + REQUIRE (r); + REQUIRE (*r == 1u); + } } + diff --git a/test/net_ip/endpoints_resolver_test.cpp b/test/net_ip/endpoints_resolver_test.cpp index 952ed26d..c6b12aa7 100644 --- a/test/net_ip/endpoints_resolver_test.cpp +++ b/test/net_ip/endpoints_resolver_test.cpp @@ -1,19 +1,17 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c make_endpoints functions. * - * @brief Test scenarios for @c make_endpoints functions. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2018-2025 by Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include "asio/ip/tcp.hpp" #include "asio/ip/udp.hpp" @@ -40,96 +38,90 @@ void make_endpoints_test (bool local, std::string_view host, std::string_view po chops::net::endpoints_resolver resolver(wk.get_io_context()); - GIVEN ("An executor work guard, host, and port strings") { - WHEN ("sync overload of make_endpoints is called") { - THEN ("a sequence of endpoints is returned or an error returned") { - INFO ("-- Host: " << host); - auto results = resolver.make_endpoints(local, host, port); - if (expected_good) { - REQUIRE(results); - INFO ("-- Num endpoints: " << results->size()); - REQUIRE_FALSE (results->empty()); - } - else { - REQUIRE_FALSE(results); - INFO ("Error code: " << results.error()); - } - } + SECTION ("Sync overload, seq of endpoints returned") { + INFO ("-- Host: " << host); + auto results = resolver.make_endpoints(local, host, port); + if (expected_good) { + REQUIRE(results); + INFO ("-- Num endpoints: " << results->size()); + REQUIRE_FALSE (results->empty()); } - AND_WHEN ("async overload of make_endpoints is called") { - THEN ("a sequence of endpoints is returned through a function object callback") { - - INFO ("-- Host: " << host); - std::promise res_prom; - auto fut = res_prom.get_future(); - resolver.make_endpoints(local, host, port, - [p = std::move(res_prom)] (const std::error_code& err, results_t res) mutable { - p.set_value(prom_ret(err, res)); - } - ); - auto a = fut.get(); - if (expected_good) { - REQUIRE_FALSE(a.first); - INFO ("-- Num endpoints: " << a.second.size()); - REQUIRE_FALSE (a.second.empty()); - } - else { - REQUIRE(a.first); - INFO ("Error val: " << a.first); - REQUIRE (a.second.empty()); - } + else { + REQUIRE_FALSE(results); + INFO ("Error code: " << results.error()); + } + } + SECTION ("Async overload, seq endpoints returned") { + INFO ("-- Host: " << host); + std::promise res_prom; + auto fut = res_prom.get_future(); + resolver.make_endpoints(local, host, port, + [p = std::move(res_prom)] (const std::error_code& err, results_t res) mutable { + p.set_value(prom_ret(err, res)); } + ); + auto a = fut.get(); + if (expected_good) { + REQUIRE_FALSE(a.first); + INFO ("-- Num endpoints: " << a.second.size()); + REQUIRE_FALSE (a.second.empty()); + } + else { + REQUIRE(a.first); + INFO ("Error val: " << a.first); + REQUIRE (a.second.empty()); } - } // end given + } wk.reset(); } -SCENARIO ( "Make endpoints remote test, TCP 1", - "[make_endpoints] [tcp]" ) { +TEST_CASE ( "Make endpoints remote test, TCP 1", + "[make_endpoints] [tcp]" ) { make_endpoints_test (false, "www.cnn.com", "80", true); } -SCENARIO ( "Make endpoints remote test, TCP 2", - "[make_endpoints] [tcp]" ) { +TEST_CASE ( "Make endpoints remote test, TCP 2", + "[make_endpoints] [tcp]" ) { make_endpoints_test (false, "www.seattletimes.com", "80", true); } -SCENARIO ( "Make endpoints local test, TCP 3", - "[make_endpoints] [tcp]" ) { +TEST_CASE ( "Make endpoints local test, TCP 3", + "[make_endpoints] [tcp]" ) { make_endpoints_test (true, "", "23000", true); } -SCENARIO ( "Make endpoints remote test, UDP 1", - "[make_endpoints] [udp]" ) { +TEST_CASE ( "Make endpoints remote test, UDP 1", + "[make_endpoints] [udp]" ) { make_endpoints_test (false, "www.cnn.com", "80", true); } -SCENARIO ( "Make endpoints remote test, UDP 2", - "[make_endpoints] [udp]" ) { +TEST_CASE ( "Make endpoints remote test, UDP 2", + "[make_endpoints] [udp]" ) { make_endpoints_test (false, "www.seattletimes.com", "80", true); } -SCENARIO ( "Make endpoints local test, UDP 3", - "[make_endpoints] [udp]" ) { +TEST_CASE ( "Make endpoints local test, UDP 3", + "[make_endpoints] [udp]" ) { make_endpoints_test (true, "", "23000", true); } /* -SCENARIO ( "Make endpoints remote test, TCP invalid", "[tcp_make_endpoints_invalid]" ) { +TEST_CASE ( "Make endpoints remote test, TCP invalid", + "[tcp_make_endpoints_invalid]" ) { make_endpoints_test (false, "frobozz.blaaaarg", "32555", false); diff --git a/test/net_ip/net_entity_test.cpp b/test/net_ip/net_entity_test.cpp index be5ac066..6a40bcde 100644 --- a/test/net_ip/net_entity_test.cpp +++ b/test/net_ip/net_entity_test.cpp @@ -1,19 +1,17 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c net_entity class. * - * @brief Test scenarios for @c net_entity class. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2018-2025 by Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include // std::shared_ptr #include // std::ref @@ -359,7 +357,7 @@ TEST_CASE ( "Net entity method and comparison testing, UDP entity, TCP acceptor, while (!err_wq.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - err_wq.close(); + err_wq.request_stop(); auto err_cnt = err_fut.get(); INFO ("Num err messages in sink: " << err_cnt); diff --git a/test/net_ip/net_ip_error_test.cpp b/test/net_ip/net_ip_error_test.cpp index 29408760..604b5d82 100644 --- a/test/net_ip/net_ip_error_test.cpp +++ b/test/net_ip/net_ip_error_test.cpp @@ -1,19 +1,17 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c net_ip error and exception code. * - * @brief Test scenarios for @c net_ip error and exception code. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2017-2025 by Cliff Green * - * Copyright (c) 2017-2018 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include @@ -24,29 +22,16 @@ void will_throw() { throw ex; } -SCENARIO ( "Error code and exception test", "[error_code_exception]" ) { - - GIVEN ("A function that throws a net_ip exception") { - WHEN ("The function throws") { - THEN ("an exception is present") { - REQUIRE_THROWS (will_throw()); - } - } - } // end given - - GIVEN ("A function that throws a net_ip exception") { - WHEN ("The function throws") { - THEN ("the exception will contain a custom error message") { - try { - will_throw(); - } - catch (const chops::net::net_ip_exception& e) { - INFO ("Error code message: " << e.err.message()); - REQUIRE(e.err); - } - } - } - } // end given +TEST_CASE ( "Error code and exception test", "[error_code_exception]" ) { + + REQUIRE_THROWS (will_throw()); + try { + will_throw(); + } + catch (const chops::net::net_ip_exception& e) { + INFO ("Error code message: " << e.err.message()); + REQUIRE(e.err); + } } diff --git a/test/net_ip/net_ip_test.cpp b/test/net_ip/net_ip_test.cpp index c153f216..a9b7c876 100644 --- a/test/net_ip/net_ip_test.cpp +++ b/test/net_ip/net_ip_test.cpp @@ -1,19 +1,17 @@ /** @file * - * @ingroup test_module + * @brief Test scenarios for @c net_ip class. * - * @brief Test scenarios for @c net_ip class. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2018-2025 by Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include // std::error_code #include // std::size_t @@ -25,6 +23,7 @@ #include #include #include +#include // std::views::iota #include "net_ip/net_ip.hpp" #include "net_ip/net_entity.hpp" @@ -38,8 +37,7 @@ #include "shared_test/msg_handling.hpp" #include "shared_test/msg_handling_start_funcs.hpp" -#include "marshall/shared_buffer.hpp" -#include "utility/repeat.hpp" +#include "buffer/shared_buffer.hpp" #include // std::cerr for error sink @@ -124,17 +122,16 @@ std::size_t acc_conn_var_test (asio::io_context& ioc, chops::net::err_wait_q& er test_counter conn_cnt = 0; INFO("Acceptor created, now creating connectors and futures, num: " << num_conns); - chops::repeat(num_conns, [&nip, &err_wq, delim, &conn_cnt, &send_vec, &conn_fut_vec] () { + for (int i : std::views::iota(0, num_conns)) { - auto conn = nip.make_tcp_connector(tcp_test_port, tcp_test_host); - auto conn_futs = get_tcp_io_futures(conn, err_wq, - false, delim, conn_cnt); + auto conn = nip.make_tcp_connector(tcp_test_port, tcp_test_host); + auto conn_futs = get_tcp_io_futures(conn, err_wq, + false, delim, conn_cnt); - send_vec.emplace_back(conn_futs.start_fut.get()); // block until connector connects - conn_fut_vec.emplace_back(std::move(conn_futs.stop_fut)); // add disconnect future + send_vec.emplace_back(conn_futs.start_fut.get()); // block until connector connects + conn_fut_vec.emplace_back(std::move(conn_futs.stop_fut)); // add disconnect future - } - ); + } for (const auto& buf : var_msg_vec) { for (auto io : send_vec) { @@ -188,24 +185,24 @@ std::size_t acc_conn_fixed_test (asio::io_context& ioc, chops::net::err_wait_q& test_counter conn_cnt = 0; std::vector> conn_futs; - chops::repeat(num_conns, [&nip, &conn_futs, &conn_cnt, exp = fixed_msg_vec.size(), &err_wq] () { - - auto conn = nip.make_tcp_connector(tcp_test_port, tcp_test_host); - auto prom_ptr = std::make_shared(); - conn_futs.push_back(std::move(prom_ptr->get_future())); - auto r = conn.start( [&conn_cnt, exp, &err_wq, prom_ptr] - (chops::net::tcp_io_interface io, std::size_t num, bool starting) { - if (starting) { - auto r = io.start_io(fixed_size_buf_size, - tcp_fixed_size_msg_hdlr(std::move(*prom_ptr), exp, conn_cnt)); - assert(r); - } - }, - chops::net::make_error_func_with_wait_queue(err_wq) - ); - assert (r); - } - ); + for (int i : std::views::iota(0, num_conns)) { + + auto exp = fixed_msg_vec.size(); + auto conn = nip.make_tcp_connector(tcp_test_port, tcp_test_host); + auto prom_ptr = std::make_shared(); + conn_futs.push_back(std::move(prom_ptr->get_future())); + auto r = conn.start( [&conn_cnt, exp, &err_wq, prom_ptr] + (chops::net::tcp_io_interface io, std::size_t num, bool starting) { + if (starting) { + auto r = io.start_io(fixed_size_buf_size, + tcp_fixed_size_msg_hdlr(std::move(*prom_ptr), exp, conn_cnt)); + assert(r); + } + }, + chops::net::make_error_func_with_wait_queue(err_wq) + ); + assert (r); + } auto n = acc_start_fut.get(); // means all connectors have connected REQUIRE (n == num_conns); @@ -245,21 +242,20 @@ std::size_t udp_test (asio::io_context& ioc, chops::net::err_wait_q& err_wq, std::vector senders; - chops::repeat(num_udp_pairs, [&senders, &err_wq, &recv_cnt, &send_cnt, &nip] (int i) { - auto recv_endp = make_udp_endpoint(udp_test_addr, udp_port_base + i); + for (int i : std::views::iota(0, num_udp_pairs)) { + auto recv_endp = make_udp_endpoint(udp_test_addr, udp_port_base + i); - auto udp_receiver = nip.make_udp_unicast(recv_endp); - auto recv_fut = get_udp_io_future(udp_receiver, err_wq, - false, recv_cnt ); - auto udp_sender = nip.make_udp_sender(); - senders.push_back(udp_sender); + auto udp_receiver = nip.make_udp_unicast(recv_endp); + auto recv_fut = get_udp_io_future(udp_receiver, err_wq, + false, recv_cnt ); + auto udp_sender = nip.make_udp_sender(); + senders.push_back(udp_sender); - auto sender_fut = get_udp_io_future(udp_sender, err_wq, - false, send_cnt, recv_endp ); - recv_fut.get(); // block until receiver ready - sender_fut.get(); // block until sender ready - } - ); + auto sender_fut = get_udp_io_future(udp_sender, err_wq, + false, send_cnt, recv_endp ); + recv_fut.get(); // block until receiver ready + sender_fut.get(); // block until sender ready + } // send messages through all of the senders std::this_thread::sleep_for(std::chrono::milliseconds(10)); @@ -315,7 +311,7 @@ void perform_test (const vec_buf& var_msg_vec, const vec_buf& fixed_msg_vec, while (!err_wq.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - err_wq.close(); + err_wq.request_stop(); auto err_cnt = err_fut.get(); INFO ("Num err messages in sink: " << err_cnt); diff --git a/test/net_ip/simple_variable_len_msg_frame_test.cpp b/test/net_ip/simple_variable_len_msg_frame_test.cpp index 643f1ace..2b8678d5 100644 --- a/test/net_ip/simple_variable_len_msg_frame_test.cpp +++ b/test/net_ip/simple_variable_len_msg_frame_test.cpp @@ -1,49 +1,37 @@ /** @file * - * @ingroup test_module + * @brief Test the simple variable length message framing functor. * - * @brief Test the simple variable length message framing functor. + * @author Cliff Green * - * @author Cliff Green + * @copyright (c) 2019-2025 by Cliff Green * - * Copyright (c) 2019 by Cliff Green - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include "asio/buffer.hpp" -#include "utility/make_byte_array.hpp" +#include "utility/byte_array.hpp" #include "net_ip/simple_variable_len_msg_frame.hpp" #include "shared_test/msg_handling.hpp" -SCENARIO ( "Simple variable length message frame", - "[simple_variable_len_msg_frame]" ) { +TEST_CASE ( "Simple variable length message frame", + "[simple_variable_len_msg_frame]" ) { using namespace chops::test; auto ba = chops::make_byte_array(0x02, 0x01); // 513 in big endian - GIVEN ("A two byte buffer that is a variable len msg header") { - WHEN ("the decode variable len msg hdr function is called") { - THEN ("the correct length is returned") { - REQUIRE(decode_variable_len_msg_hdr(ba.data(), 2) == 513); - } - } - AND_WHEN ("a simple variable len msg frame is constructed") { - asio::mutable_buffer buf(ba.data(), ba.size()); - chops::net::simple_variable_len_msg_frame mf(decode_variable_len_msg_hdr); - THEN ("the returned length toggles between the decoded length and zero") { - REQUIRE(mf(buf) == 513); - REQUIRE(mf(buf) == 0); - REQUIRE(mf(buf) == 513); - REQUIRE(mf(buf) == 0); - } - } - } // end given + REQUIRE(decode_variable_len_msg_hdr(ba.data(), 2) == 513); + asio::mutable_buffer buf(ba.data(), ba.size()); + chops::net::simple_variable_len_msg_frame mf(decode_variable_len_msg_hdr); + REQUIRE(mf(buf) == 513); + REQUIRE(mf(buf) == 0); + REQUIRE(mf(buf) == 513); + REQUIRE(mf(buf) == 0); } diff --git a/test/net_ip/tcp_connector_timeout_test.cpp b/test/net_ip/tcp_connector_timeout_test.cpp index 987e8fb2..3a5eac7d 100644 --- a/test/net_ip/tcp_connector_timeout_test.cpp +++ b/test/net_ip/tcp_connector_timeout_test.cpp @@ -1,19 +1,17 @@ /** @file * - * @ingroup test_module + * @brief Unit tests for classes and functions in tcp_connector_timeout.hpp. * - * @brief Unit tests for classes and functions in tcp_connector_timeout.hpp. + * @author Nathan Deutsch * - * @author Nathan Deutsch + * @copyright (c) 2019-2025 by Cliff Green, Nathan Deutsch * - * Copyright (c) 2019 by Cliff Green, Nathan Deutsch - * - * Distributed under the Boost Software License, Version 1.0. - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * Distributed under the Boost Software License, Version 1.0. + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include "net_ip/tcp_connector_timeout.hpp" using namespace std::chrono_literals; diff --git a/test/net_ip_component/CMakeLists.txt b/test/net_ip_component/CMakeLists.txt new file mode 100644 index 00000000..c7dac5ce --- /dev/null +++ b/test/net_ip_component/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) 2024-2025 by Cliff Green +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +cmake_minimum_required ( VERSION 3.14 FATAL_ERROR ) + +# create project +project ( net_ip_component_test LANGUAGES CXX ) + +set ( test_app_names error_delivery_test + io_output_delivery_test + output_queue_stats_test + send_to_all_test ) + +include ( ../../cmake/test_app_creation.cmake ) + +enable_testing() + +include ( ../../cmake/test_creation.cmake ) + diff --git a/test/net_ip_component/error_delivery_test.cpp b/test/net_ip_component/error_delivery_test.cpp index e1c06f54..267034a4 100644 --- a/test/net_ip_component/error_delivery_test.cpp +++ b/test/net_ip_component/error_delivery_test.cpp @@ -6,14 +6,14 @@ * * @author Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green + * Copyright (c) 2018-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include // std::size_t #include @@ -32,8 +32,8 @@ #include "shared_test/mock_classes.hpp" -SCENARIO ( "Testing ostream_error_sink_with_wait_queue function", - "[error_delivery]" ) { +TEST_CASE ( "Testing ostream_error_sink_with_wait_queue function", + "[error_delivery]" ) { using namespace chops::test; @@ -61,7 +61,7 @@ SCENARIO ( "Testing ostream_error_sink_with_wait_queue function", while (!wq.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - wq.close(); + wq.request_stop(); auto cnt = sink_fut.get(); diff --git a/test/net_ip_component/io_output_delivery_test.cpp b/test/net_ip_component/io_output_delivery_test.cpp index 7b93e1db..93fcebe8 100644 --- a/test/net_ip_component/io_output_delivery_test.cpp +++ b/test/net_ip_component/io_output_delivery_test.cpp @@ -6,14 +6,14 @@ * * @author Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green + * Copyright (c) 2018-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include #include @@ -165,7 +165,7 @@ TEST_CASE ( "Testing make_io_output_future and start_with_io_wait_queue", while (!err_wq.empty()) { std::this_thread::sleep_for(std::chrono::milliseconds(100)); } - err_wq.close(); + err_wq.request_stop(); auto err_cnt = err_fut.get(); INFO ("Num err messages in sink: " << err_cnt); diff --git a/test/net_ip_component/output_queue_stats_test.cpp b/test/net_ip_component/output_queue_stats_test.cpp index 73e40293..df251235 100644 --- a/test/net_ip_component/output_queue_stats_test.cpp +++ b/test/net_ip_component/output_queue_stats_test.cpp @@ -6,14 +6,14 @@ * * @author Cliff Green * - * Copyright (c) 2019 by Cliff Green + * Copyright (c) 2019-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include #include @@ -27,8 +27,8 @@ #include "shared_test/mock_classes.hpp" -SCENARIO ( "Testing accumulate_output_queue_stats for io_output objects", - "[accumulate_output_queue_stats]" ) { +TEST_CASE ( "Testing accumulate_output_queue_stats for io_output objects", + "[accumulate_output_queue_stats]" ) { using namespace chops::test; using io_out_mock = chops::net::basic_io_output; @@ -54,8 +54,8 @@ SCENARIO ( "Testing accumulate_output_queue_stats for io_output objects", } -SCENARIO ( "Testing accumulate_output_queue_stats for net_entity objects", - "[accumulate_net_entity_output_queue_stats]" ) { +TEST_CASE ( "Testing accumulate_output_queue_stats for net_entity objects", + "[accumulate_net_entity_output_queue_stats]" ) { // Not much runtime testing, as of yet, in this scenario, mostly compile time, using default // constructed net_entity objects diff --git a/test/net_ip_component/send_to_all_test.cpp b/test/net_ip_component/send_to_all_test.cpp index 2992d714..361174b6 100644 --- a/test/net_ip_component/send_to_all_test.cpp +++ b/test/net_ip_component/send_to_all_test.cpp @@ -6,14 +6,14 @@ * * @author Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green + * Copyright (c) 2018-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include // std::size_t @@ -22,7 +22,7 @@ #include "net_ip_component/send_to_all.hpp" #include "net_ip/queue_stats.hpp" -#include "marshall/shared_buffer.hpp" +#include "buffer/shared_buffer.hpp" #include "shared_test/mock_classes.hpp" diff --git a/test/oldCMakeLists.txt b/test/oldCMakeLists.txt new file mode 100644 index 00000000..ee73cf10 --- /dev/null +++ b/test/oldCMakeLists.txt @@ -0,0 +1,59 @@ +# Copyright 2019-2020 by Cliff Green +# +# https://github.com/connectivecpp/chops-net-ip +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +cmake_minimum_required ( VERSION 3.12 ) + +project ( chops-net-ip-test VERSION 1.0 LANGUAGES CXX ) + +include ( "${cmake_all_repos_include_dir}/unit_test_vars.cmake" ) + +include ( "${cmake_include_dir}/header_dirs_var.cmake" ) +# the following will allow shared_test headers to be picked up by test code +set (header_dirs ${header_dirs} "${CMAKE_SOURCE_DIR}/test" ) + +set ( test_sources + "${test_source_dir}/shared_test/mock_classes_test.cpp" + "${test_source_dir}/shared_test/msg_handling_test.cpp" + "${test_source_dir}/shared_test/msg_handling_start_funcs_test.cpp" + "${test_source_dir}/shared_test/io_buf_test.cpp" + "${test_source_dir}/net_ip/detail/io_common_test.cpp" + "${test_source_dir}/net_ip/detail/net_entity_common_test.cpp" + "${test_source_dir}/net_ip/detail/output_queue_test.cpp" + "${test_source_dir}/net_ip/detail/tcp_acceptor_test.cpp" + "${test_source_dir}/net_ip/detail/tcp_connector_test.cpp" + "${test_source_dir}/net_ip/detail/tcp_io_test.cpp" + "${test_source_dir}/net_ip/detail/udp_entity_io_test.cpp" + "${test_source_dir}/net_ip/detail/wp_access_test.cpp" + "${test_source_dir}/net_ip_component/error_delivery_test.cpp" + "${test_source_dir}/net_ip_component/io_output_delivery_test.cpp" + "${test_source_dir}/net_ip_component/output_queue_stats_test.cpp" + "${test_source_dir}/net_ip_component/send_to_all_test.cpp" + "${test_source_dir}/net_ip/basic_io_interface_test.cpp" + "${test_source_dir}/net_ip/basic_io_output_test.cpp" + "${test_source_dir}/net_ip/endpoints_resolver_test.cpp" + "${test_source_dir}/net_ip/net_entity_test.cpp" + "${test_source_dir}/net_ip/net_ip_error_test.cpp" + "${test_source_dir}/net_ip/simple_variable_len_msg_frame_test.cpp" + "${test_source_dir}/net_ip/tcp_connector_timeout_test.cpp" + "${test_source_dir}/net_ip/net_ip_test.cpp" ) + +include ( "${cmake_include_dir}/add_target_dependencies.cmake" ) + +include ( "${cmake_all_repos_include_dir}/add_target_info_func.cmake" ) +include ( "${cmake_all_repos_include_dir}/unit_test_main_lib.cmake" ) +include ( "${cmake_all_repos_include_dir}/target_exe_func.cmake" ) + +enable_testing() + +foreach ( test_src IN LISTS test_sources ) + get_filename_component ( targ ${test_src} NAME_WE ) + message ( "Calling unit_test_target_exe for: ${targ}" ) + unit_test_target_exe ( ${targ} ${test_src} ) +endforeach() + +# end of file + diff --git a/test/shared_test/CMakeLists.txt b/test/shared_test/CMakeLists.txt new file mode 100644 index 00000000..13bf375e --- /dev/null +++ b/test/shared_test/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) 2024-2025 by Cliff Green +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +cmake_minimum_required ( VERSION 3.14 FATAL_ERROR ) + +# create project +project ( shared_test LANGUAGES CXX ) + +set ( test_app_names io_buf_test + mock_classes_test + msg_handling_start_funcs_test + msg_handling_test ) + +include ( ../../cmake/test_app_creation.cmake ) + +enable_testing() + +include ( ../../cmake/test_creation.cmake ) + diff --git a/test/shared_test/io_buf.hpp b/test/shared_test/io_buf.hpp index 5c5f5f2e..87ced188 100644 --- a/test/shared_test/io_buf.hpp +++ b/test/shared_test/io_buf.hpp @@ -21,10 +21,8 @@ #include // std::accumulate #include -#include "marshall/shared_buffer.hpp" - -#include "utility/repeat.hpp" -#include "utility/make_byte_array.hpp" +#include "buffer/shared_buffer.hpp" +#include "utility/byte_array.hpp" namespace chops { diff --git a/test/shared_test/io_buf_test.cpp b/test/shared_test/io_buf_test.cpp index feb8d606..174e6168 100644 --- a/test/shared_test/io_buf_test.cpp +++ b/test/shared_test/io_buf_test.cpp @@ -6,14 +6,14 @@ * * @author Cliff Green * - * Copyright (c) 2019 by Cliff Green + * Copyright (c) 2019-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include "shared_test/io_buf.hpp" diff --git a/test/shared_test/mock_classes.hpp b/test/shared_test/mock_classes.hpp index dd27f58f..549a08b8 100644 --- a/test/shared_test/mock_classes.hpp +++ b/test/shared_test/mock_classes.hpp @@ -23,7 +23,7 @@ #include "asio/ip/udp.hpp" // ip::udp::endpoint -#include "marshall/shared_buffer.hpp" +#include "buffer/shared_buffer.hpp" #include "net_ip/basic_io_interface.hpp" #include "net_ip/basic_io_output.hpp" diff --git a/test/shared_test/mock_classes_test.cpp b/test/shared_test/mock_classes_test.cpp index b98845f6..473cd610 100644 --- a/test/shared_test/mock_classes_test.cpp +++ b/test/shared_test/mock_classes_test.cpp @@ -6,14 +6,14 @@ * * @author Cliff Green * - * Copyright (c) 2019 by Cliff Green + * Copyright (c) 2019-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include #include // std::size_t, std::byte @@ -26,8 +26,8 @@ #include "asio/ip/udp.hpp" #include "asio/buffer.hpp" -#include "utility/make_byte_array.hpp" -#include "marshall/shared_buffer.hpp" +#include "utility/byte_array.hpp" +#include "buffer/shared_buffer.hpp" #include "net_ip/simple_variable_len_msg_frame.hpp" @@ -38,8 +38,8 @@ chops::const_shared_buffer make_small_buf() { return chops::const_shared_buffer(ba.data(), ba.size()); } -SCENARIO ( "Mock classes testing, io_handler_mock test", - "[io_handler_mock]" ) { +TEST_CASE ( "Mock classes testing, io_handler_mock test", + "[io_handler_mock]" ) { using namespace chops::test; io_handler_mock io_mock { }; @@ -54,63 +54,37 @@ SCENARIO ( "Mock classes testing, io_handler_mock test", REQUIRE_FALSE (io_mock.send_called); - GIVEN ("A default constructed io_handler_mock") { - WHEN ("is_io_started is called") { - THEN ("the return is false") { - REQUIRE_FALSE (io_mock.is_io_started()); - } - } - AND_WHEN ("visit_socket is called") { - THEN ("the correct value is set") { - io_mock.visit_socket([] (double& d) { d += 2.0; }); - REQUIRE (io_mock.mock_sock == 44.0); - } - } - AND_WHEN ("get_output_queue_stats is called") { - THEN ("the correct value is returned") { - auto qs = io_mock.get_output_queue_stats(); - REQUIRE (qs.output_queue_size == io_mock.qs_base); - REQUIRE (qs.bytes_in_output_queue == (io_mock.qs_base+1)); - } - } - AND_WHEN ("the start_io methods are called") { - THEN ("is_io_started and related flags are true") { - io_mock.start_io(0, [] { }, [] { }); - REQUIRE (io_mock.is_io_started()); - REQUIRE (io_mock.mf_sio_called); - io_mock.start_io(0, [] { }, mock_hdr_decoder_func); - REQUIRE (io_mock.simple_var_len_sio_called); - io_mock.start_io(std::string_view(), [] { }); - REQUIRE (io_mock.delim_sio_called); - io_mock.start_io(0, [] { }); - REQUIRE (io_mock.rd_sio_called); - io_mock.start_io(asio::ip::udp::endpoint(), 0, [] { }); - REQUIRE (io_mock.rd_endp_sio_called); - io_mock.start_io(); - REQUIRE (io_mock.send_sio_called); - io_mock.start_io(asio::ip::udp::endpoint()); - REQUIRE (io_mock.send_endp_sio_called); - } - } - AND_WHEN ("send is called") { - THEN ("the send flag is set true") { - io_mock.send(make_small_buf()); - REQUIRE (io_mock.send_called); - } - } - AND_WHEN ("stop_io is called after start_io") { - THEN ("is_io_started is false") { - io_mock.start_io(std::string_view(), [] { }); - REQUIRE (io_mock.is_io_started()); - io_mock.stop_io(); - REQUIRE_FALSE (io_mock.is_io_started()); - } - } - } // end given + REQUIRE_FALSE (io_mock.is_io_started()); + io_mock.visit_socket([] (double& d) { d += 2.0; }); + REQUIRE (io_mock.mock_sock == 44.0); + auto qs = io_mock.get_output_queue_stats(); + REQUIRE (qs.output_queue_size == io_mock.qs_base); + REQUIRE (qs.bytes_in_output_queue == (io_mock.qs_base+1)); + io_mock.start_io(0, [] { }, [] { }); + REQUIRE (io_mock.is_io_started()); + REQUIRE (io_mock.mf_sio_called); + io_mock.start_io(0, [] { }, mock_hdr_decoder_func); + REQUIRE (io_mock.simple_var_len_sio_called); + io_mock.start_io(std::string_view(), [] { }); + REQUIRE (io_mock.delim_sio_called); + io_mock.start_io(0, [] { }); + REQUIRE (io_mock.rd_sio_called); + io_mock.start_io(asio::ip::udp::endpoint(), 0, [] { }); + REQUIRE (io_mock.rd_endp_sio_called); + io_mock.start_io(); + REQUIRE (io_mock.send_sio_called); + io_mock.start_io(asio::ip::udp::endpoint()); + REQUIRE (io_mock.send_endp_sio_called); + io_mock.send(make_small_buf()); + REQUIRE (io_mock.send_called); + io_mock.start_io(std::string_view(), [] { }); + REQUIRE (io_mock.is_io_started()); + io_mock.stop_io(); + REQUIRE_FALSE (io_mock.is_io_started()); } -SCENARIO ( "Mock classes testing, net_entity_mock test", - "[net_entity_mock]" ) { +TEST_CASE ( "Mock classes testing, net_entity_mock test", + "[net_entity_mock]" ) { using namespace chops::test; net_entity_mock ne_mock { }; @@ -119,60 +93,26 @@ SCENARIO ( "Mock classes testing, net_entity_mock test", REQUIRE (ne_mock.mock_ioh_sp); REQUIRE_FALSE (ne_mock.mock_ioh_sp->send_called); - GIVEN ("A default constructed net_entity_mock") { - WHEN ("is_started is called") { - THEN ("the return is false") { - REQUIRE_FALSE (ne_mock.is_started()); - } - } - AND_WHEN ("visit_socket is called") { - THEN ("the correct value is set") { - ne_mock.visit_socket([] (float& v) { v += 2.0; }); - REQUIRE (ne_mock.mock_sock == 13.0f); - } - } - AND_WHEN ("visit_io_output is called") { - THEN ("the correct flag is set") { - ne_mock.visit_io_output( - [] (io_output_mock ioh) { - ioh.send(make_small_buf()); - } - ); - REQUIRE (ne_mock.mock_ioh_sp->send_called); - } - } - AND_WHEN ("the start method is called") { - THEN ("is_started flag is true") { - auto r = ne_mock.start(io_state_chg_mock, err_func_mock); - REQUIRE_FALSE (r); - REQUIRE (ne_mock.is_started()); - } - } - AND_WHEN ("stop is called after start") { - THEN ("is_started is false") { - auto r1 = ne_mock.start(io_state_chg_mock, err_func_mock); - REQUIRE_FALSE (r1); - auto r2 = ne_mock.stop(); - REQUIRE_FALSE (r2); - REQUIRE_FALSE (ne_mock.is_started()); - } - } - AND_WHEN ("stop is called before start") { - THEN ("an error is returned") { - auto r = ne_mock.stop(); - REQUIRE (r); - INFO ("Error code is: " << r.message()); - } - } - AND_WHEN ("start is called twice") { - THEN ("an error is returned") { - auto r1 = ne_mock.start(io_state_chg_mock, err_func_mock); - REQUIRE_FALSE (r1); - auto r2 = ne_mock.start(io_state_chg_mock, err_func_mock); - REQUIRE (r2); - INFO ("Error code is: " << r2.message()); - } - } - } // end given + REQUIRE_FALSE (ne_mock.is_started()); + ne_mock.visit_socket([] (float& v) { v += 2.0; }); + REQUIRE (ne_mock.mock_sock == 13.0f); + ne_mock.visit_io_output( [] (io_output_mock ioh) { ioh.send(make_small_buf()); }); + REQUIRE (ne_mock.mock_ioh_sp->send_called); + auto r = ne_mock.start(io_state_chg_mock, err_func_mock); + REQUIRE_FALSE (r); + REQUIRE (ne_mock.is_started()); + auto r1 = ne_mock.start(io_state_chg_mock, err_func_mock); + REQUIRE (r1); + auto r2 = ne_mock.stop(); + REQUIRE_FALSE (r2); + REQUIRE_FALSE (ne_mock.is_started()); + r = ne_mock.stop(); + REQUIRE (r); + INFO ("Error code is: " << r.message()); + r1 = ne_mock.start(io_state_chg_mock, err_func_mock); + REQUIRE_FALSE (r1); + r2 = ne_mock.start(io_state_chg_mock, err_func_mock); + REQUIRE (r2); + INFO ("Error code is: " << r2.message()); } diff --git a/test/shared_test/msg_handling.hpp b/test/shared_test/msg_handling.hpp index 824807e1..7b542277 100644 --- a/test/shared_test/msg_handling.hpp +++ b/test/shared_test/msg_handling.hpp @@ -30,7 +30,7 @@ * * @author Cliff Green * - * Copyright (c) 2017-2019 by Cliff Green + * Copyright (c) 2017-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -50,6 +50,7 @@ #include #include #include +#include // std::views::iota #include #include @@ -58,11 +59,10 @@ #include "asio/ip/udp.hpp" // ip::udp::endpoint #include "asio/ip/address.hpp" // make_address -#include "utility/repeat.hpp" -#include "utility/make_byte_array.hpp" +#include "utility/byte_array.hpp" -#include "marshall/extract_append.hpp" -#include "marshall/shared_buffer.hpp" +#include "serialize/extract_append.hpp" +#include "buffer/shared_buffer.hpp" #include "net_ip/basic_io_output.hpp" #include "net_ip/queue_stats.hpp" @@ -72,7 +72,7 @@ namespace test { inline std::size_t decode_variable_len_msg_hdr(const std::byte* buf_ptr, std::size_t sz) { assert (sz == 2u); - return extract_val(buf_ptr); + return extract_val(buf_ptr); } inline chops::mutable_shared_buffer make_body_buf(std::string_view pre, @@ -86,7 +86,7 @@ inline chops::mutable_shared_buffer make_body_buf(std::string_view pre, inline chops::const_shared_buffer make_variable_len_msg(const chops::mutable_shared_buffer& body) { assert(body.size() < std::numeric_limits::max()); std::byte hdr[2]; - auto sz = append_val(hdr, static_cast(body.size())); + auto sz = append_val(hdr, static_cast(body.size())); chops::mutable_shared_buffer msg(hdr, 2); return chops::const_shared_buffer(std::move(msg.append(body.data(), body.size()))); } @@ -117,10 +117,9 @@ using vec_buf = std::vector; template vec_buf make_msg_vec(F&& func, std::string_view pre, char body_char, int num_msgs) { vec_buf vec; - chops::repeat(num_msgs, [&vec, f = std::forward(func), pre, body_char] (int i) { - vec.push_back (f(make_body_buf(pre, body_char, i+1))); - } - ); + for (int i : std::views::iota(0, num_msgs)) { + vec.push_back (func(make_body_buf(pre, body_char, i+1))); + } return vec; } @@ -139,10 +138,9 @@ inline chops::const_shared_buffer make_fixed_size_buf() { inline vec_buf make_fixed_size_msg_vec(int num_msgs) { vec_buf vec; - chops::repeat(num_msgs, [&vec] { - vec.push_back (make_fixed_size_buf()); - } - ); + for (int i : std::views::iota(0, num_msgs)) { + vec.push_back (make_fixed_size_buf()); + } return vec; } diff --git a/test/shared_test/msg_handling_start_funcs_test.cpp b/test/shared_test/msg_handling_start_funcs_test.cpp index ec9b40e2..4c26c61a 100644 --- a/test/shared_test/msg_handling_start_funcs_test.cpp +++ b/test/shared_test/msg_handling_start_funcs_test.cpp @@ -7,14 +7,14 @@ * * @author Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green + * Copyright (c) 2018-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include @@ -33,6 +33,7 @@ TEST_CASE ( "Shared Net IP test utility, msg handling start functions", "[shared_utility] [msg_handling]" ) { using namespace chops::test; + REQUIRE (true); } diff --git a/test/shared_test/msg_handling_test.cpp b/test/shared_test/msg_handling_test.cpp index c3f95559..f4e853be 100644 --- a/test/shared_test/msg_handling_test.cpp +++ b/test/shared_test/msg_handling_test.cpp @@ -12,14 +12,14 @@ * * @author Cliff Green * - * Copyright (c) 2018-2019 by Cliff Green + * Copyright (c) 2018-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include #include // std::size_t, std::byte @@ -29,12 +29,13 @@ #include // std::shared_ptr, std::make_shared #include #include // std::cerr +#include // std::views::iota #include "asio/ip/udp.hpp" #include "asio/buffer.hpp" -#include "utility/make_byte_array.hpp" -#include "marshall/shared_buffer.hpp" +#include "utility/byte_array.hpp" +#include "buffer/shared_buffer.hpp" #include "net_ip/basic_io_output.hpp" #include "net_ip/queue_stats.hpp" @@ -45,81 +46,67 @@ void make_msg_test() { using namespace chops::test; - GIVEN ("A body consisting of a preamble and a char to repeat") { - - auto body = make_body_buf("HappyNewYear!", 'Q', 10); - REQUIRE (body.size() == 23); - - WHEN ("make_variable_len_msg is called") { - auto msg = make_variable_len_msg(body); - THEN ("the correct header is prepended") { - REQUIRE (msg.size() == 25); // full size of msg - REQUIRE (*(msg.data()+0) == std::byte(0x00)); - REQUIRE (*(msg.data()+1) == std::byte(0x17)); // header is 16 bits, value 23 in big endian - REQUIRE (*(msg.data()+2) == std::byte(0x48)); // 'H' in ascii - REQUIRE (*(msg.data()+3) == std::byte(0x61)); // 'a' in ascii - REQUIRE (*(msg.data()+15) == std::byte(0x51)); // 'Q' in ascii - REQUIRE (*(msg.data()+16) == std::byte(0x51)); // 'Q' in ascii - } - } - - AND_WHEN ("make_cr_lf_text_msg is called") { - auto msg = make_cr_lf_text_msg(body); - THEN ("CR and LF are appended") { - REQUIRE (msg.size() == 25); // full size of msg - REQUIRE (*(msg.data()+0) == std::byte(0x48)); // 'H' in ascii - REQUIRE (*(msg.data()+1) == std::byte(0x61)); // 'a' in ascii - REQUIRE (*(msg.data()+13) == std::byte(0x51)); // 'Q' in ascii - REQUIRE (*(msg.data()+14) == std::byte(0x51)); // 'Q' in ascii - REQUIRE (*(msg.data()+23) == std::byte(0x0D)); // CR in ascii - REQUIRE (*(msg.data()+24) == std::byte(0x0A)); // LF in ascii - } - } + auto body = make_body_buf("HappyNewYear!", 'Q', 10); + REQUIRE (body.size() == 23u); + + SECTION ("Call make_variable_len_msg") { + auto msg = make_variable_len_msg(body); + REQUIRE (msg.size() == 25u); // full size of msg + REQUIRE (std::to_integer(*(msg.data()+0)) == 0x00); + REQUIRE (std::to_integer(*(msg.data()+1)) == 0x17); // header is 16 bits, value 23 in big endian + REQUIRE (std::to_integer(*(msg.data()+2)) == 0x48); // 'H' in ascii + REQUIRE (std::to_integer(*(msg.data()+3)) == 0x61); // 'a' in ascii + REQUIRE (std::to_integer(*(msg.data()+15)) == 0x51); // 'Q' in ascii + REQUIRE (std::to_integer(*(msg.data()+16)) == 0x51); // 'Q' in ascii + } - AND_WHEN ("make_lf_text_msg is called") { - auto msg = make_lf_text_msg(body); - THEN ("LF is appended") { - REQUIRE (msg.size() == 24); // full size of msg - REQUIRE (*(msg.data()+0) == std::byte(0x48)); // 'H' in ascii - REQUIRE (*(msg.data()+1) == std::byte(0x61)); // 'a' in ascii - REQUIRE (*(msg.data()+13) == std::byte(0x51)); // 'Q' in ascii - REQUIRE (*(msg.data()+14) == std::byte(0x51)); // 'Q' in ascii - REQUIRE (*(msg.data()+23) == std::byte(0x0A)); // LF in ascii - } - } + SECTION ("Call make_cr_lf_text_msg") { + auto msg = make_cr_lf_text_msg(body); + REQUIRE (msg.size() == 25u); // full size of msg + REQUIRE (std::to_integer(*(msg.data()+0)) == 0x48); // 'H' in ascii + REQUIRE (std::to_integer(*(msg.data()+1)) == 0x61); // 'a' in ascii + REQUIRE (std::to_integer(*(msg.data()+13)) == 0x51); // 'Q' in ascii + REQUIRE (std::to_integer(*(msg.data()+14)) == 0x51); // 'Q' in ascii + REQUIRE (std::to_integer(*(msg.data()+23)) == 0x0D); // CR in ascii + REQUIRE (std::to_integer(*(msg.data()+24)) == 0x0A); // LF in ascii + } - AND_WHEN ("a larger buffer is passed to make_variable_len_msg") { - auto body = make_body_buf("HappyNewYear!", 'Q', 500); - REQUIRE (body.size() == 513); + SECTION ("Call make_lf_text_msg") { + auto msg = make_lf_text_msg(body); + REQUIRE (msg.size() == 24u); // full size of msg + REQUIRE (std::to_integer(*(msg.data()+0)) == 0x48); // 'H' in ascii + REQUIRE (std::to_integer(*(msg.data()+1)) == 0x61); // 'a' in ascii + REQUIRE (std::to_integer(*(msg.data()+13)) == 0x51); // 'Q' in ascii + REQUIRE (std::to_integer(*(msg.data()+14)) == 0x51); // 'Q' in ascii + REQUIRE (std::to_integer(*(msg.data()+23)) == 0x0A); // LF in ascii + } - auto msg = make_variable_len_msg(body); + SECTION ("Call make_variable_len_msg with a larger buf") { + auto big_body = make_body_buf("HappyNewYear!", 'Q', 500); + REQUIRE (big_body.size() == 513u); - THEN ("the correct header is prepended") { - REQUIRE (msg.size() == 515); // full size of msg - REQUIRE (*(msg.data()+0) == std::byte(0x02)); - REQUIRE (*(msg.data()+1) == std::byte(0x01)); // header is 16 bits, value 513 in big endian - } - } + auto msg = make_variable_len_msg(big_body); + REQUIRE (msg.size() == 515u); // full size of msg + REQUIRE (std::to_integer(*(msg.data()+0)) == 0x02); + REQUIRE (std::to_integer(*(msg.data()+1)) == 0x01); // header is 16 bits, value 513 in big endian + } - } // end given } template void make_msg_vec_test(F&& f) { using namespace chops::test; - GIVEN ("A preamble and a char to repeat") { + SECTION ("Msg vector testing with a preamble and a char to repeat") { auto empty = make_empty_body_msg(f); auto delta = empty.size(); - REQUIRE (delta <= 2); - WHEN ("make_msg_vec is called") { - auto vb = make_msg_vec(f, "Good tea!", 'Z', 20); - THEN ("a vector of buffers is returned") { - REQUIRE (vb.size() == 20); - chops::repeat(20, [&vb, delta] (int i) { REQUIRE (vb[i].size() == (i+10+delta)); } ); - } + REQUIRE (delta <= 2u); + auto vb = make_msg_vec(f, "Good tea!", 'Z', 20); + REQUIRE (vb.size() == 20u); + for (int i : std::views::iota(0, 20)) { + REQUIRE (vb[i].size() == (i+10+delta)); } - } // end given + } } template @@ -132,10 +119,10 @@ std::size_t msg_hdlr_stress_test(F&& f, std::string_view pre, char body_char, in auto ioh_sp = std::make_shared(); asio::ip::udp::endpoint endp { }; - test_counter cnt(0); + test_counter cnt{0}; msg_hdlr mh(false, cnt); - int m = 0; + int m {0}; for (auto i : msgs) { auto ret = mh(asio::const_buffer(i.data(), i.size()), io_output_mock(ioh_sp), endp); if (++m % 1000 == 0) { @@ -158,15 +145,15 @@ std::size_t msg_hdlr_stress_test_lf_text_msg(std::string_view pre, char body_cha return msg_hdlr_stress_test(chops::test::make_lf_text_msg, pre, body_char, num_msgs); } -SCENARIO ( "Message handling shared test utility, make msg", - "[msg_handling] [make_msg]" ) { +TEST_CASE ( "Message handling shared test utility, make msg", + "[msg_handling] [make_msg]" ) { make_msg_test(); } -SCENARIO ( "Message handling shared test utility, make msg vec", - "[msg_handling] [make_msg_vec]" ) { +TEST_CASE ( "Message handling shared test utility, make msg vec", + "[msg_handling] [make_msg_vec]" ) { using namespace chops::test; make_msg_vec_test(make_variable_len_msg); @@ -175,8 +162,8 @@ SCENARIO ( "Message handling shared test utility, make msg vec", } -SCENARIO ( "Message handling shared test utility, msg hdlr function object", - "[msg_handling] [msg_hdlr]" ) { +TEST_CASE ( "Message handling shared test utility, msg hdlr function object", + "[msg_handling] [msg_hdlr]" ) { using namespace chops::test; auto ioh_sp = std::make_shared(); @@ -186,57 +173,43 @@ SCENARIO ( "Message handling shared test utility, msg hdlr function object", auto msg = make_variable_len_msg(make_body_buf("Bah, humbug!", 'T', 4)); auto empty = make_empty_variable_len_msg(); - GIVEN ("A mock io handler, a msg with a body, and an empty body msg") { - - WHEN ("a msg hdlr is created with reply true and send is called") { - test_counter cnt(0); - msg_hdlr mh(true, cnt); - THEN ("the shutdown message is handled correctly and count is correct") { - REQUIRE(mh(asio::const_buffer(msg.data(), msg.size()), io_output_mock(ioh_sp), endp)); - REQUIRE(ioh_sp->send_called); - REQUIRE_FALSE(mh(asio::const_buffer(empty.data(), empty.size()), - io_output_mock(ioh_sp), endp)); - REQUIRE(cnt == 1); - } - } - AND_WHEN ("a msg hdlr is created with reply false and send is called") { - test_counter cnt(0); - msg_hdlr mh(false, cnt); - THEN ("the shutdown message is handled correctly and count is correct") { - REQUIRE(mh(asio::const_buffer(msg.data(), msg.size()), io_output_mock(ioh_sp), endp)); - REQUIRE_FALSE(mh(asio::const_buffer(empty.data(), empty.size()), - io_output_mock(ioh_sp), endp)); - REQUIRE(cnt == 1); - } - } - } // end given + SECTION ("Create a msg handler with mock io, reply true when send is called") { + test_counter cnt{0}; + msg_hdlr mh(true, cnt); + REQUIRE(mh(asio::const_buffer(msg.data(), msg.size()), io_output_mock(ioh_sp), endp)); + REQUIRE(ioh_sp->send_called); + REQUIRE_FALSE(mh(asio::const_buffer(empty.data(), empty.size()), + io_output_mock(ioh_sp), endp)); + REQUIRE(cnt == 1); + } + SECTION ("Create a msg hdlr with mock io, reply false and send is called") { + test_counter cnt{0}; + msg_hdlr mh(false, cnt); + REQUIRE(mh(asio::const_buffer(msg.data(), msg.size()), io_output_mock(ioh_sp), endp)); + REQUIRE_FALSE(mh(asio::const_buffer(empty.data(), empty.size()), + io_output_mock(ioh_sp), endp)); + REQUIRE(cnt == 1); + } } -SCENARIO ( "Message handling shared test utility, msg hdlr function object async stress test", - "[msg_handling] [msg_hdlr] [stress]" ) { +TEST_CASE ( "Message handling shared test utility, msg hdlr function object async stress test", + "[msg_handling] [msg_hdlr] [stress]" ) { using namespace chops::test; constexpr int sz1 = 2000; constexpr int sz2 = 3000; constexpr int sz3 = 8000; - GIVEN ("Three types of messages and three large sizes") { - WHEN ("a msg hdlr is created and stress tested in separate async calls") { - auto cnt1 = std::async(std::launch::async, msg_hdlr_stress_test_variable_len_msg, "Async fun var len msg", 'A', sz1); - auto cnt2 = std::async(std::launch::async, msg_hdlr_stress_test_cr_lf_text_msg, "Ha, hilarity cr lf text msg", 'L', sz2); - auto cnt3 = std::async(std::launch::async, msg_hdlr_stress_test_lf_text_msg, "Nom, nom lf text msg", 'M', sz3); - - THEN ("the three return values match") { - REQUIRE(cnt1.get() == sz1); - REQUIRE(cnt2.get() == sz2); - REQUIRE(cnt3.get() == sz3); - } - } - } // end given + auto cnt1 = std::async(std::launch::async, msg_hdlr_stress_test_variable_len_msg, "Async fun var len msg", 'A', sz1); + auto cnt2 = std::async(std::launch::async, msg_hdlr_stress_test_cr_lf_text_msg, "Ha, hilarity cr lf text msg", 'L', sz2); + auto cnt3 = std::async(std::launch::async, msg_hdlr_stress_test_lf_text_msg, "Nom, nom lf text msg", 'M', sz3); + REQUIRE(cnt1.get() == sz1); + REQUIRE(cnt2.get() == sz2); + REQUIRE(cnt3.get() == sz3); } -SCENARIO ( "Message handling shared test utility, output queue stats poll condition", - "[msg_handling] [output_stats_cond]" ) { +TEST_CASE ( "Message handling shared test utility, output queue stats poll condition", + "[msg_handling] [output_stats_cond]" ) { using namespace chops::test; poll_output_queue_cond cond(100, std::cerr); @@ -249,17 +222,17 @@ SCENARIO ( "Message handling shared test utility, output queue stats poll condit } -SCENARIO ( "Message handling shared test utility, fixed size message handling", - "[msg_handling] [fixed_size]" ) { +TEST_CASE ( "Message handling shared test utility, fixed size message handling", + "[msg_handling] [fixed_size]" ) { using namespace chops::test; auto buf = make_fixed_size_buf(); REQUIRE (buf.size() == fixed_size_buf_size); - REQUIRE (*(buf.data()+0) == static_cast(0xDE)); - REQUIRE (*(buf.data()+1) == static_cast(0xAD)); - REQUIRE (*(buf.data()+2) == static_cast(0xBE)); - REQUIRE (*(buf.data()+3) == static_cast(0xEF)); - REQUIRE (*(buf.data()+32) == static_cast(0xCC)); + REQUIRE (std::to_integer(*(buf.data()+0)) == 0xDE); + REQUIRE (std::to_integer(*(buf.data()+1)) == 0xAD); + REQUIRE (std::to_integer(*(buf.data()+2)) == 0xBE); + REQUIRE (std::to_integer(*(buf.data()+3)) == 0xEF); + REQUIRE (std::to_integer(*(buf.data()+32)) == 0xCC); auto vec = make_fixed_size_msg_vec(3); REQUIRE (vec.size() == 3u); @@ -268,33 +241,26 @@ SCENARIO ( "Message handling shared test utility, fixed size message handling", REQUIRE_FALSE(ioh_sp->send_called); asio::ip::udp::endpoint endp { }; - GIVEN ("A mock io handler and a fixed size msg with a body") { - - WHEN ("a fixed size msg hdlr is created and msg hdlr invoked") { - test_counter cnt(0); - test_prom prom1; - test_prom prom2; - auto fut1 = prom1.get_future(); - auto fut2 = prom2.get_future(); - fixed_size_msg_hdlr mh1(std::move(prom1), 5u, cnt); - fixed_size_msg_hdlr mh2(std::move(prom2), 4u, cnt); - THEN ("the count is incremented correctly and promises are satisfied") { - REQUIRE(mh1(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); - REQUIRE(mh1(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); - REQUIRE(mh2(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); - REQUIRE(cnt == 3); - REQUIRE(mh1(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); - REQUIRE(mh2(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); - REQUIRE(cnt == 5); - REQUIRE(mh1(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); - REQUIRE(mh1(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); - REQUIRE(mh2(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); - REQUIRE(mh2(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); - REQUIRE(fut1.get() == 0u); - REQUIRE(fut2.get() == 0u); - REQUIRE(cnt == 9); - } - } - } // end given + test_counter cnt{0}; + test_prom prom1; + test_prom prom2; + auto fut1 { prom1.get_future() }; + auto fut2 { prom2.get_future() }; + fixed_size_msg_hdlr mh1(std::move(prom1), 5u, cnt); + fixed_size_msg_hdlr mh2(std::move(prom2), 4u, cnt); + REQUIRE(mh1(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); + REQUIRE(mh1(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); + REQUIRE(mh2(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); + REQUIRE(cnt == 3); + REQUIRE(mh1(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); + REQUIRE(mh2(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); + REQUIRE(cnt == 5); + REQUIRE(mh1(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); + REQUIRE(mh1(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); + REQUIRE(mh2(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); + REQUIRE(mh2(asio::const_buffer(buf.data(), buf.size()), io_output_mock(ioh_sp), endp)); + REQUIRE(fut1.get() == 0u); + REQUIRE(fut2.get() == 0u); + REQUIRE(cnt == 9); } diff --git a/test/test_data_blaster/CMakeLists.txt b/test/test_data_blaster/CMakeLists.txt new file mode 100644 index 00000000..82b029d8 --- /dev/null +++ b/test/test_data_blaster/CMakeLists.txt @@ -0,0 +1,20 @@ +# Copyright (c) 2024-2025 by Cliff Green +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE.txt or copy at https://www.boost.org/LICENSE_1_0.txt) + +cmake_minimum_required ( VERSION 3.14 FATAL_ERROR ) + +# create project +project ( test_data_blaster LANGUAGES CXX ) + +set ( test_app_names dsr_args_test + monitor_connector_test + monitor_msg_test ) + +include ( ../../cmake/test_app_creation.cmake ) + +enable_testing() + +include ( ../../cmake/test_creation.cmake ) + diff --git a/test/test_data_blaster/README.md b/test/test_data_blaster/README.md index 41705016..d827d4c2 100644 --- a/test/test_data_blaster/README.md +++ b/test/test_data_blaster/README.md @@ -8,7 +8,7 @@ Multiple data sender / receiver (DSR) instances are running at the same time (at A single instance of the monitor (either the C++ or Python version) shows statistics from the DSR instances. The monitor is also responsible for shutting down the DSRs. The same monitor instance can be running for both TCP and UDP DSRs (the log messages sent to the monitor from the DSRs specify whether the test data is being sent over TCP or UDP). -The message definitions between the DSRs and the monitor are text only, so binary endianness is not a factor, and will run on any platform. The data flowing between DSRs is marshalled and unmarshalled as needed by the DSRs. +The message definitions between the DSRs and the monitor are text only, so binary endianness is not a factor, and will run on any platform. The data flowing between DSRs is serialized and deserialized as needed by the DSRs. ## Usage @@ -88,7 +88,7 @@ If the "reply" command line parameter is set, an incoming message is reflected b Degenerate configurations are possible, with infinite message loops or where connection and shutdown timing is not clear. No special coding is in the T-DB to protect for bad configurations. -The DSR internal data messages uses the binary marshalled message format from the `shared_test` facilities (see `msg_handling.hpp` for specific code). The monitor messages are text based messages with all fields in a string format easy to unmarshall for Python applications. +The DSR internal data messages uses the binary serialized message format from the `shared_test` facilities (see `msg_handling.hpp` for specific code). The monitor messages are text based messages with all fields in a string format easy to deserialize for Python applications. The general logic flow: - Process command line arguments diff --git a/test/test_data_blaster/dsr_args_test.cpp b/test/test_data_blaster/dsr_args_test.cpp index 34d9ff05..046b322c 100644 --- a/test/test_data_blaster/dsr_args_test.cpp +++ b/test/test_data_blaster/dsr_args_test.cpp @@ -6,17 +6,18 @@ * * @author (fill in) * - * Copyright (c) 2019 by (fill in) + * Copyright (c) 2019-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include "test_data_blaster/dsr_args.hpp" TEST_CASE("TCP DSR arguments test", "[tcp_dsr_args_test]") { + REQUIRE (true); } diff --git a/test/test_data_blaster/monitor_connector.hpp b/test/test_data_blaster/monitor_connector.hpp index 32662f53..1fce4710 100644 --- a/test/test_data_blaster/monitor_connector.hpp +++ b/test/test_data_blaster/monitor_connector.hpp @@ -2,11 +2,11 @@ * * @ingroup test_module * - * @brief Monitor message marshalling, unmarshalling, sending, and shutdown msg handling. + * @brief Monitor message serializing, deserializing, sending, and shutdown msg handling. * * @author (fill in) * - * Copyright (c) 2019 by Cliff Green, (fill in) + * Copyright (c) 2019-2025 by Cliff Green, (fill in) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -66,4 +66,6 @@ class monitor_connector { }; } -} \ No newline at end of file +} +#endif + diff --git a/test/test_data_blaster/monitor_connector_test.cpp b/test/test_data_blaster/monitor_connector_test.cpp index 84e318f6..87b6b64e 100644 --- a/test/test_data_blaster/monitor_connector_test.cpp +++ b/test/test_data_blaster/monitor_connector_test.cpp @@ -6,16 +6,17 @@ * * @author (fill in) * - * Copyright (c) 2019 by Cliff Green, (fill in) + * Copyright (c) 2019-2025 by Cliff Green, (fill in) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include "test_data_blaster/monitor_connector.hpp" TEST_CASE("monitor connector test", "[monitor_connector_test]") { + REQUIRE (true); } diff --git a/test/test_data_blaster/monitor_msg.hpp b/test/test_data_blaster/monitor_msg.hpp index 601301c2..082c7ad2 100644 --- a/test/test_data_blaster/monitor_msg.hpp +++ b/test/test_data_blaster/monitor_msg.hpp @@ -6,7 +6,7 @@ * * @author (fill in) * - * Copyright (c) 2019 by Cliff Green, (fill in) + * Copyright (c) 2019-2025 by Cliff Green, (fill in) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -56,26 +56,30 @@ struct shutdown_msg { }; -inline chops::const_shared_buffer marshall_monitor_msg_data (const monitor_msg_data& msg_data) { +/* +inline chops::const_shared_buffer serialize_monitor_msg_data (const monitor_msg_data& msg_data) { // work in progress return null; } -inline monitor_msg_data unmarshall_monitor_msg_data (const chops::const_shared_buffer& buf) { +inline monitor_msg_data deserialize_monitor_msg_data (const chops::const_shared_buffer& buf) { // work in progress return null; } -inline chops::const_shared_buffer marshall_shutdown_message() { +inline chops::const_shared_buffer serialize_shutdown_message() { // work in progress return null; } -inline std::string unmarshall_shutdown_message() { +inline std::string deserialize_shutdown_message() { // work in progress return null; } +*/ } -} \ No newline at end of file +} +#endif + diff --git a/test/test_data_blaster/monitor_msg_test.cpp b/test/test_data_blaster/monitor_msg_test.cpp index 5384bad1..6a0266f1 100644 --- a/test/test_data_blaster/monitor_msg_test.cpp +++ b/test/test_data_blaster/monitor_msg_test.cpp @@ -6,16 +6,17 @@ * * @author (fill in) * - * Copyright (c) 2019 by Cliff Green, (fill in) + * Copyright (c) 2019-2025 by Cliff Green, (fill in) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) * */ -#include "catch2/catch.hpp" +#include "catch2/catch_test_macros.hpp" #include "test_data_blaster/monitor_msg.hpp" TEST_CASE("monitor message test", "[monitor_msg_test]") { + REQUIRE (true); } diff --git a/test/test_data_blaster/tcp_dsr.cpp b/test/test_data_blaster/tcp_dsr.cpp index f8f260a3..42830e22 100644 --- a/test/test_data_blaster/tcp_dsr.cpp +++ b/test/test_data_blaster/tcp_dsr.cpp @@ -7,7 +7,7 @@ * * @author Cliff Green * - * Copyright (c) 2019 by Cliff Green + * Copyright (c) 2019-2025 by Cliff Green * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -35,7 +35,7 @@ #include "net_ip_component/error_delivery.hpp" #include "shared_test/msg_handling.hpp" -#include "marshall/shared_buffer.hpp" +#include "buffer/shared_buffer.hpp" #include "test_data_blaster/dsr_args.hpp" #include "test_data_blaster/monitor_msg_handling.hpp"