10#include <framework/utilities/IOIntercept.h>
11#include <framework/utilities/testhelpers/Fixtures.h>
12#include <gtest/gtest.h>
18 using logconvert_params_t = std::tuple<LogConfig::ELogLevel, std::string, std::string, bool, bool>;
24 using IOInterceptDeathTest = IOInterceptTest;
27 class IOInterceptParamTest:
public IOInterceptTest,
public ::testing::WithParamInterface<logconvert_params_t> {};
30 TEST_P(IOInterceptParamTest, ConvertToLogMessage)
34 std::string raw_message, formatted_message;
35 bool useStdout, generateMessage;
36 std::tie(level, raw_message, formatted_message, useStdout, generateMessage) = GetParam();
40 (useStdout ? std::cout : std::cerr) << raw_message;
43 expectMessage(level, generateMessage ? 1 : 0,
true);
44 if (!generateMessage)
return;
46 expectMessageContent(level,
"Output from capture_name:\ncapture_name: " + formatted_message);
52 logconvert_params_t logconvert_params[] = {
79 INSTANTIATE_TEST_SUITE_P(Params, IOInterceptParamTest, ::testing::ValuesIn(logconvert_params));
82 TEST_F(IOInterceptTest, LogMessagesNoFinish)
86 logmessages.setIndent(
"-");
88 std::cout <<
"this is my message";
93 expectMessageContent(
LogConfig::c_Info,
"Output from capture_name:\n-this is my message");
97 TEST_F(IOInterceptTest, InterceptGuard)
100 logmessages.setIndent(
"-");
103 std::cout <<
"this is my message";
105 std::cout <<
"this will not be captured" << std::endl;
109 std::cerr <<
"this is my error";
111 std::cerr <<
"this will not be captured" << std::endl;
112 ASSERT_EQ(m_messages.size(), 2);
114 expectMessageContent(
LogConfig::c_Error,
"Output from capture_name:\n-this is my error");
115 m_messages.pop_back();
116 expectMessageContent(
LogConfig::c_Info,
"Output from capture_name:\n-this is my message");
120 TEST_F(IOInterceptTest, ConvertCheckIndent)
124 std::cout <<
"this is\na multi line message";
127 expectMessageContent(
LogConfig::c_Info,
"Output from indent:\nindent: this is\nindent: a multi line message");
131 TEST_F(IOInterceptTest, ConvertSetIndent)
135 std::cout <<
"this is\na multi line message";
136 capture.setIndent(
"--->");
139 expectMessageContent(
LogConfig::c_Info,
"Output from indent:\n--->this is\n--->a multi line message");
143 TEST_F(IOInterceptTest, ConvertEmptyIndent)
147 capture.setIndent(
"");
148 std::cout <<
"this is\na multi line message";
151 expectMessageContent(
LogConfig::c_Info,
"Output from indent:\nthis is\na multi line message");
155 TEST_F(IOInterceptTest, CaptureStdOut)
158 ASSERT_FALSE(capture.
finish());
159 ASSERT_TRUE(capture.
start());
160 ASSERT_TRUE(capture.
start());
161 std::cout <<
"this is a test";
162 ASSERT_TRUE(capture.
finish());
163 ASSERT_EQ(capture.
getStdOut(),
"this is a test");
164 ASSERT_FALSE(capture.
finish());
165 ASSERT_EQ(capture.
getStdOut(),
"this is a test");
168 ASSERT_TRUE(capture.
start());
169 write(fileno(stdout),
"this is a test", 14);
170 ASSERT_TRUE(capture.
finish());
171 ASSERT_EQ(capture.
getStdOut(),
"this is a test");
175 TEST_F(IOInterceptTest, CaptureStdErr)
178 ASSERT_FALSE(capture.
finish());
179 ASSERT_TRUE(capture.
start());
180 ASSERT_TRUE(capture.
start());
181 std::cerr <<
"this is a test";
182 ASSERT_TRUE(capture.
finish());
183 ASSERT_EQ(capture.
getStdErr(),
"this is a test");
184 ASSERT_FALSE(capture.
finish());
185 ASSERT_EQ(capture.
getStdErr(),
"this is a test");
188 ASSERT_TRUE(capture.
start());
189 write(fileno(stderr),
"this is a test", 14);
190 ASSERT_TRUE(capture.
finish());
191 ASSERT_EQ(capture.
getStdErr(),
"this is a test");
195 TEST_F(IOInterceptTest, CaptureLargeOutput)
198 ASSERT_TRUE(capture.
start());
201 for (
int i = 0; i < 100000; ++i) {
202 std::cout << (char)(i % 255) << std::flush;
203 if (std::cout.good()) written = i + 1;
204 out.push_back(i % 255);
206 ASSERT_TRUE(capture.
finish());
207 const std::string& captured = capture.
getStdOut();
211 ASSERT_TRUE(captured.size() <= out.size());
212 ASSERT_EQ(captured.size(), written);
213 if (captured.size() < out.size()) {
214 std::cout <<
"Output truncated after " << captured.size() <<
" bytes" << std::endl;
216 ASSERT_EQ(captured, out.substr(0, captured.size()));
218 ASSERT_TRUE(capture.
start());
219 std::cout <<
"once more";
220 ASSERT_TRUE(capture.
finish());
221 ASSERT_EQ(capture.
getStdOut(),
"once more");
224 ASSERT_TRUE(capture.
start());
226 ASSERT_TRUE(capture.
finish());
227 ASSERT_EQ(capture.
getStdOut(),
"once more");
233 void generateStdErr()
236 std::cerr <<
"start->";
238 std::cerr <<
"this should not show up" << std::endl << std::flush;
239 write(fileno(stderr),
"nor this\n", 9);
241 std::cerr <<
"<-end";
246 TEST_F(IOInterceptDeathTest, DiscardStdOut)
249 ASSERT_FALSE(discard.
finish());
250 ASSERT_TRUE(discard.
start());
251 ASSERT_TRUE(discard.
start());
252 ASSERT_TRUE(discard.
finish());
253 ASSERT_FALSE(discard.
finish());
256 EXPECT_EXIT(generateStdErr(), ::testing::ExitedWithCode(0),
"^start-><-end$");
264 std::cerr <<
"start->";
266 std::cerr <<
"now we abort" << std::endl;
271 TEST_F(IOInterceptDeathTest, HandleAbort)
273 EXPECT_EXIT(generateAbort(), ::testing::ExitedWithCode(1),
"^start->now we abort\nabort\\(\\) called, exiting\n$");
Class to intercept stdout and stderr and either capture, discard or keep them unmodified depending on...
const std::string & getStdOut() const
Return the captured stdout output if any.
bool start()
Start intercepting the output.
bool finish()
Finish intercepting the output.
const std::string & getStdErr() const
Return the captured stderr output if any.
Simple RAII guard for output interceptor.
Capture stdout and stderr and convert into log messages.
ELogLevel
Definition of the supported log levels.
@ c_Error
Error: for things that went wrong and have to be fixed.
@ c_Info
Info: for informational messages, e.g.
@ c_Warning
Warning: for potential problems that the user should pay attention to.
@ c_Result
Result: for informational summary messages, e.g.
Test fixture to be able to check the contents and types of emitted log messages in detail.
InterceptorScopeGuard< T > start_intercept(T &interceptor)
Convenience wrapper to simplify use of InterceptorScopeGuard<T>.
Abstract base class for different kinds of events.