| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- //
- // file_appender_test.cxx
- // logger_test
- //
- // Created by Sam Jaffe on 4/13/19.
- //
- #include <cstdlib>
- #include <fstream>
- #include <gmock/gmock.h>
- #include "resource_factory/prototype_factory.hpp"
- #include "logger/exception.h"
- #include "logger/log_manager.h"
- #include "logger/properties.h"
- #include "logger_impl.h"
- #include "mock_logger.h"
- class FileAppenderTest : public testing::Test {
- protected:
- void SetUp() override;
- void TearDown() override;
- std::string filename() const { return data; }
- std::shared_ptr<logging::log_appender> get(logging::properties const &) const;
- private:
- std::shared_ptr<StubLayout> playout;
- char data[24];
- };
- void FileAppenderTest::SetUp() {
- strncpy(data, "test_log_fileXXXXXX.log", sizeof(data));
- int fd = -1;
- if ((fd = mkstemps(data, 4)) != -1) {
- close(fd); // We'll open this elsewhere
- } else {
- throw std::runtime_error(strerror(errno));
- }
- playout.reset(new StubLayout);
- }
- void FileAppenderTest::TearDown() {
- playout.reset();
- remove(data);
- memset(data, 0, sizeof(data));
- }
- std::shared_ptr<logging::log_appender>
- FileAppenderTest::get(logging::properties const & props) const {
- auto pappender = logging::appenders::instance().get("File", props);
- return std::make_shared<logging::log_appender>(pappender, playout);
- }
- TEST_F(FileAppenderTest, ThrowsIfNoFilename) {
- EXPECT_THROW(logging::appenders::instance().get("File", {}),
- logging::invalid_property_type);
- }
- std::string slurp(std::string const & filename) {
- std::ifstream in(filename);
- std::stringstream ss;
- ss << in.rdbuf();
- return ss.str();
- }
- TEST_F(FileAppenderTest, WritesFile) {
- using namespace logging;
- using namespace logging::property;
- properties props{_obj({{"filename", _v(filename())}})};
- using testing::Eq;
- logpacket pkt{{}, level::error, {}, {}, "This is a test message"};
- EXPECT_NO_THROW(get(props)->write(pkt));
- EXPECT_THAT(slurp(filename()), Eq("This is a test message"));
- }
- TEST_F(FileAppenderTest, WillNotLogBelowThreshold) {
- using namespace logging;
- using namespace logging::property;
- properties props{_obj({{"filename", _v(filename())}})};
- EXPECT_FALSE(get(props)->should_log(level::warn));
- EXPECT_TRUE(get(props)->should_log(level::error));
- }
- TEST_F(FileAppenderTest, AppendsToFile) {
- using namespace logging;
- using namespace logging::property;
- properties props{_obj({{"filename", _v(filename())}})};
- using testing::Eq;
- logpacket pkt{{}, level::error, {}, {}, "Test"};
- for (int i = 0; i < 2; ++i) {
- EXPECT_NO_THROW(get(props)->write(pkt));
- }
- EXPECT_THAT(slurp(filename()), Eq("TestTest"));
- }
- TEST_F(FileAppenderTest, OverwritesFileWithSetting) {
- using namespace logging;
- using namespace logging::property;
- properties props{
- _obj({{"filename", _v(filename())}, {"fileAppend", _v(false)}})};
- using testing::Eq;
- logpacket pkt{{}, level::error, {}, {}, "Test"};
- for (int i = 0; i < 2; ++i) {
- EXPECT_NO_THROW(get(props)->write(pkt));
- }
- EXPECT_THAT(slurp(filename()), Eq("Test"));
- }
- TEST_F(FileAppenderTest, CanWriteBufferedData) {
- using namespace logging;
- using namespace logging::property;
- properties props{_obj({{"immediateFlush", _v(false)},
- {"filename", _v(filename())},
- {"bufferedIO", _v(true)},
- {"bufferSize", _v(256)}})};
- using testing::Eq;
- logpacket pkt{{}, level::error, {}, {}, "Test"};
- EXPECT_NO_THROW(get(props)->write(pkt));
- // We can't really test the results here, because the standard library is in
- // control of the actual writes...
- }
- TEST_F(FileAppenderTest, WillThrowIfCannotOpenFile) {
- using namespace logging;
- using namespace logging::property;
- properties props{
- _obj({{"filename", _v("./fake_directory_for_testing/file.log")}})};
- EXPECT_THROW(get(props), std::runtime_error);
- }
|