Compare commits

..

No commits in common. "master" and "v1.8.4" have entirely different histories.

42 changed files with 149 additions and 297 deletions

View File

@ -1,5 +0,0 @@
{
"image": "ghcr.io/fairrootgroup/fairmq-dev/fedora-38:latest",
"features": {
}
}

View File

@ -1,12 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "dev"
schedule:
interval: "monthly"
- package-ecosystem: "gitsubmodule"
directory: "/"
target-branch: "dev"
schedule:
interval: "monthly"

View File

@ -1,29 +0,0 @@
# SPDX-FileCopyrightText: 2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH, Darmstadt, Germany
#
# SPDX-License-Identifier: CC0-1.0
name: Check AUTHORS and CONTRIBUTORS in metadata
on:
push:
paths:
- AUTHORS
- CONTRIBUTORS
- codemeta.json
- .zenodo.json
pull_request:
paths:
- AUTHORS
- CONTRIBUTORS
- codemeta.json
- .zenodo.json
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Try updating metadata
run: python meta_update.py
- name: Check for Updates
run: git diff --exit-code

View File

@ -16,6 +16,6 @@ jobs:
container: container:
image: gitlab-registry.in2p3.fr/escape2020/wp3/eossr:v1.0 image: gitlab-registry.in2p3.fr/escape2020/wp3/eossr:v1.0
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v3
- name: validate codemeta - name: validate codemeta
run: eossr-metadata-validator codemeta.json run: eossr-metadata-validator codemeta.json

View File

