/*
- * 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.
#include <folly/futures/Future.h>
#include <folly/futures/Promise.h>
#include <folly/init/Init.h>
+#include <folly/lang/SafeAssert.h>
#include <folly/portability/GFlags.h>
#include <folly/portability/GMock.h>
#include <folly/portability/GTest.h>
sched_yield();
}
}
+ tmpFile.close();
std::string data;
auto ret = folly::readFile(tmpFile.path().string().c_str(), data);
EXPECT_EQ(expected, data);
}
-#ifndef _WIN32
namespace {
static std::vector<std::string>* internalWarnings;
std::string&& msg) {
internalWarnings->emplace_back(std::move(msg));
}
-}
+} // namespace
TEST(AsyncFileWriter, ioError) {
// Set the LoggerDB internal warning handler so we can record the messages
std::array<int, 2> fds;
auto rc = pipe(fds.data());
folly::checkUnixError(rc, "failed to create pipe");
+#ifndef _WIN32
signal(SIGPIPE, SIG_IGN);
+#endif
::close(fds[0]);
// Log a bunch of messages to the writer
// AsyncFileWriter should have some internal warning messages about the
// log failures. This will generally be many fewer than the number of
// messages we wrote, though, since it performs write batching.
+ //
+ // GTest on Windows doesn't support alternation in the regex syntax -_-....
+ const std::string kExpectedErrorMessage =
+#if _WIN32
+ // The `pipe` call above is actually implemented via sockets, so we get
+ // a different error message.
+ "An established connection was aborted by the software in your host machine\\.";
+#else
+ "Broken pipe";
+#endif
+
for (const auto& msg : logErrors) {
EXPECT_THAT(
msg,
testing::ContainsRegex(
- "error writing to log file .* in AsyncFileWriter.*: Broken pipe"));
+ "error writing to log file .* in AsyncFileWriter.*: " +
+ kExpectedErrorMessage));
}
EXPECT_GT(logErrors.size(), 0);
EXPECT_LE(logErrors.size(), numMessages);
return totalBytes;
}
-}
+} // namespace
TEST(AsyncFileWriter, flush) {
// Set up a pipe(), then write data to the write endpoint until it fills up
// Make sure flush completes successfully now
future.get(10ms);
}
-#endif
// A large-ish message suffix, just to consume space and help fill up
// log buffers faster.
: deadline_{steady_clock::now() +
milliseconds{FLAGS_async_discard_timeout_msec}},
readSleepUS_{static_cast<uint64_t>(
- std::min(0L, FLAGS_async_discard_read_sleep_usec))} {}
+ std::min(int64_t{0}, FLAGS_async_discard_read_sleep_usec))} {}
void clearSleepDuration() {
readSleepUS_.store(0);
}
void writerFinished(size_t threadID, size_t messagesWritten, uint32_t flags) {
auto map = perThreadWriteData_.wlock();
- assert(map->find(threadID) == map->end());
+ FOLLY_SAFE_CHECK(
+ map->find(threadID) == map->end(),
+ "multiple writer threads with same ID");
auto& data = (*map)[threadID];
data.numMessagesWritten = messagesWritten;
data.flags = flags;
int main(int argc, char* argv[]) {
testing::InitGoogleTest(&argc, argv);
folly::init(&argc, &argv);
- // Don't use async logging in the async logging tests :-)
- folly::initLoggingGlogStyle(FLAGS_logging, LogLevel::INFO, /* async */ false);
+ folly::initLogging(FLAGS_logging);
return RUN_ALL_TESTS();
}