You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
6.0 KiB
C++

/**
*
* \section COPYRIGHT
*
* Copyright 2013-2020 Software Radio Systems Limited
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the distribution.
*
*/
#ifndef SRSLTE_TEST_COMMON_H
#define SRSLTE_TEST_COMMON_H
#include "srslte/config.h"
#ifdef __cplusplus
#include "srslte/common/standard_streams.h"
#include "srslte/srslog/srslog.h"
#include <atomic>
#include <cstdio>
namespace srslte {
/// This custom sink intercepts log messages to count error and warning log entries.
class log_sink_spy : public srslog::sink
{
public:
explicit log_sink_spy(std::unique_ptr<srslog::log_formatter> f) :
srslog::sink(std::move(f)), s(srslog::get_default_sink())
{
error_counter.store(0);
warning_counter.store(0);
}
/// Identifier of this custom sink.
static const char* name() { return "log_sink_spy"; }
/// Returns the number of log entries tagged as errors.
unsigned get_error_counter() const
{
// Flush to make sure all entries have been processed by the backend.
srslog::flush();
return error_counter.load();
}
/// Returns the number of log entries tagged as warnings.
unsigned get_warning_counter() const
{
// Flush to make sure all entries have been processed by the backend.
srslog::flush();
return warning_counter.load();
}
/// Resets the counters back to 0.
void reset_counters()
{
// Flush to make sure all entries have been processed by the backend.
srslog::flush();
error_counter.store(0);
warning_counter.store(0);
}
srslog::detail::error_string write(srslog::detail::memory_buffer buffer) override
{
std::string entry(buffer.data(), buffer.size());
if (entry.find("[E]") != std::string::npos) {
error_counter.fetch_add(1);
} else if (entry.find("[W]") != std::string::npos) {
warning_counter.fetch_add(1);
}
return s.write(buffer);
}
srslog::detail::error_string flush() override { return s.flush(); }
private:
srslog::sink& s;
std::atomic<unsigned> error_counter;
std::atomic<unsigned> warning_counter;
};
/// This custom sink intercepts log messages allowing users to check if a certain log entry has been generated.
/// Calling spy.has_message("something") will return true if any log entries generated so far contain the string
/// "something".
/// The log entries history can be cleared with reset so old entries can be discarded.
class log_sink_message_spy : public srslog::sink
{
public:
explicit log_sink_message_spy(std::unique_ptr<srslog::log_formatter> f) :
srslog::sink(std::move(f)), s(srslog::get_default_sink())
{}
/// Identifier of this custom sink.
static const char* name() { return "log_sink_message_spy"; }
/// Discards all registered log entries.
void reset()
{
// Flush to make sure all entries have been processed by the backend.
srslog::flush();
entries.clear();
}
/// Returns true if the string in msg is found in the registered log entries.
bool has_message(const std::string& msg) const
{
srslog::flush();
return std::find_if(entries.cbegin(), entries.cend(), [&](const std::string& entry) {
return entry.find(msg) != std::string::npos;
}) != entries.cend();
}
srslog::detail::error_string write(srslog::detail::memory_buffer buffer) override
{
entries.emplace_back(buffer.data(), buffer.size());
return s.write(buffer);
}
srslog::detail::error_string flush() override { return s.flush(); }
private:
srslog::sink& s;
std::vector<std::string> entries;
};
} // namespace srslte
#define TESTERROR(fmt, ...) \
do { \
srslog::fetch_basic_logger("TEST").error(fmt, ##__VA_ARGS__); \
return SRSLTE_ERROR; \
} while (0)
#define TESTWARN(fmt, ...) \
do { \
srslog::fetch_basic_logger("TEST").warning(fmt, ##__VA_ARGS__); \
} while (0)
#define CONDERROR(cond, fmt, ...) \
do { \
if (cond) { \
TESTERROR(fmt, ##__VA_ARGS__); \
} \
} while (0)
#define TESTASSERT(cond) CONDERROR((not(cond)), "[%s][Line %d] Fail at \"%s\"", __FUNCTION__, __LINE__, (#cond))
#else // if C
#include <stdio.h>
#define TESTASSERT(cond) \
do { \
if (!(cond)) { \
printf("[%s][Line %d] Fail at \"%s\"\n", __FUNCTION__, __LINE__, (#cond)); \
return -1; \
} \
} while (0)
#endif // __cplusplus
#endif // SRSLTE_TEST_COMMON_H