• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  (C) Copyright 2016 Raffi Enficiaud.
2 //  Distributed under the Boost Software License, Version 1.0.
3 //  (See accompanying file LICENSE_1_0.txt or copy at
4 //  http://www.boost.org/LICENSE_1_0.txt)
5 
6 //  See http://www.boost.org/libs/test for the library home page.
7 //
8 ///@file
9 ///@brief Contains the definition of the Junit log formatter (OF_JUNIT)
10 // ***************************************************************************
11 
12 #ifndef BOOST_TEST_JUNIT_LOG_FORMATTER__
13 #define BOOST_TEST_JUNIT_LOG_FORMATTER__
14 
15 // Boost.Test
16 #include <boost/test/detail/global_typedef.hpp>
17 #include <boost/test/unit_test_log_formatter.hpp>
18 #include <boost/test/tree/test_unit.hpp>
19 
20 //#include <boost/test/results_collector.hpp>
21 
22 // STL
23 #include <cstddef> // std::size_t
24 #include <map>
25 #include <list>
26 
27 #include <boost/test/detail/suppress_warnings.hpp>
28 
29 //____________________________________________________________________________//
30 
31 namespace boost {
32 namespace unit_test {
33 namespace output {
34 
35 
36   namespace junit_impl {
37 
38     // helper for the JUnit logger
39     struct junit_log_helper
40     {
41       struct assertion_entry {
42 
43         enum log_entry_t {
44           log_entry_info,
45           log_entry_error,
46           log_entry_failure
47         };
48 
assertion_entryboost::unit_test::output::junit_impl::junit_log_helper::assertion_entry49         assertion_entry() : sealed(false)
50         {}
51 
52         std::string logentry_message; // the message associated to the JUnit error/entry
53         std::string logentry_type; // the one that will get expanded in the final junit (failure, error)
54         std::string output;        // additional information/message generated by the assertion
55 
56         log_entry_t log_entry;     // the type associated to the assertion (or error)
57 
58         bool sealed;               // indicates if the entry can accept additional information
59       };
60 
61       std::list<std::string> system_out;      // sysout: additional information
62       std::list<std::string> system_err;      // syserr: additional information
63       std::string skipping_reason;
64 
65       // list of failure, errors and messages (assertions message and the full log)
66       std::vector< assertion_entry > assertion_entries;
67 
68       bool skipping;
69 
junit_log_helperboost::unit_test::output::junit_impl::junit_log_helper70       junit_log_helper(): skipping(false)
71       {}
72 
clearboost::unit_test::output::junit_impl::junit_log_helper73       void clear() {
74           assertion_entries.clear();
75           system_out.clear();
76           system_err.clear();
77           skipping_reason.clear();
78           skipping = false;
79       }
80 
81     };
82   }
83 
84 // ************************************************************************** //
85 // **************               junit_log_formatter              ************** //
86 // ************************************************************************** //
87 
88 /// JUnit logger class
89 class junit_log_formatter : public unit_test_log_formatter {
90 public:
91 
junit_log_formatter()92     junit_log_formatter() : m_display_build_info(false)
93     {
94         // we log everything from the logger singleton point of view
95         // because we need to know about all the messages/commands going to the logger
96         // we decide what we put inside the logs internally
97         this->m_log_level = log_successful_tests;
98         m_log_level_internal = log_messages;
99     }
100 
101     // Formatter interface
102     void    log_start( std::ostream&, counter_t test_cases_amount ) BOOST_OVERRIDE;
103     void    log_finish( std::ostream& ) BOOST_OVERRIDE;
104     void    log_build_info( std::ostream&, bool ) BOOST_OVERRIDE;
105 
106     void    test_unit_start( std::ostream&, test_unit const& tu ) BOOST_OVERRIDE;
107     void    test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed ) BOOST_OVERRIDE;
108     void    test_unit_skipped( std::ostream&, test_unit const& tu, const_string reason ) BOOST_OVERRIDE;
109     void    test_unit_aborted( std::ostream& os, test_unit const& tu ) BOOST_OVERRIDE;
110     void    test_unit_timed_out( std::ostream& os, test_unit const& tu) BOOST_OVERRIDE;
111 
112     void    log_exception_start( std::ostream&, log_checkpoint_data const&, execution_exception const& ex ) BOOST_OVERRIDE;
113     void    log_exception_finish( std::ostream& ) BOOST_OVERRIDE;
114 
115     void    log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let ) BOOST_OVERRIDE;
116 
117     using   unit_test_log_formatter::log_entry_value; // bring base class functions into overload set
118     void    log_entry_value( std::ostream&, const_string value ) BOOST_OVERRIDE;
119     void    log_entry_finish( std::ostream& ) BOOST_OVERRIDE;
120 
121     void    entry_context_start( std::ostream&, log_level ) BOOST_OVERRIDE;
122     void    log_entry_context( std::ostream&, log_level, const_string ) BOOST_OVERRIDE;
123     void    entry_context_finish( std::ostream&, log_level ) BOOST_OVERRIDE;
124 
125     //! Discards changes in the log level
set_log_level(log_level ll)126     void        set_log_level(log_level ll) BOOST_OVERRIDE
127     {
128         if(ll > log_successful_tests && ll < log_messages)
129             ll = log_successful_tests;
130         else if (ll > log_all_errors)
131             ll = log_all_errors;
132 
133         this->m_log_level_internal = ll;
134     }
135 
136     //! Instead of a regular stream, returns a file name corresponding to
137     //! the current master test suite. If the file already exists, adds an index
138     //! to it.
139     std::string  get_default_stream_description() const BOOST_OVERRIDE;
140 
141 
142 private:
143     typedef std::map<test_unit_id, junit_impl::junit_log_helper> map_trace_t;
144     map_trace_t map_tests;
145     junit_impl::junit_log_helper runner_log_entry;
146 
get_current_log_entry()147     junit_impl::junit_log_helper& get_current_log_entry() {
148         if(list_path_to_root.empty())
149             return runner_log_entry;
150         map_trace_t::iterator it = map_tests.find(list_path_to_root.back());
151         return (it == map_tests.end() ? runner_log_entry : it->second);
152     }
153 
154     std::list<test_unit_id> list_path_to_root;
155     bool m_display_build_info;
156     bool m_is_last_assertion_or_error; // true if failure, false if error
157 
158     log_level m_log_level_internal;
159     friend class junit_result_helper;
160 };
161 
162 } // namespace output
163 } // namespace unit_test
164 } // namespace boost
165 
166 #include <boost/test/detail/enable_warnings.hpp>
167 
168 #endif // BOOST_TEST_JUNIT_LOG_FORMATTER__
169