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