@ -1,5 +1,5 @@
################################################################################ ################################################################################
# Copyright (C) 2018-2024 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH # # Copyright (C) 2018-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# # # #
# This software is distributed under the terms of the # # This software is distributed under the terms of the #
# GNU Lesser General Public Licence (LGPL) version 3, # # GNU Lesser General Public Licence (LGPL) version 3, #
@ -8,7 +8,8 @@
# Project ###################################################################### # Project ######################################################################
cmake_minimum_required(VERSION 3.15...3.30 FATAL_ERROR) cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
cmake_policy(VERSION 3.15...3.26)
list(PREPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) list(PREPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
include(GitHelper) include(GitHelper)

10
Jenkinsfile vendored
View File

@ -43,7 +43,7 @@ def jobMatrix(String type, List specs) {
sh "bash ${jobscript}" sh "bash ${jobscript}"
} else { // selector == "slurm" } else { // selector == "slurm"
def imageurl = "oras://ghcr.io/fairrootgroup/fairmq-dev/${os}-${ver}-sif:latest" def imageurl = "oras://ghcr.io/fairrootgroup/fairmq-dev/${os}-${ver}-sif:latest"
def execopts = "--ipc --uts --pid -B/shared" def execopts = "--net --ipc --uts --pid -B/shared"
def containercmd = "singularity exec ${execopts} ${imageurl} bash -l -c \\\"${ctestcmd} ${extra}\\\"" def containercmd = "singularity exec ${execopts} ${imageurl} bash -l -c \\\"${ctestcmd} ${extra}\\\""
sh """\ sh """\
echo \"echo \\\"*** Job started at .......: \\\$(date -R)\\\"\" >> ${jobscript} echo \"echo \\\"*** Job started at .......: \\\$(date -R)\\\"\" >> ${jobscript}
@ -87,18 +87,14 @@ pipeline{
def builds = jobMatrix('build', [ def builds = jobMatrix('build', [
[os: 'ubuntu', ver: '20.04', arch: 'x86_64', compiler: 'gcc-9'], [os: 'ubuntu', ver: '20.04', arch: 'x86_64', compiler: 'gcc-9'],
[os: 'ubuntu', ver: '22.04', arch: 'x86_64', compiler: 'gcc-11'], [os: 'ubuntu', ver: '22.04', arch: 'x86_64', compiler: 'gcc-11'],
[os: 'ubuntu', ver: '24.04', arch: 'x86_64', compiler: 'gcc-13'],
[os: 'fedora', ver: '33', arch: 'x86_64', compiler: 'gcc-10'], [os: 'fedora', ver: '33', arch: 'x86_64', compiler: 'gcc-10'],
[os: 'fedora', ver: '34', arch: 'x86_64', compiler: 'gcc-11'], [os: 'fedora', ver: '34', arch: 'x86_64', compiler: 'gcc-11'],
[os: 'fedora', ver: '35', arch: 'x86_64', compiler: 'gcc-11'], [os: 'fedora', ver: '35', arch: 'x86_64', compiler: 'gcc-11'],
[os: 'fedora', ver: '36', arch: 'x86_64', compiler: 'gcc-12'], [os: 'fedora', ver: '36', arch: 'x86_64', compiler: 'gcc-12'],
[os: 'fedora', ver: '37', arch: 'x86_64', compiler: 'gcc-12'], [os: 'fedora', ver: '37', arch: 'x86_64', compiler: 'gcc-12'],
[os: 'fedora', ver: '38', arch: 'x86_64', compiler: 'gcc-13'], [os: 'fedora', ver: '38', arch: 'x86_64', compiler: 'gcc-13'],
[os: 'fedora', ver: '39', arch: 'x86_64', compiler: 'gcc-13'], [os: 'macos', ver: '12', arch: 'x86_64', compiler: 'apple-clang-14'],
[os: 'fedora', ver: '40', arch: 'x86_64', compiler: 'gcc-14'], [os: 'macos', ver: '13', arch: 'arm64', compiler: 'apple-clang-14'],
[os: 'macos', ver: '14', arch: 'x86_64', compiler: 'apple-clang-16'],
[os: 'macos', ver: '15', arch: 'x86_64', compiler: 'apple-clang-16'],
[os: 'macos', ver: '15', arch: 'arm64', compiler: 'apple-clang-16'],
]) ])
def all_debug = "-DCMAKE_BUILD_TYPE=Debug" def all_debug = "-DCMAKE_BUILD_TYPE=Debug"

View File

@ -45,9 +45,9 @@ Recommended:
```bash ```bash
git clone https://github.com/FairRootGroup/FairMQ fairmq_source git clone https://github.com/FairRootGroup/FairMQ fairmq_source
cmake -S fairmq_source -B fairmq_build -GNinja -DCMAKE_BUILD_TYPE=Release [-DBUILD_TESTING=ON] cmake -S fairmq_source -B fairmq_build -GNinja -DCMAKE_BUILD_TYPE=Release
cmake --build fairmq_build cmake --build fairmq_build
[ctest --test-dir fairmq_build --output-on-failure --schedule-random -j<ncpus>] # needs -DBUILD_TESTING=ON ctest --test-dir fairmq_build --output-on-failure --schedule-random -j<ncpus>
cmake --install fairmq_build --prefix $(pwd)/fairmq_install cmake --install fairmq_build --prefix $(pwd)/fairmq_install
``` ```
@ -56,24 +56,6 @@ Please consult the [manpages of your CMake version](https://cmake.org/cmake/help
If dependencies are not installed in standard system directories, you can hint the installation location via If dependencies are not installed in standard system directories, you can hint the installation location via
`-DCMAKE_PREFIX_PATH=...` or per dependency via `-D{DEPENDENCY}_ROOT=...` (`*_ROOT` variables can also be environment variables). `-DCMAKE_PREFIX_PATH=...` or per dependency via `-D{DEPENDENCY}_ROOT=...` (`*_ROOT` variables can also be environment variables).
## Installation via Spack
Prerequisite: [Spack](https://spack.readthedocs.io/en/latest/getting_started.html)
```bash
spack info fairmq # inspect build options
spack install fairmq # build latest packaged version with default options
```
Build FairMQ's dependencies via Spack for development:
```bash
git clone -b dev https://github.com/FairRootGroup/FairMQ fairmq_source
spack --env fairmq_source install # installs deps declared in fairmq_source/spack.yaml
spack env activate fairmq_source # sets $CMAKE_PREFIX_PATH which is used by CMake to find FairMQ's deps
cmake -S fairmq_source -B fairmq_build -GNinja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON
# develop, compile, test
spack env deactivate # at end of dev session, or simply close the shell
```
## Usage ## Usage

View File

@ -1,5 +1,5 @@
################################################################################ ################################################################################
# Copyright (C) 2018-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH # # Copyright (C) 2018-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# # # #
# This software is distributed under the terms of the # # This software is distributed under the terms of the #
# GNU Lesser General Public Licence (LGPL) version 3, # # GNU Lesser General Public Licence (LGPL) version 3, #
@ -41,7 +41,7 @@ if(BUILD_TESTING)
endif() endif()
find_package2(BUNDLED GTest REQUIRED) find_package2(BUNDLED GTest REQUIRED)
if(GTest_BUNDLED) if(GTest_BUNDLED)
set(GTest_VERSION "Dec 26 2024 @7d76a23") set(GTest_VERSION "Apr 8 2022 @a1cc8c55")
set(GTest_PREFIX "<bundled>") set(GTest_PREFIX "<bundled>")
endif() endif()
endif() endif()

View File

@ -11,7 +11,7 @@ SAMPLER+=" --id sampler1"
SAMPLER+=" --severity debug" SAMPLER+=" --severity debug"
SAMPLER+=" --msg-size $msgSize" SAMPLER+=" --msg-size $msgSize"
SAMPLER+=" --transport $transport" SAMPLER+=" --transport $transport"
#SAMPLER+=" --rc-segment-size 0" SAMPLER+=" --rc-segment-size 0"
SAMPLER+=" --shm-monitor true" SAMPLER+=" --shm-monitor true"
SAMPLER+=" --chan-name data1" SAMPLER+=" --chan-name data1"
SAMPLER+=" --channel-config name=data1,type=push,method=bind,address=tcp://127.0.0.1:7777" SAMPLER+=" --channel-config name=data1,type=push,method=bind,address=tcp://127.0.0.1:7777"

2
extern/googletest vendored

@ -1 +1 @@
Subproject commit 7d76a231b0e29caf86e68d1df858308cd53b2a66 Subproject commit a1cc8c55195661a58ad60c3bb062a0b9c302710d

View File

@ -1,5 +1,5 @@
################################################################################ ################################################################################
# Copyright (C) 2012-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH # # Copyright (C) 2012-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH #
# # # #
# This software is distributed under the terms of the # # This software is distributed under the terms of the #
# GNU Lesser General Public Licence (LGPL) version 3, # # GNU Lesser General Public Licence (LGPL) version 3, #
@ -63,21 +63,14 @@ if(BUILD_FAIRMQ)
Tools.h Tools.h
TransportFactory.h TransportFactory.h
Transports.h Transports.h
TransportEnum.h
UnmanagedRegion.h UnmanagedRegion.h
options/FairMQProgOptions.h options/FairMQProgOptions.h
runDevice.h runDevice.h
runFairMQDevice.h runFairMQDevice.h
shmem/Common.h shmem/Common.h
shmem/Manager.h
shmem/Message.h
shmem/Monitor.h shmem/Monitor.h
shmem/Poller.h
shmem/Segment.h shmem/Segment.h
shmem/Socket.h
shmem/TransportFactory.h
shmem/UnmanagedRegion.h shmem/UnmanagedRegion.h
shmem/UnmanagedRegionImpl.h
tools/Compiler.h tools/Compiler.h
tools/CppSTL.h tools/CppSTL.h
tools/Exceptions.h tools/Exceptions.h
@ -102,6 +95,12 @@ if(BUILD_FAIRMQ)
plugins/Builtin.h plugins/Builtin.h
plugins/config/Config.h plugins/config/Config.h
plugins/control/Control.h plugins/control/Control.h
shmem/Message.h
shmem/Poller.h
shmem/UnmanagedRegionImpl.h
shmem/Socket.h
shmem/TransportFactory.h
shmem/Manager.h
zeromq/Common.h zeromq/Common.h
zeromq/Context.h zeromq/Context.h
zeromq/Message.h zeromq/Message.h
@ -119,7 +118,6 @@ if(BUILD_FAIRMQ)
Channel.cxx Channel.cxx
Device.cxx Device.cxx
DeviceRunner.cxx DeviceRunner.cxx
EventManager.cxx
JSONParser.cxx JSONParser.cxx
MemoryResources.cxx MemoryResources.cxx
Plugin.cxx Plugin.cxx

View File

@ -12,7 +12,6 @@
#include <fairmq/Channel.h> #include <fairmq/Channel.h>
#include <fairmq/Properties.h> #include <fairmq/Properties.h>
#include <fairmq/Tools.h> #include <fairmq/Tools.h>
#include <fairmq/Transports.h>
#include <random> #include <random>
#include <regex> #include <regex>
#include <set> #include <set>
@ -384,10 +383,4 @@ bool Channel::BindEndpoint(string& endpoint)
} }
} }
std::string Channel::GetTransportName() const { return TransportName(fTransportType); }
Transport Channel::GetTransportType() const { return fTransportType; }
void Channel::UpdateTransport(const std::string& transport) { fTransportType = TransportType(transport); Invalidate(); }
} // namespace fair::mq } // namespace fair::mq

