244 lines
8.5 KiB
C++
244 lines
8.5 KiB
C++
/*
|
|
* Copyright Andrey Semashev 2007 - 2015.
|
|
* Distributed under the Boost Software License, Version 1.0.
|
|
* (See accompanying file LICENSE_1_0.txt or copy at
|
|
* http://www.boost.org/LICENSE_1_0.txt)
|
|
*/
|
|
/*!
|
|
* \file core.cpp
|
|
* \author Andrey Semashev
|
|
* \date 08.02.2009
|
|
*
|
|
* \brief This header contains tests for the logging core.
|
|
*/
|
|
|
|
#define BOOST_TEST_MODULE core
|
|
|
|
#include <cstddef>
|
|
#include <map>
|
|
#include <string>
|
|
#include <boost/smart_ptr/shared_ptr.hpp>
|
|
#include <boost/move/utility_core.hpp>
|
|
#include <boost/test/unit_test.hpp>
|
|
#include <boost/log/core/core.hpp>
|
|
#include <boost/log/attributes/constant.hpp>
|
|
#include <boost/log/attributes/attribute_set.hpp>
|
|
#include <boost/log/attributes/attribute_value_set.hpp>
|
|
#include <boost/log/expressions.hpp>
|
|
#include <boost/log/sinks/sink.hpp>
|
|
#include <boost/log/core/record.hpp>
|
|
#ifndef BOOST_LOG_NO_THREADS
|
|
#include <boost/thread/thread.hpp>
|
|
#endif // BOOST_LOG_NO_THREADS
|
|
#include "char_definitions.hpp"
|
|
#include "test_sink.hpp"
|
|
|
|
namespace logging = boost::log;
|
|
namespace attrs = logging::attributes;
|
|
namespace sinks = logging::sinks;
|
|
namespace expr = logging::expressions;
|
|
|
|
// The test checks that message filtering works
|
|
BOOST_AUTO_TEST_CASE(filtering)
|
|
{
|
|
typedef logging::attribute_set attr_set;
|
|
typedef logging::core core;
|
|
typedef logging::record record_type;
|
|
typedef test_data< char > data;
|
|
|
|
attrs::constant< int > attr1(10);
|
|
attrs::constant< double > attr2(5.5);
|
|
|
|
attr_set set1;
|
|
set1[data::attr1()] = attr1;
|
|
set1[data::attr2()] = attr2;
|
|
|
|
boost::shared_ptr< core > pCore = core::get();
|
|
boost::shared_ptr< test_sink > pSink(new test_sink());
|
|
pCore->add_sink(pSink);
|
|
|
|
// No filtering at all
|
|
{
|
|
record_type rec = pCore->open_record(set1);
|
|
BOOST_REQUIRE(rec);
|
|
pCore->push_record(boost::move(rec));
|
|
BOOST_CHECK_EQUAL(pSink->m_RecordCounter, 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr1()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr2()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr3()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr4()], 0UL);
|
|
pSink->clear();
|
|
}
|
|
|
|
// Core-level filtering
|
|
{
|
|
pCore->set_filter(expr::has_attr(data::attr3()));
|
|
record_type rec = pCore->open_record(set1);
|
|
BOOST_CHECK(!rec);
|
|
BOOST_CHECK_EQUAL(pSink->m_RecordCounter, 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr1()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr2()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr3()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr4()], 0UL);
|
|
pSink->clear();
|
|
}
|
|
{
|
|
pCore->set_filter(expr::has_attr(data::attr2()));
|
|
record_type rec = pCore->open_record(set1);
|
|
BOOST_REQUIRE(rec);
|
|
pCore->push_record(boost::move(rec));
|
|
BOOST_CHECK_EQUAL(pSink->m_RecordCounter, 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr1()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr2()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr3()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr4()], 0UL);
|
|
pSink->clear();
|
|
}
|
|
|
|
// Sink-level filtering
|
|
{
|
|
pCore->reset_filter();
|
|
pSink->set_filter(expr::has_attr(data::attr2()));
|
|
record_type rec = pCore->open_record(set1);
|
|
BOOST_REQUIRE(rec);
|
|
pCore->push_record(boost::move(rec));
|
|
BOOST_CHECK_EQUAL(pSink->m_RecordCounter, 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr1()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr2()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr3()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr4()], 0UL);
|
|
pSink->clear();
|
|
}
|
|
{
|
|
pSink->set_filter(expr::has_attr(data::attr3()));
|
|
record_type rec = pCore->open_record(set1);
|
|
BOOST_CHECK(!rec);
|
|
BOOST_CHECK_EQUAL(pSink->m_RecordCounter, 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr1()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr2()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr3()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr4()], 0UL);
|
|
pSink->clear();
|
|
pSink->reset_filter();
|
|
}
|
|
// Only one sink of the two accepts the record
|
|
{
|
|
pSink->set_filter(expr::has_attr(data::attr2()));
|
|
|
|
boost::shared_ptr< test_sink > pSink2(new test_sink());
|
|
pCore->add_sink(pSink2);
|
|
pSink2->set_filter(expr::has_attr(data::attr3()));
|
|
|
|
record_type rec = pCore->open_record(set1);
|
|
BOOST_REQUIRE(rec);
|
|
pCore->push_record(boost::move(rec));
|
|
|
|
BOOST_CHECK_EQUAL(pSink->m_RecordCounter, 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr1()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr2()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr3()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr4()], 0UL);
|
|
pSink->clear();
|
|
|
|
BOOST_CHECK_EQUAL(pSink2->m_RecordCounter, 0UL);
|
|
BOOST_CHECK_EQUAL(pSink2->m_Consumed[data::attr1()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink2->m_Consumed[data::attr2()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink2->m_Consumed[data::attr3()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink2->m_Consumed[data::attr4()], 0UL);
|
|
pCore->remove_sink(pSink2);
|
|
}
|
|
|
|
pCore->remove_sink(pSink);
|
|
pCore->reset_filter();
|
|
}
|
|
|
|
#ifndef BOOST_LOG_NO_THREADS
|
|
namespace {
|
|
|
|
//! A test routine that runs in a separate thread
|
|
void thread_attributes_test()
|
|
{
|
|
typedef test_data< char > data;
|
|
typedef logging::core core;
|
|
typedef logging::record record_type;
|
|
typedef logging::attribute_set attr_set;
|
|
attrs::constant< short > attr4(255);
|
|
|
|
boost::shared_ptr< core > pCore = core::get();
|
|
pCore->add_thread_attribute(data::attr4(), attr4);
|
|
|
|
attr_set set1;
|
|
record_type rec = pCore->open_record(set1);
|
|
BOOST_CHECK(rec);
|
|
if (rec)
|
|
pCore->push_record(boost::move(rec));
|
|
}
|
|
|
|
} // namespace
|
|
#endif // BOOST_LOG_NO_THREADS
|
|
|
|
// The test checks that global and thread-specific attributes work
|
|
BOOST_AUTO_TEST_CASE(attributes)
|
|
{
|
|
typedef logging::attribute_set attr_set;
|
|
typedef logging::core core;
|
|
typedef logging::record record_type;
|
|
typedef test_data< char > data;
|
|
|
|
attrs::constant< int > attr1(10);
|
|
attrs::constant< double > attr2(5.5);
|
|
attrs::constant< std::string > attr3("Hello, world!");
|
|
|
|
attr_set set1;
|
|
set1[data::attr1()] = attr1;
|
|
|
|
boost::shared_ptr< core > pCore = core::get();
|
|
boost::shared_ptr< test_sink > pSink(new test_sink());
|
|
pCore->add_sink(pSink);
|
|
|
|
attr_set::iterator itGlobal = pCore->add_global_attribute(data::attr2(), attr2).first;
|
|
attr_set::iterator itThread = pCore->add_thread_attribute(data::attr3(), attr3).first;
|
|
|
|
{
|
|
attr_set glob = pCore->get_global_attributes();
|
|
BOOST_CHECK_EQUAL(glob.size(), 1UL);
|
|
BOOST_CHECK_EQUAL(glob.count(data::attr2()), 1UL);
|
|
|
|
attr_set thr = pCore->get_thread_attributes();
|
|
BOOST_CHECK_EQUAL(thr.size(), 1UL);
|
|
BOOST_CHECK_EQUAL(thr.count(data::attr3()), 1UL);
|
|
}
|
|
{
|
|
record_type rec = pCore->open_record(set1);
|
|
BOOST_REQUIRE(rec);
|
|
pCore->push_record(boost::move(rec));
|
|
BOOST_CHECK_EQUAL(pSink->m_RecordCounter, 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr1()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr2()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr3()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr4()], 0UL);
|
|
pSink->clear();
|
|
}
|
|
#ifndef BOOST_LOG_NO_THREADS
|
|
{
|
|
boost::thread th(&thread_attributes_test);
|
|
th.join();
|
|
BOOST_CHECK_EQUAL(pSink->m_RecordCounter, 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr1()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr2()], 1UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr3()], 0UL);
|
|
BOOST_CHECK_EQUAL(pSink->m_Consumed[data::attr4()], 1UL);
|
|
pSink->clear();
|
|
|
|
// Thread-specific attributes must not interfere
|
|
attr_set thr = pCore->get_thread_attributes();
|
|
BOOST_CHECK_EQUAL(thr.size(), 1UL);
|
|
BOOST_CHECK_EQUAL(thr.count(data::attr3()), 1UL);
|
|
}
|
|
#endif // BOOST_LOG_NO_THREADS
|
|
|
|
pCore->remove_global_attribute(itGlobal);
|
|
pCore->remove_thread_attribute(itThread);
|
|
pCore->remove_sink(pSink);
|
|
}
|