| // Copyright 2016 The Bazel Authors. All rights reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #include <fstream> | |
| #include <iostream> | |
| #include <memory> | |
| #include <string> | |
| #include "src/main/cpp/blaze_util_platform.h" | |
| #include "src/main/cpp/util/bazel_log_handler.h" | |
| #include "src/main/cpp/util/file.h" | |
| #include "src/main/cpp/util/logging.h" | |
| #include "src/main/cpp/util/path.h" | |
| #include "googlemock/include/gmock/gmock.h" | |
| #include "googletest/include/gtest/gtest.h" | |
| namespace blaze_util { | |
| using ::testing::HasSubstr; | |
| using ::testing::Not; | |
| // Note: gmock uses different regex syntax on different platforms. MatchesRegex | |
| // is still useful since the '.' wildcard can help match formatted log lines | |
| // like `[INFO 11:22:33.444 filename:134] message` | |
| // but should not be used for more fine grained testing. | |
| using ::testing::MatchesRegex; | |
| using ::testing::ContainsRegex; | |
| class LoggingTest : public ::testing::Test { | |
| protected: | |
| void SetUp() { | |
| // Set the value of $TMP first, because CaptureStderr retrieves a temp | |
| // directory path and on Windows, the corresponding function (GetTempPathA) | |
| // reads $TMP. | |
| blaze::SetEnv("TMP", blaze::GetPathEnv("TEST_TMPDIR")); | |
| } | |
| void TearDown() { blaze_util::SetLogHandler(nullptr); } | |
| }; | |
| TEST(LoggingTest, LogLevelNamesMatch) { | |
| EXPECT_STREQ("INFO", LogLevelName(LOGLEVEL_INFO)); | |
| EXPECT_STREQ("USER", LogLevelName(LOGLEVEL_USER)); | |
| EXPECT_STREQ("WARNING", LogLevelName(LOGLEVEL_WARNING)); | |
| EXPECT_STREQ("ERROR", LogLevelName(LOGLEVEL_ERROR)); | |
| EXPECT_STREQ("FATAL", LogLevelName(LOGLEVEL_FATAL)); | |
| } | |
| // Tests for when no log handler is set. | |
| TEST(LoggingTest, NoHandler_InfoLogsIgnored) { | |
| testing::internal::CaptureStderr(); | |
| blaze_util::SetLogHandler(nullptr); | |
| // Log something. | |
| std::string teststring = "test that the info log messages get ignored"; | |
| BAZEL_LOG(INFO) << teststring; | |
| // Check that stderr does not receive the message. | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, Not(HasSubstr(teststring))); | |
| } | |
| TEST(LoggingTest, NoHandler_UserLogsPrinted) { | |
| testing::internal::CaptureStderr(); | |
| blaze_util::SetLogHandler(nullptr); | |
| // Log something. | |
| std::string teststring = "test that the user log messages are not ignored"; | |
| BAZEL_LOG(USER) << teststring; | |
| // Check that stderr receives the message. | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, HasSubstr(teststring)); | |
| } | |
| TEST(LoggingTest, NoHandler_WarningsPrinted) { | |
| testing::internal::CaptureStderr(); | |
| blaze_util::SetLogHandler(nullptr); | |
| // Log something. | |
| BAZEL_LOG(WARNING) << "test that warnings are printed"; | |
| std::string expectedString = "WARNING: test that warnings are printed"; | |
| // Check that stderr receives the message. | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, HasSubstr(expectedString)); | |
| } | |
| TEST(LoggingTest, NoHandler_ErrorsPrinted) { | |
| testing::internal::CaptureStderr(); | |
| blaze_util::SetLogHandler(nullptr); | |
| // Log something. | |
| BAZEL_LOG(ERROR) << "test that errors are printed"; | |
| std::string expectedError = "ERROR: test that errors are printed"; | |
| // Check that stderr receives the message. | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, HasSubstr(expectedError)); | |
| } | |
| // Tests for the BazelLogHandler, with no call to SetLoggingOutputStream. | |
| TEST(LoggingTest, BazelLogHandler_DumpsToCerrAtDestruction) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| // Log something. | |
| std::string teststring = "test that log messages get dumped to stderr"; | |
| BAZEL_LOG(INFO) << teststring; | |
| // Check that stderr isn't getting anything yet. | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, Not(HasSubstr(teststring))); | |
| testing::internal::CaptureStderr(); | |
| // Destruct the log handler and get the stderr remains. | |
| blaze_util::SetLogHandler(nullptr); | |
| stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, HasSubstr(teststring)); | |
| } | |
| // Tests for the BazelLogHandler's buffer after SetLoggingOutputStream(nullptr). | |
| TEST(LoggingTest, BazelLogHandler_DoesNotDumpToStderrIfOuputStreamSetToNull) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| // Log something. | |
| std::string teststring = "test that this log message is lost."; | |
| BAZEL_LOG(INFO) << teststring; | |
| blaze_util::SetLoggingOutputStream(nullptr); | |
| // Destruct the log handler and check if stderr got anything. | |
| blaze_util::SetLogHandler(nullptr); | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, Not(HasSubstr(teststring))); | |
| } | |
| TEST(LoggingTest, BazelLogHandler_DoesNotPrintInfoLogsIfOuputStreamSetToNull) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| blaze_util::SetLoggingOutputStream(nullptr); | |
| std::string teststring = "test that the log message is lost."; | |
| BAZEL_LOG(INFO) << teststring; | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, Not(HasSubstr(teststring))); | |
| } | |
| TEST(LoggingTest, BazelLogHandler_PrintsUserLogsEvenIfOuputStreamSetToNull) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| blaze_util::SetLoggingOutputStream(nullptr); | |
| std::string teststring = "some user message"; | |
| BAZEL_LOG(USER) << teststring; | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, HasSubstr(teststring)); | |
| } | |
| TEST(LoggingTest, BazelLogHandler_PrintsWarningsEvenIfOuputStreamSetToNull) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| blaze_util::SetLoggingOutputStream(nullptr); | |
| BAZEL_LOG(WARNING) << "this is a warning"; | |
| std::string expectedWarning = "WARNING: this is a warning"; | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, HasSubstr(expectedWarning)); | |
| } | |
| TEST(LoggingTest, BazelLogHandler_PrintsErrorsEvenIfOuputStreamSetToNull) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| blaze_util::SetLoggingOutputStream(nullptr); | |
| BAZEL_LOG(ERROR) << "this is an error, alert!"; | |
| std::string expectedError = "ERROR: this is an error, alert!"; | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, HasSubstr(expectedError)); | |
| } | |
| TEST(LoggingTest, | |
| BazelLogHandler_BufferedInfoLogsGetLostEvenIfOutputStreamSetToNull) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| // Log something before telling the loghandler where to send it. | |
| std::string teststring = "this message should be lost."; | |
| BAZEL_LOG(INFO) << teststring; | |
| // Ask that the debug logs not be kept. | |
| blaze_util::SetLoggingOutputStream(nullptr); | |
| // Set a null log handler, which causes the BazelLogHandler to be destructed. | |
| // This prompts its logs to be flushed, so we can capture them. | |
| blaze_util::SetLogHandler(nullptr); | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, Not(HasSubstr(teststring))); | |
| } | |
| TEST(LoggingTest, | |
| BazelLogHandler_BufferedWarningLogsRedirectedAfterOutputStreamSetToNull) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| // Log something before telling the loghandler where to send it. | |
| std::string teststring = "test that this message gets directed to cerr"; | |
| BAZEL_LOG(WARNING) << teststring; | |
| std::string expectedWarning = | |
| "WARNING: test that this message gets directed to cerr"; | |
| // Ask that the debug logs not be kept. | |
| blaze_util::SetLoggingOutputStream(nullptr); | |
| // Set a null log handler, which causes the BazelLogHandler to be destructed. | |
| // This prompts its logs to be flushed, so we can capture them. | |
| blaze_util::SetLogHandler(nullptr); | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, HasSubstr(expectedWarning)); | |
| } | |
| // Tests for the BazelLogHandler & SetLoggingOutputStream | |
| TEST(LoggingTest, BazelLogHandler_DirectingLogsToBufferStreamWorks) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| // Ask that the logs get output to a string buffer (keep a ptr to it so we can | |
| // check its contents) | |
| std::unique_ptr<std::stringstream> stringbuf(new std::stringstream()); | |
| std::stringstream* stringbuf_ptr = stringbuf.get(); | |
| blaze_util::SetLoggingOutputStream(std::move(stringbuf)); | |
| std::string teststring = "testing log getting directed to a stringbuffer."; | |
| BAZEL_LOG(INFO) << teststring; | |
| // Check that output went to the buffer. | |
| std::string output(stringbuf_ptr->str()); | |
| EXPECT_THAT(output, HasSubstr(teststring)); | |
| // Check that the output never went to stderr. | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, Not(HasSubstr(teststring))); | |
| } | |
| TEST(LoggingTest, BazelLogHandler_BufferedLogsSentToSpecifiedStream) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| std::string teststring = | |
| "test sending logs to the buffer before setting the output stream"; | |
| BAZEL_LOG(INFO) << teststring; | |
| // Check that stderr isn't getting anything. | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, Not(HasSubstr(teststring))); | |
| testing::internal::CaptureStderr(); | |
| // Ask that the logs get output to a string buffer (keep a ptr to it so we can | |
| // check its contents) | |
| std::unique_ptr<std::stringstream> stringbuf(new std::stringstream()); | |
| std::stringstream* stringbuf_ptr = stringbuf.get(); | |
| blaze_util::SetLoggingOutputStream(std::move(stringbuf)); | |
| // Check that the buffered logs were sent. | |
| std::string output(stringbuf_ptr->str()); | |
| EXPECT_THAT(output, | |
| MatchesRegex(".INFO.* test sending logs to the buffer " | |
| "before setting the output stream\n")); | |
| // Check that the output did not go to stderr. | |
| stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, Not(HasSubstr(teststring))); | |
| } | |
| TEST(LoggingTest, BazelLogHandler_WarningsSentToBufferStream) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| // Ask that the logs get output to a string buffer (keep a ptr to it so we can | |
| // check its contents) | |
| std::unique_ptr<std::stringstream> stringbuf(new std::stringstream()); | |
| std::stringstream* stringbuf_ptr = stringbuf.get(); | |
| blaze_util::SetLoggingOutputStream(std::move(stringbuf)); | |
| std::string teststring = "test warning"; | |
| BAZEL_LOG(WARNING) << teststring; | |
| // Check that output went to the buffer. | |
| std::string output(stringbuf_ptr->str()); | |
| EXPECT_THAT(output, MatchesRegex(".WARNING.* test warning\n")); | |
| // Check that the output never went to stderr. | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, Not(HasSubstr(teststring))); | |
| } | |
| TEST(LoggingTest, BazelLogHandler_ErrorsSentToBufferStream) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| // Ask that the logs get output to a string buffer (keep a ptr to it so we can | |
| // check its contents) | |
| std::unique_ptr<std::stringstream> stringbuf(new std::stringstream()); | |
| std::stringstream* stringbuf_ptr = stringbuf.get(); | |
| blaze_util::SetLoggingOutputStream(std::move(stringbuf)); | |
| std::string teststring = "test error"; | |
| BAZEL_LOG(ERROR) << teststring; | |
| // Check that output went to the buffer. | |
| std::string output(stringbuf_ptr->str()); | |
| EXPECT_THAT(output, MatchesRegex(".ERROR.* test error\n")); | |
| // Check that the output never went to stderr. | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, Not(HasSubstr(teststring))); | |
| } | |
| TEST(LoggingTest, BazelLogHandler_ImpossibleFile) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| // Deliberately try to log to an impossible location, check that we error out. | |
| std::unique_ptr<std::ofstream> bad_logfile_stream_( | |
| new std::ofstream("/this/doesnt/exist.log", std::fstream::out)); | |
| blaze_util::SetLoggingOutputStream(std::move(bad_logfile_stream_)); | |
| // Set a null log handler, which causes the BazelLogHandler to be destructed. | |
| // This prompts its logs to be flushed, so we can capture them.. | |
| blaze_util::SetLogHandler(nullptr); | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, | |
| MatchesRegex(".ERROR.* Provided stream failed.\n")); | |
| } | |
| // Tests for the BazelLogHandler & SetLoggingOutputStreamToStderr | |
| TEST(LoggingTest, BazelLogHandler_DirectingLogsToCerrWorks) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| // Ask that the logs get output to stderr | |
| blaze_util::SetLoggingOutputStreamToStderr(); | |
| // Log something. | |
| std::string teststring = "test that the log messages get directed to cerr"; | |
| BAZEL_LOG(INFO) << teststring; | |
| // Set a null log handler, which causes the BazelLogHandler to be destructed. | |
| // This prompts its logs to be flushed, so we can capture them. | |
| blaze_util::SetLogHandler(nullptr); | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, HasSubstr(teststring)); | |
| } | |
| TEST(LoggingTest, BazelLogHandler_BufferedLogsGetDirectedToCerr) { | |
| // Set up logging and be prepared to capture stderr at destruction. | |
| testing::internal::CaptureStderr(); | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| // Log something before telling the loghandler where to send it. | |
| std::string teststring = "test that this message gets directed to cerr"; | |
| BAZEL_LOG(INFO) << teststring; | |
| // Ask that the logs get output to stderr | |
| blaze_util::SetLoggingOutputStreamToStderr(); | |
| // Set a null log handler, which causes the BazelLogHandler to be destructed. | |
| // This prompts its logs to be flushed, so we can capture them. | |
| blaze_util::SetLogHandler(nullptr); | |
| std::string stderr_output = testing::internal::GetCapturedStderr(); | |
| EXPECT_THAT(stderr_output, HasSubstr(teststring)); | |
| } | |
| // We use the LoggingDeathTest test case to make sure that the death tests are | |
| // run in a single threaded environment, where it is safe to fork. These tests | |
| // are run before the other tests, which can be run in parallel. | |
| #if GTEST_HAS_DEATH_TEST | |
| using LoggingDeathTest = LoggingTest; | |
| TEST(LoggingDeathTest, NoHandler_FatalStatementUsesInternalErrorCode) { | |
| // When no handler is specified, we still expect fatal messages to get | |
| // printed to stderr. | |
| ASSERT_EXIT({ BAZEL_LOG(FATAL) << "something's wrong!"; }, | |
| ::testing::ExitedWithCode(37), "FATAL: something's wrong!"); | |
| } | |
| TEST(LoggingDeathTest, | |
| BazelLogHandler_UnsetOutputStream_FatalStatementUsesInternalErrorCode) { | |
| ASSERT_EXIT( | |
| { | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| BAZEL_LOG(FATAL) << "something's wrong!"; | |
| }, | |
| ::testing::ExitedWithCode(37), "\\[FATAL .*\\] something's wrong!"); | |
| } | |
| TEST(LoggingDeathTest, | |
| BazelLogHandler_Deactivated_FatalStatementUsesInternalErrorCode) { | |
| ASSERT_EXIT( | |
| { | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| blaze_util::SetLoggingOutputStream(nullptr); | |
| BAZEL_LOG(FATAL) << "something's wrong!"; | |
| }, | |
| ::testing::ExitedWithCode(37), "FATAL: something's wrong!"); | |
| } | |
| TEST(LoggingDeathTest, | |
| BazelLogHandler_Stderr_FatalStatementUsesInternalErrorCode) { | |
| ASSERT_EXIT( | |
| { | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| blaze_util::SetLoggingOutputStreamToStderr(); | |
| BAZEL_LOG(FATAL) << "something's wrong!"; | |
| }, | |
| ::testing::ExitedWithCode(37), "\\[FATAL .*\\] something's wrong!"); | |
| } | |
| TEST(LoggingDeathTest, NoHandler_BazelDieDiesWithCustomExitCode) { | |
| ASSERT_EXIT({ BAZEL_DIE(42) << "dying with exit code 42."; }, | |
| ::testing::ExitedWithCode(42), "FATAL: dying with exit code 42."); | |
| } | |
| TEST(LoggingDeathTest, | |
| BazelLogHandler_UnsetOutputStream_BazelDieDiesWithCustomExitCode) { | |
| ASSERT_EXIT( | |
| { | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| BAZEL_DIE(42) << "dying with exit code 42."; | |
| }, | |
| ::testing::ExitedWithCode(42), | |
| "\\[FATAL .*\\] dying with exit code 42."); | |
| } | |
| TEST(LoggingDeathTest, | |
| BazelLogHandler_Deactivated_BazelDieDiesWithCustomExitCode) { | |
| ASSERT_EXIT( | |
| { | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| blaze_util::SetLoggingOutputStream(nullptr); | |
| BAZEL_DIE(42) << "dying with exit code 42."; | |
| }, | |
| ::testing::ExitedWithCode(42), "FATAL: dying with exit code 42."); | |
| } | |
| TEST(LoggingDeathTest, BazelLogHandler_Stderr_BazelDieDiesWithCustomExitCode) { | |
| ASSERT_EXIT( | |
| { | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| blaze_util::SetLoggingOutputStreamToStderr(); | |
| BAZEL_DIE(42) << "dying with exit code 42."; | |
| }, | |
| ::testing::ExitedWithCode(42), | |
| "\\[FATAL .*\\] dying with exit code 42."); | |
| } | |
| TEST(LoggingDeathTest, | |
| BazelLogHandler_CustomStream_BazelDiePrintsToStderrAndCustomStream) { | |
| std::string logfile = | |
| blaze_util::JoinPath(blaze::GetPathEnv("TEST_TMPDIR"), "logfile"); | |
| ASSERT_EXIT( | |
| { | |
| std::unique_ptr<blaze_util::BazelLogHandler> handler( | |
| new blaze_util::BazelLogHandler()); | |
| blaze_util::SetLogHandler(std::move(handler)); | |
| // Ask that the logs get output to a file (the string buffer setup used | |
| // in the non-death tests doesn't work here.) | |
| std::unique_ptr<std::ofstream> logfile_stream_( | |
| new std::ofstream(logfile, std::fstream::out)); | |
| blaze_util::SetLoggingOutputStream(std::move(logfile_stream_)); | |
| BAZEL_DIE(42) << "dying with exit code 42."; | |
| }, | |
| ::testing::ExitedWithCode(42), "FATAL: dying with exit code 42."); | |
| // Check that the error is also in the custom stream. | |
| std::string output; | |
| ASSERT_TRUE(blaze_util::ReadFile(logfile, &output)); | |
| // Unlike in earlier tests, this string is read from a file, and since Windows | |
| // uses the newline '\r\n', compared to the linux \n, we prefer to keep the | |
| // test simple and not test the end of the line explicitly. | |
| EXPECT_THAT(output, | |
| ContainsRegex("\\[FATAL .*\\] dying with exit code 42.")); | |
| } | |
| #endif // GTEST_HAS_DEATH_TEST | |
| } // namespace blaze_util |