blob: ae37416bc888f1cf38176b88aff9c417be1315f7 [file] [log] [blame]
Alexander Afanasyevf22ebaf2015-12-17 21:23:05 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2015 Regents of the University of California.
4 *
5 * Based on work by Martin Ba (http://stackoverflow.com/a/26718189)
6 *
7 * This file is distributed under the Boost Software License, Version 1.0.
8 * (See http://www.boost.org/LICENSE_1_0.txt)
9 */
10
11#ifndef NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
12#define NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP
13
14#include <boost/version.hpp>
15
16#if BOOST_VERSION >= 105900
17#include <boost/test/unit_test_parameters.hpp>
18#else
19#include <boost/test/detail/unit_test_parameters.hpp>
20#endif // BOOST_VERSION >= 105900
21
22#include <boost/test/unit_test_log_formatter.hpp>
23#include <boost/test/output/compiler_log_formatter.hpp>
24#include <boost/test/output/xml_log_formatter.hpp>
25
26namespace boost {
27namespace unit_test {
28namespace output {
29
30/**
31 * @brief Log formatter for Boost.Test that outputs the logging to multiple formatters
32 *
33 * The log formatter is designed to output to one or multiple formatters at the same time. For
34 * example, one HRF formatter can output to the standard output, while XML formatter output to
35 * the file.
36 *
37 * Usage:
38 *
39 * // Call in init_unit_test_suite: (this will override the --log_format parameter)
40 * auto formatter = new boost::unit_test::output::multi_log_formatter; // same as already configured logger
41 *
42 * // Prepare and add additional logger(s)
43 * formatter.add(std::make_shared<boost::unit_test::output::xml_log_formatter>(),
44 * std::make_shared<std::ofstream>("out.xml"));
45 *
46 * boost::unit_test::unit_test_log.set_formatter(formatter);
47 *
48 * @note Calling `boost::unit_test::unit_test_log.set_stream(...)` will change the stream for
49 * the original logger.
50 */
51class multi_log_formatter : public unit_test_log_formatter
52{
53public:
54 /**
55 * @brief Create instance of the logger, based on the configured logger instance
56 */
57 multi_log_formatter()
58 {
59 auto format =
60#if BOOST_VERSION > 105900
61 runtime_config::get<output_format>(runtime_config::LOG_FORMAT);
62#else
63 runtime_config::log_format();
64#endif // BOOST_VERSION > 105900
65
66 switch (format) {
67 default:
68#if BOOST_VERSION >= 105900
69 case OF_CLF:
70#else
71 case CLF:
72#endif // BOOST_VERSION >= 105900
73 m_loggers.push_back({std::make_shared<compiler_log_formatter>(), nullptr});
74 break;
75#if BOOST_VERSION >= 105900
76 case OF_XML:
77#else
78 case XML:
79#endif // BOOST_VERSION >= 105900
80 m_loggers.push_back({std::make_shared<xml_log_formatter>(), nullptr});
81 break;
82 }
83 }
84
85 void
86 add(std::shared_ptr<unit_test_log_formatter> formatter, std::shared_ptr<std::ostream> os)
87 {
88 m_loggers.push_back({formatter, os});
89 }
90
91 // Formatter interface
92 void
93 log_start(std::ostream& os, counter_t test_cases_amount)
94 {
95 for (auto& l : m_loggers)
96 l.logger->log_start(l.os == nullptr ? os : *l.os, test_cases_amount);
97 }
98
99 void
100 log_finish(std::ostream& os)
101 {
102 for (auto& l : m_loggers)
103 l.logger->log_finish(l.os == nullptr ? os : *l.os);
104 }
105
106 void
107 log_build_info(std::ostream& os)
108 {
109 for (auto& l : m_loggers)
110 l.logger->log_build_info(l.os == nullptr ? os : *l.os);
111 }
112
113 void
114 test_unit_start(std::ostream& os, const test_unit& tu)
115 {
116 for (auto& l : m_loggers)
117 l.logger->test_unit_start(l.os == nullptr ? os : *l.os, tu);
118 }
119
120 void
121 test_unit_finish(std::ostream& os, const test_unit& tu, unsigned long elapsed)
122 {
123 for (auto& l : m_loggers)
124 l.logger->test_unit_finish(l.os == nullptr ? os : *l.os, tu, elapsed);
125 }
126
127 void
128 test_unit_skipped(std::ostream& os, const test_unit& tu)
129 {
130 for (auto& l : m_loggers)
131 l.logger->test_unit_skipped(l.os == nullptr ? os : *l.os, tu);
132 }
133
134#if BOOST_VERSION >= 105900
135 void
136 log_exception_start(std::ostream& os, const log_checkpoint_data& lcd, const execution_exception& ex)
137 {
138 for (auto& l : m_loggers)
139 l.logger->log_exception_start(l.os == nullptr ? os : *l.os, lcd, ex);
140 }
141
142 void
143 log_exception_finish(std::ostream& os)
144 {
145 for (auto& l : m_loggers)
146 l.logger->log_exception_finish(l.os == nullptr ? os : *l.os);
147 }
148#else
149 void
150 log_exception(std::ostream& os, const log_checkpoint_data& lcd, const execution_exception& ex)
151 {
152 for (auto& l : m_loggers)
153 l.logger->log_exception(l.os == nullptr ? os : *l.os, lcd, ex);
154 }
155#endif // BOOST_VERSION >= 105900
156
157 void
158 log_entry_start(std::ostream& os, const log_entry_data& entry_data, log_entry_types let)
159 {
160 for (auto& l : m_loggers)
161 l.logger->log_entry_start(l.os == nullptr ? os : *l.os, entry_data, let);
162 }
163
164 void
165 log_entry_value(std::ostream& os, const_string value)
166 {
167 for (auto& l : m_loggers)
168 l.logger->log_entry_value(l.os == nullptr ? os : *l.os, value);
169 }
170
171 void
172 log_entry_finish(std::ostream& os)
173 {
174 for (auto& l : m_loggers)
175 l.logger->log_entry_finish(l.os == nullptr ? os : *l.os);
176 }
177
178#if BOOST_VERSION >= 105900
179 void
180 entry_context_start(std::ostream& os, log_level level)
181 {
182 for (auto& l : m_loggers)
183 l.logger->entry_context_start(l.os == nullptr ? os : *l.os, level);
184 }
185
186 void
187 log_entry_context(std::ostream& os, const_string value)
188 {
189 for (auto& l : m_loggers)
190 l.logger->log_entry_context(l.os == nullptr ? os : *l.os, value);
191 }
192
193 void
194 entry_context_finish(std::ostream& os)
195 {
196 for (auto& l : m_loggers)
197 l.logger->entry_context_finish(l.os == nullptr ? os : *l.os);
198 }
199#endif // BOOST_VERSION >= 105900
200
201private:
202 struct LoggerInfo
203 {
204 std::shared_ptr<unit_test_log_formatter> logger;
205 std::shared_ptr<std::ostream> os;
206 };
207 std::vector<LoggerInfo> m_loggers;
208};
209
210} // namespace output
211} // namespace unit_test
212} // namespace boost
213
214#endif // NDN_TESTS_BOOST_MULTI_LOG_FORMATTER_HPP