Imported Upstream version 1.57.0
[platform/upstream/boost.git] / libs / log / test / run / attr_named_scope.cpp
1 /*
2  *          Copyright Andrey Semashev 2007 - 2014.
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     {
40         static logging::string_literal scope1() { return logging::str_literal("scope1"); }
41         static logging::string_literal scope2() { return logging::str_literal("scope2"); }
42         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
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
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
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
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
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 }