View File

@ -14,7 +14,7 @@
#include <fairmq/Properties.h> #include <fairmq/Properties.h>
#include <fairmq/Socket.h> #include <fairmq/Socket.h>
#include <fairmq/TransportFactory.h> #include <fairmq/TransportFactory.h>
#include <fairmq/TransportEnum.h> #include <fairmq/Transports.h>
#include <fairmq/UnmanagedRegion.h> #include <fairmq/UnmanagedRegion.h>
#include <cstdint> // int64_t #include <cstdint> // int64_t
@ -145,11 +145,11 @@ class Channel
/// Get channel transport name ("default", "zeromq" or "shmem") /// Get channel transport name ("default", "zeromq" or "shmem")
/// @return Returns channel transport name (e.g. "default", "zeromq" or "shmem") /// @return Returns channel transport name (e.g. "default", "zeromq" or "shmem")
std::string GetTransportName() const; std::string GetTransportName() const { return TransportName(fTransportType); }
/// Get channel transport type /// Get channel transport type
/// @return Returns channel transport type /// @return Returns channel transport type
mq::Transport GetTransportType() const; mq::Transport GetTransportType() const { return fTransportType; }
/// Get socket send buffer size (in number of messages) /// Get socket send buffer size (in number of messages)
/// @return Returns socket send buffer size (in number of messages) /// @return Returns socket send buffer size (in number of messages)
@ -221,7 +221,7 @@ class Channel
/// Set channel transport /// Set channel transport
/// @param transport transport string ("default", "zeromq" or "shmem") /// @param transport transport string ("default", "zeromq" or "shmem")
void UpdateTransport(const std::string& transport); void UpdateTransport(const std::string& transport) { fTransportType = TransportType(transport); Invalidate(); }
/// Set socket send buffer size /// Set socket send buffer size
/// @param sndBufSize Socket send buffer size (in number of messages) /// @param sndBufSize Socket send buffer size (in number of messages)
@ -438,7 +438,7 @@ class Channel
} }
void CheckSendCompatibility(Parts& parts) { CheckSendCompatibility(parts.fParts); } void CheckSendCompatibility(Parts& parts) { CheckSendCompatibility(parts.fParts); }
void CheckSendCompatibility(Parts::container & msgVec) void CheckSendCompatibility(std::vector<MessagePtr>& msgVec)
{ {
for (auto& msg : msgVec) { for (auto& msg : msgVec) {
if (fTransportType != msg->GetType()) { if (fTransportType != msg->GetType()) {
@ -468,7 +468,7 @@ class Channel
} }
void CheckReceiveCompatibility(Parts& parts) { CheckReceiveCompatibility(parts.fParts); } void CheckReceiveCompatibility(Parts& parts) { CheckReceiveCompatibility(parts.fParts); }
void CheckReceiveCompatibility(Parts::container& msgVec) void CheckReceiveCompatibility(std::vector<MessagePtr>& msgVec)
{ {
for (auto& msg : msgVec) { for (auto& msg : msgVec) {
if (fTransportType != msg->GetType()) { if (fTransportType != msg->GetType()) {

View File

@ -9,7 +9,6 @@
// FairMQ // FairMQ
#include <fairmq/Device.h> #include <fairmq/Device.h>
#include <fairmq/Tools.h> #include <fairmq/Tools.h>
#include <fairmq/Transports.h>
// boost // boost
#include <boost/algorithm/string.hpp> // join/split #include <boost/algorithm/string.hpp> // join/split

View File

@ -19,7 +19,7 @@
#include <fairmq/StateQueue.h> #include <fairmq/StateQueue.h>
#include <fairmq/Tools.h> #include <fairmq/Tools.h>
#include <fairmq/TransportFactory.h> #include <fairmq/TransportFactory.h>
#include <fairmq/TransportEnum.h> #include <fairmq/Transports.h>
#include <fairmq/UnmanagedRegion.h> #include <fairmq/UnmanagedRegion.h>
// logger // logger

View File

@ -1,20 +0,0 @@
/********************************************************************************
* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#include "EventManager.h"
#include <string>
#include <typeindex>
template std::shared_ptr<
fair::mq::EventManager::Signal<fair::mq::PropertyChangeAsString, std::string>>
fair::mq::EventManager::GetSignal<fair::mq::PropertyChangeAsString, std::string>(
const std::pair<std::type_index, std::type_index>& key) const;
template void fair::mq::EventManager::Subscribe<fair::mq::PropertyChangeAsString, std::string>(
const std::string& subscriber,
std::function<void(typename fair::mq::PropertyChangeAsString::KeyType, std::string)>);

View File

@ -1,5 +1,5 @@
/******************************************************************************** /********************************************************************************
* Copyright (C) 2014-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * Copyright (C) 2014-2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* * * *
* This software is distributed under the terms of the * * This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, * * GNU Lesser General Public Licence (LGPL) version 3, *
@ -57,8 +57,27 @@ class EventManager
template<typename E, typename ...Args> template<typename E, typename ...Args>
using Signal = boost::signals2::signal<void(typename E::KeyType, Args...)>; using Signal = boost::signals2::signal<void(typename E::KeyType, Args...)>;
template<typename E, typename... Args> template<typename E, typename ...Args>
auto Subscribe(const std::string& subscriber, std::function<void(typename E::KeyType, Args...)> callback) -> void; auto Subscribe(const std::string& subscriber, std::function<void(typename E::KeyType, Args...)> callback) -> void
{
const std::type_index event_type_index{typeid(E)};
const std::type_index callback_type_index{typeid(std::function<void(typename E::KeyType, Args...)>)};
const auto signalsKey = std::make_pair(event_type_index, callback_type_index);
const auto connectionsKey = std::make_pair(subscriber, signalsKey);
const auto connection = GetSignal<E, Args...>(signalsKey)->connect(callback);
{
std::lock_guard<std::mutex> lock{fMutex};
if (fConnections.find(connectionsKey) != fConnections.end())
{
fConnections.at(connectionsKey).disconnect();
fConnections.erase(connectionsKey);
}
fConnections.insert({connectionsKey, connection});
}
}
template<typename E, typename ...Args> template<typename E, typename ...Args>
auto Unsubscribe(const std::string& subscriber) -> void auto Unsubscribe(const std::string& subscriber) -> void
@ -100,58 +119,21 @@ class EventManager
mutable std::mutex fMutex; mutable std::mutex fMutex;
template<typename E, typename ...Args> template<typename E, typename ...Args>
auto GetSignal(const SignalsKey& key) const -> std::shared_ptr<Signal<E, Args...>>; auto GetSignal(const SignalsKey& key) const -> std::shared_ptr<Signal<E, Args...>>
}; /* class EventManager */
struct PropertyChangeAsString : Event<std::string> {};
template<typename E, typename... Args>
auto EventManager::GetSignal(const SignalsKey& key) const -> std::shared_ptr<Signal<E, Args...>>
{
std::lock_guard<std::mutex> lock{fMutex};
if (fSignals.find(key) == fSignals.end()) {
// wrapper is needed because boost::signals2::signal is neither copyable nor movable
// and I don't know how else to insert it into the map
auto signal = std::make_shared<Signal<E, Args...>>();
fSignals.insert(std::make_pair(key, signal));
}
return boost::any_cast<std::shared_ptr<Signal<E, Args...>>>(fSignals.at(key));
}
template<typename E, typename... Args>
auto EventManager::Subscribe(const std::string& subscriber,
std::function<void(typename E::KeyType, Args...)> callback) -> void
{
const std::type_index event_type_index{typeid(E)};
const std::type_index callback_type_index{
typeid(std::function<void(typename E::KeyType, Args...)>)};
const auto signalsKey = std::make_pair(event_type_index, callback_type_index);
const auto connectionsKey = std::make_pair(subscriber, signalsKey);
const auto connection = GetSignal<E, Args...>(signalsKey)->connect(callback);
{ {
std::lock_guard<std::mutex> lock{fMutex}; std::lock_guard<std::mutex> lock{fMutex};
if (fConnections.find(connectionsKey) != fConnections.end()) { if (fSignals.find(key) == fSignals.end())
fConnections.at(connectionsKey).disconnect(); {
fConnections.erase(connectionsKey); // wrapper is needed because boost::signals2::signal is neither copyable nor movable
// and I don't know how else to insert it into the map
auto signal = std::make_shared<Signal<E, Args...>>();
fSignals.insert(std::make_pair(key, signal));
} }
fConnections.insert({connectionsKey, connection});
return boost::any_cast<std::shared_ptr<Signal<E, Args...>>>(fSignals.at(key));
} }
} }; /* class EventManager */
extern template std::shared_ptr<
fair::mq::EventManager::Signal<fair::mq::PropertyChangeAsString, std::string>>
fair::mq::EventManager::GetSignal<fair::mq::PropertyChangeAsString, std::string>(
const std::pair<std::type_index, std::type_index>& key) const;
extern template void
fair::mq::EventManager::Subscribe<fair::mq::PropertyChangeAsString, std::string>(
const std::string& subscriber,
std::function<void(typename fair::mq::PropertyChangeAsString::KeyType, std::string)>);
} // namespace fair::mq } // namespace fair::mq

View File

@ -17,7 +17,7 @@
#include <boost/container/container_fwd.hpp> #include <boost/container/container_fwd.hpp>
#include <boost/container/flat_map.hpp> #include <boost/container/flat_map.hpp>
#include <memory_resource> #include <boost/container/pmr/memory_resource.hpp>
#include <cstring> #include <cstring>
#include <fairmq/Message.h> #include <fairmq/Message.h>
#include <stdexcept> #include <stdexcept>
@ -27,7 +27,7 @@ namespace fair::mq {
class TransportFactory; class TransportFactory;
using byte = unsigned char; using byte = unsigned char;
namespace pmr = std::pmr; namespace pmr = boost::container::pmr;
/// All FairMQ related memory resources need to inherit from this interface /// All FairMQ related memory resources need to inherit from this interface
/// class for the /// class for the

View File

@ -10,7 +10,7 @@
#define FAIR_MQ_MESSAGE_H #define FAIR_MQ_MESSAGE_H
#include <cstddef> // for size_t #include <cstddef> // for size_t
#include <fairmq/TransportEnum.h> #include <fairmq/Transports.h>
#include <memory> // unique_ptr #include <memory> // unique_ptr
#include <stdexcept> #include <stdexcept>

View File

@ -448,6 +448,3 @@ void ProgOptions::PrintOptionsRaw() const
} }
} // namespace fair::mq } // namespace fair::mq
template void fair::mq::ProgOptions::SetProperty<std::string>(const std::string& key, std::string val);
template void fair::mq::ProgOptions::SetProperty<int>(const std::string& key, int val);

View File

@ -129,7 +129,17 @@ class ProgOptions
/// @param key /// @param key
/// @param val /// @param val
template<typename T> template<typename T>
void SetProperty(const std::string& key, T val); void SetProperty(const std::string& key, T val)
{
std::unique_lock<std::mutex> lock(fMtx);
SetVarMapValue<typename std::decay<T>::type>(key, val);
lock.unlock();
fEvents.Emit<fair::mq::PropertyChange, typename std::decay<T>::type>(key, val);
fEvents.Emit<fair::mq::PropertyChangeAsString, std::string>(key, GetPropertyAsString(key));
}
/// @brief Updates an existing config property (or fails if it doesn't exist) /// @brief Updates an existing config property (or fails if it doesn't exist)
/// @param key /// @param key
@ -265,20 +275,5 @@ class ProgOptions
}; };
} // namespace fair::mq } // namespace fair::mq
template <typename T>
void fair::mq::ProgOptions::SetProperty(const std::string& key, T val)
{
std::unique_lock<std::mutex> lock(fMtx);
SetVarMapValue<typename std::decay<T>::type>(key, val);
lock.unlock();
fEvents.Emit<fair::mq::PropertyChange, typename std::decay<T>::type>(key, val);
fEvents.Emit<fair::mq::PropertyChangeAsString, std::string>(key, GetPropertyAsString(key));
}
extern template void fair::mq::ProgOptions::SetProperty<int>(const std::string& key, int val);
extern template void fair::mq::ProgOptions::SetProperty<std::string>(const std::string& key, std::string val);
#endif /* FAIR_MQ_PROGOPTIONS_H */ #endif /* FAIR_MQ_PROGOPTIONS_H */

View File

@ -1,5 +1,5 @@
/******************************************************************************** /********************************************************************************
* Copyright (C) 2014-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * Copyright (C) 2014-2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* * * *
* This software is distributed under the terms of the * * This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, * * GNU Lesser General Public Licence (LGPL) version 3, *
@ -29,6 +29,7 @@ using Property = boost::any;
using Properties = std::map<std::string, Property>; using Properties = std::map<std::string, Property>;
struct PropertyChange : Event<std::string> {}; struct PropertyChange : Event<std::string> {};
struct PropertyChangeAsString : Event<std::string> {};
class PropertyHelper class PropertyHelper
{ {

View File

@ -52,8 +52,8 @@ struct Socket
virtual int64_t Send(MessagePtr& msg, int timeout = -1) = 0; virtual int64_t Send(MessagePtr& msg, int timeout = -1) = 0;
virtual int64_t Receive(MessagePtr& msg, int timeout = -1) = 0; virtual int64_t Receive(MessagePtr& msg, int timeout = -1) = 0;
virtual int64_t Send(Parts::container& msgVec, int timeout = -1) = 0; virtual int64_t Send(std::vector<std::unique_ptr<Message>>& msgVec, int timeout = -1) = 0;
virtual int64_t Receive(Parts::container & msgVec, int timeout = -1) = 0; virtual int64_t Receive(std::vector<std::unique_ptr<Message>>& msgVec, int timeout = -1) = 0;
virtual int64_t Send(Parts& parts, int timeout = -1) { return Send(parts.fParts, timeout); } virtual int64_t Send(Parts& parts, int timeout = -1) { return Send(parts.fParts, timeout); }
virtual int64_t Receive(Parts& parts, int timeout = -1) { return Receive(parts.fParts, timeout); } virtual int64_t Receive(Parts& parts, int timeout = -1) { return Receive(parts.fParts, timeout); }

View File

@ -1,22 +0,0 @@
/********************************************************************************
* Copyright (C) 2014-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* *
* This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" *
********************************************************************************/
#ifndef FAIR_MQ_TRANSPORTENUMS_H
#define FAIR_MQ_TRANSPORTENUMS_H
namespace fair::mq {
enum class Transport {
DEFAULT,
ZMQ,
SHM
};
}
#endif // FAIR_MQ_TRANSPORTENUMS_H

View File

@ -14,7 +14,7 @@
#include <fairmq/Message.h> #include <fairmq/Message.h>
#include <fairmq/Poller.h> #include <fairmq/Poller.h>
#include <fairmq/Socket.h> #include <fairmq/Socket.h>
#include <fairmq/TransportEnum.h> #include <fairmq/Transports.h>
#include <fairmq/UnmanagedRegion.h> #include <fairmq/UnmanagedRegion.h>
#include <memory> // shared_ptr #include <memory> // shared_ptr
#include <stdexcept> #include <stdexcept>

View File

@ -10,7 +10,6 @@
#define FAIR_MQ_TRANSPORTS_H #define FAIR_MQ_TRANSPORTS_H
#include <fairmq/tools/Strings.h> #include <fairmq/tools/Strings.h>
#include <fairmq/TransportEnum.h>
#include <memory> #include <memory>
#include <ostream> #include <ostream>
#include <stdexcept> #include <stdexcept>
@ -19,6 +18,13 @@
namespace fair::mq { namespace fair::mq {
enum class Transport
{
DEFAULT,
ZMQ,
SHM
};
struct TransportError : std::runtime_error struct TransportError : std::runtime_error
{ {
using std::runtime_error::runtime_error; using std::runtime_error::runtime_error;

View File

@ -9,7 +9,7 @@
#ifndef FAIR_MQ_UNMANAGEDREGION_H #ifndef FAIR_MQ_UNMANAGEDREGION_H
#define FAIR_MQ_UNMANAGEDREGION_H #define FAIR_MQ_UNMANAGEDREGION_H
#include <fairmq/TransportEnum.h> #include <fairmq/Transports.h>
#include <cstddef> // size_t #include <cstddef> // size_t
#include <cstdint> // uint32_t #include <cstdint> // uint32_t

View File

@ -1,5 +1,5 @@
/******************************************************************************** /********************************************************************************
* Copyright (C) 2018-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * Copyright (C) 2018-2022 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* * * *
* This software is distributed under the terms of the * * This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, * * GNU Lesser General Public Licence (LGPL) version 3, *
@ -19,7 +19,7 @@
#define FAIRMQ_GIT_DATE "@PROJECT_GIT_DATE@" #define FAIRMQ_GIT_DATE "@PROJECT_GIT_DATE@"
#define FAIRMQ_REPO_URL "https://github.com/FairRootGroup/FairMQ" #define FAIRMQ_REPO_URL "https://github.com/FairRootGroup/FairMQ"
#define FAIRMQ_LICENSE "LGPL-3.0" #define FAIRMQ_LICENSE "LGPL-3.0"
#define FAIRMQ_COPYRIGHT "2012-2025 GSI" #define FAIRMQ_COPYRIGHT "2012-2023 GSI"
#define FAIRMQ_BUILD_TYPE "@CMAKE_BUILD_TYPE@" #define FAIRMQ_BUILD_TYPE "@CMAKE_BUILD_TYPE@"
#endif // FAIR_MQ_VERSION_H #endif // FAIR_MQ_VERSION_H

View File

@ -65,17 +65,13 @@ Control::Control(const string& name, Plugin::Version version, const string& main
}); });
try { try {
auto control = GetProperty<string>("control"); TakeDeviceControl();
if (control != "none") { auto control = GetProperty<string>("control");
TakeDeviceControl();
}
if (control == "static") { if (control == "static") {
LOG(debug) << "Running builtin controller: static"; LOG(debug) << "Running builtin controller: static";
fControllerThread = thread(&Control::StaticMode, this); fControllerThread = thread(&Control::StaticMode, this);
} else if (control == "none") {
LOG(debug) << "Builtin controller: disabled";
} else if (control == "gui") { } else if (control == "gui") {
LOG(debug) << "Running builtin controller: gui"; LOG(debug) << "Running builtin controller: gui";
fControllerThread = thread(&Control::GUIMode, this); fControllerThread = thread(&Control::GUIMode, this);
@ -146,7 +142,7 @@ auto ControlPluginProgramOptions() -> Plugin::ProgOptions
namespace po = boost::program_options; namespace po = boost::program_options;
auto pluginOptions = po::options_description{"Control (builtin) Plugin"}; auto pluginOptions = po::options_description{"Control (builtin) Plugin"};
pluginOptions.add_options() pluginOptions.add_options()
("control", po::value<string>()->default_value("dynamic"), "Control mode, 'static' or 'dynamic' (aliases for dynamic are external and interactive), 'none', 'gui'") ("control", po::value<string>()->default_value("dynamic"), "Control mode, 'static' or 'dynamic' (aliases for dynamic are external and interactive)")
("catch-signals", po::value<int >()->default_value(1), "Enable signal handling (1/0)."); ("catch-signals", po::value<int >()->default_value(1), "Enable signal handling (1/0).");
return pluginOptions; return pluginOptions;
} }
@ -275,11 +271,11 @@ auto Control::InteractiveMode() -> void
try { try {
RunStartupSequence(); RunStartupSequence();
if (!fDeviceShutdownRequested) { if(!fDeviceShutdownRequested) {
RunREPL(); RunREPL();
} }
if (!fDeviceShutdownRequested) { if(!fDeviceShutdownRequested) {
RunShutdownSequence(); RunShutdownSequence();
} }
} catch (PluginServices::DeviceControlError& e) { } catch (PluginServices::DeviceControlError& e) {
@ -408,7 +404,7 @@ try {
// or for device shutdown request (Ctrl-C) // or for device shutdown request (Ctrl-C)
fStateQueue.WaitForNextOrCustom([this]{ return fDeviceShutdownRequested.load(); }); fStateQueue.WaitForNextOrCustom([this]{ return fDeviceShutdownRequested.load(); });
if (!fDeviceShutdownRequested) { if(!fDeviceShutdownRequested) {
RunShutdownSequence(); RunShutdownSequence();
} }
} catch (PluginServices::DeviceControlError& e) { } catch (PluginServices::DeviceControlError& e) {
@ -425,7 +421,7 @@ try {
// Wait for device shutdown request (Ctrl-C) // Wait for device shutdown request (Ctrl-C)
fStateQueue.WaitForCustom([this]{ return fDeviceShutdownRequested.load(); }); fStateQueue.WaitForCustom([this]{ return fDeviceShutdownRequested.load(); });
if (!fDeviceShutdownRequested) { if(!fDeviceShutdownRequested) {
RunShutdownSequence(); RunShutdownSequence();
} }
} catch (PluginServices::DeviceControlError& e) { } catch (PluginServices::DeviceControlError& e) {

View File

@ -13,8 +13,7 @@
#include <functional> // std::equal_to #include <functional> // std::equal_to
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
// #include <boost/interprocess/allocators/adaptive_pool.hpp> #include <boost/interprocess/allocators/adaptive_pool.hpp>
#include <boost/interprocess/allocators/node_allocator.hpp>
#include <boost/interprocess/allocators/allocator.hpp> #include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/containers/map.hpp> #include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/containers/string.hpp> #include <boost/interprocess/containers/string.hpp>
@ -70,10 +69,9 @@ struct RefCount
static constexpr size_t numNodesPerBlock = 4096; static constexpr size_t numNodesPerBlock = 4096;
// Maximum number of totally free blocks that the adaptive node pool will hold. // Maximum number of totally free blocks that the adaptive node pool will hold.
// The rest of the totally free blocks will be deallocated with the segment manager. // The rest of the totally free blocks will be deallocated with the segment manager.
// static constexpr size_t maxFreeBlocks = 2; static constexpr size_t maxFreeBlocks = 2;
using RefCountPool = boost::interprocess::node_allocator<RefCount, boost::interprocess::managed_shared_memory::segment_manager, numNodesPerBlock>; using RefCountPool = boost::interprocess::adaptive_pool<RefCount, boost::interprocess::managed_shared_memory::segment_manager, numNodesPerBlock, maxFreeBlocks>;
// using RefCountPool = boost::interprocess::adaptive_pool<RefCount, boost::interprocess::managed_shared_memory::segment_manager, numNodesPerBlock, maxFreeBlocks>;
using SegmentManager = boost::interprocess::managed_shared_memory::segment_manager; using SegmentManager = boost::interprocess::managed_shared_memory::segment_manager;
using VoidAlloc = boost::interprocess::allocator<void, SegmentManager>; using VoidAlloc = boost::interprocess::allocator<void, SegmentManager>;

View File

@ -14,7 +14,6 @@
#include "UnmanagedRegionImpl.h" #include "UnmanagedRegionImpl.h"
#include <fairmq/Message.h> #include <fairmq/Message.h>
#include <fairmq/UnmanagedRegion.h> #include <fairmq/UnmanagedRegion.h>
#include <fairmq/Transports.h>
#include <fairlogger/Logger.h> #include <fairlogger/Logger.h>

View File

@ -274,9 +274,7 @@ bool Monitor::PrintShm(const ShmId& shmId)
try { try {
managed_shared_memory rcCountSegment(open_read_only, MakeShmName(shmId.shmId, "rrc", id).c_str()); managed_shared_memory rcCountSegment(open_read_only, MakeShmName(shmId.shmId, "rrc", id).c_str());
auto size = rcCountSegment.get_size(); ss << ", rcCountSegment size: " << rcCountSegment.get_size() << ", free: " << rcCountSegment.get_free_memory();
auto free = rcCountSegment.get_free_memory();
ss << ", rcCountSegment size: " << size << ", free: " << free << ", used: " << size - free;
} catch (bie&) { } catch (bie&) {
ss << ", rcCountSegment: not found"; ss << ", rcCountSegment: not found";
} }

View File

@ -10,7 +10,6 @@
#include <fairmq/shmem/Common.h> #include <fairmq/shmem/Common.h>
#include <fairmq/shmem/Monitor.h> #include <fairmq/shmem/Monitor.h>
#include <fairmq/Transports.h>
#include <cstdint> #include <cstdint>
#include <string> #include <string>

View File

@ -200,7 +200,7 @@ class Socket final : public fair::mq::Socket
} }
} }
int64_t Send(Parts::container& msgVec, int timeout = -1) override int64_t Send(std::vector<MessagePtr>& msgVec, int timeout = -1) override
{ {
int flags = 0; int flags = 0;
if (timeout == 0) { if (timeout == 0) {
@ -260,7 +260,7 @@ class Socket final : public fair::mq::Socket
return static_cast<int>(TransferCode::error); return static_cast<int>(TransferCode::error);
} }
int64_t Receive(Parts::container& msgVec, int timeout = -1) override int64_t Receive(std::vector<MessagePtr>& msgVec, int timeout = -1) override
{ {
int flags = 0; int flags = 0;
if (timeout == 0) { if (timeout == 0) {

View File

@ -13,7 +13,6 @@
#include <fairmq/shmem/Monitor.h> #include <fairmq/shmem/Monitor.h>
#include <fairmq/tools/Strings.h> #include <fairmq/tools/Strings.h>
#include <fairmq/UnmanagedRegion.h> #include <fairmq/UnmanagedRegion.h>
#include <fairmq/Transports.h>
#include <fairlogger/Logger.h> #include <fairlogger/Logger.h>
@ -193,7 +192,7 @@ struct UnmanagedRegion
RefCount& MakeRefCount(uint16_t initialCount = 1) RefCount& MakeRefCount(uint16_t initialCount = 1)
{ {
RefCount* refCount = fRefCountPool->allocate_one().get(); RefCount* refCount = fRefCountPool->allocate(1).get();
new (refCount) RefCount(initialCount); new (refCount) RefCount(initialCount);
return *refCount; return *refCount;
} }
@ -201,7 +200,7 @@ struct UnmanagedRegion
void RemoveRefCount(RefCount& refCount) void RemoveRefCount(RefCount& refCount)
{ {
refCount.~RefCount(); refCount.~RefCount();
fRefCountPool->deallocate_one(&refCount); fRefCountPool->deallocate(&refCount, 1);
} }
~UnmanagedRegion() ~UnmanagedRegion()

View File

@ -1,5 +1,5 @@
/******************************************************************************** /********************************************************************************
* Copyright (C) 2017-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * Copyright (C) 2017-2021 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* * * *
* This software is distributed under the terms of the * * This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, * * GNU Lesser General Public Licence (LGPL) version 3, *
@ -8,12 +8,12 @@
#include <fairlogger/Logger.h> #include <fairlogger/Logger.h>
#include <fairmq/tools/Network.h> #include <fairmq/tools/Network.h>
#include <fairmq/tools/Strings.h>
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
#define _GNU_SOURCE // To get defns of NI_MAXSERV and NI_MAXHOST #define _GNU_SOURCE // To get defns of NI_MAXSERV and NI_MAXHOST
#endif #endif
#include <algorithm>
#include <array> #include <array>
#include <boost/algorithm/string.hpp> // trim #include <boost/algorithm/string.hpp> // trim
#include <boost/asio.hpp> #include <boost/asio.hpp>
@ -158,22 +158,33 @@ string getDefaultRouteNetworkInterface()
} }
string getIpFromHostname(const string& hostname) string getIpFromHostname(const string& hostname)
try { {
boost::asio::io_context ioc; boost::asio::io_context ioc;
boost::asio::ip::tcp::resolver resolver(ioc);
auto const result = resolver.resolve(boost::asio::ip::tcp::v4(), hostname, ""); using namespace boost::asio::ip;
try {
tcp::resolver resolver(ioc);
tcp::resolver::query query(hostname, "");
tcp::resolver::iterator end;
auto it = find_if(static_cast<basic_resolver_iterator<tcp>>(resolver.resolve(query)),
end,
[](const tcp::endpoint& ep) { return ep.address().is_v4(); });
if (it != end) {
stringstream ss;
ss << static_cast<tcp::endpoint>(*it).address();
return ss.str();
}
if (result.empty()) {
LOG(warn) << "could not find ipv4 address for hostname '" << hostname << "'"; LOG(warn) << "could not find ipv4 address for hostname '" << hostname << "'";
return "";
} catch (exception& e) {
LOG(error) << "could not resolve hostname '" << hostname << "', reason: " << e.what();
return ""; return "";
} }
return ToString(result.begin()->endpoint().address());
}
catch (std::exception const& ex)
{
LOG(error) << "could not resolve hostname '" << hostname << "', reason: " << ex.what();
return "";
} }
} // namespace fair::mq::tools } // namespace fair::mq::tools

View File

@ -1,5 +1,5 @@
/******************************************************************************** /********************************************************************************
* Copyright (C) 2017-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * Copyright (C) 2017-2023 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* * * *
* This software is distributed under the terms of the * * This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, * * GNU Lesser General Public Licence (LGPL) version 3, *
@ -64,22 +64,22 @@ execute_result execute(const string& cmd, const string& prefix, const string& in
p.Print(cmd); p.Print(cmd);
ba::io_context ioc; ba::io_service ios;
// containers for std_in // containers for std_in
ba::const_buffer inputBuffer(ba::buffer(input)); ba::const_buffer inputBuffer(ba::buffer(input));
bp::async_pipe inputPipe(ioc); bp::async_pipe inputPipe(ios);
// containers for std_out // containers for std_out
ba::streambuf outputBuffer; ba::streambuf outputBuffer;
bp::async_pipe outputPipe(ioc); bp::async_pipe outputPipe(ios);
// containers for std_err // containers for std_err
ba::streambuf errorBuffer; ba::streambuf errorBuffer;
bp::async_pipe errorPipe(ioc); bp::async_pipe errorPipe(ios);
const string delimiter = "\n"; const string delimiter = "\n";
ba::steady_timer inputTimer(ioc); ba::steady_timer inputTimer(ios);
inputTimer.expires_after(std::chrono::milliseconds(1000)); // NOLINT inputTimer.expires_after(std::chrono::milliseconds(1000)); // NOLINT
ba::steady_timer signalTimer(ioc); ba::steady_timer signalTimer(ios);
signalTimer.expires_after(std::chrono::milliseconds(2000)); // NOLINT signalTimer.expires_after(std::chrono::milliseconds(2000)); // NOLINT
// child process // child process
@ -154,7 +154,7 @@ execute_result execute(const string& cmd, const string& prefix, const string& in
}; };
ba::async_read_until(errorPipe, errorBuffer, delimiter, onStdErr); ba::async_read_until(errorPipe, errorBuffer, delimiter, onStdErr);
ioc.run(); ios.run();
c.wait(); c.wait();
result.exit_code = c.exit_code(); result.exit_code = c.exit_code();

View File

@ -154,7 +154,7 @@ class Socket final : public fair::mq::Socket
} }
} }
int64_t Send(Parts::container& msgVec, int timeout = -1) override int64_t Send(std::vector<std::unique_ptr<fair::mq::Message>>& msgVec, int timeout = -1) override
{ {
int flags = 0; int flags = 0;
if (timeout == 0) { if (timeout == 0) {
@ -206,7 +206,7 @@ class Socket final : public fair::mq::Socket
} }
} }
int64_t Receive(Parts::container& msgVec, int timeout = -1) override int64_t Receive(std::vector<std::unique_ptr<fair::mq::Message>>& msgVec, int timeout = -1) override
{ {
int flags = 0; int flags = 0;
if (timeout == 0) { if (timeout == 0) {

View File

@ -253,7 +253,7 @@ add_testsuite(Tools
LINKS FairMQ LINKS FairMQ
INCLUDES ${CMAKE_CURRENT_SOURCE_DIR} INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
TIMEOUT 5 TIMEOUT 20
${environment} ${environment}
) )

View File

@ -27,7 +27,7 @@ class TestDevice : public Device
{ {
public: public:
TestDevice(const string& transport) TestDevice(const string& transport)
: fDeviceThread(&Device::RunStateMachine, this) : fDeviceThread(&Device::RunStateMachine, this)
{ {
SetTransport(transport); SetTransport(transport);
test::Control(*this, test::Cycle::ToRun); test::Control(*this, test::Cycle::ToRun);

View File

@ -16,7 +16,6 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <cstring> #include <cstring>
#include <string>
#include <vector> #include <vector>
namespace namespace
@ -102,7 +101,7 @@ TEST(MemoryResources, allocator)
size_t session{tools::UuidHash()}; size_t session{tools::UuidHash()};
ProgOptions config; ProgOptions config;
config.SetProperty<std::string>("session", to_string(session)); config.SetProperty<string>("session", to_string(session));
FactoryType factoryZMQ = TransportFactory::CreateTransportFactory("zeromq", fair::mq::tools::Uuid(), &config); FactoryType factoryZMQ = TransportFactory::CreateTransportFactory("zeromq", fair::mq::tools::Uuid(), &config);
@ -130,7 +129,7 @@ TEST(MemoryResources, getMessage)
size_t session{tools::UuidHash()}; size_t session{tools::UuidHash()};
ProgOptions config; ProgOptions config;
config.SetProperty<std::string>("session", to_string(session)); config.SetProperty<string>("session", to_string(session));
config.SetProperty<bool>("shm-monitor", true); config.SetProperty<bool>("shm-monitor", true);
FactoryType factoryZMQ = TransportFactory::CreateTransportFactory("zeromq", fair::mq::tools::Uuid(), &config); FactoryType factoryZMQ = TransportFactory::CreateTransportFactory("zeromq", fair::mq::tools::Uuid(), &config);

View File

@ -1,37 +1,28 @@
/******************************************************************************** /********************************************************************************
* Copyright (C) 2018-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * Copyright (C) 2018 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
* * * *
* This software is distributed under the terms of the * * This software is distributed under the terms of the *
* GNU Lesser General Public Licence (LGPL) version 3, * * GNU Lesser General Public Licence (LGPL) version 3, *
* copied verbatim in the file "LICENSE" * * copied verbatim in the file "LICENSE" *
********************************************************************************/ ********************************************************************************/
#include <fairmq/tools/Network.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <fairmq/tools/Network.h>
#include <string> #include <string>
namespace namespace
{ {
TEST(Tools, NetworkDefaultIP) using namespace std;
using namespace fair::mq;
TEST(Tools, Network)
{ {
auto const interface = fair::mq::tools::getDefaultRouteNetworkInterface(); string interface = fair::mq::tools::getDefaultRouteNetworkInterface();
EXPECT_NE(interface, ""); EXPECT_NE(interface, "");
auto const interfaceIP = fair::mq::tools::getInterfaceIP(interface); string interfaceIP = fair::mq::tools::getInterfaceIP(interface);
EXPECT_NE(interfaceIP, ""); EXPECT_NE(interfaceIP, "");
} }
TEST(Tools, NetworkIPv4Localhost)
{
auto const ip = fair::mq::tools::getIpFromHostname("localhost");
EXPECT_FALSE(ip.empty());
EXPECT_EQ(ip, "127.0.0.1");
}
TEST(Tools, NetworkInvalidHostname)
{
auto const ip = fair::mq::tools::getIpFromHostname("non.existent.domain.invalid");
EXPECT_TRUE(ip.empty());
}
} /* namespace */ } /* namespace */