/*
- * Copyright 2004-present Facebook, Inc.
+ * Copyright 2017-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
#include <folly/experimental/logging/FileHandlerFactory.h>
+#include <folly/experimental/logging/StreamHandlerFactory.h>
#include <folly/Exception.h>
#include <folly/experimental/TestUtil.h>
#include <folly/experimental/logging/ImmediateFileWriter.h>
#include <folly/experimental/logging/StandardLogHandler.h>
#include <folly/portability/GTest.h>
+#include <folly/test/TestUtils.h>
using namespace folly;
using folly::test::TemporaryFile;
size_t expectedMaxBufferSize) {
auto asyncWriter = dynamic_cast<const AsyncFileWriter*>(writer);
ASSERT_TRUE(asyncWriter)
- << "FileHandlerFactory should have created an AsyncFileWriter";
+ << "handler factory should have created an AsyncFileWriter";
EXPECT_EQ(expectedMaxBufferSize, asyncWriter->getMaxBufferSize());
// Make sure this refers to the expected output file
size_t expectedMaxBufferSize) {
auto asyncWriter = dynamic_cast<const AsyncFileWriter*>(writer);
ASSERT_TRUE(asyncWriter)
- << "FileHandlerFactory should have created an AsyncFileWriter";
+ << "handler factory should have created an AsyncFileWriter";
EXPECT_EQ(expectedMaxBufferSize, asyncWriter->getMaxBufferSize());
EXPECT_EQ(expectedFD, asyncWriter->getFile().fd());
}
FileHandlerFactory factory;
TemporaryFile tmpFile{"logging_test"};
- auto options = FileHandlerFactory::Options{
+ auto options = LogHandlerFactory::Options{
make_pair("path", tmpFile.path().string()),
};
auto handler = factory.createHandler(options);
auto formatter =
std::dynamic_pointer_cast<GlogStyleFormatter>(stdHandler->getFormatter());
EXPECT_TRUE(formatter)
- << "FileHandlerFactory should have created a GlogStyleFormatter";
+ << "handler factory should have created a GlogStyleFormatter";
checkAsyncWriter(
stdHandler->getWriter().get(),
AsyncFileWriter::kDefaultMaxBufferSize);
}
-TEST(FileHandlerFactory, stderrStream) {
- FileHandlerFactory factory;
+TEST(StreamHandlerFactory, stderrStream) {
+ StreamHandlerFactory factory;
TemporaryFile tmpFile{"logging_test"};
- auto options = FileHandlerFactory::Options{
+ auto options = StreamHandlerFactory::Options{
make_pair("stream", "stderr"),
};
auto handler = factory.createHandler(options);
auto formatter =
std::dynamic_pointer_cast<GlogStyleFormatter>(stdHandler->getFormatter());
EXPECT_TRUE(formatter)
- << "FileHandlerFactory should have created a GlogStyleFormatter";
+ << "handler factory should have created a GlogStyleFormatter";
checkAsyncWriter(
stdHandler->getWriter().get(),
AsyncFileWriter::kDefaultMaxBufferSize);
}
-TEST(FileHandlerFactory, stdoutWithMaxBuffer) {
- FileHandlerFactory factory;
+TEST(StreamHandlerFactory, stdoutWithMaxBuffer) {
+ StreamHandlerFactory factory;
TemporaryFile tmpFile{"logging_test"};
- auto options = FileHandlerFactory::Options{
+ auto options = StreamHandlerFactory::Options{
make_pair("stream", "stdout"),
make_pair("max_buffer_size", "4096"),
};
auto formatter =
std::dynamic_pointer_cast<GlogStyleFormatter>(stdHandler->getFormatter());
EXPECT_TRUE(formatter)
- << "FileHandlerFactory should have created a GlogStyleFormatter";
+ << "handler factory should have created a GlogStyleFormatter";
checkAsyncWriter(stdHandler->getWriter().get(), STDOUT_FILENO, 4096);
}
FileHandlerFactory factory;
TemporaryFile tmpFile{"logging_test"};
- auto options = FileHandlerFactory::Options{
+ auto options = LogHandlerFactory::Options{
make_pair("path", tmpFile.path().string()),
make_pair("max_buffer_size", "4096000"),
};
auto formatter =
std::dynamic_pointer_cast<GlogStyleFormatter>(stdHandler->getFormatter());
EXPECT_TRUE(formatter)
- << "FileHandlerFactory should have created a GlogStyleFormatter";
+ << "handler factory should have created a GlogStyleFormatter";
checkAsyncWriter(
stdHandler->getWriter().get(), tmpFile.path().string().c_str(), 4096000);
}
-TEST(FileHandlerFactory, nonAsyncStderr) {
- FileHandlerFactory factory;
+TEST(StreamHandlerFactory, nonAsyncStderr) {
+ StreamHandlerFactory factory;
TemporaryFile tmpFile{"logging_test"};
- auto options = FileHandlerFactory::Options{
+ auto options = LogHandlerFactory::Options{
make_pair("stream", "stderr"),
make_pair("async", "no"),
};
auto formatter =
std::dynamic_pointer_cast<GlogStyleFormatter>(stdHandler->getFormatter());
EXPECT_TRUE(formatter)
- << "FileHandlerFactory should have created a GlogStyleFormatter";
+ << "handler factory should have created a GlogStyleFormatter";
auto writer =
std::dynamic_pointer_cast<ImmediateFileWriter>(stdHandler->getWriter());
TEST(FileHandlerFactory, errors) {
FileHandlerFactory factory;
TemporaryFile tmpFile{"logging_test"};
+ using Options = LogHandlerFactory::Options;
{
- auto options = FileHandlerFactory::Options{};
- EXPECT_THROW(factory.createHandler(options), std::invalid_argument)
- << "one of path or stream required";
+ auto options = Options{};
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "no path specified for file handler");
}
{
- auto options = FileHandlerFactory::Options{
- make_pair("path", tmpFile.path().string()),
- make_pair("stream", "stderr"),
+ auto options = Options{
+ {"path", tmpFile.path().string()},
+ {"stream", "stderr"},
};
- EXPECT_THROW(factory.createHandler(options), std::invalid_argument)
- << "path and stream cannot both be specified";
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "unknown option \"stream\"");
}
{
- auto options = FileHandlerFactory::Options{
- make_pair("stream", "nonstdout"),
+ auto options = Options{
+ {"stream", "nonstdout"},
};
- EXPECT_THROW(factory.createHandler(options), std::invalid_argument)
- << "invalid stream";
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "unknown option \"stream\"");
}
{
- auto options = FileHandlerFactory::Options{
- make_pair("stream", "stderr"),
- make_pair("async", "foobar"),
+ auto options = Options{
+ {"path", tmpFile.path().string()},
+ {"async", "xyz"},
};
- EXPECT_THROW(factory.createHandler(options), std::invalid_argument)
- << "invalid async value";
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "^error processing option \"async\": Invalid value for bool: \"xyz\"$");
}
{
- auto options = FileHandlerFactory::Options{
- make_pair("stream", "stderr"),
- make_pair("async", "false"),
- make_pair("max_buffer_size", "1234"),
+ auto options = Options{
+ {"path", tmpFile.path().string()},
+ {"async", "false"},
+ {"max_buffer_size", "1234"},
};
- EXPECT_THROW(factory.createHandler(options), std::invalid_argument)
- << "max_buffer_size only valid for async writers";
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "the \"max_buffer_size\" option is only valid for async file handlers");
}
{
- auto options = FileHandlerFactory::Options{
- make_pair("stream", "stderr"),
- make_pair("max_buffer_size", "hello"),
+ auto options = Options{
+ {"path", tmpFile.path().string()},
+ {"max_buffer_size", "hello"},
};
- EXPECT_THROW(factory.createHandler(options), std::invalid_argument)
- << "max_buffer_size must be an integer";
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "^error processing option \"max_buffer_size\": "
+ "Non-digit character found: \"hello\"$");
}
{
- auto options = FileHandlerFactory::Options{
- make_pair("stream", "stderr"),
- make_pair("max_buffer_size", "0"),
+ auto options = Options{
+ {"path", tmpFile.path().string()},
+ {"max_buffer_size", "0"},
+ };
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "^error processing option \"max_buffer_size\": "
+ "must be a positive integer$");
+ }
+
+ {
+ auto options = Options{
+ {"path", tmpFile.path().string()},
+ {"foo", "bar"},
+ };
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "^unknown option \"foo\"$");
+ }
+}
+
+TEST(StreamHandlerFactory, errors) {
+ StreamHandlerFactory factory;
+ using Options = LogHandlerFactory::Options;
+
+ {
+ auto options = Options{};
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "no stream name specified for stream handler");
+ }
+
+ {
+ auto options = Options{
+ {"path", "/tmp/log.txt"},
+ {"stream", "stderr"},
+ };
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "unknown option \"path\"");
+ }
+
+ {
+ auto options = Options{
+ {"stream", "nonstdout"},
+ };
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "unknown stream \"nonstdout\": expected one of stdout or stderr");
+ }
+
+ {
+ auto options = Options{
+ {"stream", "stderr"},
+ {"async", "xyz"},
+ };
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "^error processing option \"async\": Invalid value for bool: \"xyz\"$");
+ }
+
+ {
+ auto options = Options{
+ {"stream", "stderr"},
+ {"async", "false"},
+ {"max_buffer_size", "1234"},
+ };
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "^the \"max_buffer_size\" option is only valid for "
+ "async file handlers$");
+ }
+
+ {
+ auto options = Options{
+ {"stream", "stderr"},
+ {"max_buffer_size", "hello"},
+ };
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "^error processing option \"max_buffer_size\": "
+ "Non-digit character found: \"hello\"$");
+ }
+
+ {
+ auto options = Options{
+ {"stream", "stderr"},
+ {"max_buffer_size", "0"},
};
- EXPECT_THROW(factory.createHandler(options), std::invalid_argument)
- << "max_buffer_size must be a positive integer";
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "^error processing option \"max_buffer_size\": "
+ "must be a positive integer$");
}
{
- auto options = FileHandlerFactory::Options{
+ auto options = Options{
make_pair("stream", "stderr"),
make_pair("foo", "bar"),
};
- EXPECT_THROW(factory.createHandler(options), std::invalid_argument)
- << "unknown parameter foo";
+ EXPECT_THROW_RE(
+ factory.createHandler(options),
+ std::invalid_argument,
+ "unknown option \"foo\"");
}
}