Unverified Commit 67caa511 authored by syl's avatar syl Committed by GitHub
Browse files

add support for conan dependency manager. (#17)

* enh(perl): switch to gtest

* fix(perl): remove some dead code.

* enh(tests): switch to googletest.

* enh(log): add spdlog support for perl_connectors.

* fix(chore): use same connectors version for both connectos.

* fix(perl): fix compile
parent ac9fee4b
......@@ -4,3 +4,4 @@ perl/test/connector/paths.hh
ssh/test/connector/binary.hh
build/*
.idea/*
cmake-build-debug/*
# Global options.
cmake_minimum_required(VERSION 2.8.12)
project(connectors CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_definitions("-D_GLIBCXX_USE_CXX11_ABI=0")
set(CONNECTOR_MAJOR 20)
set(CONNECTOR_MINOR 04)
set(CONNECTOR_PATCH 0)
set(CONNECTOR_VERSION "${CONNECTOR_MAJOR}.${CONNECTOR_MINOR}.${CONNECTOR_PATCH}")
add_definitions(-DCENTREON_CONNECTOR_VERSION=\"${CONNECTOR_VERSION}\")
include(${CMAKE_SOURCE_DIR}/cmake/Findclib.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/FindSSH.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/Findperl.cmake)
include(${CMAKE_BINARY_DIR}/conan_paths.cmake)
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
add_definitions(${spdlog_DEFINITIONS})
include_directories(${fmt_INCLUDE_DIRS})
include_directories(${spdlog_INCLUDE_DIRS})
# Generate code to dynamically load modules.
add_custom_command(OUTPUT "${CMAKE_SOURCE_DIR}/perl/src/xs_init.cc"
COMMAND "${PERL_EXECUTABLE}" "-MExtUtils::Embed" "-e" "xsinit" "--" "-o" "${CMAKE_SOURCE_DIR}/perl/src/xs_init.cc")
# Disable some warnings generated by Embedded Perl.
get_property(EMBEDDED_PERL_CXXFLAGS SOURCE ${CMAKE_SOURCE_DIR}/perl/src/embedded_perl.cc
PROPERTY COMPILE_FLAGS)
if (EMBEDDED_PERL_CXXFLAGS)
string(REGEX REPLACE "-pedantic *"
EMBEDDED_PERL_CXXFLAGS "${EMBEDDED_PERL_CXXFLAGS}")
set_property(SOURCE "${CMAKE_SOURCE_DIR}/perl/src/embedded_perl.cc"
PROPERTY COMPILE_FLAGS "${EMBEDDED_PERL_CXXFLAGS}")
endif ()
# We will use pkg-config if available.
add_subdirectory(perl)
add_subdirectory(ssh)
\ No newline at end of file
add_subdirectory(ssh)
# Testing.
option(WITH_TESTING "Build unit tests." OFF)
if (WITH_TESTING)
find_package(gtest REQUIRED)
include_directories(${gtest_INCLUDE_DIRS})
include_directories(/usr/lib64/perl5/CORE)
link_directories(${gtest_LIB_DIRS})
include_directories(${CMAKE_SOURCE_DIR}/perl/inc)
include_directories(${CMAKE_SOURCE_DIR}/ssh/inc)
add_definitions(-DBUILD_PATH="${CMAKE_BINARY_DIR}")
add_executable(ut
# Core sources
${CMAKE_SOURCE_DIR}/perl/src/embedded_perl.cc
${CMAKE_SOURCE_DIR}/perl/src/log_v2.cc
${CMAKE_SOURCE_DIR}/perl/src/pipe_handle.cc
${CMAKE_SOURCE_DIR}/perl/src/script.cc
${CMAKE_SOURCE_DIR}/perl/src/xs_init.cc
${CMAKE_SOURCE_DIR}/ssh/src/checks/check.cc
${CMAKE_SOURCE_DIR}/ssh/src/checks/result.cc
${CMAKE_SOURCE_DIR}/ssh/src/checks/timeout.cc
${CMAKE_SOURCE_DIR}/ssh/src/multiplexer.cc
${CMAKE_SOURCE_DIR}/ssh/src/orders/options.cc
${CMAKE_SOURCE_DIR}/ssh/src/orders/parser.cc
${CMAKE_SOURCE_DIR}/ssh/src/sessions/credentials.cc
${CMAKE_SOURCE_DIR}/ssh/src/sessions/session.cc
${CMAKE_SOURCE_DIR}/ssh/src/sessions/socket_handle.cc
${CMAKE_SOURCE_DIR}/ssh/src/reporter.cc
# Test sources.
${CMAKE_SOURCE_DIR}/perl/test/main.cc
${CMAKE_SOURCE_DIR}/perl/test/connector.cc
${CMAKE_SOURCE_DIR}/perl/test/embedded_perl.cc
${CMAKE_SOURCE_DIR}/ssh/test/buffer_handle.cc
${CMAKE_SOURCE_DIR}/ssh/test/checks.cc
${CMAKE_SOURCE_DIR}/ssh/test/connector.cc
${CMAKE_SOURCE_DIR}/ssh/test/fake_listener.cc
${CMAKE_SOURCE_DIR}/ssh/test/orders.cc
${CMAKE_SOURCE_DIR}/ssh/test/reporter.cc
${CMAKE_SOURCE_DIR}/ssh/test/sessions.cc
)
target_link_libraries(ut ${gtest_LIBS} ${CLIB_LIBRARIES} ${PERL_LIBRARIES} ${fmt_LIBS} ${spdlog_LIBS} ${LIBSSH2_LIBRARIES})
endif (WITH_TESTING)
[requires]
gtest/1.8.1@bincrafters/stable
spdlog/1.4.2@bincrafters/stable
[generators]
cmake_paths
cmake_find_package
......@@ -16,34 +16,10 @@
## For more information : contact@centreon.com
##
# Global options.
include(${CMAKE_SOURCE_DIR}/cmake/Findclib.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/Findperl.cmake)
include_directories("${PROJECT_SOURCE_DIR}/inc" "/usr/lib64/perl5/CORE")
# Project version.
set(CONNECTOR_PERL_MAJOR 20)
set(CONNECTOR_PERL_MINOR 04)
set(CONNECTOR_PERL_PATCH 0)
set(CONNECTOR_PERL_VERSION "${CONNECTOR_PERL_MAJOR}.${CONNECTOR_PERL_MINOR}.${CONNECTOR_PERL_PATCH}")
add_definitions(-DCENTREON_CONNECTOR_PERL_VERSION=\"${CONNECTOR_PERL_VERSION}\")
# Generate code to dynamically load modules.
add_custom_command(OUTPUT "${CMAKE_SOURCE_DIR}/perl/src/xs_init.cc"
COMMAND "${PERL_EXECUTABLE}" "-MExtUtils::Embed" "-e" "xsinit" "--" "-o" "${CMAKE_SOURCE_DIR}/perl/src/xs_init.cc")
# Disable some warnings generated by Embedded Perl.
get_property(EMBEDDED_PERL_CXXFLAGS SOURCE ${SRC_DIR}/embedded_perl.cc
PROPERTY COMPILE_FLAGS)
if (EMBEDDED_PERL_CXXFLAGS)
string(REGEX REPLACE "-pedantic *"
EMBEDDED_PERL_CXXFLAGS "${EMBEDDED_PERL_CXXFLAGS}")
set_property(SOURCE "${SRC_DIR}/embedded_perl.cc"
PROPERTY COMPILE_FLAGS "${EMBEDDED_PERL_CXXFLAGS}")
endif ()
include_directories(${CMAKE_SOURCE_DIR}/perl/inc/)
# Perl connector.
add_executable(centreon_connector_perl
......@@ -54,6 +30,7 @@ add_executable(centreon_connector_perl
${CMAKE_SOURCE_DIR}/perl/src/checks/result.cc
${CMAKE_SOURCE_DIR}/perl/src/checks/timeout.cc
${CMAKE_SOURCE_DIR}/perl/src/embedded_perl.cc
${CMAKE_SOURCE_DIR}/perl/src/log_v2.cc
${CMAKE_SOURCE_DIR}/perl/src/multiplexer.cc
${CMAKE_SOURCE_DIR}/perl/src/options.cc
${CMAKE_SOURCE_DIR}/perl/src/orders/parser.cc
......@@ -78,7 +55,7 @@ add_executable(centreon_connector_perl
${CMAKE_SOURCE_DIR}/perl/inc/com/centreon/connector/perl/reporter.hh
)
target_link_libraries(centreon_connector_perl ${CLIB_LIBRARIES} ${PERL_LIBRARIES} pthread)
target_link_libraries(centreon_connector_perl ${CLIB_LIBRARIES} ${PERL_LIBRARIES} ${spdlog_LIBS} ${fmt_LIBS} pthread)
# Installation path.
if (WITH_PREFIX)
......@@ -101,99 +78,3 @@ if (WITH_COVERAGE)
include(CodeCoverage.cmake)
APPEND_COVERAGE_COMPILER_FLAGS()
endif ()
# Testing.
option(WITH_TESTING "Build unit tests." OFF)
if (WITH_TESTING)
# Enable testing.
enable_testing()
include_directories("${PROJECT_SOURCE_DIR}")
set(CONNECTOR_TEST_DIR "${PROJECT_SOURCE_DIR}/test/connector")
get_property(CONNECTOR_PERL_BINARY
TARGET "${CONNECTOR}"
PROPERTY LOCATION)
configure_file(
"${TEST_DIR}/connector/paths.hh.in"
"${TEST_DIR}/connector/paths.hh")
set(CONNECTOR_TEST_LIST
${TEST_DIR}/embedded_perl/run_simple_1.cc
${TEST_DIR}/embedded_perl/run_simple_2.cc
)
foreach (name ${CONNECTOR_TEST_LIST})
# name cc file => bin_name binary name
string(REGEX REPLACE "^${TEST_DIR}/" "" bin_name ${name})
string(REGEX REPLACE "/" "_" bin_name ${bin_name})
string(REGEX REPLACE ".cc$" "" bin_name ${bin_name})
add_executable("${bin_name}" "${name}")
target_link_libraries("${bin_name}" "${CONNECTORLIB}")
add_test("${bin_name}" "${bin_name}")
list(APPEND TEST_BIN_LIST ${bin_name})
endforeach ()
#
# Process tests.
#
# Help.
add_test("connector_help" "${CONNECTOR}" "--help")
list(APPEND TEST_BIN_TEST "connector_help")
# Version.
add_test("connector_version" "${CONNECTOR}" "--version")
list(APPEND TEST_BIN_TEST "connector_version")
# Invalid flag.
add_test("connector_invalid_flag" "${CONNECTOR}" "--merethis")
list(APPEND TEST_BIN_LIST "connector_invalid_flag")
set_tests_properties("connector_invalid_flag"
PROPERTIES WILL_FAIL TRUE)
# Execution library.
add_library("test_execute" STATIC
"${TEST_DIR}/connector/misc.cc"
"${TEST_DIR}/connector/misc.hh")
set(TEST_LIBRARIES ${CLIB_LIBRARIES} "test_execute")
# EOF on stdin.
set(TEST_NAME "connector_eof_on_stdin")
add_executable("${TEST_NAME}"
"${TEST_DIR}/connector/eof_on_stdin.cc")
target_link_libraries("${TEST_NAME}" ${CLIB_LIBRARIES})
add_test("${TEST_NAME}" "${TEST_NAME}")
list(APPEND TEST_BIN_LIST "connector_eof_on_stdin")
set(TEST_LIST
${TEST_DIR}/connector/non_existent_script.cc
${TEST_DIR}/connector/timeout_term.cc
${TEST_DIR}/connector/timeout_kill.cc
${TEST_DIR}/connector/execute_single_script.cc
${TEST_DIR}/connector/execute_single_script_log_file.cc
${TEST_DIR}/connector/execute_multiple_scripts.cc
${TEST_DIR}/connector/execute_with_additional_code.cc
${TEST_DIR}/connector/execute_module_loading.cc
)
foreach (name ${TEST_LIST})
# name cc file => bin_name binary name
string(REGEX REPLACE "^${TEST_DIR}/" "" bin_name ${name})
string(REGEX REPLACE "/" "_" bin_name ${bin_name})
string(REGEX REPLACE ".cc$" "" bin_name ${bin_name})
add_executable("${bin_name}" "${name}")
target_link_libraries("${bin_name}" "${TEST_LIBRARIES}")
add_test("${bin_name}" "${bin_name}")
list(APPEND TEST_BIN_LIST ${bin_name})
endforeach ()
if (WITH_COVERAGE)
set(COVERAGE_EXCLUDES '${PROJECT_BINARY_DIR}/*' '${PROJECT_SOURCE_DIR}/test/*' '/usr/include/*')
SETUP_TARGET_FOR_COVERAGE(
NAME test-coverage
EXECUTABLE ctest
DEPENDENCIES
${TEST_BIN_LIST}
)
endif ()
endif ()
......@@ -43,11 +43,7 @@ class timeout : public com::centreon::task {
timeout(check* chk = NULL, bool final = false);
timeout(timeout const& t) = delete;
timeout& operator=(timeout const& t) = delete;
check* get_check() const throw();
bool is_final() const throw();
void run();
void set_check(check* chk) throw();
void set_final(bool final) throw();
};
} // namespace checks
......
......@@ -53,7 +53,6 @@ class embedded_perl {
embedded_perl(int* argc, char*** argv, char*** env, char const* code = NULL);
embedded_perl(embedded_perl const& ep);
embedded_perl& operator=(embedded_perl const& ep);
void _write(char const* data, size_t len);
umap<std::string, SV*> _parsed;
static char const* const _script;
......
/*
* Copyright 2020 Centreon (https://www.centreon.com/)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For more information : contact@centreon.com
*
*/
#ifndef CONNECTORS_PERL_INC_COM_CENTREON_CONNECTOR_PERL_LOG_V2_H_
#define CONNECTORS_PERL_INC_COM_CENTREON_CONNECTOR_PERL_LOG_V2_H_
#include <spdlog/common.h>
#include <spdlog/spdlog.h>
#include <memory>
class log_v2 {
private:
std::shared_ptr<spdlog::logger> _core_log;
log_v2();
~log_v2();
public:
static log_v2& instance();
void set_level(spdlog::level::level_enum level);
void switch_to_stdout();
void switch_to_file(std::string const& filename);
static std::shared_ptr<spdlog::logger> core();
};
#endif // CONNECTORS_PERL_INC_COM_CENTREON_CONNECTOR_PERL_LOG_V2_H_
/*
** Copyright 2011-2013 Centreon
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
** For more information : contact@centreon.com
*/
#ifndef CCC_PERL_MAIN_IO_HH_
#define CCC_PERL_MAIN_IO_HH_
#include <string>
#include "com/centreon/connector/perl/namespace.hh"
CCC_PERL_BEGIN()
/**
* @class main_io main_io.hh
* @brief Manage I/O on standard input and standard output.
*
* This singleton manages I/O on standard input (wait for
* orders from the monitoring engine) and on standard output
* (provide check results).
*/
class main_io {
public:
~main_io();
static main_io& instance();
int read();
int write();
void write(std::string const& data);
bool write_wanted() const;
private:
main_io();
main_io(main_io const& mio);
main_io& operator=(main_io const& mio);
int _parse(std::string const& cmd);
std::string _rbuffer;
std::string _wbuffer;
};
CCC_PERL_END()
#endif /* !CCC_PERL_MAIN_IO_HH_ */
......@@ -17,15 +17,17 @@
*/
#include "com/centreon/connector/perl/checks/check.hh"
#include <csignal>
#include <cstdlib>
#include <memory>
#include "com/centreon/connector/perl/checks/listener.hh"
#include "com/centreon/connector/perl/checks/result.hh"
#include "com/centreon/connector/perl/checks/timeout.hh"
#include "com/centreon/connector/perl/log_v2.h"
#include "com/centreon/connector/perl/embedded_perl.hh"
#include "com/centreon/connector/perl/multiplexer.hh"
#include "com/centreon/logging/logger.hh"
using namespace com::centreon;
using namespace com::centreon::connector::perl::checks;
......@@ -86,7 +88,8 @@ pid_t check::execute(unsigned long long cmd_id,
_err.set_fd(fds[2]);
// Store command ID.
log_debug(logging::low) << "check " << this << " has ID " << cmd_id;
log_v2::core()->debug("check {0} has ID {1}", static_cast<void*>(this),
cmd_id);
_cmd_id = cmd_id;
// Register with multiplexer.
......@@ -108,8 +111,8 @@ pid_t check::execute(unsigned long long cmd_id,
* @param[in] listnr New listener.
*/
void check::listen(listener* listnr) {
log_debug(logging::medium)
<< "check " << this << " is listened by " << listnr;
log_v2::core()->debug("check {0} is listened by {1}",
static_cast<void*>(this), static_cast<void*>(listnr));
_listnr = listnr;
}
......@@ -120,8 +123,7 @@ void check::listen(listener* listnr) {
*/
void check::on_timeout(bool final) {
// Log message.
log_error(logging::low) << "check " << _cmd_id << " (pid=" << _child
<< ") reached timeout";
log_v2::core()->error("check {0} (pid={1}) reached timeout", _cmd_id, _child);
// Reset timeout task ID.
_timeout = 0;
......@@ -154,11 +156,10 @@ void check::read(handle& h) {
char buffer[1024];
unsigned long rb(h.read(buffer, sizeof(buffer)));
if (&h == &_err) {
log_debug(logging::high)
<< "reading from process " << _child << "'s stdout";
log_v2::core()->debug("reading from process {}'s stdout", _child);
_stderr.append(buffer, rb);
} else {
log_debug(logging::high) << "reading from process " << _child << "' stderr";
log_v2::core()->debug("reading from process {}'s stderr", _child);
_stdout.append(buffer, rb);
}
}
......@@ -170,8 +171,7 @@ void check::read(handle& h) {
*/
void check::terminated(int exit_code) {
// Read possibly remaining data.
log_debug(logging::medium)
<< "reading remaining data from process " << _child;
log_v2::core()->debug("reading remaining data from process {}", _child);
try {
char buffer[1024];
unsigned long rb(_out.read(buffer, sizeof(buffer)));
......@@ -210,8 +210,8 @@ void check::terminated(int exit_code) {
* @param[in] listnr Old listener.
*/
void check::unlisten(listener* listnr) {
log_debug(logging::medium)
<< "listener " << listnr << " stops listening check " << this;
log_v2::core()->debug("listener {0} stops listening check {1}",
static_cast<void*>(_listnr), static_cast<void*>(this));
_listnr = NULL;
}
......
......@@ -35,24 +35,6 @@ using namespace com::centreon::connector::perl::checks;
*/
timeout::timeout(check* chk, bool final) : _check(chk), _final(final) {}
/**
* Get the check object.
*
* @return Check object.
*/
check* timeout::get_check() const throw() {
return _check;
}
/**
* Is this a final timeout ?
*
* @return true if the timeout is final.
*/
bool timeout::is_final() const throw() {
return _final;
}
/**
* Notify check of timeout.
*/
......@@ -60,21 +42,3 @@ void timeout::run() {
if (_check)
_check->on_timeout(_final);
}
/**
* Set target check.
*
* @param[in] chk Target check.
*/
void timeout::set_check(check* chk) throw() {
_check = chk;
}
/**
* Set whether this timeout is final.
*
* @param[in] final New final parameter.
*/
void timeout::set_final(bool final) throw() {
_final = final;
}
......@@ -16,16 +16,20 @@
** For more information : contact@centreon.com
*/
#include "com/centreon/connector/perl/log_v2.h"
#include "com/centreon/connector/perl/pipe_handle.hh"
#include "com/centreon/exceptions/basic.hh"
#include "com/centreon/connector/perl/embedded_perl.hh"
#include <EXTERN.h>
#include <perl.h>
#include <unistd.h>
#include <cstdlib>
#include <iostream>
#include <list>
#include "com/centreon/connector/perl/pipe_handle.hh"
#include "com/centreon/exceptions/basic.hh"
#include "com/centreon/logging/logger.hh"
using namespace com::centreon;
using namespace com::centreon::connector::perl;
......@@ -54,12 +58,13 @@ embedded_perl::~embedded_perl() {
// Clean only if within parent process.
if (_self == getpid()) {
// Clean Perl interpreter.
log_info(logging::low) << "cleaning up Embedded Perl";
log_v2::core()->info("cleaning up Embedded Perl");
if (my_perl) {
PL_perl_destruct_level = 1;
perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
my_perl = nullptr;
}
}
}
......@@ -112,9 +117,9 @@ pid_t embedded_perl::run(std::string const& cmd, int fds[3]) {
args = cmd.substr(pos + 1);
} else
file = cmd;
log_debug(logging::medium) << "command " << cmd << "\n"
<< " - file " << file << "\n"
<< " - args " << args;
log_v2::core()->debug("command {}", cmd);
log_v2::core()->debug(" - file {}", file);
log_v2::core()->debug(" - args {}", args);
// Check if file has already been compiled.
SV* handle;
......@@ -123,7 +128,7 @@ pid_t embedded_perl::run(std::string const& cmd, int fds[3]) {
if (it == _parsed.end()) {
// Compile Perl file.
{
log_debug(logging::medium) << "parsing file " << file;
log_v2::core()->debug("parsing file {}", file);
char const* argv[3];
argv[0] = file.c_str();
argv[1] = "0";
......@@ -277,7 +282,7 @@ embedded_perl::embedded_perl(int* argc,
// Set original PID.
_self = getpid();
log_debug(logging::high) << "self PID is " << _self;
log_v2::core()->debug("self PID is {}", _self);
// Temporary script path.
char script_path[] = SCRIPT_PATH;
......@@ -288,7 +293,7 @@ embedded_perl::embedded_perl(int* argc,
char const* msg(strerror(errno));
throw(basic_error() << "could not create temporary file: " << msg);
}
log_info(logging::high) << "temporary script path is " << script_path;
log_v2::core()->info("temporary script path is {}", script_path);
// Write embedded script.
std::list<char const*> l;
......@@ -318,10 +323,12 @@ embedded_perl::embedded_perl(int* argc,
}
// Initialize Perl interpreter.
log_info(logging::low) << "loading Embedded Perl interpreter";
PERL_SYS_INIT3(argc, argv, env);
if (!(my_perl = perl_alloc()))
log_v2::core()->info("loading Embedded Perl interpreter");
if (!(my_perl = perl_alloc())) {
log_v2::core()->error("could not allocate Perl interpreter");
throw(basic_error() << "could not allocate Perl interpreter");
}
perl_construct(my_perl);
PL_origalen = 1;
PL_perl_destruct_level = 1;
......@@ -331,8 +338,11 @@ embedded_perl::embedded_perl(int* argc,
embedding[0] = "";
embedding[1] = script_path;
if (perl_parse(my_perl, &xs_init, sizeof(embedding) / sizeof(*embedding),
(char**)embedding, NULL))
(char**)embedding, NULL)) {
log_v2::core()->error("could not parse embedded Perl script");
throw(basic_error() << "could not parse embedded Perl script");
}
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;