From 0b199e779ad9629550870ed913dfb2e850b80d47 Mon Sep 17 00:00:00 2001 From: Alexey Rybalchenko Date: Thu, 1 Nov 2018 11:23:00 +0100 Subject: [PATCH] Add test for interface IP detection tools --- fairmq/tools/Network.cxx | 89 ++++++++++++++-------------------------- fairmq/tools/Network.h | 2 +- test/CMakeLists.txt | 11 +++++ test/tools/_network.cxx | 28 +++++++++++++ 4 files changed, 70 insertions(+), 60 deletions(-) create mode 100644 test/tools/_network.cxx diff --git a/fairmq/tools/Network.cxx b/fairmq/tools/Network.cxx index e95680b9..d1a4c14f 100644 --- a/fairmq/tools/Network.cxx +++ b/fairmq/tools/Network.cxx @@ -28,6 +28,7 @@ #include #include #include +#include #include using namespace std; @@ -40,54 +41,52 @@ namespace tools { // returns a map with network interface names as keys and their IP addresses as values -int getHostIPs(map& addressMap) +map getHostIPs() { + map addressMap; struct ifaddrs *ifaddr, *ifa; int s; char host[NI_MAXHOST]; - if (getifaddrs(&ifaddr) == -1) - { + if (getifaddrs(&ifaddr) == -1) { perror("getifaddrs"); - return -1; + throw runtime_error("getifaddrs failed"); } - for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) - { - if (ifa->ifa_addr == NULL) - { + for (ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == nullptr) { continue; } - if (ifa->ifa_addr->sa_family == AF_INET) - { - s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); - if (s != 0) - { + if (ifa->ifa_addr->sa_family == AF_INET) { + s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST); + if (s != 0) { cout << "getnameinfo() failed: " << gai_strerror(s) << endl; - return -1; + throw runtime_error("getnameinfo() failed"); } addressMap.insert(pair(ifa->ifa_name, host)); } } + freeifaddrs(ifaddr); - return 0; + return addressMap; } // get IP address of a given interface name string getInterfaceIP(const string& interface) { - map IPs; - getHostIPs(IPs); - if (IPs.count(interface)) - { - return IPs[interface]; - } - else - { - LOG(error) << "Could not find provided network interface: \"" << interface << "\"!, exiting."; + try { + auto IPs = getHostIPs(); + if (IPs.count(interface)) { + return IPs[interface]; + } else { + LOG(error) << "Could not find provided network interface: \"" << interface << "\"!, exiting."; + return ""; + } + } catch (runtime_error& re) { + cout << "could not get interface IP: " << re.what(); return ""; } } @@ -104,28 +103,22 @@ string getDefaultRouteNetworkInterface() unique_ptr file(popen("ip route | grep default | cut -d \" \" -f 5 | head -n 1", "r"), pclose); #endif - if (!file) - { + if (!file) { LOG(error) << "Could not detect default route network interface name - popen() failed!"; return ""; } - while (!feof(file.get())) - { - if (fgets(buffer.data(), 128, file.get()) != NULL) - { + while (!feof(file.get())) { + if (fgets(buffer.data(), 128, file.get()) != nullptr) { interfaceName += buffer.data(); } } boost::algorithm::trim(interfaceName); - if (interfaceName == "") - { + if (interfaceName == "") { LOG(error) << "Could not detect default route network interface name"; - } - else - { + } else { LOG(debug) << "Detected network interface name for the default route: " << interfaceName; } @@ -134,30 +127,8 @@ string getDefaultRouteNetworkInterface() string getIpFromHostname(const string& hostname) { - try { - namespace bai = boost::asio::ip; - boost::asio::io_service ios; - bai::tcp::resolver resolver(ios); - bai::tcp::resolver::query query(hostname, ""); - bai::tcp::resolver::iterator end; - - auto it = find_if(static_cast>(resolver.resolve(query)), end, [](const bai::tcp::endpoint& ep) { - return ep.address().is_v4(); - }); - - if (it != end) { - stringstream ss; - ss << static_cast(*it).address(); - return ss.str(); - } - - 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 ""; - } + boost::asio::io_service ios; + return getIpFromHostname(hostname, ios); } string getIpFromHostname(const string& hostname, boost::asio::io_service& ios) diff --git a/fairmq/tools/Network.h b/fairmq/tools/Network.h index d80680ac..a00c410e 100644 --- a/fairmq/tools/Network.h +++ b/fairmq/tools/Network.h @@ -32,7 +32,7 @@ namespace tools { // returns a map with network interface names as keys and their IP addresses as values -int getHostIPs(std::map& addressMap); +std::map getHostIPs(); // get IP address of a given interface name std::string getInterfaceIP(const std::string& interface); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7ff12aba..b7096ac0 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -198,6 +198,17 @@ add_testsuite(FairMQ.StateMachine TIMEOUT 10 ) +add_testsuite(FairMQ.Tools + SOURCES + ${CMAKE_CURRENT_BINARY_DIR}/runner.cxx + tools/_network.cxx + + LINKS FairMQ + INCLUDES ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + TIMEOUT 10 +) + add_testsuite(FairMQ.Transport SOURCES ${CMAKE_CURRENT_BINARY_DIR}/runner.cxx diff --git a/test/tools/_network.cxx b/test/tools/_network.cxx new file mode 100644 index 00000000..33fd455b --- /dev/null +++ b/test/tools/_network.cxx @@ -0,0 +1,28 @@ +/******************************************************************************** + * Copyright (C) 2018 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 +#include + +#include + +namespace +{ + +using namespace std; +using namespace fair::mq; + +TEST(Tools, Network) +{ + string interface = fair::mq::tools::getDefaultRouteNetworkInterface(); + EXPECT_NE(interface, ""); + string interfaceIP = fair::mq::tools::getInterfaceIP(interface); + EXPECT_NE(interfaceIP, ""); +} + +} /* namespace */