1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
/*
* 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 attr_named_scope.cpp
* \author Andrey Semashev
* \date 25.01.2009
*
* \brief This header contains tests for the named scope attribute.
*/
#define BOOST_TEST_MODULE attr_named_scope
#include <sstream>
#include <boost/mpl/vector.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/log/attributes/attribute.hpp>
#include <boost/log/attributes/named_scope.hpp>
#include <boost/log/attributes/attribute_value.hpp>
#include <boost/log/attributes/value_extraction.hpp>
#include <boost/log/utility/string_literal.hpp>
#include <boost/log/utility/value_ref.hpp>
#include "char_definitions.hpp"
namespace logging = boost::log;
namespace attrs = logging::attributes;
namespace {
template< typename >
struct scope_test_data;
template< >
struct scope_test_data< char >
{
static logging::string_literal scope1() { return logging::str_literal("scope1"); }
static logging::string_literal scope2() { return logging::str_literal("scope2"); }
static logging::string_literal file() { return logging::str_literal(__FILE__); }
};
} // namespace
// The test verifies that the scope macros are defined
BOOST_AUTO_TEST_CASE(macros)
{
#ifdef BOOST_LOG_USE_CHAR
BOOST_CHECK(BOOST_IS_DEFINED(BOOST_LOG_NAMED_SCOPE(name)));
BOOST_CHECK(BOOST_IS_DEFINED(BOOST_LOG_FUNCTION()));
#endif // BOOST_LOG_USE_CHAR
}
// The test checks that scope tracking works correctly
BOOST_AUTO_TEST_CASE(scope_tracking)
{
typedef attrs::named_scope named_scope;
typedef named_scope::sentry sentry;
typedef attrs::named_scope_list scopes;
typedef attrs::named_scope_entry scope;
typedef scope_test_data< char > scope_data;
named_scope attr;
// First scope
const unsigned int line1 = __LINE__;
sentry scope1(scope_data::scope1(), scope_data::file(), line1);
BOOST_CHECK(!named_scope::get_scopes().empty());
BOOST_CHECK_EQUAL(named_scope::get_scopes().size(), 1UL);
logging::attribute_value val = attr.get_value();
BOOST_REQUIRE(!!val);
logging::value_ref< scopes > sc = val.extract< scopes >();
BOOST_REQUIRE(!!sc);
BOOST_REQUIRE(!sc->empty());
BOOST_CHECK_EQUAL(sc->size(), 1UL);
scope const& s1 = sc->front();
BOOST_CHECK(s1.scope_name == scope_data::scope1());
BOOST_CHECK(s1.file_name == scope_data::file());
BOOST_CHECK(s1.line == line1);
// Second scope
const unsigned int line2 = __LINE__;
scope new_scope(scope_data::scope2(), scope_data::file(), line2);
named_scope::push_scope(new_scope);
BOOST_CHECK(!named_scope::get_scopes().empty());
BOOST_CHECK_EQUAL(named_scope::get_scopes().size(), 2UL);
val = attr.get_value();
BOOST_REQUIRE(!!val);
sc = val.extract< scopes >();
BOOST_REQUIRE(!!sc);
BOOST_REQUIRE(!sc->empty());
BOOST_CHECK_EQUAL(sc->size(), 2UL);
scopes::const_iterator it = sc->begin();
scope const& s2 = *(it++);
BOOST_CHECK(s2.scope_name == scope_data::scope1());
BOOST_CHECK(s2.file_name == scope_data::file());
BOOST_CHECK(s2.line == line1);
scope const& s3 = *(it++);
BOOST_CHECK(s3.scope_name == scope_data::scope2());
BOOST_CHECK(s3.file_name == scope_data::file());
BOOST_CHECK(s3.line == line2);
BOOST_CHECK(it == sc->end());
// Second scope goes out
named_scope::pop_scope();
BOOST_CHECK(!named_scope::get_scopes().empty());
BOOST_CHECK_EQUAL(named_scope::get_scopes().size(), 1UL);
val = attr.get_value();
BOOST_REQUIRE(!!val);
sc = val.extract< scopes >();
BOOST_REQUIRE(!!sc);
BOOST_REQUIRE(!sc->empty());
BOOST_CHECK_EQUAL(sc->size(), 1UL);
scope const& s4 = sc->back(); // should be the same as front
BOOST_CHECK(s4.scope_name == scope_data::scope1());
BOOST_CHECK(s4.file_name == scope_data::file());
BOOST_CHECK(s4.line == line1);
}
// The test checks that detaching from thread works correctly
BOOST_AUTO_TEST_CASE(detaching_from_thread)
{
typedef attrs::named_scope named_scope;
typedef named_scope::sentry sentry;
typedef attrs::named_scope_list scopes;
typedef scope_test_data< char > scope_data;
named_scope attr;
sentry scope1(scope_data::scope1(), scope_data::file(), __LINE__);
logging::attribute_value val1 = attr.get_value();
val1.detach_from_thread();
sentry scope2(scope_data::scope2(), scope_data::file(), __LINE__);
logging::attribute_value val2 = attr.get_value();
val2.detach_from_thread();
logging::value_ref< scopes > sc1 = val1.extract< scopes >(), sc2 = val2.extract< scopes >();
BOOST_REQUIRE(!!sc1);
BOOST_REQUIRE(!!sc2);
BOOST_CHECK_EQUAL(sc1->size(), 1UL);
BOOST_CHECK_EQUAL(sc2->size(), 2UL);
}
// The test checks that output streaming is possible
BOOST_AUTO_TEST_CASE(ostreaming)
{
typedef attrs::named_scope named_scope;
typedef named_scope::sentry sentry;
typedef scope_test_data< char > scope_data;
sentry scope1(scope_data::scope1(), scope_data::file(), __LINE__);
sentry scope2(scope_data::scope2(), scope_data::file(), __LINE__);
std::basic_ostringstream< char > strm;
strm << named_scope::get_scopes();
BOOST_CHECK(!strm.str().empty());
}
// The test checks that the scope list becomes thread-independent after copying
BOOST_AUTO_TEST_CASE(copying)
{
typedef attrs::named_scope named_scope;
typedef named_scope::sentry sentry;
typedef attrs::named_scope_list scopes;
typedef scope_test_data< char > scope_data;
sentry scope1(scope_data::scope1(), scope_data::file(), __LINE__);
scopes sc = named_scope::get_scopes();
sentry scope2(scope_data::scope2(), scope_data::file(), __LINE__);
BOOST_CHECK_EQUAL(sc.size(), 1UL);
BOOST_CHECK_EQUAL(named_scope::get_scopes().size(), 2UL);
}
|