• 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   filt_attr.cpp
9  * \author Andrey Semashev
10  * \date   31.01.2009
11  *
12  * \brief  This header contains tests for the \c attr filter.
13  */
14 
15 #define BOOST_TEST_MODULE filt_attr
16 
17 #include <memory>
18 #include <string>
19 #include <algorithm>
20 #include <boost/regex.hpp>
21 #include <boost/mpl/vector.hpp>
22 #include <boost/phoenix/bind.hpp>
23 #include <boost/test/unit_test.hpp>
24 #include <boost/log/attributes/constant.hpp>
25 #include <boost/log/attributes/attribute_set.hpp>
26 #include <boost/log/attributes/attribute_value_set.hpp>
27 #include <boost/log/utility/type_dispatch/standard_types.hpp>
28 #include <boost/log/support/regex.hpp>
29 #include <boost/log/expressions.hpp>
30 #include "char_definitions.hpp"
31 
32 namespace phoenix = boost::phoenix;
33 
34 namespace logging = boost::log;
35 namespace attrs = logging::attributes;
36 namespace expr = logging::expressions;
37 
38 // The test checks that general conditions work
BOOST_AUTO_TEST_CASE(general_conditions)39 BOOST_AUTO_TEST_CASE(general_conditions)
40 {
41     typedef logging::attribute_set attr_set;
42     typedef logging::attribute_value_set attr_values;
43     typedef logging::filter filter;
44     typedef test_data< char > data;
45 
46     attrs::constant< int > attr1(10);
47     attrs::constant< double > attr2(5.5);
48     attrs::constant< std::string > attr3("Hello, world!");
49 
50     attr_set set1, set2, set3;
51     set1[data::attr1()] = attr1;
52     set1[data::attr2()] = attr2;
53     set1[data::attr3()] = attr3;
54 
55     attr_values values1(set1, set2, set3);
56     values1.freeze();
57 
58     filter f = expr::attr< int >(data::attr1()) == 10;
59     BOOST_CHECK(f(values1));
60 
61     f = expr::attr< int >(data::attr1()) < 0;
62     BOOST_CHECK(!f(values1));
63 
64     f = expr::attr< float >(data::attr1()).or_throw() > 0;
65     BOOST_CHECK_THROW(f(values1), logging::runtime_error);
66     f = expr::attr< float >(data::attr1()) > 0;
67     BOOST_CHECK(!f(values1));
68 
69     f = expr::attr< int >(data::attr4()).or_throw() >= 1;
70     BOOST_CHECK_THROW(f(values1), logging::runtime_error);
71     f = expr::attr< int >(data::attr4()) >= 1;
72     BOOST_CHECK(!f(values1));
73 
74     f = expr::attr< int >(data::attr4()) < 1;
75     BOOST_CHECK(!f(values1));
76 
77     f = expr::attr< logging::numeric_types >(data::attr2()) > 5;
78     BOOST_CHECK(f(values1));
79 
80     f = expr::attr< std::string >(data::attr3()) == "Hello, world!";
81     BOOST_CHECK(f(values1));
82 
83     f = expr::attr< std::string >(data::attr3()) > "AAA";
84     BOOST_CHECK(f(values1));
85 }
86 
87 // The test checks that is_in_range condition works
BOOST_AUTO_TEST_CASE(in_range_check)88 BOOST_AUTO_TEST_CASE(in_range_check)
89 {
90     typedef logging::attribute_set attr_set;
91     typedef logging::attribute_value_set attr_values;
92     typedef logging::filter filter;
93     typedef test_data< char > data;
94 
95     attrs::constant< int > attr1(10);
96     attrs::constant< double > attr2(5.5);
97     attrs::constant< std::string > attr3("Hello, world!");
98 
99     attr_set set1, set2, set3;
100     set1[data::attr1()] = attr1;
101     set1[data::attr2()] = attr2;
102     set1[data::attr3()] = attr3;
103 
104     attr_values values1(set1, set2, set3);
105     values1.freeze();
106 
107     filter f = expr::is_in_range(expr::attr< int >(data::attr1()), 5, 20);
108     BOOST_CHECK(f(values1));
109 
110     f = expr::is_in_range(expr::attr< int >(data::attr1()), 5, 10);
111     BOOST_CHECK(!f(values1));
112 
113     f = expr::is_in_range(expr::attr< int >(data::attr1()), 10, 20);
114     BOOST_CHECK(f(values1));
115 
116     f = expr::is_in_range(expr::attr< logging::numeric_types >(data::attr2()), 5, 6);
117     BOOST_CHECK(f(values1));
118 
119     f = expr::is_in_range(expr::attr< std::string >(data::attr3()), "AAA", "zzz");
120     BOOST_CHECK(f(values1));
121 
122     // Check that strings are saved into the filter by value
123     char buf1[128];
124     char buf2[128];
125     std::strcpy(buf1, "AAA");
126     std::strcpy(buf2, "zzz");
127     f = expr::is_in_range(expr::attr< std::string >(data::attr3()), buf1, buf2);
128     std::fill_n(buf1, sizeof(buf1), static_cast< char >(0));
129     std::fill_n(buf2, sizeof(buf2), static_cast< char >(0));
130     BOOST_CHECK(f(values1));
131 
132     std::strcpy(buf1, "AAA");
133     std::strcpy(buf2, "zzz");
134     f = expr::is_in_range(expr::attr< std::string >(data::attr3()),
135         static_cast< const char* >(buf1), static_cast< const char* >(buf2));
136     std::fill_n(buf1, sizeof(buf1), static_cast< char >(0));
137     std::fill_n(buf2, sizeof(buf2), static_cast< char >(0));
138     BOOST_CHECK(f(values1));
139 }
140 
141 namespace {
142 
143     struct predicate
144     {
145         typedef bool result_type;
146 
predicate__anonc546ca0f0111::predicate147         explicit predicate(unsigned int& present_counter, bool& result) :
148             m_PresentCounter(present_counter),
149             m_Result(result)
150         {
151         }
152 
153         template< typename T, typename TagT >
operator ()__anonc546ca0f0111::predicate154         result_type operator() (logging::value_ref< T, TagT > const& val) const
155         {
156             m_PresentCounter += !val.empty();
157             return m_Result;
158         }
159 
160     private:
161         unsigned int& m_PresentCounter;
162         bool& m_Result;
163     };
164 
165 } // namespace
166 
167 // The test checks that phoenix::bind interaction works
BOOST_AUTO_TEST_CASE(bind_support_check)168 BOOST_AUTO_TEST_CASE(bind_support_check)
169 {
170     typedef logging::attribute_set attr_set;
171     typedef logging::attribute_value_set attr_values;
172     typedef logging::filter filter;
173     typedef test_data< char > data;
174 
175     attrs::constant< int > attr1(10);
176     attrs::constant< double > attr2(5.5);
177     attrs::constant< std::string > attr3("Hello, world!");
178 
179     attr_set set1, set2, set3;
180     set1[data::attr1()] = attr1;
181     set1[data::attr2()] = attr2;
182     set1[data::attr3()] = attr3;
183 
184     attr_values values1(set1, set2, set3);
185     values1.freeze();
186 
187     unsigned int present_counter = 0;
188     bool predicate_result = false;
189 
190     filter f = phoenix::bind(predicate(present_counter, predicate_result), expr::attr< int >(data::attr1()));
191     BOOST_CHECK_EQUAL(f(values1), predicate_result);
192     BOOST_CHECK_EQUAL(present_counter, 1U);
193 
194     predicate_result = true;
195     BOOST_CHECK_EQUAL(f(values1), predicate_result);
196     BOOST_CHECK_EQUAL(present_counter, 2U);
197 
198     f = phoenix::bind(predicate(present_counter, predicate_result), expr::attr< logging::numeric_types >(data::attr2()));
199     BOOST_CHECK_EQUAL(f(values1), predicate_result);
200     BOOST_CHECK_EQUAL(present_counter, 3U);
201 
202     f = phoenix::bind(predicate(present_counter, predicate_result), expr::attr< int >(data::attr2()).or_throw());
203     BOOST_CHECK_THROW(f(values1), logging::runtime_error);
204     f = phoenix::bind(predicate(present_counter, predicate_result), expr::attr< int >(data::attr2()));
205     BOOST_CHECK_EQUAL(f(values1), true);
206     BOOST_CHECK_EQUAL(present_counter, 3U);
207 
208     f = phoenix::bind(predicate(present_counter, predicate_result), expr::attr< int >(data::attr4()).or_throw());
209     BOOST_CHECK_THROW(f(values1), logging::runtime_error);
210     f = phoenix::bind(predicate(present_counter, predicate_result), expr::attr< int >(data::attr4()));
211     BOOST_CHECK_EQUAL(f(values1), true);
212     BOOST_CHECK_EQUAL(present_counter, 3U);
213 }
214 
215 // The test checks that begins_with condition works
BOOST_AUTO_TEST_CASE(begins_with_check)216 BOOST_AUTO_TEST_CASE(begins_with_check)
217 {
218     typedef logging::attribute_set attr_set;
219     typedef logging::attribute_value_set attr_values;
220     typedef logging::filter filter;
221     typedef test_data< char > data;
222 
223     attrs::constant< int > attr1(10);
224     attrs::constant< double > attr2(5.5);
225     attrs::constant< std::string > attr3("Hello, world!");
226 
227     attr_set set1, set2, set3;
228     set1[data::attr1()] = attr1;
229     set1[data::attr2()] = attr2;
230     set1[data::attr3()] = attr3;
231 
232     attr_values values1(set1, set2, set3);
233     values1.freeze();
234 
235     filter f = expr::begins_with(expr::attr< std::string >(data::attr3()), "Hello");
236     BOOST_CHECK(f(values1));
237 
238     f = expr::begins_with(expr::attr< std::string >(data::attr3()), "hello");
239     BOOST_CHECK(!f(values1));
240 
241     f = expr::begins_with(expr::attr< std::string >(data::attr3()).or_throw(), "Bye");
242     BOOST_CHECK(!f(values1));
243 
244     f = expr::begins_with(expr::attr< std::string >(data::attr3()).or_throw(), "world!");
245     BOOST_CHECK(!f(values1));
246 
247     f = expr::begins_with(expr::attr< std::string >(data::attr2()), "Hello");
248     BOOST_CHECK(!f(values1));
249 
250     f = expr::begins_with(expr::attr< std::string >(data::attr4()), "Hello");
251     BOOST_CHECK(!f(values1));
252 }
253 
254 // The test checks that ends_with condition works
BOOST_AUTO_TEST_CASE(ends_with_check)255 BOOST_AUTO_TEST_CASE(ends_with_check)
256 {
257     typedef logging::attribute_set attr_set;
258     typedef logging::attribute_value_set attr_values;
259     typedef logging::filter filter;
260     typedef test_data< char > data;
261 
262     attrs::constant< int > attr1(10);
263     attrs::constant< double > attr2(5.5);
264     attrs::constant< std::string > attr3("Hello, world!");
265 
266     attr_set set1, set2, set3;
267     set1[data::attr1()] = attr1;
268     set1[data::attr2()] = attr2;
269     set1[data::attr3()] = attr3;
270 
271     attr_values values1(set1, set2, set3);
272     values1.freeze();
273 
274     filter f = expr::ends_with(expr::attr< std::string >(data::attr3()), "world!");
275     BOOST_CHECK(f(values1));
276 
277     f = expr::ends_with(expr::attr< std::string >(data::attr3()), "World!");
278     BOOST_CHECK(!f(values1));
279 
280     f = expr::ends_with(expr::attr< std::string >(data::attr3()).or_throw(), "Bye");
281     BOOST_CHECK(!f(values1));
282 
283     f = expr::ends_with(expr::attr< std::string >(data::attr3()).or_throw(), "Hello");
284     BOOST_CHECK(!f(values1));
285 
286     f = expr::ends_with(expr::attr< std::string >(data::attr2()), "world!");
287     BOOST_CHECK(!f(values1));
288 
289     f = expr::ends_with(expr::attr< std::string >(data::attr4()), "world!");
290     BOOST_CHECK(!f(values1));
291 }
292 
293 // The test checks that contains condition works
BOOST_AUTO_TEST_CASE(contains_check)294 BOOST_AUTO_TEST_CASE(contains_check)
295 {
296     typedef logging::attribute_set attr_set;
297     typedef logging::attribute_value_set attr_values;
298     typedef logging::filter filter;
299     typedef test_data< char > data;
300 
301     attrs::constant< int > attr1(10);
302     attrs::constant< double > attr2(5.5);
303     attrs::constant< std::string > attr3("Hello, world!");
304 
305     attr_set set1, set2, set3;
306     set1[data::attr1()] = attr1;
307     set1[data::attr2()] = attr2;
308     set1[data::attr3()] = attr3;
309 
310     attr_values values1(set1, set2, set3);
311     values1.freeze();
312 
313     filter f = expr::contains(expr::attr< std::string >(data::attr3()), "Hello");
314     BOOST_CHECK(f(values1));
315 
316     f = expr::contains(expr::attr< std::string >(data::attr3()), "hello");
317     BOOST_CHECK(!f(values1));
318 
319     f = expr::contains(expr::attr< std::string >(data::attr3()).or_throw(), "o, w");
320     BOOST_CHECK(f(values1));
321 
322     f = expr::contains(expr::attr< std::string >(data::attr3()).or_throw(), "world!");
323     BOOST_CHECK(f(values1));
324 
325     f = expr::contains(expr::attr< std::string >(data::attr2()), "Hello");
326     BOOST_CHECK(!f(values1));
327 
328     f = expr::contains(expr::attr< std::string >(data::attr4()), "Hello");
329     BOOST_CHECK(!f(values1));
330 }
331 
332 // The test checks that matches condition works
BOOST_AUTO_TEST_CASE(matches_check)333 BOOST_AUTO_TEST_CASE(matches_check)
334 {
335     typedef logging::attribute_set attr_set;
336     typedef logging::attribute_value_set attr_values;
337     typedef logging::filter filter;
338     typedef test_data< char > data;
339 
340     attrs::constant< int > attr1(10);
341     attrs::constant< double > attr2(5.5);
342     attrs::constant< std::string > attr3("Hello, world!");
343 
344     attr_set set1, set2, set3;
345     set1[data::attr1()] = attr1;
346     set1[data::attr2()] = attr2;
347     set1[data::attr3()] = attr3;
348 
349     attr_values values1(set1, set2, set3);
350     values1.freeze();
351 
352     boost::regex rex("hello");
353     filter f = expr::matches(expr::attr< std::string >(data::attr3()), rex);
354     BOOST_CHECK(!f(values1));
355 
356     rex = ".*world.*";
357     f = expr::matches(expr::attr< std::string >(data::attr3()).or_throw(), rex);
358     BOOST_CHECK(f(values1));
359 
360     rex = ".*";
361     f = expr::matches(expr::attr< std::string >(data::attr2()), rex);
362     BOOST_CHECK(!f(values1));
363 
364     f = expr::matches(expr::attr< std::string >(data::attr4()), rex);
365     BOOST_CHECK(!f(values1));
366 }
367 
368 // The test checks that the filter composition works
BOOST_AUTO_TEST_CASE(composition_check)369 BOOST_AUTO_TEST_CASE(composition_check)
370 {
371     typedef logging::attribute_set attr_set;
372     typedef logging::attribute_value_set attr_values;
373     typedef logging::filter filter;
374     typedef test_data< char > data;
375 
376     attrs::constant< int > attr1(10);
377     attrs::constant< double > attr2(5.5);
378     attrs::constant< std::string > attr3("Hello, world!");
379 
380     attr_set set1, set2, set3;
381     attr_values values1(set1, set2, set3);
382     values1.freeze();
383     set1[data::attr2()] = attr2;
384     attr_values values2(set1, set2, set3);
385     values2.freeze();
386     set1[data::attr3()] = attr3;
387     set1[data::attr1()] = attr1;
388     attr_values values3(set1, set2, set3);
389     values3.freeze();
390 
391     filter f =
392         expr::attr< int >(data::attr1()) <= 10 ||
393         expr::is_in_range(expr::attr< double >(data::attr2()), 2.2, 7.7);
394     BOOST_CHECK(!f(values1));
395     BOOST_CHECK(f(values2));
396     BOOST_CHECK(f(values3));
397 
398     f = expr::attr< int >(data::attr1()) == 10 &&
399         expr::begins_with(expr::attr< std::string >(data::attr3()), "Hello");
400     BOOST_CHECK(!f(values1));
401     BOOST_CHECK(!f(values2));
402     BOOST_CHECK(f(values3));
403 }
404