From df39c67591139cf2eef190f37bd0e82f086f0908 Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Wed, 30 Jan 2019 12:27:43 -0500 Subject: [PATCH 01/13] filesystem: break out RawFile/RawInstance from File/Instance The RawFile + RawInstance classes will be used to hold platform-specific filesystem code. The File/Instance classes will be used to add stats collecting and periodic flushing -- they will be platform agnostic. This is step 2/3 in adding Windows filesystem support. Signed-off-by: Sam Smith Signed-off-by: Sophie Wigmore --- include/envoy/api/os_sys_calls.h | 13 +- include/envoy/filesystem/filesystem.h | 121 +++++-- source/common/api/BUILD | 1 + source/common/api/api_impl.cc | 2 +- source/common/api/api_impl.h | 4 + source/common/api/os_sys_calls_impl.cc | 10 - source/common/api/os_sys_calls_impl.h | 2 - source/common/filesystem/BUILD | 12 +- source/common/filesystem/filesystem_impl.cc | 118 ++----- source/common/filesystem/filesystem_impl.h | 22 +- source/common/filesystem/raw_instance_impl.cc | 144 ++++++++ source/common/filesystem/raw_instance_impl.h | 42 +++ test/common/filesystem/BUILD | 18 +- .../common/filesystem/filesystem_impl_test.cc | 312 ++++++------------ .../filesystem/raw_instance_impl_test.cc | 213 ++++++++++++ test/mocks/api/mocks.cc | 22 +- test/mocks/api/mocks.h | 11 - test/mocks/filesystem/mocks.cc | 39 ++- test/mocks/filesystem/mocks.h | 45 +++ 19 files changed, 743 insertions(+), 408 deletions(-) create mode 100644 source/common/filesystem/raw_instance_impl.cc create mode 100644 source/common/filesystem/raw_instance_impl.h create mode 100644 test/common/filesystem/raw_instance_impl_test.cc diff --git a/include/envoy/api/os_sys_calls.h b/include/envoy/api/os_sys_calls.h index 51f90a1afa6d4..d3edee58fa6df 100644 --- a/include/envoy/api/os_sys_calls.h +++ b/include/envoy/api/os_sys_calls.h @@ -34,6 +34,7 @@ typedef SysCallResult SysCallIntResult; typedef SysCallResult SysCallSizeResult; typedef SysCallResult SysCallPtrResult; typedef SysCallResult SysCallStringResult; +typedef SysCallResult SysCallBoolResult; class OsSysCalls { public: @@ -49,18 +50,6 @@ class OsSysCalls { */ virtual SysCallIntResult ioctl(int sockfd, unsigned long int request, void* argp) PURE; - /** - * Open file by full_path with given flags and mode. - * @return file descriptor. - */ - virtual SysCallIntResult open(const std::string& full_path, int flags, int mode) PURE; - - /** - * Write num_bytes to fd from buffer. - * @return number of bytes written if non negative, otherwise error code. - */ - virtual SysCallSizeResult write(int fd, const void* buffer, size_t num_bytes) PURE; - /** * @see writev (man 2 writev) */ diff --git a/include/envoy/filesystem/filesystem.h b/include/envoy/filesystem/filesystem.h index 63915bee12f28..35f7164e7a9f8 100644 --- a/include/envoy/filesystem/filesystem.h +++ b/include/envoy/filesystem/filesystem.h @@ -14,58 +14,56 @@ namespace Envoy { namespace Filesystem { /** - * Abstraction for a file on disk. + * Abstraction for a basic file on disk. */ -class File { +class RawFile { public: - virtual ~File() {} + virtual ~RawFile() {} /** - * Write data to the file. + * Open the file with O_RDWR | O_APPEND | O_CREAT + * The file will be closed when this object is destructed + * + * @return bool whether the open succeeded */ - virtual void write(absl::string_view) PURE; + virtual Api::SysCallBoolResult open() PURE; /** - * Reopen the file. + * Write the buffer to the file. The file must be explicitly opened before writing. + * + * @return ssize_t number of bytes written, or -1 for failure */ - virtual void reopen() PURE; + virtual Api::SysCallSizeResult write(absl::string_view buffer) PURE; /** - * Synchronously flush all pending data to disk. + * Close the file. + * + * @return bool whether the close succeeded */ - virtual void flush() PURE; -}; + virtual Api::SysCallBoolResult close() PURE; -typedef std::shared_ptr FileSharedPtr; - -/** - * Captures state, properties, and stats of a file-system. - */ -class Instance { -public: - virtual ~Instance() {} + /** + * @return bool is the file open + */ + virtual bool isOpen() PURE; /** - * Creates a file, overriding the flush-interval set in the class. - * - * @param path The path of the file to open. - * @param dispatcher The dispatcher used for set up timers to run flush(). - * @param lock The lock. - * @param file_flush_interval_msec Number of milliseconds to delay before flushing. + * @return string the file path */ - virtual FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, - Thread::BasicLockable& lock, - std::chrono::milliseconds file_flush_interval_msec) PURE; + virtual std::string path() PURE; +}; + +typedef std::unique_ptr RawFilePtr; + +class RawInstance { +public: + virtual ~RawInstance() {} /** - * Creates a file, using the default flush-interval for the class. - * - * @param path The path of the file to open. - * @param dispatcher The dispatcher used for set up timers to run flush(). - * @param lock The lock. + * @param path The path of the RawFile + * @return a RawFilePtr. The file is not opened. */ - virtual FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, - Thread::BasicLockable& lock) PURE; + virtual RawFilePtr createRawFile(const std::string& path) PURE; /** * @return bool whether a file exists on disk and can be opened for read. @@ -109,6 +107,61 @@ class Instance { virtual bool illegalPath(const std::string& path) PURE; }; +/** + * Abstraction for a file on disk. It is specifically designed for writing access logs. + */ +class File { +public: + virtual ~File() {} + + /** + * Write data to the file. + */ + virtual void write(absl::string_view) PURE; + + /** + * Reopen the file. + */ + virtual void reopen() PURE; + + /** + * Synchronously flush all pending data to disk. + */ + virtual void flush() PURE; +}; + +typedef std::shared_ptr FileSharedPtr; + +/** + * Captures state, properties, and stats of a file-system. + */ +class Instance : public RawInstance { +public: + virtual ~Instance() {} + + /** + * Creates a file, overriding the flush-interval set in the class. + * + * @param path The path of the file to open. + * @param dispatcher The dispatcher used for set up timers to run flush(). + * @param lock The lock. + * @param file_flush_interval_msec Number of milliseconds to delay before flushing. + */ + virtual FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, + Thread::BasicLockable& lock, + std::chrono::milliseconds file_flush_interval_msec) PURE; + + /** + * Creates a file, using the default flush-interval for the class. + * + * @param path The path of the file to open. + * @param dispatcher The dispatcher used for set up timers to run flush(). + * @param lock The lock. + */ + virtual FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, + Thread::BasicLockable& lock) PURE; +}; + typedef std::unique_ptr WatcherPtr; enum class FileType { Regular, Directory, Other }; diff --git a/source/common/api/BUILD b/source/common/api/BUILD index c42676952895d..02d0b50293b1c 100644 --- a/source/common/api/BUILD +++ b/source/common/api/BUILD @@ -18,6 +18,7 @@ envoy_cc_library( "//source/common/common:thread_lib", "//source/common/event:dispatcher_lib", "//source/common/filesystem:filesystem_lib", + "//source/common/filesystem:raw_instance_lib", ], ) diff --git a/source/common/api/api_impl.cc b/source/common/api/api_impl.cc index 4f93d2b0417aa..e31c6a917928c 100644 --- a/source/common/api/api_impl.cc +++ b/source/common/api/api_impl.cc @@ -12,7 +12,7 @@ namespace Api { Impl::Impl(std::chrono::milliseconds file_flush_interval_msec, Thread::ThreadFactory& thread_factory, Stats::Store& stats_store) : thread_factory_(thread_factory), - file_system_(file_flush_interval_msec, thread_factory, stats_store) {} + file_system_(file_flush_interval_msec, thread_factory, stats_store, raw_instance_) {} Event::DispatcherPtr Impl::allocateDispatcher(Event::TimeSystem& time_system) { return std::make_unique(time_system, *this); diff --git a/source/common/api/api_impl.h b/source/common/api/api_impl.h index 8223e7d90443c..340206d937040 100644 --- a/source/common/api/api_impl.h +++ b/source/common/api/api_impl.h @@ -9,6 +9,7 @@ #include "envoy/thread/thread.h" #include "common/filesystem/filesystem_impl.h" +#include "common/filesystem/raw_instance_impl.h" namespace Envoy { namespace Api { @@ -28,6 +29,9 @@ class Impl : public Api { private: Thread::ThreadFactory& thread_factory_; + // TODO(sesmith177): Inject a RawInstance& when we have separate versions + // for POSIX / Windows + Filesystem::RawInstanceImpl raw_instance_; Filesystem::InstanceImpl file_system_; }; diff --git a/source/common/api/os_sys_calls_impl.cc b/source/common/api/os_sys_calls_impl.cc index c6e6a43c17e15..e0c42130a9076 100644 --- a/source/common/api/os_sys_calls_impl.cc +++ b/source/common/api/os_sys_calls_impl.cc @@ -18,21 +18,11 @@ SysCallIntResult OsSysCallsImpl::ioctl(int sockfd, unsigned long int request, vo return {rc, errno}; } -SysCallIntResult OsSysCallsImpl::open(const std::string& full_path, int flags, int mode) { - const int rc = ::open(full_path.c_str(), flags, mode); - return {rc, errno}; -} - SysCallIntResult OsSysCallsImpl::close(int fd) { const int rc = ::close(fd); return {rc, errno}; } -SysCallSizeResult OsSysCallsImpl::write(int fd, const void* buffer, size_t num_bytes) { - const ssize_t rc = ::write(fd, buffer, num_bytes); - return {rc, errno}; -} - SysCallSizeResult OsSysCallsImpl::writev(int fd, const iovec* iovec, int num_iovec) { const ssize_t rc = ::writev(fd, iovec, num_iovec); return {rc, errno}; diff --git a/source/common/api/os_sys_calls_impl.h b/source/common/api/os_sys_calls_impl.h index eed6d1798645f..c5991190b7fc2 100644 --- a/source/common/api/os_sys_calls_impl.h +++ b/source/common/api/os_sys_calls_impl.h @@ -12,8 +12,6 @@ class OsSysCallsImpl : public OsSysCalls { // Api::OsSysCalls SysCallIntResult bind(int sockfd, const sockaddr* addr, socklen_t addrlen) override; SysCallIntResult ioctl(int sockfd, unsigned long int request, void* argp) override; - SysCallIntResult open(const std::string& full_path, int flags, int mode) override; - SysCallSizeResult write(int fd, const void* buffer, size_t num_bytes) override; SysCallSizeResult writev(int fd, const iovec* iovec, int num_iovec) override; SysCallSizeResult readv(int fd, const iovec* iovec, int num_iovec) override; SysCallSizeResult recv(int socket, void* buffer, size_t length, int flags) override; diff --git a/source/common/filesystem/BUILD b/source/common/filesystem/BUILD index f4f0d62e7d0b7..5631afa2607e4 100644 --- a/source/common/filesystem/BUILD +++ b/source/common/filesystem/BUILD @@ -43,16 +43,22 @@ envoy_cc_library( srcs = ["filesystem_impl.cc"], hdrs = ["filesystem_impl.h"], deps = [ - "//include/envoy/api:api_interface", - "//include/envoy/api:os_sys_calls_interface", "//include/envoy/event:dispatcher_interface", "//include/envoy/filesystem:filesystem_interface", - "//source/common/api:os_sys_calls_lib", "//source/common/buffer:buffer_lib", "//source/common/common:thread_lib", ], ) +envoy_cc_library( + name = "raw_instance_lib", + srcs = ["raw_instance_impl.cc"], + hdrs = ["raw_instance_impl.h"], + deps = [ + "//include/envoy/filesystem:filesystem_interface", + ], +) + envoy_cc_library( name = "watcher_lib", srcs = select({ diff --git a/source/common/filesystem/filesystem_impl.cc b/source/common/filesystem/filesystem_impl.cc index 06492edac6ab4..cdf8f0233bd3d 100644 --- a/source/common/filesystem/filesystem_impl.cc +++ b/source/common/filesystem/filesystem_impl.cc @@ -1,16 +1,5 @@ #include "common/filesystem/filesystem_impl.h" -#include -#include - -#include -#include -#include -#include -#include -#include -#include - #include "envoy/common/exception.h" #include "envoy/common/time.h" #include "envoy/event/dispatcher.h" @@ -22,22 +11,21 @@ #include "common/common/lock_guard.h" #include "common/common/stack_array.h" -#include "absl/strings/match.h" - namespace Envoy { namespace Filesystem { InstanceImpl::InstanceImpl(std::chrono::milliseconds file_flush_interval_msec, - Thread::ThreadFactory& thread_factory, Stats::Store& stats_store) + Thread::ThreadFactory& thread_factory, Stats::Store& stats_store, + RawInstance& raw_instance) : file_flush_interval_msec_(file_flush_interval_msec), file_stats_{FILESYSTEM_STATS(POOL_COUNTER_PREFIX(stats_store, "filesystem."), POOL_GAUGE_PREFIX(stats_store, "filesystem."))}, - thread_factory_(thread_factory) {} + thread_factory_(thread_factory), raw_instance_(raw_instance) {} FileSharedPtr InstanceImpl::createFile(const std::string& path, Event::Dispatcher& dispatcher, Thread::BasicLockable& lock, std::chrono::milliseconds file_flush_interval_msec) { - return std::make_shared(path, dispatcher, lock, file_stats_, + return std::make_shared(createRawFile(path), dispatcher, lock, file_stats_, file_flush_interval_msec, thread_factory_); }; @@ -46,96 +34,47 @@ FileSharedPtr InstanceImpl::createFile(const std::string& path, Event::Dispatche return createFile(path, dispatcher, lock, file_flush_interval_msec_); } -bool InstanceImpl::fileExists(const std::string& path) { - std::ifstream input_file(path); - return input_file.is_open(); +RawFilePtr InstanceImpl::createRawFile(const std::string& path) { + return raw_instance_.createRawFile(path); } -bool InstanceImpl::directoryExists(const std::string& path) { - DIR* const dir = ::opendir(path.c_str()); - const bool dir_exists = nullptr != dir; - if (dir_exists) { - ::closedir(dir); - } +bool InstanceImpl::fileExists(const std::string& path) { return raw_instance_.fileExists(path); } - return dir_exists; +bool InstanceImpl::directoryExists(const std::string& path) { + return raw_instance_.directoryExists(path); } -ssize_t InstanceImpl::fileSize(const std::string& path) { - struct stat info; - if (::stat(path.c_str(), &info) != 0) { - return -1; - } - return info.st_size; -} +ssize_t InstanceImpl::fileSize(const std::string& path) { return raw_instance_.fileSize(path); } std::string InstanceImpl::fileReadToEnd(const std::string& path) { - std::ios::sync_with_stdio(false); - - std::ifstream file(path); - if (!file) { - throw EnvoyException(fmt::format("unable to read file: {}", path)); - } - - std::stringstream file_string; - file_string << file.rdbuf(); - - return file_string.str(); + return raw_instance_.fileReadToEnd(path); } Api::SysCallStringResult InstanceImpl::canonicalPath(const std::string& path) { - // TODO(htuch): When we are using C++17, switch to std::filesystem::canonical. - char* resolved_path = ::realpath(path.c_str(), nullptr); - if (resolved_path == nullptr) { - return {std::string(), errno}; - } - std::string resolved_path_string{resolved_path}; - ::free(resolved_path); - return {resolved_path_string, 0}; + return raw_instance_.canonicalPath(path); } -bool InstanceImpl::illegalPath(const std::string& path) { - const Api::SysCallStringResult canonical_path = canonicalPath(path); - if (canonical_path.rc_.empty()) { - ENVOY_LOG_MISC(debug, "Unable to determine canonical path for {}: {}", path, - ::strerror(canonical_path.errno_)); - return true; - } - - // Platform specific path sanity; we provide a convenience to avoid Envoy - // instances poking in bad places. We may have to consider conditioning on - // platform in the future, growing these or relaxing some constraints (e.g. - // there are valid reasons to go via /proc for file paths). - // TODO(htuch): Optimize this as a hash lookup if we grow any further. - if (absl::StartsWith(canonical_path.rc_, "/dev") || - absl::StartsWith(canonical_path.rc_, "/sys") || - absl::StartsWith(canonical_path.rc_, "/proc")) { - return true; - } - return false; -} +bool InstanceImpl::illegalPath(const std::string& path) { return raw_instance_.illegalPath(path); } -FileImpl::FileImpl(const std::string& path, Event::Dispatcher& dispatcher, +FileImpl::FileImpl(RawFilePtr&& raw_file, Event::Dispatcher& dispatcher, Thread::BasicLockable& lock, FileSystemStats& stats, std::chrono::milliseconds flush_interval_msec, Thread::ThreadFactory& thread_factory) - : path_(path), file_lock_(lock), flush_timer_(dispatcher.createTimer([this]() -> void { + : raw_file_(std::move(raw_file)), file_lock_(lock), + flush_timer_(dispatcher.createTimer([this]() -> void { stats_.flushed_by_timer_.inc(); flush_event_.notifyOne(); flush_timer_->enableTimer(flush_interval_msec_); })), - os_sys_calls_(Api::OsSysCallsSingleton::get()), thread_factory_(thread_factory), - flush_interval_msec_(flush_interval_msec), stats_(stats) { + thread_factory_(thread_factory), flush_interval_msec_(flush_interval_msec), stats_(stats) { open(); } void FileImpl::open() { - Api::SysCallIntResult result = - os_sys_calls_.open(path_, O_RDWR | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - fd_ = result.rc_; - if (-1 == fd_) { + const auto result = raw_file_->open(); + if (!result.rc_) { throw EnvoyException( - fmt::format("unable to open file '{}': {}", path_, strerror(result.errno_))); + fmt::format("unable to open file '{}': {}", raw_file_->path(), strerror(result.errno_))); } } @@ -153,12 +92,14 @@ FileImpl::~FileImpl() { } // Flush any remaining data. If file was not opened for some reason, skip flushing part. - if (fd_ != -1) { + if (raw_file_->isOpen()) { if (flush_buffer_.length() > 0) { doWrite(flush_buffer_); } - os_sys_calls_.close(fd_); + const auto result = raw_file_->close(); + ASSERT(result.rc_, fmt::format("unable to close file '{}': {}", raw_file_->path(), + strerror(result.errno_))); } } @@ -178,7 +119,8 @@ void FileImpl::doWrite(Buffer::Instance& buffer) { { Thread::LockGuard lock(file_lock_); for (const Buffer::RawSlice& slice : slices) { - const Api::SysCallSizeResult result = os_sys_calls_.write(fd_, slice.mem_, slice.len_); + absl::string_view data(static_cast(slice.mem_), slice.len_); + const Api::SysCallSizeResult result = raw_file_->write(data); ASSERT(result.rc_ == static_cast(slice.len_)); stats_.write_completed_.inc(); } @@ -213,12 +155,14 @@ void FileImpl::flushThreadFunc() { ASSERT(flush_buffer_.length() == 0); } - // if we failed to open file before (-1 == fd_), then simply ignore - if (fd_ != -1) { + // if we failed to open file before, then simply ignore + if (raw_file_->isOpen()) { try { if (reopen_file_) { reopen_file_ = false; - os_sys_calls_.close(fd_); + const auto result = raw_file_->close(); + ASSERT(result.rc_, fmt::format("unable to close file '{}': {}", raw_file_->path(), + strerror(result.errno_))); open(); } diff --git a/source/common/filesystem/filesystem_impl.h b/source/common/filesystem/filesystem_impl.h index a28317bbfa2d5..ce2b590a57ee4 100644 --- a/source/common/filesystem/filesystem_impl.h +++ b/source/common/filesystem/filesystem_impl.h @@ -2,12 +2,8 @@ #include #include -#include -#include #include -#include "envoy/api/api.h" -#include "envoy/api/os_sys_calls.h" #include "envoy/event/dispatcher.h" #include "envoy/filesystem/filesystem.h" #include "envoy/stats/stats_macros.h" @@ -32,20 +28,21 @@ struct FileSystemStats { namespace Filesystem { -/** - * Captures state, properties, and stats of a file-system. - */ class InstanceImpl : public Instance { public: + // Filesystem::Instance InstanceImpl(std::chrono::milliseconds file_flush_interval_msec, - Thread::ThreadFactory& thread_factory, Stats::Store& store); + Thread::ThreadFactory& thread_factory, Stats::Store& store, + RawInstance& raw_instance); - // Filesystem::Instance FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, Thread::BasicLockable& lock, std::chrono::milliseconds file_flush_interval_msec) override; FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, Thread::BasicLockable& lock) override; + + // Filesystem::RawInstance + RawFilePtr createRawFile(const std::string& path) override; bool fileExists(const std::string& path) override; bool directoryExists(const std::string& path) override; ssize_t fileSize(const std::string& path) override; @@ -57,6 +54,7 @@ class InstanceImpl : public Instance { const std::chrono::milliseconds file_flush_interval_msec_; FileSystemStats file_stats_; Thread::ThreadFactory& thread_factory_; + RawInstance& raw_instance_; }; /** @@ -68,7 +66,7 @@ class InstanceImpl : public Instance { */ class FileImpl : public File { public: - FileImpl(const std::string& path, Event::Dispatcher& dispatcher, Thread::BasicLockable& lock, + FileImpl(RawFilePtr&& raw_file, Event::Dispatcher& dispatcher, Thread::BasicLockable& lock, FileSystemStats& stats_, std::chrono::milliseconds flush_interval_msec, Thread::ThreadFactory& thread_factory); ~FileImpl(); @@ -96,8 +94,7 @@ class FileImpl : public File { // Minimum size before the flush thread will be told to flush. static const uint64_t MIN_FLUSH_SIZE = 1024 * 64; - int fd_; - std::string path_; + RawFilePtr raw_file_; // These locks are always acquired in the following order if multiple locks are held: // 1) write_lock_ @@ -133,7 +130,6 @@ class FileImpl : public File { // continue to fill. This buffer is then used for the // final write to disk. Event::TimerPtr flush_timer_; - Api::OsSysCalls& os_sys_calls_; Thread::ThreadFactory& thread_factory_; const std::chrono::milliseconds flush_interval_msec_; // Time interval buffer gets flushed no // matter if it reached the MIN_FLUSH_SIZE diff --git a/source/common/filesystem/raw_instance_impl.cc b/source/common/filesystem/raw_instance_impl.cc new file mode 100644 index 0000000000000..8d8e7f13e367f --- /dev/null +++ b/source/common/filesystem/raw_instance_impl.cc @@ -0,0 +1,144 @@ +#include "common/filesystem/raw_instance_impl.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "envoy/common/exception.h" + +#include "common/common/assert.h" +#include "common/common/fmt.h" +#include "common/common/logger.h" + +#include "absl/strings/match.h" + +namespace Envoy { +namespace Filesystem { + +RawFileImpl::RawFileImpl(const std::string& path) : fd_(-1), path_(path) {} + +RawFileImpl::~RawFileImpl() { + const auto result = close(); + ASSERT(result.rc_); +} + +Api::SysCallBoolResult RawFileImpl::open() { + if (isOpen()) { + return {true, 0}; + } + + const int flags = O_RDWR | O_APPEND | O_CREAT; + const int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + + fd_ = ::open(path_.c_str(), flags, mode); + if (-1 == fd_) { + return {false, errno}; + } + return {true, 0}; +} + +Api::SysCallSizeResult RawFileImpl::write(absl::string_view buffer) { + const ssize_t rc = ::write(fd_, buffer.data(), buffer.size()); + return {rc, errno}; +} + +Api::SysCallBoolResult RawFileImpl::close() { + if (!isOpen()) { + return {true, 0}; + } + + const int rc = ::close(fd_); + if (rc == -1) { + return {false, errno}; + } + + fd_ = -1; + return {true, 0}; +} + +bool RawFileImpl::isOpen() { return fd_ != -1; } + +std::string RawFileImpl::path() { return path_; } + +RawFilePtr RawInstanceImpl::createRawFile(const std::string& path) { + return std::make_unique(path); +} + +bool RawInstanceImpl::fileExists(const std::string& path) { + std::ifstream input_file(path); + return input_file.is_open(); +} + +bool RawInstanceImpl::directoryExists(const std::string& path) { + DIR* const dir = ::opendir(path.c_str()); + const bool dir_exists = nullptr != dir; + if (dir_exists) { + ::closedir(dir); + } + + return dir_exists; +} + +ssize_t RawInstanceImpl::fileSize(const std::string& path) { + struct stat info; + if (::stat(path.c_str(), &info) != 0) { + return -1; + } + return info.st_size; +} + +std::string RawInstanceImpl::fileReadToEnd(const std::string& path) { + std::ios::sync_with_stdio(false); + + std::ifstream file(path); + if (!file) { + throw EnvoyException(fmt::format("unable to read file: {}", path)); + } + + std::stringstream file_string; + file_string << file.rdbuf(); + + return file_string.str(); +} + +Api::SysCallStringResult RawInstanceImpl::canonicalPath(const std::string& path) { + // TODO(htuch): When we are using C++17, switch to std::filesystem::canonical. + char* resolved_path = ::realpath(path.c_str(), nullptr); + if (resolved_path == nullptr) { + return {std::string(), errno}; + } + std::string resolved_path_string{resolved_path}; + ::free(resolved_path); + return {resolved_path_string, 0}; +} + +bool RawInstanceImpl::illegalPath(const std::string& path) { + const Api::SysCallStringResult canonical_path = canonicalPath(path); + if (canonical_path.rc_.empty()) { + ENVOY_LOG_MISC(debug, "Unable to determine canonical path for {}: {}", path, + ::strerror(canonical_path.errno_)); + return true; + } + + // Platform specific path sanity; we provide a convenience to avoid Envoy + // instances poking in bad places. We may have to consider conditioning on + // platform in the future, growing these or relaxing some constraints (e.g. + // there are valid reasons to go via /proc for file paths). + // TODO(htuch): Optimize this as a hash lookup if we grow any further. + if (absl::StartsWith(canonical_path.rc_, "/dev") || + absl::StartsWith(canonical_path.rc_, "/sys") || + absl::StartsWith(canonical_path.rc_, "/proc")) { + return true; + } + return false; +} + +} // namespace Filesystem +} // namespace Envoy diff --git a/source/common/filesystem/raw_instance_impl.h b/source/common/filesystem/raw_instance_impl.h new file mode 100644 index 0000000000000..4de54d9b8eaba --- /dev/null +++ b/source/common/filesystem/raw_instance_impl.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include + +#include "envoy/filesystem/filesystem.h" + +namespace Envoy { +namespace Filesystem { + +class RawFileImpl : public RawFile { +public: + RawFileImpl(const std::string& path); + ~RawFileImpl(); + + // Filesystem::RawFile + Api::SysCallBoolResult open() override; + Api::SysCallSizeResult write(absl::string_view buffer) override; + Api::SysCallBoolResult close() override; + bool isOpen() override; + std::string path() override; + +private: + int fd_; + const std::string path_; + friend class RawInstanceImplTest; +}; + +class RawInstanceImpl : public RawInstance { +public: + // Filesystem::RawInstance + RawFilePtr createRawFile(const std::string& path) override; + bool fileExists(const std::string& path) override; + bool directoryExists(const std::string& path) override; + ssize_t fileSize(const std::string& path) override; + std::string fileReadToEnd(const std::string& path) override; + Api::SysCallStringResult canonicalPath(const std::string& path) override; + bool illegalPath(const std::string& path) override; +}; + +} // namespace Filesystem +} // namespace Envoy diff --git a/test/common/filesystem/BUILD b/test/common/filesystem/BUILD index 9538338b6614c..bae5fe0c4aabb 100644 --- a/test/common/filesystem/BUILD +++ b/test/common/filesystem/BUILD @@ -12,20 +12,20 @@ envoy_cc_test( name = "filesystem_impl_test", srcs = ["filesystem_impl_test.cc"], deps = [ - "//source/common/api:api_lib", - "//source/common/api:os_sys_calls_lib", - "//source/common/common:thread_lib", - "//source/common/event:dispatcher_includes", - "//source/common/event:dispatcher_lib", "//source/common/filesystem:filesystem_lib", "//source/common/stats:isolated_store_lib", - "//source/common/stats:stats_lib", - "//test/mocks/api:api_mocks", "//test/mocks/event:event_mocks", "//test/mocks/filesystem:filesystem_mocks", "//test/test_common:environment_lib", - "//test/test_common:threadsafe_singleton_injector_lib", - "//test/test_common:utility_lib", + ], +) + +envoy_cc_test( + name = "raw_instance_impl_test", + srcs = ["raw_instance_impl_test.cc"], + deps = [ + "//source/common/filesystem:raw_instance_lib", + "//test/test_common:environment_lib", ], ) diff --git a/test/common/filesystem/filesystem_impl_test.cc b/test/common/filesystem/filesystem_impl_test.cc index 4e4558c835919..ef8e12567b149 100644 --- a/test/common/filesystem/filesystem_impl_test.cc +++ b/test/common/filesystem/filesystem_impl_test.cc @@ -1,25 +1,21 @@ #include #include -#include "common/api/api_impl.h" -#include "common/api/os_sys_calls_impl.h" #include "common/common/lock_guard.h" #include "common/common/thread.h" #include "common/event/dispatcher_impl.h" #include "common/filesystem/filesystem_impl.h" #include "common/stats/isolated_store_impl.h" -#include "test/mocks/api/mocks.h" #include "test/mocks/event/mocks.h" #include "test/mocks/filesystem/mocks.h" #include "test/test_common/environment.h" -#include "test/test_common/threadsafe_singleton_injector.h" -#include "test/test_common/utility.h" #include "gmock/gmock.h" #include "gtest/gtest.h" using testing::_; +using testing::ByMove; using testing::InSequence; using testing::Invoke; using testing::NiceMock; @@ -29,132 +25,61 @@ using testing::Sequence; using testing::Throw; namespace Envoy { +namespace Filesystem { class FileSystemImplTest : public testing::Test { protected: FileSystemImplTest() - : file_system_(std::chrono::milliseconds(10000), Thread::threadFactoryForTest(), - stats_store_) {} + : raw_file_(new NiceMock), + file_system_(std::chrono::milliseconds(10000), Thread::threadFactoryForTest(), stats_store_, + raw_instance_) { + EXPECT_CALL(raw_instance_, createRawFile(_)) + .WillOnce(Return(ByMove(std::unique_ptr>(raw_file_)))); + } + NiceMock* raw_file_; const std::chrono::milliseconds timeout_40ms_{40}; Stats::IsolatedStoreImpl stats_store_; - Filesystem::InstanceImpl file_system_; + NiceMock raw_instance_; + InstanceImpl file_system_; }; TEST_F(FileSystemImplTest, BadFile) { Event::MockDispatcher dispatcher; Thread::MutexBasicLockable lock; EXPECT_CALL(dispatcher, createTimer_(_)); + EXPECT_CALL(*raw_file_, open_()).WillOnce(Return(Api::SysCallBoolResult{false, 0})); EXPECT_THROW(file_system_.createFile("", dispatcher, lock), EnvoyException); } -TEST_F(FileSystemImplTest, fileExists) { - EXPECT_TRUE(file_system_.fileExists("/dev/null")); - EXPECT_FALSE(file_system_.fileExists("/dev/blahblahblah")); -} - -TEST_F(FileSystemImplTest, directoryExists) { - EXPECT_TRUE(file_system_.directoryExists("/dev")); - EXPECT_FALSE(file_system_.directoryExists("/dev/null")); - EXPECT_FALSE(file_system_.directoryExists("/dev/blahblah")); -} - -TEST_F(FileSystemImplTest, fileSize) { - EXPECT_EQ(0, file_system_.fileSize("/dev/null")); - EXPECT_EQ(-1, file_system_.fileSize("/dev/blahblahblah")); - const std::string data = "test string\ntest"; - const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); - EXPECT_EQ(data.length(), file_system_.fileSize(file_path)); -} - -TEST_F(FileSystemImplTest, fileReadToEndSuccess) { - const std::string data = "test string\ntest"; - const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); - - EXPECT_EQ(data, file_system_.fileReadToEnd(file_path)); -} - -// Files are read into std::string; verify that all bytes (eg non-ascii characters) come back -// unmodified -TEST_F(FileSystemImplTest, fileReadToEndSuccessBinary) { - std::string data; - for (unsigned i = 0; i < 256; i++) { - data.push_back(i); - } - const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); - - const std::string read = file_system_.fileReadToEnd(file_path); - const std::vector binary_read(read.begin(), read.end()); - EXPECT_EQ(binary_read.size(), 256); - for (unsigned i = 0; i < 256; i++) { - EXPECT_EQ(binary_read.at(i), i); - } -} - -TEST_F(FileSystemImplTest, fileReadToEndDoesNotExist) { - unlink(TestEnvironment::temporaryPath("envoy_this_not_exist").c_str()); - EXPECT_THROW(file_system_.fileReadToEnd(TestEnvironment::temporaryPath("envoy_this_not_exist")), - EnvoyException); -} - -TEST_F(FileSystemImplTest, CanonicalPathSuccess) { - EXPECT_EQ("/", file_system_.canonicalPath("//").rc_); -} - -TEST_F(FileSystemImplTest, CanonicalPathFail) { - const Api::SysCallStringResult result = file_system_.canonicalPath("/_some_non_existent_file"); - EXPECT_TRUE(result.rc_.empty()); - EXPECT_STREQ("No such file or directory", ::strerror(result.errno_)); -} - -TEST_F(FileSystemImplTest, IllegalPath) { - EXPECT_FALSE(file_system_.illegalPath("/")); - EXPECT_TRUE(file_system_.illegalPath("/dev")); - EXPECT_TRUE(file_system_.illegalPath("/dev/")); - EXPECT_TRUE(file_system_.illegalPath("/proc")); - EXPECT_TRUE(file_system_.illegalPath("/proc/")); - EXPECT_TRUE(file_system_.illegalPath("/sys")); - EXPECT_TRUE(file_system_.illegalPath("/sys/")); - EXPECT_TRUE(file_system_.illegalPath("/_some_non_existent_file")); -} - TEST_F(FileSystemImplTest, flushToLogFilePeriodically) { NiceMock dispatcher; NiceMock* timer = new NiceMock(&dispatcher); - Thread::MutexBasicLockable mutex; - NiceMock os_sys_calls; - TestThreadsafeSingletonInjector os_calls(&os_sys_calls); - EXPECT_CALL(os_sys_calls, open_(_, _, _)).WillOnce(Return(5)); - Filesystem::FileSharedPtr file = file_system_.createFile("", dispatcher, mutex, timeout_40ms_); + EXPECT_CALL(*raw_file_, open_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); + FileSharedPtr file = file_system_.createFile("", dispatcher, mutex, timeout_40ms_); EXPECT_CALL(*timer, enableTimer(timeout_40ms_)); - EXPECT_CALL(os_sys_calls, write_(_, _, _)) - .WillOnce(Invoke([](int fd, const void* buffer, size_t num_bytes) -> ssize_t { - std::string written = std::string(reinterpret_cast(buffer), num_bytes); - EXPECT_EQ("test", written); - EXPECT_EQ(5, fd); - - return num_bytes; + EXPECT_CALL(*raw_file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("test")); + return {static_cast(data.length()), 0}; })); file->write("test"); { - Thread::LockGuard lock(os_sys_calls.write_mutex_); - while (os_sys_calls.num_writes_ != 1) { - os_sys_calls.write_event_.wait(os_sys_calls.write_mutex_); + Thread::LockGuard lock(raw_file_->write_mutex_); + while (raw_file_->num_writes_ != 1) { + raw_file_->write_event_.wait(raw_file_->write_mutex_); } } - EXPECT_CALL(os_sys_calls, write_(_, _, _)) - .WillOnce(Invoke([](int fd, const void* buffer, size_t num_bytes) -> ssize_t { - std::string written = std::string(reinterpret_cast(buffer), num_bytes); - EXPECT_EQ("test2", written); - EXPECT_EQ(5, fd); - - return num_bytes; + EXPECT_CALL(*raw_file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("test2")); + return {static_cast(data.length()), 0}; })); // make sure timer is re-enabled on callback call @@ -163,22 +88,20 @@ TEST_F(FileSystemImplTest, flushToLogFilePeriodically) { timer->callback_(); { - Thread::LockGuard lock(os_sys_calls.write_mutex_); - while (os_sys_calls.num_writes_ != 2) { - os_sys_calls.write_event_.wait(os_sys_calls.write_mutex_); + Thread::LockGuard lock(raw_file_->write_mutex_); + while (raw_file_->num_writes_ != 2) { + raw_file_->write_event_.wait(raw_file_->write_mutex_); } } + EXPECT_CALL(*raw_file_, close_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); } TEST_F(FileSystemImplTest, flushToLogFileOnDemand) { NiceMock dispatcher; NiceMock* timer = new NiceMock(&dispatcher); - Thread::MutexBasicLockable mutex; - NiceMock os_sys_calls; - TestThreadsafeSingletonInjector os_calls(&os_sys_calls); - EXPECT_CALL(os_sys_calls, open_(_, _, _)).WillOnce(Return(5)); + EXPECT_CALL(*raw_file_, open_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); Filesystem::FileSharedPtr file = file_system_.createFile("", dispatcher, mutex, timeout_40ms_); EXPECT_CALL(*timer, enableTimer(timeout_40ms_)); @@ -186,46 +109,42 @@ TEST_F(FileSystemImplTest, flushToLogFileOnDemand) { // The first write to a given file will start the flush thread, which can flush // immediately (race on whether it will or not). So do a write and flush to // get that state out of the way, then test that small writes don't trigger a flush. - EXPECT_CALL(os_sys_calls, write_(_, _, _)) - .WillOnce(Invoke([](int, const void*, size_t num_bytes) -> ssize_t { return num_bytes; })); + EXPECT_CALL(*raw_file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + return {static_cast(data.length()), 0}; + })); file->write("prime-it"); file->flush(); uint32_t expected_writes = 1; { - Thread::LockGuard lock(os_sys_calls.write_mutex_); - EXPECT_EQ(expected_writes, os_sys_calls.num_writes_); + Thread::LockGuard lock(raw_file_->write_mutex_); + EXPECT_EQ(expected_writes, raw_file_->num_writes_); } - EXPECT_CALL(os_sys_calls, write_(_, _, _)) - .WillOnce(Invoke([](int fd, const void* buffer, size_t num_bytes) -> ssize_t { - std::string written = std::string(reinterpret_cast(buffer), num_bytes); - EXPECT_EQ("test", written); - EXPECT_EQ(5, fd); - - return num_bytes; + EXPECT_CALL(*raw_file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("test")); + return {static_cast(data.length()), 0}; })); file->write("test"); { - Thread::LockGuard lock(os_sys_calls.write_mutex_); - EXPECT_EQ(expected_writes, os_sys_calls.num_writes_); + Thread::LockGuard lock(raw_file_->write_mutex_); + EXPECT_EQ(expected_writes, raw_file_->num_writes_); } file->flush(); expected_writes++; { - Thread::LockGuard lock(os_sys_calls.write_mutex_); - EXPECT_EQ(expected_writes, os_sys_calls.num_writes_); + Thread::LockGuard lock(raw_file_->write_mutex_); + EXPECT_EQ(expected_writes, raw_file_->num_writes_); } - EXPECT_CALL(os_sys_calls, write_(_, _, _)) - .WillOnce(Invoke([](int fd, const void* buffer, size_t num_bytes) -> ssize_t { - std::string written = std::string(reinterpret_cast(buffer), num_bytes); - EXPECT_EQ("test2", written); - EXPECT_EQ(5, fd); - - return num_bytes; + EXPECT_CALL(*raw_file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("test2")); + return {static_cast(data.length()), 0}; })); // make sure timer is re-enabled on callback call @@ -235,68 +154,64 @@ TEST_F(FileSystemImplTest, flushToLogFileOnDemand) { expected_writes++; { - Thread::LockGuard lock(os_sys_calls.write_mutex_); - while (os_sys_calls.num_writes_ != expected_writes) { - os_sys_calls.write_event_.wait(os_sys_calls.write_mutex_); + Thread::LockGuard lock(raw_file_->write_mutex_); + while (raw_file_->num_writes_ != expected_writes) { + raw_file_->write_event_.wait(raw_file_->write_mutex_); } } + EXPECT_CALL(*raw_file_, close_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); } TEST_F(FileSystemImplTest, reopenFile) { NiceMock dispatcher; NiceMock* timer = new NiceMock(&dispatcher); - Thread::MutexBasicLockable mutex; - NiceMock os_sys_calls; - TestThreadsafeSingletonInjector os_calls(&os_sys_calls); Sequence sq; - EXPECT_CALL(os_sys_calls, open_(_, _, _)).InSequence(sq).WillOnce(Return(5)); + EXPECT_CALL(*raw_file_, open_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); Filesystem::FileSharedPtr file = file_system_.createFile("", dispatcher, mutex, timeout_40ms_); - EXPECT_CALL(os_sys_calls, write_(_, _, _)) + EXPECT_CALL(*raw_file_, write_(_)) .InSequence(sq) - .WillOnce(Invoke([](int fd, const void* buffer, size_t num_bytes) -> ssize_t { - std::string written = std::string(reinterpret_cast(buffer), num_bytes); - EXPECT_EQ("before", written); - EXPECT_EQ(5, fd); - - return num_bytes; + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("before")); + return {static_cast(data.length()), 0}; })); file->write("before"); timer->callback_(); { - Thread::LockGuard lock(os_sys_calls.write_mutex_); - while (os_sys_calls.num_writes_ != 1) { - os_sys_calls.write_event_.wait(os_sys_calls.write_mutex_); + Thread::LockGuard lock(raw_file_->write_mutex_); + while (raw_file_->num_writes_ != 1) { + raw_file_->write_event_.wait(raw_file_->write_mutex_); } } - EXPECT_CALL(os_sys_calls, close(5)).InSequence(sq); - EXPECT_CALL(os_sys_calls, open_(_, _, _)).InSequence(sq).WillOnce(Return(10)); - - EXPECT_CALL(os_sys_calls, write_(_, _, _)) + EXPECT_CALL(*raw_file_, close_()) .InSequence(sq) - .WillOnce(Invoke([](int fd, const void* buffer, size_t num_bytes) -> ssize_t { - std::string written = std::string(reinterpret_cast(buffer), num_bytes); - EXPECT_EQ("reopened", written); - EXPECT_EQ(10, fd); + .WillOnce(Return(Api::SysCallBoolResult{true, 0})); + EXPECT_CALL(*raw_file_, open_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); - return num_bytes; + EXPECT_CALL(*raw_file_, write_(_)) + .InSequence(sq) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("reopened")); + return {static_cast(data.length()), 0}; })); - EXPECT_CALL(os_sys_calls, close(10)).InSequence(sq); + EXPECT_CALL(*raw_file_, close_()) + .InSequence(sq) + .WillOnce(Return(Api::SysCallBoolResult{true, 0})); file->reopen(); file->write("reopened"); timer->callback_(); { - Thread::LockGuard lock(os_sys_calls.write_mutex_); - while (os_sys_calls.num_writes_ != 2) { - os_sys_calls.write_event_.wait(os_sys_calls.write_mutex_); + Thread::LockGuard lock(raw_file_->write_mutex_); + while (raw_file_->num_writes_ != 2) { + raw_file_->write_event_.wait(raw_file_->write_mutex_); } } } @@ -304,33 +219,30 @@ TEST_F(FileSystemImplTest, reopenFile) { TEST_F(FileSystemImplTest, reopenThrows) { NiceMock dispatcher; NiceMock* timer = new NiceMock(&dispatcher); - Thread::MutexBasicLockable mutex; - Stats::IsolatedStoreImpl stats_store; - NiceMock os_sys_calls; - TestThreadsafeSingletonInjector os_calls(&os_sys_calls); - EXPECT_CALL(os_sys_calls, write_(_, _, _)) - .WillRepeatedly(Invoke([](int fd, const void* buffer, size_t num_bytes) -> ssize_t { - UNREFERENCED_PARAMETER(fd); - UNREFERENCED_PARAMETER(buffer); - - return num_bytes; + EXPECT_CALL(*raw_file_, write_(_)) + .WillRepeatedly(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + return {static_cast(data.length()), 0}; })); Sequence sq; - EXPECT_CALL(os_sys_calls, open_(_, _, _)).InSequence(sq).WillOnce(Return(5)); + EXPECT_CALL(*raw_file_, open_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); Filesystem::FileSharedPtr file = file_system_.createFile("", dispatcher, mutex, timeout_40ms_); - EXPECT_CALL(os_sys_calls, close(5)).InSequence(sq); - EXPECT_CALL(os_sys_calls, open_(_, _, _)).InSequence(sq).WillOnce(Return(-1)); + EXPECT_CALL(*raw_file_, close_()) + .InSequence(sq) + .WillOnce(Return(Api::SysCallBoolResult{true, 0})); + EXPECT_CALL(*raw_file_, open_()) + .InSequence(sq) + .WillOnce(Return(Api::SysCallBoolResult{false, 0})); file->write("test write"); timer->callback_(); { - Thread::LockGuard lock(os_sys_calls.write_mutex_); - while (os_sys_calls.num_writes_ != 1) { - os_sys_calls.write_event_.wait(os_sys_calls.write_mutex_); + Thread::LockGuard lock(raw_file_->write_mutex_); + while (raw_file_->num_writes_ != 1) { + raw_file_->write_event_.wait(raw_file_->write_mutex_); } } file->reopen(); @@ -339,9 +251,9 @@ TEST_F(FileSystemImplTest, reopenThrows) { timer->callback_(); { - Thread::LockGuard lock(os_sys_calls.open_mutex_); - while (os_sys_calls.num_open_ != 2) { - os_sys_calls.open_event_.wait(os_sys_calls.open_mutex_); + Thread::LockGuard lock(raw_file_->open_mutex_); + while (raw_file_->num_opens_ != 2) { + raw_file_->open_event_.wait(raw_file_->open_mutex_); } } @@ -353,53 +265,45 @@ TEST_F(FileSystemImplTest, reopenThrows) { TEST_F(FileSystemImplTest, bigDataChunkShouldBeFlushedWithoutTimer) { NiceMock dispatcher; Thread::MutexBasicLockable mutex; - Stats::IsolatedStoreImpl stats_store; - NiceMock os_sys_calls; - TestThreadsafeSingletonInjector os_calls(&os_sys_calls); + EXPECT_CALL(*raw_file_, open_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); Filesystem::FileSharedPtr file = file_system_.createFile("", dispatcher, mutex, timeout_40ms_); - EXPECT_CALL(os_sys_calls, write_(_, _, _)) - .WillOnce(Invoke([](int fd, const void* buffer, size_t num_bytes) -> ssize_t { - UNREFERENCED_PARAMETER(fd); - - std::string written = std::string(reinterpret_cast(buffer), num_bytes); - std::string expected("a"); - EXPECT_EQ(expected, written); - - return num_bytes; + EXPECT_CALL(*raw_file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("a")); + return {static_cast(data.length()), 0}; })); file->write("a"); { - Thread::LockGuard lock(os_sys_calls.write_mutex_); - while (os_sys_calls.num_writes_ != 1) { - os_sys_calls.write_event_.wait(os_sys_calls.write_mutex_); + Thread::LockGuard lock(raw_file_->write_mutex_); + while (raw_file_->num_writes_ != 1) { + raw_file_->write_event_.wait(raw_file_->write_mutex_); } } // First write happens without waiting on thread_flush_. Now make a big string and it should be // flushed even when timer is not enabled - EXPECT_CALL(os_sys_calls, write_(_, _, _)) - .WillOnce(Invoke([](int fd, const void* buffer, size_t num_bytes) -> ssize_t { - UNREFERENCED_PARAMETER(fd); - - std::string written = std::string(reinterpret_cast(buffer), num_bytes); + EXPECT_CALL(*raw_file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { std::string expected(1024 * 64 + 1, 'b'); - EXPECT_EQ(expected, written); - - return num_bytes; + EXPECT_EQ(0, data.compare(expected)); + return {static_cast(data.length()), 0}; })); std::string big_string(1024 * 64 + 1, 'b'); file->write(big_string); { - Thread::LockGuard lock(os_sys_calls.write_mutex_); - while (os_sys_calls.num_writes_ != 2) { - os_sys_calls.write_event_.wait(os_sys_calls.write_mutex_); + Thread::LockGuard lock(raw_file_->write_mutex_); + while (raw_file_->num_writes_ != 2) { + raw_file_->write_event_.wait(raw_file_->write_mutex_); } } + EXPECT_CALL(*raw_file_, close_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); } + +} // namespace Filesystem } // namespace Envoy diff --git a/test/common/filesystem/raw_instance_impl_test.cc b/test/common/filesystem/raw_instance_impl_test.cc new file mode 100644 index 0000000000000..f2a8f999f9b24 --- /dev/null +++ b/test/common/filesystem/raw_instance_impl_test.cc @@ -0,0 +1,213 @@ +#include +#include + +#include "common/common/assert.h" +#include "common/filesystem/raw_instance_impl.h" + +#include "test/test_common/environment.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace Envoy { +namespace Filesystem { + +class RawInstanceImplTest : public testing::Test { +protected: + int getFd(RawFile* file) { + auto file_impl = dynamic_cast(file); + RELEASE_ASSERT(file_impl != nullptr, "failed to cast RawFile* to RawFileImpl*"); + return file_impl->fd_; + } + + RawInstanceImpl raw_instance_; +}; + +TEST_F(RawInstanceImplTest, fileExists) { + EXPECT_TRUE(raw_instance_.fileExists("/dev/null")); + EXPECT_FALSE(raw_instance_.fileExists("/dev/blahblahblah")); +} + +TEST_F(RawInstanceImplTest, directoryExists) { + EXPECT_TRUE(raw_instance_.directoryExists("/dev")); + EXPECT_FALSE(raw_instance_.directoryExists("/dev/null")); + EXPECT_FALSE(raw_instance_.directoryExists("/dev/blahblah")); +} + +TEST_F(RawInstanceImplTest, fileSize) { + EXPECT_EQ(0, raw_instance_.fileSize("/dev/null")); + EXPECT_EQ(-1, raw_instance_.fileSize("/dev/blahblahblah")); + const std::string data = "test string\ntest"; + const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); + EXPECT_EQ(data.length(), raw_instance_.fileSize(file_path)); +} + +TEST_F(RawInstanceImplTest, fileReadToEndSuccess) { + const std::string data = "test string\ntest"; + const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); + + EXPECT_EQ(data, raw_instance_.fileReadToEnd(file_path)); +} + +// Files are read into std::string; verify that all bytes (eg non-ascii characters) come back +// unmodified +TEST_F(RawInstanceImplTest, fileReadToEndSuccessBinary) { + std::string data; + for (unsigned i = 0; i < 256; i++) { + data.push_back(i); + } + const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); + + const std::string read = raw_instance_.fileReadToEnd(file_path); + const std::vector binary_read(read.begin(), read.end()); + EXPECT_EQ(binary_read.size(), 256); + for (unsigned i = 0; i < 256; i++) { + EXPECT_EQ(binary_read.at(i), i); + } +} + +TEST_F(RawInstanceImplTest, fileReadToEndDoesNotExist) { + unlink(TestEnvironment::temporaryPath("envoy_this_not_exist").c_str()); + EXPECT_THROW(raw_instance_.fileReadToEnd(TestEnvironment::temporaryPath("envoy_this_not_exist")), + EnvoyException); +} + +TEST_F(RawInstanceImplTest, CanonicalPathSuccess) { + EXPECT_EQ("/", raw_instance_.canonicalPath("//").rc_); +} + +TEST_F(RawInstanceImplTest, CanonicalPathFail) { + const Api::SysCallStringResult result = raw_instance_.canonicalPath("/_some_non_existent_file"); + EXPECT_TRUE(result.rc_.empty()); + EXPECT_STREQ("No such file or directory", ::strerror(result.errno_)); +} + +TEST_F(RawInstanceImplTest, IllegalPath) { + EXPECT_FALSE(raw_instance_.illegalPath("/")); + EXPECT_TRUE(raw_instance_.illegalPath("/dev")); + EXPECT_TRUE(raw_instance_.illegalPath("/dev/")); + EXPECT_TRUE(raw_instance_.illegalPath("/proc")); + EXPECT_TRUE(raw_instance_.illegalPath("/proc/")); + EXPECT_TRUE(raw_instance_.illegalPath("/sys")); + EXPECT_TRUE(raw_instance_.illegalPath("/sys/")); + EXPECT_TRUE(raw_instance_.illegalPath("/_some_non_existent_file")); +} + +TEST_F(RawInstanceImplTest, ConstructedFileNotOpen) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + RawFilePtr file = raw_instance_.createRawFile(new_file_path); + EXPECT_FALSE(file->isOpen()); +} + +TEST_F(RawInstanceImplTest, Open) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + RawFilePtr file = raw_instance_.createRawFile(new_file_path); + const auto result = file->open(); + EXPECT_TRUE(result.rc_); + EXPECT_TRUE(file->isOpen()); +} + +TEST_F(RawInstanceImplTest, OpenTwice) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + RawFilePtr file = raw_instance_.createRawFile(new_file_path); + EXPECT_EQ(getFd(file.get()), -1); + + auto result = file->open(); + const int intial_fd = getFd(file.get()); + EXPECT_TRUE(result.rc_); + EXPECT_TRUE(file->isOpen()); + + // check that we don't leak a file descriptor + result = file->open(); + EXPECT_EQ(intial_fd, getFd(file.get())); + EXPECT_TRUE(result.rc_); + EXPECT_TRUE(file->isOpen()); +} + +TEST_F(RawInstanceImplTest, OpenBadFilePath) { + RawFilePtr file = raw_instance_.createRawFile(""); + const auto result = file->open(); + EXPECT_FALSE(result.rc_); +} + +TEST_F(RawInstanceImplTest, ExistingFile) { + const std::string file_path = + TestEnvironment::writeStringToFileForTest("test_envoy", "existing file"); + + { + RawFilePtr file = raw_instance_.createRawFile(file_path); + const auto open_result = file->open(); + EXPECT_TRUE(open_result.rc_); + std::string data(" new data"); + const Api::SysCallSizeResult result = file->write(data); + EXPECT_EQ(data.length(), result.rc_); + } + + auto contents = TestEnvironment::readFileToStringForTest(file_path); + EXPECT_EQ("existing file new data", contents); +} + +TEST_F(RawInstanceImplTest, NonExistingFile) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + { + RawFilePtr file = raw_instance_.createRawFile(new_file_path); + const auto open_result = file->open(); + EXPECT_TRUE(open_result.rc_); + std::string data(" new data"); + const Api::SysCallSizeResult result = file->write(data); + EXPECT_EQ(data.length(), result.rc_); + } + + auto contents = TestEnvironment::readFileToStringForTest(new_file_path); + EXPECT_EQ(" new data", contents); +} + +TEST_F(RawInstanceImplTest, Close) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + RawFilePtr file = raw_instance_.createRawFile(new_file_path); + const auto result = file->close(); + EXPECT_TRUE(result.rc_); + EXPECT_FALSE(file->isOpen()); +} + +TEST_F(RawInstanceImplTest, CloseTwice) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + RawFilePtr file = raw_instance_.createRawFile(new_file_path); + auto result = file->close(); + EXPECT_TRUE(result.rc_); + EXPECT_FALSE(file->isOpen()); + + // check that closing an already closed file doesn't error + result = file->close(); + EXPECT_TRUE(result.rc_); + EXPECT_FALSE(file->isOpen()); +} + +TEST_F(RawInstanceImplTest, WriteAfterClose) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + RawFilePtr file = raw_instance_.createRawFile(new_file_path); + auto bool_result = file->open(); + EXPECT_TRUE(bool_result.rc_); + bool_result = file->close(); + EXPECT_TRUE(bool_result.rc_); + const Api::SysCallSizeResult result = file->write(" new data"); + EXPECT_EQ(-1, result.rc_); + EXPECT_EQ(EBADF, result.errno_); +} + +} // namespace Filesystem +} // namespace Envoy diff --git a/test/mocks/api/mocks.cc b/test/mocks/api/mocks.cc index a805a623d7c32..94c02314103fd 100644 --- a/test/mocks/api/mocks.cc +++ b/test/mocks/api/mocks.cc @@ -16,30 +16,10 @@ MockApi::MockApi() { ON_CALL(*this, fileSystem()).WillByDefault(ReturnRef(file_s MockApi::~MockApi() {} -MockOsSysCalls::MockOsSysCalls() { num_writes_ = num_open_ = 0; } +MockOsSysCalls::MockOsSysCalls() {} MockOsSysCalls::~MockOsSysCalls() {} -SysCallIntResult MockOsSysCalls::open(const std::string& full_path, int flags, int mode) { - Thread::LockGuard lock(open_mutex_); - - int rc = open_(full_path, flags, mode); - num_open_++; - open_event_.notifyOne(); - - return SysCallIntResult{rc, errno}; -} - -SysCallSizeResult MockOsSysCalls::write(int fd, const void* buffer, size_t num_bytes) { - Thread::LockGuard lock(write_mutex_); - - ssize_t rc = write_(fd, buffer, num_bytes); - num_writes_++; - write_event_.notifyOne(); - - return SysCallSizeResult{rc, errno}; -} - SysCallIntResult MockOsSysCalls::setsockopt(int sockfd, int level, int optname, const void* optval, socklen_t optlen) { ASSERT(optlen == sizeof(int)); diff --git a/test/mocks/api/mocks.h b/test/mocks/api/mocks.h index 31dc57f9fe236..faae891bb2097 100644 --- a/test/mocks/api/mocks.h +++ b/test/mocks/api/mocks.h @@ -7,7 +7,6 @@ #include "envoy/api/os_sys_calls.h" #include "envoy/event/dispatcher.h" #include "envoy/event/timer.h" -#include "envoy/stats/store.h" #include "common/api/os_sys_calls_impl.h" @@ -42,8 +41,6 @@ class MockOsSysCalls : public OsSysCallsImpl { ~MockOsSysCalls(); // Api::OsSysCalls - SysCallSizeResult write(int fd, const void* buffer, size_t num_bytes) override; - SysCallIntResult open(const std::string& full_path, int flags, int mode) override; SysCallIntResult setsockopt(int sockfd, int level, int optname, const void* optval, socklen_t optlen) override; SysCallIntResult getsockopt(int sockfd, int level, int optname, void* optval, @@ -52,8 +49,6 @@ class MockOsSysCalls : public OsSysCallsImpl { MOCK_METHOD3(bind, SysCallIntResult(int sockfd, const sockaddr* addr, socklen_t addrlen)); MOCK_METHOD3(ioctl, SysCallIntResult(int sockfd, unsigned long int request, void* argp)); MOCK_METHOD1(close, SysCallIntResult(int)); - MOCK_METHOD3(open_, int(const std::string& full_path, int flags, int mode)); - MOCK_METHOD3(write_, ssize_t(int, const void*, size_t)); MOCK_METHOD3(writev, SysCallSizeResult(int, const iovec*, int)); MOCK_METHOD3(readv, SysCallSizeResult(int, const iovec*, int)); MOCK_METHOD4(recv, SysCallSizeResult(int socket, void* buffer, size_t length, int flags)); @@ -70,12 +65,6 @@ class MockOsSysCalls : public OsSysCallsImpl { int(int sockfd, int level, int optname, void* optval, socklen_t* optlen)); MOCK_METHOD3(socket, SysCallIntResult(int domain, int type, int protocol)); - size_t num_writes_; - size_t num_open_; - Thread::MutexBasicLockable write_mutex_; - Thread::MutexBasicLockable open_mutex_; - Thread::CondVar write_event_; - Thread::CondVar open_event_; // Map from (sockfd,level,optname) to boolean socket option. using SockOptKey = std::tuple; std::map boolsockopts_; diff --git a/test/mocks/filesystem/mocks.cc b/test/mocks/filesystem/mocks.cc index 42bc97cda3445..1f7b2383b7a9a 100644 --- a/test/mocks/filesystem/mocks.cc +++ b/test/mocks/filesystem/mocks.cc @@ -1,10 +1,47 @@ #include "test/mocks/filesystem/mocks.h" -#include +#include "common/common/lock_guard.h" namespace Envoy { namespace Filesystem { +MockRawFile::MockRawFile() : num_opens_(0), num_writes_(0), is_open_(false) {} +MockRawFile::~MockRawFile() {} + +Api::SysCallBoolResult MockRawFile::open() { + Thread::LockGuard lock(open_mutex_); + + const Api::SysCallBoolResult result = open_(); + is_open_ = result.rc_; + num_opens_++; + open_event_.notifyOne(); + + return result; +} + +Api::SysCallSizeResult MockRawFile::write(absl::string_view buffer) { + Thread::LockGuard lock(write_mutex_); + if (!is_open_) { + return {-1, EBADF}; + } + + const Api::SysCallSizeResult result = write_(buffer); + num_writes_++; + write_event_.notifyOne(); + + return result; +} + +Api::SysCallBoolResult MockRawFile::close() { + const Api::SysCallBoolResult result = close_(); + is_open_ = !result.rc_; + + return result; +} + +MockRawInstance::MockRawInstance() {} +MockRawInstance::~MockRawInstance() {} + MockFile::MockFile() {} MockFile::~MockFile() {} diff --git a/test/mocks/filesystem/mocks.h b/test/mocks/filesystem/mocks.h index 45e6e60b61d64..c65eed3e6d0ad 100644 --- a/test/mocks/filesystem/mocks.h +++ b/test/mocks/filesystem/mocks.h @@ -12,6 +12,48 @@ namespace Envoy { namespace Filesystem { +class MockRawFile : public RawFile { +public: + MockRawFile(); + ~MockRawFile(); + + // Filesystem::RawFile + Api::SysCallBoolResult open() override; + Api::SysCallSizeResult write(absl::string_view buffer) override; + Api::SysCallBoolResult close() override; + bool isOpen() override { return is_open_; }; + MOCK_METHOD0(path, std::string()); + + MOCK_METHOD0(open_, Api::SysCallBoolResult()); + MOCK_METHOD1(write_, Api::SysCallSizeResult(absl::string_view buffer)); + MOCK_METHOD0(close_, Api::SysCallBoolResult()); + + size_t num_opens_; + size_t num_writes_; + Thread::MutexBasicLockable open_mutex_; + Thread::MutexBasicLockable write_mutex_; + Thread::CondVar open_event_; + Thread::CondVar write_event_; + +private: + bool is_open_; +}; + +class MockRawInstance : public RawInstance { +public: + MockRawInstance(); + ~MockRawInstance(); + + // Filesystem::RawInstance + MOCK_METHOD1(createRawFile, RawFilePtr(const std::string&)); + MOCK_METHOD1(fileExists, bool(const std::string&)); + MOCK_METHOD1(directoryExists, bool(const std::string&)); + MOCK_METHOD1(fileSize, ssize_t(const std::string&)); + MOCK_METHOD1(fileReadToEnd, std::string(const std::string&)); + MOCK_METHOD1(canonicalPath, Api::SysCallStringResult(const std::string&)); + MOCK_METHOD1(illegalPath, bool(const std::string&)); +}; + class MockFile : public File { public: MockFile(); @@ -33,6 +75,9 @@ class MockInstance : public Instance { Thread::BasicLockable&, std::chrono::milliseconds)); MOCK_METHOD3(createFile, FileSharedPtr(const std::string&, Event::Dispatcher&, Thread::BasicLockable&)); + + // Filesystem::RawInstance + MOCK_METHOD1(createRawFile, RawFilePtr(const std::string&)); MOCK_METHOD1(fileExists, bool(const std::string&)); MOCK_METHOD1(directoryExists, bool(const std::string&)); MOCK_METHOD1(fileSize, ssize_t(const std::string&)); From 62f808656b0da2cfe9e4349b162030ca627b5661 Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Wed, 30 Jan 2019 13:34:22 -0500 Subject: [PATCH 02/13] fix typo Signed-off-by: Sam Smith --- test/common/filesystem/raw_instance_impl_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/common/filesystem/raw_instance_impl_test.cc b/test/common/filesystem/raw_instance_impl_test.cc index f2a8f999f9b24..83533baaa918d 100644 --- a/test/common/filesystem/raw_instance_impl_test.cc +++ b/test/common/filesystem/raw_instance_impl_test.cc @@ -119,13 +119,13 @@ TEST_F(RawInstanceImplTest, OpenTwice) { EXPECT_EQ(getFd(file.get()), -1); auto result = file->open(); - const int intial_fd = getFd(file.get()); + const int initial_fd = getFd(file.get()); EXPECT_TRUE(result.rc_); EXPECT_TRUE(file->isOpen()); // check that we don't leak a file descriptor result = file->open(); - EXPECT_EQ(intial_fd, getFd(file.get())); + EXPECT_EQ(initial_fd, getFd(file.get())); EXPECT_TRUE(result.rc_); EXPECT_TRUE(file->isOpen()); } From 1f291bf8cfd83eb3e74a2c2fe2f3a58ed212125d Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Mon, 4 Feb 2019 09:54:35 -0500 Subject: [PATCH 03/13] add CREATE + RDWR to spelling dictionary Signed-off-by: Sam Smith --- tools/spelling_dictionary.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/spelling_dictionary.txt b/tools/spelling_dictionary.txt index f7a4911917f8a..0eff9e9c91630 100644 --- a/tools/spelling_dictionary.txt +++ b/tools/spelling_dictionary.txt @@ -29,6 +29,7 @@ CPU CQ CR CRC +CREAT CRL CRLFs CRT @@ -174,6 +175,7 @@ RBAC RCU RDN RDS +RDWR REQ RFC RHS From 779da9c5649146cd5cecd80778db4c2f17c5cd99 Mon Sep 17 00:00:00 2001 From: Yael Harel Date: Tue, 5 Feb 2019 15:16:23 -0500 Subject: [PATCH 04/13] Address feedback Signed-off-by: Sam Smith Signed-off-by: Yael Harel --- include/envoy/filesystem/filesystem.h | 5 +++++ source/common/filesystem/filesystem_impl.cc | 8 ++++---- source/common/filesystem/raw_instance_impl.cc | 4 +++- source/common/filesystem/raw_instance_impl.h | 1 + test/common/filesystem/raw_instance_impl_test.cc | 16 ++++++++-------- test/mocks/filesystem/mocks.h | 1 + 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/include/envoy/filesystem/filesystem.h b/include/envoy/filesystem/filesystem.h index 35f7164e7a9f8..1d8534c0c29dc 100644 --- a/include/envoy/filesystem/filesystem.h +++ b/include/envoy/filesystem/filesystem.h @@ -51,6 +51,11 @@ class RawFile { * @return string the file path */ virtual std::string path() PURE; + + /** + * @return string a human-readable string describing the error code + */ + virtual std::string errorToString(int error) PURE; }; typedef std::unique_ptr RawFilePtr; diff --git a/source/common/filesystem/filesystem_impl.cc b/source/common/filesystem/filesystem_impl.cc index cdf8f0233bd3d..b87457652d5a9 100644 --- a/source/common/filesystem/filesystem_impl.cc +++ b/source/common/filesystem/filesystem_impl.cc @@ -71,7 +71,7 @@ FileImpl::FileImpl(RawFilePtr&& raw_file, Event::Dispatcher& dispatcher, } void FileImpl::open() { - const auto result = raw_file_->open(); + const Api::SysCallBoolResult result = raw_file_->open(); if (!result.rc_) { throw EnvoyException( fmt::format("unable to open file '{}': {}", raw_file_->path(), strerror(result.errno_))); @@ -97,7 +97,7 @@ FileImpl::~FileImpl() { doWrite(flush_buffer_); } - const auto result = raw_file_->close(); + const Api::SysCallBoolResult result = raw_file_->close(); ASSERT(result.rc_, fmt::format("unable to close file '{}': {}", raw_file_->path(), strerror(result.errno_))); } @@ -160,9 +160,9 @@ void FileImpl::flushThreadFunc() { try { if (reopen_file_) { reopen_file_ = false; - const auto result = raw_file_->close(); + const Api::SysCallBoolResult result = raw_file_->close(); ASSERT(result.rc_, fmt::format("unable to close file '{}': {}", raw_file_->path(), - strerror(result.errno_))); + raw_file_->errorToString(result.errno_))); open(); } diff --git a/source/common/filesystem/raw_instance_impl.cc b/source/common/filesystem/raw_instance_impl.cc index 3a8d04e9c27b0..ac2bfe47888ac 100644 --- a/source/common/filesystem/raw_instance_impl.cc +++ b/source/common/filesystem/raw_instance_impl.cc @@ -25,7 +25,7 @@ namespace Filesystem { RawFileImpl::RawFileImpl(const std::string& path) : fd_(-1), path_(path) {} RawFileImpl::~RawFileImpl() { - const auto result = close(); + const Api::SysCallBoolResult result = close(); ASSERT(result.rc_); } @@ -67,6 +67,8 @@ bool RawFileImpl::isOpen() { return fd_ != -1; } std::string RawFileImpl::path() { return path_; } +std::string RawFileImpl::errorToString(int error) { return ::strerror(error); } + RawFilePtr RawInstanceImpl::createRawFile(const std::string& path) { return std::make_unique(path); } diff --git a/source/common/filesystem/raw_instance_impl.h b/source/common/filesystem/raw_instance_impl.h index 4de54d9b8eaba..4a07ec9d88063 100644 --- a/source/common/filesystem/raw_instance_impl.h +++ b/source/common/filesystem/raw_instance_impl.h @@ -19,6 +19,7 @@ class RawFileImpl : public RawFile { Api::SysCallBoolResult close() override; bool isOpen() override; std::string path() override; + std::string errorToString(int error) override; private: int fd_; diff --git a/test/common/filesystem/raw_instance_impl_test.cc b/test/common/filesystem/raw_instance_impl_test.cc index c30a4fe2ecdba..ed442534f80bb 100644 --- a/test/common/filesystem/raw_instance_impl_test.cc +++ b/test/common/filesystem/raw_instance_impl_test.cc @@ -113,7 +113,7 @@ TEST_F(RawInstanceImplTest, Open) { ::unlink(new_file_path.c_str()); RawFilePtr file = raw_instance_.createRawFile(new_file_path); - const auto result = file->open(); + const Api::SysCallBoolResult result = file->open(); EXPECT_TRUE(result.rc_); EXPECT_TRUE(file->isOpen()); } @@ -125,7 +125,7 @@ TEST_F(RawInstanceImplTest, OpenTwice) { RawFilePtr file = raw_instance_.createRawFile(new_file_path); EXPECT_EQ(getFd(file.get()), -1); - auto result = file->open(); + Api::SysCallBoolResult result = file->open(); const int initial_fd = getFd(file.get()); EXPECT_TRUE(result.rc_); EXPECT_TRUE(file->isOpen()); @@ -139,7 +139,7 @@ TEST_F(RawInstanceImplTest, OpenTwice) { TEST_F(RawInstanceImplTest, OpenBadFilePath) { RawFilePtr file = raw_instance_.createRawFile(""); - const auto result = file->open(); + const Api::SysCallBoolResult result = file->open(); EXPECT_FALSE(result.rc_); } @@ -149,7 +149,7 @@ TEST_F(RawInstanceImplTest, ExistingFile) { { RawFilePtr file = raw_instance_.createRawFile(file_path); - const auto open_result = file->open(); + const Api::SysCallBoolResult open_result = file->open(); EXPECT_TRUE(open_result.rc_); std::string data(" new data"); const Api::SysCallSizeResult result = file->write(data); @@ -166,7 +166,7 @@ TEST_F(RawInstanceImplTest, NonExistingFile) { { RawFilePtr file = raw_instance_.createRawFile(new_file_path); - const auto open_result = file->open(); + const Api::SysCallBoolResult open_result = file->open(); EXPECT_TRUE(open_result.rc_); std::string data(" new data"); const Api::SysCallSizeResult result = file->write(data); @@ -182,7 +182,7 @@ TEST_F(RawInstanceImplTest, Close) { ::unlink(new_file_path.c_str()); RawFilePtr file = raw_instance_.createRawFile(new_file_path); - const auto result = file->close(); + const Api::SysCallBoolResult result = file->close(); EXPECT_TRUE(result.rc_); EXPECT_FALSE(file->isOpen()); } @@ -192,7 +192,7 @@ TEST_F(RawInstanceImplTest, CloseTwice) { ::unlink(new_file_path.c_str()); RawFilePtr file = raw_instance_.createRawFile(new_file_path); - auto result = file->close(); + Api::SysCallBoolResult result = file->close(); EXPECT_TRUE(result.rc_); EXPECT_FALSE(file->isOpen()); @@ -207,7 +207,7 @@ TEST_F(RawInstanceImplTest, WriteAfterClose) { ::unlink(new_file_path.c_str()); RawFilePtr file = raw_instance_.createRawFile(new_file_path); - auto bool_result = file->open(); + Api::SysCallBoolResult bool_result = file->open(); EXPECT_TRUE(bool_result.rc_); bool_result = file->close(); EXPECT_TRUE(bool_result.rc_); diff --git a/test/mocks/filesystem/mocks.h b/test/mocks/filesystem/mocks.h index c65eed3e6d0ad..017aa4a5866f4 100644 --- a/test/mocks/filesystem/mocks.h +++ b/test/mocks/filesystem/mocks.h @@ -23,6 +23,7 @@ class MockRawFile : public RawFile { Api::SysCallBoolResult close() override; bool isOpen() override { return is_open_; }; MOCK_METHOD0(path, std::string()); + MOCK_METHOD1(errorToString, std::string(int)); MOCK_METHOD0(open_, Api::SysCallBoolResult()); MOCK_METHOD1(write_, Api::SysCallSizeResult(absl::string_view buffer)); From 1b22c96c4b4da40d60e2efb26e0ee7fe165610e2 Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Tue, 5 Feb 2019 16:45:33 -0500 Subject: [PATCH 05/13] add todo Signed-off-by: Sam Smith Signed-off-by: Yael Harel --- include/envoy/filesystem/filesystem.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/envoy/filesystem/filesystem.h b/include/envoy/filesystem/filesystem.h index 1d8534c0c29dc..5d959fbc0948a 100644 --- a/include/envoy/filesystem/filesystem.h +++ b/include/envoy/filesystem/filesystem.h @@ -54,6 +54,7 @@ class RawFile { /** * @return string a human-readable string describing the error code + * TODO(sesmith177) Abstract this method so it isn't dependant on integer error codes */ virtual std::string errorToString(int error) PURE; }; From ac7d4c1169e1642d77b535ef8e21c7e10eb9767b Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Wed, 6 Feb 2019 08:45:09 -0500 Subject: [PATCH 06/13] typedef -> using Signed-off-by: Sam Smith --- include/envoy/filesystem/filesystem.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/envoy/filesystem/filesystem.h b/include/envoy/filesystem/filesystem.h index 5d959fbc0948a..47d52c90bbd50 100644 --- a/include/envoy/filesystem/filesystem.h +++ b/include/envoy/filesystem/filesystem.h @@ -59,7 +59,7 @@ class RawFile { virtual std::string errorToString(int error) PURE; }; -typedef std::unique_ptr RawFilePtr; +using RawFilePtr = std::unique_ptr; class RawInstance { public: @@ -136,7 +136,7 @@ class File { virtual void flush() PURE; }; -typedef std::shared_ptr FileSharedPtr; +using FileSharedPtr = std::shared_ptr; /** * Captures state, properties, and stats of a file-system. @@ -168,8 +168,6 @@ class Instance : public RawInstance { Thread::BasicLockable& lock) PURE; }; -typedef std::unique_ptr WatcherPtr; - enum class FileType { Regular, Directory, Other }; struct DirectoryEntry { From a2c8c4f79c92c50b996c63dcb7b3c9a40b480297 Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Wed, 6 Feb 2019 13:58:06 -0500 Subject: [PATCH 07/13] wip Signed-off-by: Sam Smith wip Signed-off-by: Sam Smith wip Signed-off-by: Sam Smith --- include/envoy/access_log/BUILD | 1 - include/envoy/access_log/access_log.h | 35 +- include/envoy/filesystem/BUILD | 1 + include/envoy/filesystem/filesystem.h | 77 +--- source/common/access_log/BUILD | 2 + .../access_log/access_log_manager_impl.cc | 173 ++++++++- .../access_log/access_log_manager_impl.h | 114 +++++- source/common/api/BUILD | 2 - source/common/api/api_impl.cc | 8 +- source/common/api/api_impl.h | 7 +- source/common/common/BUILD | 1 - source/common/common/logger_delegates.h | 3 +- source/common/filesystem/BUILD | 12 - source/common/filesystem/filesystem_impl.cc | 272 ++++++--------- source/common/filesystem/filesystem_impl.h | 140 ++------ source/common/filesystem/raw_instance_impl.cc | 150 -------- source/common/filesystem/raw_instance_impl.h | 43 --- .../upstream/health_checker_base_impl.h | 2 +- .../common/upstream/outlier_detection_impl.h | 2 +- .../file/file_access_log_impl.h | 2 +- .../filters/network/mongo_proxy/proxy.h | 2 +- source/server/config_validation/api.cc | 5 +- source/server/config_validation/api.h | 4 +- source/server/config_validation/server.cc | 7 +- source/server/server.cc | 7 +- .../access_log_manager_impl_test.cc | 330 +++++++++++++++++- .../common/filesystem/filesystem_impl_test.cc | 261 -------------- test/mocks/access_log/mocks.cc | 3 + test/mocks/access_log/mocks.h | 17 +- test/mocks/filesystem/mocks.cc | 16 +- test/mocks/filesystem/mocks.h | 43 +-- test/test_common/utility.cc | 14 +- 32 files changed, 806 insertions(+), 950 deletions(-) delete mode 100644 source/common/filesystem/raw_instance_impl.cc delete mode 100644 source/common/filesystem/raw_instance_impl.h diff --git a/include/envoy/access_log/BUILD b/include/envoy/access_log/BUILD index d05c37b156130..da0469451a0b8 100644 --- a/include/envoy/access_log/BUILD +++ b/include/envoy/access_log/BUILD @@ -12,7 +12,6 @@ envoy_cc_library( name = "access_log_interface", hdrs = ["access_log.h"], deps = [ - "//include/envoy/filesystem:filesystem_interface", "//include/envoy/http:header_map_interface", "//include/envoy/stream_info:stream_info_interface", ], diff --git a/include/envoy/access_log/access_log.h b/include/envoy/access_log/access_log.h index 5f04026a2aae0..b210e87c58b1f 100644 --- a/include/envoy/access_log/access_log.h +++ b/include/envoy/access_log/access_log.h @@ -4,13 +4,34 @@ #include #include "envoy/common/pure.h" -#include "envoy/filesystem/filesystem.h" #include "envoy/http/header_map.h" #include "envoy/stream_info/stream_info.h" namespace Envoy { namespace AccessLog { +class AccessLogFile { +public: + virtual ~AccessLogFile() {} + + /** + * Write data to the file. + */ + virtual void write(absl::string_view) PURE; + + /** + * Reopen the file. + */ + virtual void reopen() PURE; + + /** + * Synchronously flush all pending data to disk. + */ + virtual void flush() PURE; +}; + +using AccessLogFileSharedPtr = std::shared_ptr; + class AccessLogManager { public: virtual ~AccessLogManager() {} @@ -25,10 +46,10 @@ class AccessLogManager { * @param file_name specifies the file to create/open. * @return the opened file. */ - virtual Filesystem::FileSharedPtr createAccessLog(const std::string& file_name) PURE; + virtual AccessLogFileSharedPtr createAccessLog(const std::string& file_name) PURE; }; -typedef std::unique_ptr AccessLogManagerPtr; +using AccessLogManagerPtr = std::unique_ptr; /** * Interface for access log filters. @@ -45,7 +66,7 @@ class Filter { const Http::HeaderMap& request_headers) PURE; }; -typedef std::unique_ptr FilterPtr; +using FilterPtr = std::unique_ptr; /** * Abstract access logger for requests and connections. @@ -67,7 +88,7 @@ class Instance { const StreamInfo::StreamInfo& stream_info) PURE; }; -typedef std::shared_ptr InstanceSharedPtr; +using InstanceSharedPtr = std::shared_ptr; /** * Interface for access log formatter. @@ -91,7 +112,7 @@ class Formatter { const StreamInfo::StreamInfo& stream_info) const PURE; }; -typedef std::unique_ptr FormatterPtr; +using FormatterPtr = std::unique_ptr; /** * Interface for access log provider. @@ -115,7 +136,7 @@ class FormatterProvider { const StreamInfo::StreamInfo& stream_info) const PURE; }; -typedef std::unique_ptr FormatterProviderPtr; +using FormatterProviderPtr = std::unique_ptr; } // namespace AccessLog } // namespace Envoy diff --git a/include/envoy/filesystem/BUILD b/include/envoy/filesystem/BUILD index 022c770c1c4ae..d61b9ed36d0a1 100644 --- a/include/envoy/filesystem/BUILD +++ b/include/envoy/filesystem/BUILD @@ -12,6 +12,7 @@ envoy_cc_library( name = "filesystem_interface", hdrs = ["filesystem.h"], deps = [ + "//include/envoy/api:os_sys_calls_interface", "//include/envoy/event:dispatcher_interface", ], ) diff --git a/include/envoy/filesystem/filesystem.h b/include/envoy/filesystem/filesystem.h index 47d52c90bbd50..938d16df8fd76 100644 --- a/include/envoy/filesystem/filesystem.h +++ b/include/envoy/filesystem/filesystem.h @@ -4,9 +4,8 @@ #include #include +#include "envoy/api/os_sys_calls.h" #include "envoy/common/pure.h" -#include "envoy/event/dispatcher.h" -#include "envoy/thread/thread.h" #include "absl/strings/string_view.h" @@ -16,9 +15,9 @@ namespace Filesystem { /** * Abstraction for a basic file on disk. */ -class RawFile { +class File { public: - virtual ~RawFile() {} + virtual ~File() {} /** * Open the file with O_RDWR | O_APPEND | O_CREAT @@ -59,17 +58,20 @@ class RawFile { virtual std::string errorToString(int error) PURE; }; -using RawFilePtr = std::unique_ptr; +using FilePtr = std::unique_ptr; -class RawInstance { +/** + * Abstraction for some basic filesystem operations + */ +class Instance { public: - virtual ~RawInstance() {} + virtual ~Instance() {} /** - * @param path The path of the RawFile - * @return a RawFilePtr. The file is not opened. + * @param path The path of the File + * @return a FilePtr. The file is not opened. */ - virtual RawFilePtr createRawFile(const std::string& path) PURE; + virtual FilePtr createFile(const std::string& path) PURE; /** * @return bool whether a file exists on disk and can be opened for read. @@ -113,61 +115,6 @@ class RawInstance { virtual bool illegalPath(const std::string& path) PURE; }; -/** - * Abstraction for a file on disk. It is specifically designed for writing access logs. - */ -class File { -public: - virtual ~File() {} - - /** - * Write data to the file. - */ - virtual void write(absl::string_view) PURE; - - /** - * Reopen the file. - */ - virtual void reopen() PURE; - - /** - * Synchronously flush all pending data to disk. - */ - virtual void flush() PURE; -}; - -using FileSharedPtr = std::shared_ptr; - -/** - * Captures state, properties, and stats of a file-system. - */ -class Instance : public RawInstance { -public: - virtual ~Instance() {} - - /** - * Creates a file, overriding the flush-interval set in the class. - * - * @param path The path of the file to open. - * @param dispatcher The dispatcher used for set up timers to run flush(). - * @param lock The lock. - * @param file_flush_interval_msec Number of milliseconds to delay before flushing. - */ - virtual FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, - Thread::BasicLockable& lock, - std::chrono::milliseconds file_flush_interval_msec) PURE; - - /** - * Creates a file, using the default flush-interval for the class. - * - * @param path The path of the file to open. - * @param dispatcher The dispatcher used for set up timers to run flush(). - * @param lock The lock. - */ - virtual FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, - Thread::BasicLockable& lock) PURE; -}; - enum class FileType { Regular, Directory, Other }; struct DirectoryEntry { diff --git a/source/common/access_log/BUILD b/source/common/access_log/BUILD index c7be03032909e..48bb5b769d97d 100644 --- a/source/common/access_log/BUILD +++ b/source/common/access_log/BUILD @@ -30,6 +30,8 @@ envoy_cc_library( deps = [ "//include/envoy/access_log:access_log_interface", "//include/envoy/api:api_interface", + "//source/common/buffer:buffer_lib", + "//source/common/common:thread_lib", ], ) diff --git a/source/common/access_log/access_log_manager_impl.cc b/source/common/access_log/access_log_manager_impl.cc index ecc62535b0b6f..14a27be7b61e5 100644 --- a/source/common/access_log/access_log_manager_impl.cc +++ b/source/common/access_log/access_log_manager_impl.cc @@ -2,6 +2,11 @@ #include +#include "common/common/assert.h" +#include "common/common/fmt.h" +#include "common/common/lock_guard.h" +#include "common/common/stack_array.h" + namespace Envoy { namespace AccessLog { @@ -11,14 +16,178 @@ void AccessLogManagerImpl::reopen() { } } -Filesystem::FileSharedPtr AccessLogManagerImpl::createAccessLog(const std::string& file_name) { +AccessLogFileSharedPtr AccessLogManagerImpl::createAccessLog(const std::string& file_name) { if (access_logs_.count(file_name)) { return access_logs_[file_name]; } - access_logs_[file_name] = api_.fileSystem().createFile(file_name, dispatcher_, lock_); + access_logs_[file_name] = std::make_shared( + api_.fileSystem().createFile(file_name), dispatcher_, lock_, file_stats_, + file_flush_interval_msec_, api_.threadFactory()); return access_logs_[file_name]; } +AccessLogFileImpl::AccessLogFileImpl(Filesystem::FilePtr&& file, Event::Dispatcher& dispatcher, + Thread::BasicLockable& lock, AccessLogFileStats& stats, + std::chrono::milliseconds flush_interval_msec, + Thread::ThreadFactory& thread_factory) + : file_(std::move(file)), file_lock_(lock), + flush_timer_(dispatcher.createTimer([this]() -> void { + stats_.flushed_by_timer_.inc(); + flush_event_.notifyOne(); + flush_timer_->enableTimer(flush_interval_msec_); + })), + thread_factory_(thread_factory), flush_interval_msec_(flush_interval_msec), stats_(stats) { + open(); +} + +void AccessLogFileImpl::open() { + const Api::SysCallBoolResult result = file_->open(); + if (!result.rc_) { + throw EnvoyException(fmt::format("unable to open file '{}': {}", file_->path(), + file_->errorToString(result.errno_))); + } +} + +void AccessLogFileImpl::reopen() { reopen_file_ = true; } + +AccessLogFileImpl::~AccessLogFileImpl() { + { + Thread::LockGuard lock(write_lock_); + flush_thread_exit_ = true; + flush_event_.notifyOne(); + } + + if (flush_thread_ != nullptr) { + flush_thread_->join(); + } + + // Flush any remaining data. If file was not opened for some reason, skip flushing part. + if (file_->isOpen()) { + if (flush_buffer_.length() > 0) { + doWrite(flush_buffer_); + } + + const Api::SysCallBoolResult result = file_->close(); + ASSERT(result.rc_, fmt::format("unable to close file '{}': {}", file_->path(), + file_->errorToString(result.errno_))); + } +} + +void AccessLogFileImpl::doWrite(Buffer::Instance& buffer) { + uint64_t num_slices = buffer.getRawSlices(nullptr, 0); + STACK_ARRAY(slices, Buffer::RawSlice, num_slices); + buffer.getRawSlices(slices.begin(), num_slices); + + // We must do the actual writes to disk under lock, so that we don't intermix chunks from + // different AccessLogFileImpl pointing to the same underlying file. This can happen either via + // hot restart or if calling code opens the same underlying file into a different + // AccessLogFileImpl in the same process. + // TODO PERF: Currently, we use a single cross process lock to serialize all disk writes. This + // will never block network workers, but does mean that only a single flush thread can + // actually flush to disk. In the future it would be nice if we did away with the cross + // process lock or had multiple locks. + { + Thread::LockGuard lock(file_lock_); + for (const Buffer::RawSlice& slice : slices) { + absl::string_view data(static_cast(slice.mem_), slice.len_); + const Api::SysCallSizeResult result = file_->write(data); + ASSERT(result.rc_ == static_cast(slice.len_)); + stats_.write_completed_.inc(); + } + } + + stats_.write_total_buffered_.sub(buffer.length()); + buffer.drain(buffer.length()); +} + +void AccessLogFileImpl::flushThreadFunc() { + + while (true) { + std::unique_lock flush_lock; + + { + Thread::LockGuard write_lock(write_lock_); + + // flush_event_ can be woken up either by large enough flush_buffer or by timer. + // In case it was timer, flush_buffer_ can be empty. + while (flush_buffer_.length() == 0 && !flush_thread_exit_) { + // CondVar::wait() does not throw, so it's safe to pass the mutex rather than the guard. + flush_event_.wait(write_lock_); + } + + if (flush_thread_exit_) { + return; + } + + flush_lock = std::unique_lock(flush_lock_); + ASSERT(flush_buffer_.length() > 0); + about_to_write_buffer_.move(flush_buffer_); + ASSERT(flush_buffer_.length() == 0); + } + + // if we failed to open file before, then simply ignore + if (file_->isOpen()) { + try { + if (reopen_file_) { + reopen_file_ = false; + const Api::SysCallBoolResult result = file_->close(); + ASSERT(result.rc_, fmt::format("unable to close file '{}': {}", file_->path(), + file_->errorToString(result.errno_))); + open(); + } + + doWrite(about_to_write_buffer_); + } catch (const EnvoyException&) { + stats_.reopen_failed_.inc(); + } + } + } +} + +void AccessLogFileImpl::flush() { + std::unique_lock flush_buffer_lock; + + { + Thread::LockGuard write_lock(write_lock_); + + // flush_lock_ must be held while checking this or else it is + // possible that flushThreadFunc() has already moved data from + // flush_buffer_ to about_to_write_buffer_, has unlocked write_lock_, + // but has not yet completed doWrite(). This would allow flush() to + // return before the pending data has actually been written to disk. + flush_buffer_lock = std::unique_lock(flush_lock_); + + if (flush_buffer_.length() == 0) { + return; + } + + about_to_write_buffer_.move(flush_buffer_); + ASSERT(flush_buffer_.length() == 0); + } + + doWrite(about_to_write_buffer_); +} + +void AccessLogFileImpl::write(absl::string_view data) { + Thread::LockGuard lock(write_lock_); + + if (flush_thread_ == nullptr) { + createFlushStructures(); + } + + stats_.write_buffered_.inc(); + stats_.write_total_buffered_.add(data.length()); + flush_buffer_.add(data.data(), data.size()); + if (flush_buffer_.length() > MIN_FLUSH_SIZE) { + flush_event_.notifyOne(); + } +} + +void AccessLogFileImpl::createFlushStructures() { + flush_thread_ = thread_factory_.createThread([this]() -> void { flushThreadFunc(); }); + flush_timer_->enableTimer(flush_interval_msec_); +} + } // namespace AccessLog } // namespace Envoy diff --git a/source/common/access_log/access_log_manager_impl.h b/source/common/access_log/access_log_manager_impl.h index 502ca50c74e86..d009a933042d1 100644 --- a/source/common/access_log/access_log_manager_impl.h +++ b/source/common/access_log/access_log_manager_impl.h @@ -5,24 +5,130 @@ #include "envoy/access_log/access_log.h" #include "envoy/api/api.h" +#include "envoy/event/dispatcher.h" +#include "envoy/filesystem/filesystem.h" +#include "envoy/stats/stats_macros.h" +#include "envoy/stats/store.h" + +#include "common/buffer/buffer_impl.h" +#include "common/common/thread.h" namespace Envoy { + +// clang-format off +#define ACCESS_LOG_FILE_STATS(COUNTER, GAUGE) \ + COUNTER(write_buffered) \ + COUNTER(write_completed) \ + COUNTER(flushed_by_timer) \ + COUNTER(reopen_failed) \ + GAUGE (write_total_buffered) +// clang-format on + +struct AccessLogFileStats { + ACCESS_LOG_FILE_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT) +}; + namespace AccessLog { class AccessLogManagerImpl : public AccessLogManager { public: - AccessLogManagerImpl(Api::Api& api, Event::Dispatcher& dispatcher, Thread::BasicLockable& lock) - : api_(api), dispatcher_(dispatcher), lock_(lock) {} + AccessLogManagerImpl(std::chrono::milliseconds file_flush_interval_msec, Api::Api& api, + Event::Dispatcher& dispatcher, Thread::BasicLockable& lock, + Stats::Store& stats_store) + : file_flush_interval_msec_(file_flush_interval_msec), api_(api), dispatcher_(dispatcher), + lock_(lock), file_stats_{ACCESS_LOG_FILE_STATS( + POOL_COUNTER_PREFIX(stats_store, "access_log_file."), + POOL_GAUGE_PREFIX(stats_store, "access_log_file."))} {} // AccessLog::AccessLogManager void reopen() override; - Filesystem::FileSharedPtr createAccessLog(const std::string& file_name) override; + AccessLogFileSharedPtr createAccessLog(const std::string& file_name) override; private: + const std::chrono::milliseconds file_flush_interval_msec_; Api::Api& api_; Event::Dispatcher& dispatcher_; Thread::BasicLockable& lock_; - std::unordered_map access_logs_; + AccessLogFileStats file_stats_; + std::unordered_map access_logs_; +}; + +/** + * This is a file implementation geared for writing out access logs. It turn out that in certain + * cases even if a standard file is opened with O_NONBLOCK, the kernel can still block when writing. + * This implementation uses a flush thread per file, with the idea there there aren't that many + * files. If this turns out to be a good implementation we can potentially have a single flush + * thread that flushes all files, but we will start with this. + */ +class AccessLogFileImpl : public AccessLogFile { +public: + AccessLogFileImpl(Filesystem::FilePtr&& file, Event::Dispatcher& dispatcher, + Thread::BasicLockable& lock, AccessLogFileStats& stats_, + std::chrono::milliseconds flush_interval_msec, + Thread::ThreadFactory& thread_factory); + ~AccessLogFileImpl(); + + // AccessLog::AccessLogFile + void write(absl::string_view data) override; + + /** + * Reopen file asynchronously. + * This only sets reopen flag, actual reopen operation is delayed. + * Reopen happens before the next write operation. + */ + void reopen() override; + void flush() override; + +private: + void doWrite(Buffer::Instance& buffer); + void flushThreadFunc(); + void open(); + void createFlushStructures(); + + // Minimum size before the flush thread will be told to flush. + static const uint64_t MIN_FLUSH_SIZE = 1024 * 64; + + Filesystem::FilePtr file_; + + // These locks are always acquired in the following order if multiple locks are held: + // 1) write_lock_ + // 2) flush_lock_ + // 3) file_lock_ + Thread::BasicLockable& file_lock_; // This lock is used only by the flush thread when writing + // to disk. This is used to make sure that file blocks do + // not get interleaved by multiple processes writing to + // the same file during hot-restart. + Thread::MutexBasicLockable flush_lock_; // This lock is used to prevent simultaneous flushes from + // the flush thread and a synchronous flush. This protects + // concurrent access to the about_to_write_buffer_, fd_, + // and all other data used during flushing and file + // re-opening. + Thread::MutexBasicLockable + write_lock_; // The lock is used when filling the flush buffer. It allows + // multiple threads to write to the same file at relatively + // high performance. It is always local to the process. + Thread::ThreadPtr flush_thread_; + Thread::CondVar flush_event_; + std::atomic flush_thread_exit_{}; + std::atomic reopen_file_{}; + Buffer::OwnedImpl + flush_buffer_ GUARDED_BY(write_lock_); // This buffer is used by multiple threads. It gets + // filled and then flushed either when max size is + // reached or when a timer fires. + // TODO(jmarantz): this should be GUARDED_BY(flush_lock_) but the analysis cannot poke through + // the std::make_unique assignment. I do not believe it's possible to annotate this properly now + // due to limitations in the clang thread annotation analysis. + Buffer::OwnedImpl about_to_write_buffer_; // This buffer is used only by the flush thread. Data + // is moved from flush_buffer_ under lock, and then + // the lock is released so that flush_buffer_ can + // continue to fill. This buffer is then used for the + // final write to disk. + Event::TimerPtr flush_timer_; + Thread::ThreadFactory& thread_factory_; + const std::chrono::milliseconds flush_interval_msec_; // Time interval buffer gets flushed no + // matter if it reached the MIN_FLUSH_SIZE + // or not. + AccessLogFileStats& stats_; }; } // namespace AccessLog diff --git a/source/common/api/BUILD b/source/common/api/BUILD index 02d0b50293b1c..92623ea51279f 100644 --- a/source/common/api/BUILD +++ b/source/common/api/BUILD @@ -14,11 +14,9 @@ envoy_cc_library( hdrs = ["api_impl.h"], deps = [ "//include/envoy/api:api_interface", - "//source/common/api:os_sys_calls_lib", "//source/common/common:thread_lib", "//source/common/event:dispatcher_lib", "//source/common/filesystem:filesystem_lib", - "//source/common/filesystem:raw_instance_lib", ], ) diff --git a/source/common/api/api_impl.cc b/source/common/api/api_impl.cc index 74d3e2777db60..ee4feb56b4f15 100644 --- a/source/common/api/api_impl.cc +++ b/source/common/api/api_impl.cc @@ -9,12 +9,8 @@ namespace Envoy { namespace Api { -Impl::Impl(std::chrono::milliseconds file_flush_interval_msec, - Thread::ThreadFactory& thread_factory, Stats::Store& stats_store, - Event::TimeSystem& time_system) - : thread_factory_(thread_factory), - file_system_(file_flush_interval_msec, thread_factory, stats_store, raw_instance_), - time_system_(time_system) {} +Impl::Impl(Thread::ThreadFactory& thread_factory, Event::TimeSystem& time_system) + : thread_factory_(thread_factory), time_system_(time_system) {} Event::DispatcherPtr Impl::allocateDispatcher() { return std::make_unique(*this); diff --git a/source/common/api/api_impl.h b/source/common/api/api_impl.h index 8a617cfb72f05..77c778df1b4e7 100644 --- a/source/common/api/api_impl.h +++ b/source/common/api/api_impl.h @@ -9,7 +9,6 @@ #include "envoy/thread/thread.h" #include "common/filesystem/filesystem_impl.h" -#include "common/filesystem/raw_instance_impl.h" namespace Envoy { namespace Api { @@ -19,8 +18,7 @@ namespace Api { */ class Impl : public Api { public: - Impl(std::chrono::milliseconds file_flush_interval_msec, Thread::ThreadFactory& thread_factory, - Stats::Store& stats_store, Event::TimeSystem& time_system); + Impl(Thread::ThreadFactory& thread_factory, Event::TimeSystem& time_system); // Api::Api Event::DispatcherPtr allocateDispatcher() override; @@ -30,9 +28,6 @@ class Impl : public Api { private: Thread::ThreadFactory& thread_factory_; - // TODO(sesmith177): Inject a RawInstance& when we have separate versions - // for POSIX / Windows - Filesystem::RawInstanceImpl raw_instance_; Filesystem::InstanceImpl file_system_; Event::TimeSystem& time_system_; }; diff --git a/source/common/common/BUILD b/source/common/common/BUILD index 76ed1b37bc4bf..c01c9db0ac5df 100644 --- a/source/common/common/BUILD +++ b/source/common/common/BUILD @@ -134,7 +134,6 @@ envoy_cc_library( ":macros", ":minimal_logger_lib", "//include/envoy/access_log:access_log_interface", - "//include/envoy/filesystem:filesystem_interface", ], ) diff --git a/source/common/common/logger_delegates.h b/source/common/common/logger_delegates.h index 1dcd4d6926943..67264d29c3a33 100644 --- a/source/common/common/logger_delegates.h +++ b/source/common/common/logger_delegates.h @@ -5,7 +5,6 @@ #include #include "envoy/access_log/access_log.h" -#include "envoy/filesystem/filesystem.h" #include "common/common/logger.h" #include "common/common/macros.h" @@ -31,7 +30,7 @@ class FileSinkDelegate : public SinkDelegate { void flush() override; private: - Filesystem::FileSharedPtr log_file_; + AccessLog::AccessLogFileSharedPtr log_file_; }; } // namespace Logger diff --git a/source/common/filesystem/BUILD b/source/common/filesystem/BUILD index 5631afa2607e4..99b0c654fc404 100644 --- a/source/common/filesystem/BUILD +++ b/source/common/filesystem/BUILD @@ -42,18 +42,6 @@ envoy_cc_library( name = "filesystem_lib", srcs = ["filesystem_impl.cc"], hdrs = ["filesystem_impl.h"], - deps = [ - "//include/envoy/event:dispatcher_interface", - "//include/envoy/filesystem:filesystem_interface", - "//source/common/buffer:buffer_lib", - "//source/common/common:thread_lib", - ], -) - -envoy_cc_library( - name = "raw_instance_lib", - srcs = ["raw_instance_impl.cc"], - hdrs = ["raw_instance_impl.h"], deps = [ "//include/envoy/filesystem:filesystem_interface", ], diff --git a/source/common/filesystem/filesystem_impl.cc b/source/common/filesystem/filesystem_impl.cc index b87457652d5a9..420d3273e5203 100644 --- a/source/common/filesystem/filesystem_impl.cc +++ b/source/common/filesystem/filesystem_impl.cc @@ -1,221 +1,149 @@ #include "common/filesystem/filesystem_impl.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include + #include "envoy/common/exception.h" -#include "envoy/common/time.h" -#include "envoy/event/dispatcher.h" -#include "envoy/thread/thread.h" -#include "common/api/os_sys_calls_impl.h" #include "common/common/assert.h" #include "common/common/fmt.h" -#include "common/common/lock_guard.h" -#include "common/common/stack_array.h" +#include "common/common/logger.h" + +#include "absl/strings/match.h" namespace Envoy { namespace Filesystem { -InstanceImpl::InstanceImpl(std::chrono::milliseconds file_flush_interval_msec, - Thread::ThreadFactory& thread_factory, Stats::Store& stats_store, - RawInstance& raw_instance) - : file_flush_interval_msec_(file_flush_interval_msec), - file_stats_{FILESYSTEM_STATS(POOL_COUNTER_PREFIX(stats_store, "filesystem."), - POOL_GAUGE_PREFIX(stats_store, "filesystem."))}, - thread_factory_(thread_factory), raw_instance_(raw_instance) {} - -FileSharedPtr InstanceImpl::createFile(const std::string& path, Event::Dispatcher& dispatcher, - Thread::BasicLockable& lock, - std::chrono::milliseconds file_flush_interval_msec) { - return std::make_shared(createRawFile(path), dispatcher, lock, file_stats_, - file_flush_interval_msec, thread_factory_); -}; - -FileSharedPtr InstanceImpl::createFile(const std::string& path, Event::Dispatcher& dispatcher, - Thread::BasicLockable& lock) { - return createFile(path, dispatcher, lock, file_flush_interval_msec_); -} +FileImpl::FileImpl(const std::string& path) : fd_(-1), path_(path) {} -RawFilePtr InstanceImpl::createRawFile(const std::string& path) { - return raw_instance_.createRawFile(path); +FileImpl::~FileImpl() { + const Api::SysCallBoolResult result = close(); + ASSERT(result.rc_); } -bool InstanceImpl::fileExists(const std::string& path) { return raw_instance_.fileExists(path); } - -bool InstanceImpl::directoryExists(const std::string& path) { - return raw_instance_.directoryExists(path); -} +Api::SysCallBoolResult FileImpl::open() { + if (isOpen()) { + return {true, 0}; + } -ssize_t InstanceImpl::fileSize(const std::string& path) { return raw_instance_.fileSize(path); } + const int flags = O_RDWR | O_APPEND | O_CREAT; + const int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; -std::string InstanceImpl::fileReadToEnd(const std::string& path) { - return raw_instance_.fileReadToEnd(path); + fd_ = ::open(path_.c_str(), flags, mode); + if (-1 == fd_) { + return {false, errno}; + } + return {true, 0}; } -Api::SysCallStringResult InstanceImpl::canonicalPath(const std::string& path) { - return raw_instance_.canonicalPath(path); +Api::SysCallSizeResult FileImpl::write(absl::string_view buffer) { + const ssize_t rc = ::write(fd_, buffer.data(), buffer.size()); + return {rc, errno}; } -bool InstanceImpl::illegalPath(const std::string& path) { return raw_instance_.illegalPath(path); } - -FileImpl::FileImpl(RawFilePtr&& raw_file, Event::Dispatcher& dispatcher, - Thread::BasicLockable& lock, FileSystemStats& stats, - std::chrono::milliseconds flush_interval_msec, - Thread::ThreadFactory& thread_factory) - : raw_file_(std::move(raw_file)), file_lock_(lock), - flush_timer_(dispatcher.createTimer([this]() -> void { - stats_.flushed_by_timer_.inc(); - flush_event_.notifyOne(); - flush_timer_->enableTimer(flush_interval_msec_); - })), - thread_factory_(thread_factory), flush_interval_msec_(flush_interval_msec), stats_(stats) { - open(); -} +Api::SysCallBoolResult FileImpl::close() { + if (!isOpen()) { + return {true, 0}; + } -void FileImpl::open() { - const Api::SysCallBoolResult result = raw_file_->open(); - if (!result.rc_) { - throw EnvoyException( - fmt::format("unable to open file '{}': {}", raw_file_->path(), strerror(result.errno_))); + const int rc = ::close(fd_); + if (rc == -1) { + return {false, errno}; } + + fd_ = -1; + return {true, 0}; } -void FileImpl::reopen() { reopen_file_ = true; } +bool FileImpl::isOpen() { return fd_ != -1; } -FileImpl::~FileImpl() { - { - Thread::LockGuard lock(write_lock_); - flush_thread_exit_ = true; - flush_event_.notifyOne(); - } +std::string FileImpl::path() { return path_; } - if (flush_thread_ != nullptr) { - flush_thread_->join(); - } +std::string FileImpl::errorToString(int error) { return ::strerror(error); } - // Flush any remaining data. If file was not opened for some reason, skip flushing part. - if (raw_file_->isOpen()) { - if (flush_buffer_.length() > 0) { - doWrite(flush_buffer_); - } +FilePtr InstanceImpl::createFile(const std::string& path) { + return std::make_unique(path); +} - const Api::SysCallBoolResult result = raw_file_->close(); - ASSERT(result.rc_, fmt::format("unable to close file '{}': {}", raw_file_->path(), - strerror(result.errno_))); - } +bool InstanceImpl::fileExists(const std::string& path) { + std::ifstream input_file(path); + return input_file.is_open(); } -void FileImpl::doWrite(Buffer::Instance& buffer) { - uint64_t num_slices = buffer.getRawSlices(nullptr, 0); - STACK_ARRAY(slices, Buffer::RawSlice, num_slices); - buffer.getRawSlices(slices.begin(), num_slices); - - // We must do the actual writes to disk under lock, so that we don't intermix chunks from - // different FileImpl pointing to the same underlying file. This can happen either via hot - // restart or if calling code opens the same underlying file into a different FileImpl in the - // same process. - // TODO PERF: Currently, we use a single cross process lock to serialize all disk writes. This - // will never block network workers, but does mean that only a single flush thread can - // actually flush to disk. In the future it would be nice if we did away with the cross - // process lock or had multiple locks. - { - Thread::LockGuard lock(file_lock_); - for (const Buffer::RawSlice& slice : slices) { - absl::string_view data(static_cast(slice.mem_), slice.len_); - const Api::SysCallSizeResult result = raw_file_->write(data); - ASSERT(result.rc_ == static_cast(slice.len_)); - stats_.write_completed_.inc(); - } +bool InstanceImpl::directoryExists(const std::string& path) { + DIR* const dir = ::opendir(path.c_str()); + const bool dir_exists = nullptr != dir; + if (dir_exists) { + ::closedir(dir); } - stats_.write_total_buffered_.sub(buffer.length()); - buffer.drain(buffer.length()); + return dir_exists; } -void FileImpl::flushThreadFunc() { - - while (true) { - std::unique_lock flush_lock; - - { - Thread::LockGuard write_lock(write_lock_); - - // flush_event_ can be woken up either by large enough flush_buffer or by timer. - // In case it was timer, flush_buffer_ can be empty. - while (flush_buffer_.length() == 0 && !flush_thread_exit_) { - // CondVar::wait() does not throw, so it's safe to pass the mutex rather than the guard. - flush_event_.wait(write_lock_); - } - - if (flush_thread_exit_) { - return; - } - - flush_lock = std::unique_lock(flush_lock_); - ASSERT(flush_buffer_.length() > 0); - about_to_write_buffer_.move(flush_buffer_); - ASSERT(flush_buffer_.length() == 0); - } - - // if we failed to open file before, then simply ignore - if (raw_file_->isOpen()) { - try { - if (reopen_file_) { - reopen_file_ = false; - const Api::SysCallBoolResult result = raw_file_->close(); - ASSERT(result.rc_, fmt::format("unable to close file '{}': {}", raw_file_->path(), - raw_file_->errorToString(result.errno_))); - open(); - } - - doWrite(about_to_write_buffer_); - } catch (const EnvoyException&) { - stats_.reopen_failed_.inc(); - } - } +ssize_t InstanceImpl::fileSize(const std::string& path) { + struct stat info; + if (::stat(path.c_str(), &info) != 0) { + return -1; } + return info.st_size; } -void FileImpl::flush() { - std::unique_lock flush_buffer_lock; - - { - Thread::LockGuard write_lock(write_lock_); - - // flush_lock_ must be held while checking this or else it is - // possible that flushThreadFunc() has already moved data from - // flush_buffer_ to about_to_write_buffer_, has unlocked write_lock_, - // but has not yet completed doWrite(). This would allow flush() to - // return before the pending data has actually been written to disk. - flush_buffer_lock = std::unique_lock(flush_lock_); +std::string InstanceImpl::fileReadToEnd(const std::string& path) { + if (illegalPath(path)) { + throw EnvoyException(fmt::format("Invalid path: {}", path)); + } - if (flush_buffer_.length() == 0) { - return; - } + std::ios::sync_with_stdio(false); - about_to_write_buffer_.move(flush_buffer_); - ASSERT(flush_buffer_.length() == 0); + std::ifstream file(path); + if (!file) { + throw EnvoyException(fmt::format("unable to read file: {}", path)); } - doWrite(about_to_write_buffer_); -} + std::stringstream file_string; + file_string << file.rdbuf(); -void FileImpl::write(absl::string_view data) { - Thread::LockGuard lock(write_lock_); + return file_string.str(); +} - if (flush_thread_ == nullptr) { - createFlushStructures(); +Api::SysCallStringResult InstanceImpl::canonicalPath(const std::string& path) { + // TODO(htuch): When we are using C++17, switch to std::filesystem::canonical. + char* resolved_path = ::realpath(path.c_str(), nullptr); + if (resolved_path == nullptr) { + return {std::string(), errno}; } + std::string resolved_path_string{resolved_path}; + ::free(resolved_path); + return {resolved_path_string, 0}; +} - stats_.write_buffered_.inc(); - stats_.write_total_buffered_.add(data.length()); - flush_buffer_.add(data.data(), data.size()); - if (flush_buffer_.length() > MIN_FLUSH_SIZE) { - flush_event_.notifyOne(); +bool InstanceImpl::illegalPath(const std::string& path) { + const Api::SysCallStringResult canonical_path = canonicalPath(path); + if (canonical_path.rc_.empty()) { + ENVOY_LOG_MISC(debug, "Unable to determine canonical path for {}: {}", path, + ::strerror(canonical_path.errno_)); + return true; } -} -void FileImpl::createFlushStructures() { - flush_thread_ = thread_factory_.createThread([this]() -> void { flushThreadFunc(); }); - flush_timer_->enableTimer(flush_interval_msec_); + // Platform specific path sanity; we provide a convenience to avoid Envoy + // instances poking in bad places. We may have to consider conditioning on + // platform in the future, growing these or relaxing some constraints (e.g. + // there are valid reasons to go via /proc for file paths). + // TODO(htuch): Optimize this as a hash lookup if we grow any further. + if (absl::StartsWith(canonical_path.rc_, "/dev") || + absl::StartsWith(canonical_path.rc_, "/sys") || + absl::StartsWith(canonical_path.rc_, "/proc")) { + return true; + } + return false; } } // namespace Filesystem diff --git a/source/common/filesystem/filesystem_impl.h b/source/common/filesystem/filesystem_impl.h index ce2b590a57ee4..ec6424932323e 100644 --- a/source/common/filesystem/filesystem_impl.h +++ b/source/common/filesystem/filesystem_impl.h @@ -1,141 +1,43 @@ #pragma once -#include -#include +#include #include -#include "envoy/event/dispatcher.h" #include "envoy/filesystem/filesystem.h" -#include "envoy/stats/stats_macros.h" -#include "envoy/stats/store.h" - -#include "common/buffer/buffer_impl.h" -#include "common/common/thread.h" namespace Envoy { -// clang-format off -#define FILESYSTEM_STATS(COUNTER, GAUGE) \ - COUNTER(write_buffered) \ - COUNTER(write_completed) \ - COUNTER(flushed_by_timer) \ - COUNTER(reopen_failed) \ - GAUGE (write_total_buffered) -// clang-format on +namespace Filesystem { -struct FileSystemStats { - FILESYSTEM_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT) -}; +class FileImpl : public File { +public: + FileImpl(const std::string& path); + ~FileImpl(); -namespace Filesystem { + // Filesystem::File + Api::SysCallBoolResult open() override; + Api::SysCallSizeResult write(absl::string_view buffer) override; + Api::SysCallBoolResult close() override; + bool isOpen() override; + std::string path() override; + std::string errorToString(int error) override; + +private: + int fd_; + const std::string path_; + friend class FileSystemImplTest; +}; class InstanceImpl : public Instance { public: // Filesystem::Instance - InstanceImpl(std::chrono::milliseconds file_flush_interval_msec, - Thread::ThreadFactory& thread_factory, Stats::Store& store, - RawInstance& raw_instance); - - FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, - Thread::BasicLockable& lock, - std::chrono::milliseconds file_flush_interval_msec) override; - FileSharedPtr createFile(const std::string& path, Event::Dispatcher& dispatcher, - Thread::BasicLockable& lock) override; - - // Filesystem::RawInstance - RawFilePtr createRawFile(const std::string& path) override; + FilePtr createFile(const std::string& path) override; bool fileExists(const std::string& path) override; bool directoryExists(const std::string& path) override; ssize_t fileSize(const std::string& path) override; std::string fileReadToEnd(const std::string& path) override; Api::SysCallStringResult canonicalPath(const std::string& path) override; bool illegalPath(const std::string& path) override; - -private: - const std::chrono::milliseconds file_flush_interval_msec_; - FileSystemStats file_stats_; - Thread::ThreadFactory& thread_factory_; - RawInstance& raw_instance_; -}; - -/** - * This is a file implementation geared for writing out access logs. It turn out that in certain - * cases even if a standard file is opened with O_NONBLOCK, the kernel can still block when writing. - * This implementation uses a flush thread per file, with the idea there there aren't that many - * files. If this turns out to be a good implementation we can potentially have a single flush - * thread that flushes all files, but we will start with this. - */ -class FileImpl : public File { -public: - FileImpl(RawFilePtr&& raw_file, Event::Dispatcher& dispatcher, Thread::BasicLockable& lock, - FileSystemStats& stats_, std::chrono::milliseconds flush_interval_msec, - Thread::ThreadFactory& thread_factory); - ~FileImpl(); - - // Filesystem::File - void write(absl::string_view data) override; - - /** - * Filesystem::File - * Reopen file asynchronously. - * This only sets reopen flag, actual reopen operation is delayed. - * Reopen happens before the next write operation. - */ - void reopen() override; - - // Filesystem::File - void flush() override; - -private: - void doWrite(Buffer::Instance& buffer); - void flushThreadFunc(); - void open(); - void createFlushStructures(); - - // Minimum size before the flush thread will be told to flush. - static const uint64_t MIN_FLUSH_SIZE = 1024 * 64; - - RawFilePtr raw_file_; - - // These locks are always acquired in the following order if multiple locks are held: - // 1) write_lock_ - // 2) flush_lock_ - // 3) file_lock_ - Thread::BasicLockable& file_lock_; // This lock is used only by the flush thread when writing - // to disk. This is used to make sure that file blocks do - // not get interleaved by multiple processes writing to - // the same file during hot-restart. - Thread::MutexBasicLockable flush_lock_; // This lock is used to prevent simultaneous flushes from - // the flush thread and a synchronous flush. This protects - // concurrent access to the about_to_write_buffer_, fd_, - // and all other data used during flushing and file - // re-opening. - Thread::MutexBasicLockable - write_lock_; // The lock is used when filling the flush buffer. It allows - // multiple threads to write to the same file at relatively - // high performance. It is always local to the process. - Thread::ThreadPtr flush_thread_; - Thread::CondVar flush_event_; - std::atomic flush_thread_exit_{}; - std::atomic reopen_file_{}; - Buffer::OwnedImpl - flush_buffer_ GUARDED_BY(write_lock_); // This buffer is used by multiple threads. It gets - // filled and then flushed either when max size is - // reached or when a timer fires. - // TODO(jmarantz): this should be GUARDED_BY(flush_lock_) but the analysis cannot poke through - // the std::make_unique assignment. I do not believe it's possible to annotate this properly now - // due to limitations in the clang thread annotation analysis. - Buffer::OwnedImpl about_to_write_buffer_; // This buffer is used only by the flush thread. Data - // is moved from flush_buffer_ under lock, and then - // the lock is released so that flush_buffer_ can - // continue to fill. This buffer is then used for the - // final write to disk. - Event::TimerPtr flush_timer_; - Thread::ThreadFactory& thread_factory_; - const std::chrono::milliseconds flush_interval_msec_; // Time interval buffer gets flushed no - // matter if it reached the MIN_FLUSH_SIZE - // or not. - FileSystemStats& stats_; }; } // namespace Filesystem -} // namespace Envoy +} // namespace Envoy \ No newline at end of file diff --git a/source/common/filesystem/raw_instance_impl.cc b/source/common/filesystem/raw_instance_impl.cc deleted file mode 100644 index ac2bfe47888ac..0000000000000 --- a/source/common/filesystem/raw_instance_impl.cc +++ /dev/null @@ -1,150 +0,0 @@ -#include "common/filesystem/raw_instance_impl.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "envoy/common/exception.h" - -#include "common/common/assert.h" -#include "common/common/fmt.h" -#include "common/common/logger.h" - -#include "absl/strings/match.h" - -namespace Envoy { -namespace Filesystem { - -RawFileImpl::RawFileImpl(const std::string& path) : fd_(-1), path_(path) {} - -RawFileImpl::~RawFileImpl() { - const Api::SysCallBoolResult result = close(); - ASSERT(result.rc_); -} - -Api::SysCallBoolResult RawFileImpl::open() { - if (isOpen()) { - return {true, 0}; - } - - const int flags = O_RDWR | O_APPEND | O_CREAT; - const int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - - fd_ = ::open(path_.c_str(), flags, mode); - if (-1 == fd_) { - return {false, errno}; - } - return {true, 0}; -} - -Api::SysCallSizeResult RawFileImpl::write(absl::string_view buffer) { - const ssize_t rc = ::write(fd_, buffer.data(), buffer.size()); - return {rc, errno}; -} - -Api::SysCallBoolResult RawFileImpl::close() { - if (!isOpen()) { - return {true, 0}; - } - - const int rc = ::close(fd_); - if (rc == -1) { - return {false, errno}; - } - - fd_ = -1; - return {true, 0}; -} - -bool RawFileImpl::isOpen() { return fd_ != -1; } - -std::string RawFileImpl::path() { return path_; } - -std::string RawFileImpl::errorToString(int error) { return ::strerror(error); } - -RawFilePtr RawInstanceImpl::createRawFile(const std::string& path) { - return std::make_unique(path); -} - -bool RawInstanceImpl::fileExists(const std::string& path) { - std::ifstream input_file(path); - return input_file.is_open(); -} - -bool RawInstanceImpl::directoryExists(const std::string& path) { - DIR* const dir = ::opendir(path.c_str()); - const bool dir_exists = nullptr != dir; - if (dir_exists) { - ::closedir(dir); - } - - return dir_exists; -} - -ssize_t RawInstanceImpl::fileSize(const std::string& path) { - struct stat info; - if (::stat(path.c_str(), &info) != 0) { - return -1; - } - return info.st_size; -} - -std::string RawInstanceImpl::fileReadToEnd(const std::string& path) { - if (illegalPath(path)) { - throw EnvoyException(fmt::format("Invalid path: {}", path)); - } - - std::ios::sync_with_stdio(false); - - std::ifstream file(path); - if (!file) { - throw EnvoyException(fmt::format("unable to read file: {}", path)); - } - - std::stringstream file_string; - file_string << file.rdbuf(); - - return file_string.str(); -} - -Api::SysCallStringResult RawInstanceImpl::canonicalPath(const std::string& path) { - // TODO(htuch): When we are using C++17, switch to std::filesystem::canonical. - char* resolved_path = ::realpath(path.c_str(), nullptr); - if (resolved_path == nullptr) { - return {std::string(), errno}; - } - std::string resolved_path_string{resolved_path}; - ::free(resolved_path); - return {resolved_path_string, 0}; -} - -bool RawInstanceImpl::illegalPath(const std::string& path) { - const Api::SysCallStringResult canonical_path = canonicalPath(path); - if (canonical_path.rc_.empty()) { - ENVOY_LOG_MISC(debug, "Unable to determine canonical path for {}: {}", path, - ::strerror(canonical_path.errno_)); - return true; - } - - // Platform specific path sanity; we provide a convenience to avoid Envoy - // instances poking in bad places. We may have to consider conditioning on - // platform in the future, growing these or relaxing some constraints (e.g. - // there are valid reasons to go via /proc for file paths). - // TODO(htuch): Optimize this as a hash lookup if we grow any further. - if (absl::StartsWith(canonical_path.rc_, "/dev") || - absl::StartsWith(canonical_path.rc_, "/sys") || - absl::StartsWith(canonical_path.rc_, "/proc")) { - return true; - } - return false; -} - -} // namespace Filesystem -} // namespace Envoy diff --git a/source/common/filesystem/raw_instance_impl.h b/source/common/filesystem/raw_instance_impl.h deleted file mode 100644 index 4a07ec9d88063..0000000000000 --- a/source/common/filesystem/raw_instance_impl.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include - -#include "envoy/filesystem/filesystem.h" - -namespace Envoy { -namespace Filesystem { - -class RawFileImpl : public RawFile { -public: - RawFileImpl(const std::string& path); - ~RawFileImpl(); - - // Filesystem::RawFile - Api::SysCallBoolResult open() override; - Api::SysCallSizeResult write(absl::string_view buffer) override; - Api::SysCallBoolResult close() override; - bool isOpen() override; - std::string path() override; - std::string errorToString(int error) override; - -private: - int fd_; - const std::string path_; - friend class RawInstanceImplTest; -}; - -class RawInstanceImpl : public RawInstance { -public: - // Filesystem::RawInstance - RawFilePtr createRawFile(const std::string& path) override; - bool fileExists(const std::string& path) override; - bool directoryExists(const std::string& path) override; - ssize_t fileSize(const std::string& path) override; - std::string fileReadToEnd(const std::string& path) override; - Api::SysCallStringResult canonicalPath(const std::string& path) override; - bool illegalPath(const std::string& path) override; -}; - -} // namespace Filesystem -} // namespace Envoy diff --git a/source/common/upstream/health_checker_base_impl.h b/source/common/upstream/health_checker_base_impl.h index 1485d1020d74a..2fd1d7f56a91f 100644 --- a/source/common/upstream/health_checker_base_impl.h +++ b/source/common/upstream/health_checker_base_impl.h @@ -162,7 +162,7 @@ class HealthCheckEventLoggerImpl : public HealthCheckEventLogger { const HostDescription& host, std::function callback) const; TimeSource& time_source_; - Filesystem::FileSharedPtr file_; + AccessLog::AccessLogFileSharedPtr file_; }; } // namespace Upstream diff --git a/source/common/upstream/outlier_detection_impl.h b/source/common/upstream/outlier_detection_impl.h index 639a483c9abd6..fb7efd2b03ea6 100644 --- a/source/common/upstream/outlier_detection_impl.h +++ b/source/common/upstream/outlier_detection_impl.h @@ -278,7 +278,7 @@ class EventLoggerImpl : public EventLogger { const HostDescriptionConstSharedPtr& host, absl::optional time); - Filesystem::FileSharedPtr file_; + AccessLog::AccessLogFileSharedPtr file_; TimeSource& time_source_; }; diff --git a/source/extensions/access_loggers/file/file_access_log_impl.h b/source/extensions/access_loggers/file/file_access_log_impl.h index 93bee65b0f7ad..b14b396befd8e 100644 --- a/source/extensions/access_loggers/file/file_access_log_impl.h +++ b/source/extensions/access_loggers/file/file_access_log_impl.h @@ -21,7 +21,7 @@ class FileAccessLog : public AccessLog::Instance { const StreamInfo::StreamInfo& stream_info) override; private: - Filesystem::FileSharedPtr log_file_; + AccessLog::AccessLogFileSharedPtr log_file_; AccessLog::FilterPtr filter_; AccessLog::FormatterPtr formatter_; }; diff --git a/source/extensions/filters/network/mongo_proxy/proxy.h b/source/extensions/filters/network/mongo_proxy/proxy.h index 17ff06639031e..e595b5d42cbd9 100644 --- a/source/extensions/filters/network/mongo_proxy/proxy.h +++ b/source/extensions/filters/network/mongo_proxy/proxy.h @@ -93,7 +93,7 @@ class AccessLog { private: TimeSource& time_source_; - Filesystem::FileSharedPtr file_; + Envoy::AccessLog::AccessLogFileSharedPtr file_; }; typedef std::shared_ptr AccessLogSharedPtr; diff --git a/source/server/config_validation/api.cc b/source/server/config_validation/api.cc index 4763d043b4480..becc0eb9da58f 100644 --- a/source/server/config_validation/api.cc +++ b/source/server/config_validation/api.cc @@ -5,10 +5,9 @@ namespace Envoy { namespace Api { -ValidationImpl::ValidationImpl(std::chrono::milliseconds file_flush_interval_msec, - Thread::ThreadFactory& thread_factory, Stats::Store& stats_store, +ValidationImpl::ValidationImpl(Thread::ThreadFactory& thread_factory, Event::TimeSystem& time_system) - : Impl(file_flush_interval_msec, thread_factory, stats_store, time_system) {} + : Impl(thread_factory, time_system) {} Event::DispatcherPtr ValidationImpl::allocateDispatcher() { return Event::DispatcherPtr{new Event::ValidationDispatcher(*this)}; diff --git a/source/server/config_validation/api.h b/source/server/config_validation/api.h index ef05bfdc70319..375d2ec0d6917 100644 --- a/source/server/config_validation/api.h +++ b/source/server/config_validation/api.h @@ -15,9 +15,7 @@ namespace Api { */ class ValidationImpl : public Impl { public: - ValidationImpl(std::chrono::milliseconds file_flush_interval_msec, - Thread::ThreadFactory& thread_factory, Stats::Store& stats_store, - Event::TimeSystem& time_system); + ValidationImpl(Thread::ThreadFactory& thread_factory, Event::TimeSystem& time_system); Event::DispatcherPtr allocateDispatcher() override; }; diff --git a/source/server/config_validation/server.cc b/source/server/config_validation/server.cc index b2220e00acb5d..3c9fce50608cb 100644 --- a/source/server/config_validation/server.cc +++ b/source/server/config_validation/server.cc @@ -41,11 +41,12 @@ ValidationInstance::ValidationInstance(Options& options, Event::TimeSystem& time ComponentFactory& component_factory, Thread::ThreadFactory& thread_factory) : options_(options), stats_store_(store), - api_(new Api::ValidationImpl(options.fileFlushIntervalMsec(), thread_factory, store, - time_system)), + api_(new Api::ValidationImpl(thread_factory, time_system)), dispatcher_(api_->allocateDispatcher()), singleton_manager_(new Singleton::ManagerImpl(api_->threadFactory().currentThreadId())), - access_log_manager_(*api_, *dispatcher_, access_log_lock), mutex_tracer_(nullptr) { + access_log_manager_(options.fileFlushIntervalMsec(), *api_, *dispatcher_, access_log_lock, + store), + mutex_tracer_(nullptr) { try { initialize(options, local_address, component_factory); } catch (const EnvoyException& e) { diff --git a/source/server/server.cc b/source/server/server.cc index 475c23b60e2a9..5a9fc81e99a93 100644 --- a/source/server/server.cc +++ b/source/server/server.cc @@ -54,8 +54,7 @@ InstanceImpl::InstanceImpl(Options& options, Event::TimeSystem& time_system, ThreadLocal::Instance& tls, Thread::ThreadFactory& thread_factory) : shutdown_(false), options_(options), time_system_(time_system), restarter_(restarter), start_time_(time(nullptr)), original_start_time_(start_time_), stats_store_(store), - thread_local_(tls), - api_(new Api::Impl(options.fileFlushIntervalMsec(), thread_factory, store, time_system)), + thread_local_(tls), api_(new Api::Impl(thread_factory, time_system)), secret_manager_(std::make_unique()), dispatcher_(api_->allocateDispatcher()), singleton_manager_(new Singleton::ManagerImpl(api_->threadFactory().currentThreadId())), @@ -63,7 +62,9 @@ InstanceImpl::InstanceImpl(Options& options, Event::TimeSystem& time_system, random_generator_(std::move(random_generator)), listener_component_factory_(*this), worker_factory_(thread_local_, *api_, hooks), dns_resolver_(dispatcher_->createDnsResolver({})), - access_log_manager_(*api_, *dispatcher_, access_log_lock), terminated_(false), + access_log_manager_(options.fileFlushIntervalMsec(), *api_, *dispatcher_, access_log_lock, + store), + terminated_(false), mutex_tracer_(options.mutexTracingEnabled() ? &Envoy::MutexTracerImpl::getOrCreateTracer() : nullptr) { diff --git a/test/common/access_log/access_log_manager_impl_test.cc b/test/common/access_log/access_log_manager_impl_test.cc index cde2c1a0fb8fc..ad97f5e46d384 100644 --- a/test/common/access_log/access_log_manager_impl_test.cc +++ b/test/common/access_log/access_log_manager_impl_test.cc @@ -12,34 +12,326 @@ #include "gmock/gmock.h" using testing::_; +using testing::NiceMock; using testing::Return; +using testing::ReturnNew; using testing::ReturnRef; +using testing::Sequence; namespace Envoy { namespace AccessLog { -TEST(AccessLogManagerImpl, reopenAllFiles) { - Api::MockApi api; - Filesystem::MockInstance file_system; - EXPECT_CALL(api, fileSystem()).WillRepeatedly(ReturnRef(file_system)); - Event::MockDispatcher dispatcher; - Thread::MutexBasicLockable lock; - - std::shared_ptr log1(new Filesystem::MockFile()); - std::shared_ptr log2(new Filesystem::MockFile()); - AccessLogManagerImpl access_log_manager(api, dispatcher, lock); - EXPECT_CALL(file_system, createFile("foo", _, _)).WillOnce(Return(log1)); - access_log_manager.createAccessLog("foo"); - EXPECT_CALL(file_system, createFile("bar", _, _)).WillOnce(Return(log2)); - access_log_manager.createAccessLog("bar"); +class AccessLogManagerImplTest : public TestBase { +protected: + AccessLogManagerImplTest() + : file_(new NiceMock), thread_factory_(Thread::threadFactoryForTest()), + access_log_manager_(timeout_40ms_, api_, dispatcher_, lock_, store_) { + EXPECT_CALL(file_system_, createFile("foo")) + .WillOnce(Return(ByMove(std::unique_ptr>(file_)))); + + EXPECT_CALL(api_, fileSystem()).WillRepeatedly(ReturnRef(file_system_)); + EXPECT_CALL(api_, threadFactory()).WillRepeatedly(ReturnRef(thread_factory_)); + } + + NiceMock api_; + NiceMock file_system_; + NiceMock* file_; + const std::chrono::milliseconds timeout_40ms_{40}; + Stats::IsolatedStoreImpl store_; + Thread::ThreadFactory& thread_factory_; + NiceMock dispatcher_; + Thread::MutexBasicLockable lock_; + AccessLogManagerImpl access_log_manager_; +}; + +TEST_F(AccessLogManagerImplTest, BadFile) { + EXPECT_CALL(dispatcher_, createTimer_(_)); + EXPECT_CALL(*file_, open_()).WillOnce(Return(Api::SysCallBoolResult{false, 0})); + EXPECT_THROW(access_log_manager_.createAccessLog("foo"), EnvoyException); +} + +TEST_F(AccessLogManagerImplTest, flushToLogFilePeriodically) { + NiceMock* timer = new NiceMock(&dispatcher_); + + EXPECT_CALL(*file_, open_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); + AccessLogFileSharedPtr log_file = access_log_manager_.createAccessLog("foo"); + + EXPECT_CALL(*timer, enableTimer(timeout_40ms_)); + EXPECT_CALL(*file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("test")); + return {static_cast(data.length()), 0}; + })); + + log_file->write("test"); + + { + Thread::LockGuard lock(file_->write_mutex_); + while (file_->num_writes_ != 1) { + file_->write_event_.wait(file_->write_mutex_); + } + } + + EXPECT_CALL(*file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("test2")); + return {static_cast(data.length()), 0}; + })); + + // make sure timer is re-enabled on callback call + log_file->write("test2"); + EXPECT_CALL(*timer, enableTimer(timeout_40ms_)); + timer->callback_(); + + { + Thread::LockGuard lock(file_->write_mutex_); + while (file_->num_writes_ != 2) { + file_->write_event_.wait(file_->write_mutex_); + } + } + EXPECT_CALL(*file_, close_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); +} + +TEST_F(AccessLogManagerImplTest, flushToLogFileOnDemand) { + NiceMock* timer = new NiceMock(&dispatcher_); + + EXPECT_CALL(*file_, open_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); + AccessLogFileSharedPtr log_file = access_log_manager_.createAccessLog("foo"); + + EXPECT_CALL(*timer, enableTimer(timeout_40ms_)); + + // The first write to a given file will start the flush thread, which can flush + // immediately (race on whether it will or not). So do a write and flush to + // get that state out of the way, then test that small writes don't trigger a flush. + EXPECT_CALL(*file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + return {static_cast(data.length()), 0}; + })); + log_file->write("prime-it"); + log_file->flush(); + uint32_t expected_writes = 1; + { + Thread::LockGuard lock(file_->write_mutex_); + EXPECT_EQ(expected_writes, file_->num_writes_); + } + + EXPECT_CALL(*file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("test")); + return {static_cast(data.length()), 0}; + })); + + log_file->write("test"); + + { + Thread::LockGuard lock(file_->write_mutex_); + EXPECT_EQ(expected_writes, file_->num_writes_); + } + + log_file->flush(); + expected_writes++; + { + Thread::LockGuard lock(file_->write_mutex_); + EXPECT_EQ(expected_writes, file_->num_writes_); + } + + EXPECT_CALL(*file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("test2")); + return {static_cast(data.length()), 0}; + })); + + // make sure timer is re-enabled on callback call + log_file->write("test2"); + EXPECT_CALL(*timer, enableTimer(timeout_40ms_)); + timer->callback_(); + expected_writes++; + + { + Thread::LockGuard lock(file_->write_mutex_); + while (file_->num_writes_ != expected_writes) { + file_->write_event_.wait(file_->write_mutex_); + } + } + EXPECT_CALL(*file_, close_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); +} + +TEST_F(AccessLogManagerImplTest, reopenFile) { + NiceMock* timer = new NiceMock(&dispatcher_); + + Sequence sq; + EXPECT_CALL(*file_, open_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); + AccessLogFileSharedPtr log_file = access_log_manager_.createAccessLog("foo"); + + EXPECT_CALL(*file_, write_(_)) + .InSequence(sq) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("before")); + return {static_cast(data.length()), 0}; + })); + + log_file->write("before"); + timer->callback_(); + + { + Thread::LockGuard lock(file_->write_mutex_); + while (file_->num_writes_ != 1) { + file_->write_event_.wait(file_->write_mutex_); + } + } + + EXPECT_CALL(*file_, close_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); + EXPECT_CALL(*file_, open_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); + + EXPECT_CALL(*file_, write_(_)) + .InSequence(sq) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("reopened")); + return {static_cast(data.length()), 0}; + })); + + EXPECT_CALL(*file_, close_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); + + log_file->reopen(); + log_file->write("reopened"); + timer->callback_(); + + { + Thread::LockGuard lock(file_->write_mutex_); + while (file_->num_writes_ != 2) { + file_->write_event_.wait(file_->write_mutex_); + } + } +} + +TEST_F(AccessLogManagerImplTest, reopenThrows) { + NiceMock* timer = new NiceMock(&dispatcher_); + + EXPECT_CALL(*file_, write_(_)) + .WillRepeatedly(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + return {static_cast(data.length()), 0}; + })); + + Sequence sq; + EXPECT_CALL(*file_, open_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); + + AccessLogFileSharedPtr log_file = access_log_manager_.createAccessLog("foo"); + EXPECT_CALL(*file_, close_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); + EXPECT_CALL(*file_, open_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{false, 0})); + + log_file->write("test write"); + timer->callback_(); + { + Thread::LockGuard lock(file_->write_mutex_); + while (file_->num_writes_ != 1) { + file_->write_event_.wait(file_->write_mutex_); + } + } + log_file->reopen(); + + log_file->write("this is to force reopen"); + timer->callback_(); + + { + Thread::LockGuard lock(file_->open_mutex_); + while (file_->num_opens_ != 2) { + file_->open_event_.wait(file_->open_mutex_); + } + } + + // write call should not cause any exceptions + log_file->write("random data"); + timer->callback_(); +} + +TEST_F(AccessLogManagerImplTest, bigDataChunkShouldBeFlushedWithoutTimer) { + EXPECT_CALL(*file_, open_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); + AccessLogFileSharedPtr log_file = access_log_manager_.createAccessLog("foo"); + + EXPECT_CALL(*file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + EXPECT_EQ(0, data.compare("a")); + return {static_cast(data.length()), 0}; + })); + + log_file->write("a"); + + { + Thread::LockGuard lock(file_->write_mutex_); + while (file_->num_writes_ != 1) { + file_->write_event_.wait(file_->write_mutex_); + } + } + + // First write happens without waiting on thread_flush_. Now make a big string and it should be + // flushed even when timer is not enabled + EXPECT_CALL(*file_, write_(_)) + .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + std::string expected(1024 * 64 + 1, 'b'); + EXPECT_EQ(0, data.compare(expected)); + return {static_cast(data.length()), 0}; + })); + + std::string big_string(1024 * 64 + 1, 'b'); + log_file->write(big_string); + + { + Thread::LockGuard lock(file_->write_mutex_); + while (file_->num_writes_ != 2) { + file_->write_event_.wait(file_->write_mutex_); + } + } + EXPECT_CALL(*file_, close_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); +} + +TEST_F(AccessLogManagerImplTest, reopenAllFiles) { + EXPECT_CALL(dispatcher_, createTimer_(_)).WillRepeatedly(ReturnNew>()); + + EXPECT_CALL(*file_, open_()).Times(2).WillRepeatedly(Return(Api::SysCallBoolResult{true, 0})); + AccessLogFileSharedPtr log = access_log_manager_.createAccessLog("foo"); + + NiceMock* file2 = new NiceMock; + EXPECT_CALL(file_system_, createFile("bar")) + .WillOnce(Return(ByMove(std::unique_ptr>(file2)))); + EXPECT_CALL(*file2, open_()).Times(2).WillRepeatedly(Return(Api::SysCallBoolResult{true, 0})); + AccessLogFileSharedPtr log2 = access_log_manager_.createAccessLog("bar"); // Make sure that getting the access log with the same name returns the same underlying file. - EXPECT_EQ(log1, access_log_manager.createAccessLog("foo")); - EXPECT_EQ(log2, access_log_manager.createAccessLog("bar")); + EXPECT_EQ(log, access_log_manager_.createAccessLog("foo")); + EXPECT_EQ(log2, access_log_manager_.createAccessLog("bar")); + + EXPECT_CALL(*file_, close_()).Times(2).WillRepeatedly(Return(Api::SysCallBoolResult{true, 0})); + EXPECT_CALL(*file2, close_()).Times(2).WillRepeatedly(Return(Api::SysCallBoolResult{true, 0})); + + // Test that reopen reopens all of the files + EXPECT_CALL(*file_, write_(_)) + .WillRepeatedly(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + return {static_cast(data.length()), 0}; + })); + + EXPECT_CALL(*file2, write_(_)) + .WillRepeatedly(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { + return {static_cast(data.length()), 0}; + })); + + access_log_manager_.reopen(); + + log->write("this is to force reopen"); + log2->write("this is to force reopen"); + + { + Thread::LockGuard lock(file_->open_mutex_); + while (file_->num_opens_ != 2) { + file_->open_event_.wait(file_->open_mutex_); + } + } - EXPECT_CALL(*log1, reopen()); - EXPECT_CALL(*log2, reopen()); - access_log_manager.reopen(); + { + Thread::LockGuard lock(file2->open_mutex_); + while (file2->num_opens_ != 2) { + file2->open_event_.wait(file2->open_mutex_); + } + } } } // namespace AccessLog diff --git a/test/common/filesystem/filesystem_impl_test.cc b/test/common/filesystem/filesystem_impl_test.cc index da4040de928ee..51f17749d1a36 100644 --- a/test/common/filesystem/filesystem_impl_test.cc +++ b/test/common/filesystem/filesystem_impl_test.cc @@ -45,266 +45,5 @@ class FileSystemImplTest : public TestBase { InstanceImpl file_system_; }; -TEST_F(FileSystemImplTest, BadFile) { - Event::MockDispatcher dispatcher; - Thread::MutexBasicLockable lock; - EXPECT_CALL(dispatcher, createTimer_(_)); - EXPECT_CALL(*raw_file_, open_()).WillOnce(Return(Api::SysCallBoolResult{false, 0})); - EXPECT_THROW(file_system_.createFile("", dispatcher, lock), EnvoyException); -} - -TEST_F(FileSystemImplTest, flushToLogFilePeriodically) { - NiceMock dispatcher; - NiceMock* timer = new NiceMock(&dispatcher); - Thread::MutexBasicLockable mutex; - - EXPECT_CALL(*raw_file_, open_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); - FileSharedPtr file = file_system_.createFile("", dispatcher, mutex, timeout_40ms_); - - EXPECT_CALL(*timer, enableTimer(timeout_40ms_)); - EXPECT_CALL(*raw_file_, write_(_)) - .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { - EXPECT_EQ(0, data.compare("test")); - return {static_cast(data.length()), 0}; - })); - - file->write("test"); - - { - Thread::LockGuard lock(raw_file_->write_mutex_); - while (raw_file_->num_writes_ != 1) { - raw_file_->write_event_.wait(raw_file_->write_mutex_); - } - } - - EXPECT_CALL(*raw_file_, write_(_)) - .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { - EXPECT_EQ(0, data.compare("test2")); - return {static_cast(data.length()), 0}; - })); - - // make sure timer is re-enabled on callback call - file->write("test2"); - EXPECT_CALL(*timer, enableTimer(timeout_40ms_)); - timer->callback_(); - - { - Thread::LockGuard lock(raw_file_->write_mutex_); - while (raw_file_->num_writes_ != 2) { - raw_file_->write_event_.wait(raw_file_->write_mutex_); - } - } - EXPECT_CALL(*raw_file_, close_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); -} - -TEST_F(FileSystemImplTest, flushToLogFileOnDemand) { - NiceMock dispatcher; - NiceMock* timer = new NiceMock(&dispatcher); - Thread::MutexBasicLockable mutex; - - EXPECT_CALL(*raw_file_, open_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); - Filesystem::FileSharedPtr file = file_system_.createFile("", dispatcher, mutex, timeout_40ms_); - - EXPECT_CALL(*timer, enableTimer(timeout_40ms_)); - - // The first write to a given file will start the flush thread, which can flush - // immediately (race on whether it will or not). So do a write and flush to - // get that state out of the way, then test that small writes don't trigger a flush. - EXPECT_CALL(*raw_file_, write_(_)) - .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { - return {static_cast(data.length()), 0}; - })); - file->write("prime-it"); - file->flush(); - uint32_t expected_writes = 1; - { - Thread::LockGuard lock(raw_file_->write_mutex_); - EXPECT_EQ(expected_writes, raw_file_->num_writes_); - } - - EXPECT_CALL(*raw_file_, write_(_)) - .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { - EXPECT_EQ(0, data.compare("test")); - return {static_cast(data.length()), 0}; - })); - - file->write("test"); - - { - Thread::LockGuard lock(raw_file_->write_mutex_); - EXPECT_EQ(expected_writes, raw_file_->num_writes_); - } - - file->flush(); - expected_writes++; - { - Thread::LockGuard lock(raw_file_->write_mutex_); - EXPECT_EQ(expected_writes, raw_file_->num_writes_); - } - - EXPECT_CALL(*raw_file_, write_(_)) - .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { - EXPECT_EQ(0, data.compare("test2")); - return {static_cast(data.length()), 0}; - })); - - // make sure timer is re-enabled on callback call - file->write("test2"); - EXPECT_CALL(*timer, enableTimer(timeout_40ms_)); - timer->callback_(); - expected_writes++; - - { - Thread::LockGuard lock(raw_file_->write_mutex_); - while (raw_file_->num_writes_ != expected_writes) { - raw_file_->write_event_.wait(raw_file_->write_mutex_); - } - } - EXPECT_CALL(*raw_file_, close_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); -} - -TEST_F(FileSystemImplTest, reopenFile) { - NiceMock dispatcher; - NiceMock* timer = new NiceMock(&dispatcher); - Thread::MutexBasicLockable mutex; - - Sequence sq; - EXPECT_CALL(*raw_file_, open_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); - Filesystem::FileSharedPtr file = file_system_.createFile("", dispatcher, mutex, timeout_40ms_); - - EXPECT_CALL(*raw_file_, write_(_)) - .InSequence(sq) - .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { - EXPECT_EQ(0, data.compare("before")); - return {static_cast(data.length()), 0}; - })); - - file->write("before"); - timer->callback_(); - - { - Thread::LockGuard lock(raw_file_->write_mutex_); - while (raw_file_->num_writes_ != 1) { - raw_file_->write_event_.wait(raw_file_->write_mutex_); - } - } - - EXPECT_CALL(*raw_file_, close_()) - .InSequence(sq) - .WillOnce(Return(Api::SysCallBoolResult{true, 0})); - EXPECT_CALL(*raw_file_, open_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); - - EXPECT_CALL(*raw_file_, write_(_)) - .InSequence(sq) - .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { - EXPECT_EQ(0, data.compare("reopened")); - return {static_cast(data.length()), 0}; - })); - - EXPECT_CALL(*raw_file_, close_()) - .InSequence(sq) - .WillOnce(Return(Api::SysCallBoolResult{true, 0})); - - file->reopen(); - file->write("reopened"); - timer->callback_(); - - { - Thread::LockGuard lock(raw_file_->write_mutex_); - while (raw_file_->num_writes_ != 2) { - raw_file_->write_event_.wait(raw_file_->write_mutex_); - } - } -} - -TEST_F(FileSystemImplTest, reopenThrows) { - NiceMock dispatcher; - NiceMock* timer = new NiceMock(&dispatcher); - Thread::MutexBasicLockable mutex; - - EXPECT_CALL(*raw_file_, write_(_)) - .WillRepeatedly(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { - return {static_cast(data.length()), 0}; - })); - - Sequence sq; - EXPECT_CALL(*raw_file_, open_()).InSequence(sq).WillOnce(Return(Api::SysCallBoolResult{true, 0})); - - Filesystem::FileSharedPtr file = file_system_.createFile("", dispatcher, mutex, timeout_40ms_); - EXPECT_CALL(*raw_file_, close_()) - .InSequence(sq) - .WillOnce(Return(Api::SysCallBoolResult{true, 0})); - EXPECT_CALL(*raw_file_, open_()) - .InSequence(sq) - .WillOnce(Return(Api::SysCallBoolResult{false, 0})); - - file->write("test write"); - timer->callback_(); - { - Thread::LockGuard lock(raw_file_->write_mutex_); - while (raw_file_->num_writes_ != 1) { - raw_file_->write_event_.wait(raw_file_->write_mutex_); - } - } - file->reopen(); - - file->write("this is to force reopen"); - timer->callback_(); - - { - Thread::LockGuard lock(raw_file_->open_mutex_); - while (raw_file_->num_opens_ != 2) { - raw_file_->open_event_.wait(raw_file_->open_mutex_); - } - } - - // write call should not cause any exceptions - file->write("random data"); - timer->callback_(); -} - -TEST_F(FileSystemImplTest, bigDataChunkShouldBeFlushedWithoutTimer) { - NiceMock dispatcher; - Thread::MutexBasicLockable mutex; - - EXPECT_CALL(*raw_file_, open_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); - Filesystem::FileSharedPtr file = file_system_.createFile("", dispatcher, mutex, timeout_40ms_); - - EXPECT_CALL(*raw_file_, write_(_)) - .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { - EXPECT_EQ(0, data.compare("a")); - return {static_cast(data.length()), 0}; - })); - - file->write("a"); - - { - Thread::LockGuard lock(raw_file_->write_mutex_); - while (raw_file_->num_writes_ != 1) { - raw_file_->write_event_.wait(raw_file_->write_mutex_); - } - } - - // First write happens without waiting on thread_flush_. Now make a big string and it should be - // flushed even when timer is not enabled - EXPECT_CALL(*raw_file_, write_(_)) - .WillOnce(Invoke([](absl::string_view data) -> Api::SysCallSizeResult { - std::string expected(1024 * 64 + 1, 'b'); - EXPECT_EQ(0, data.compare(expected)); - return {static_cast(data.length()), 0}; - })); - - std::string big_string(1024 * 64 + 1, 'b'); - file->write(big_string); - - { - Thread::LockGuard lock(raw_file_->write_mutex_); - while (raw_file_->num_writes_ != 2) { - raw_file_->write_event_.wait(raw_file_->write_mutex_); - } - } - EXPECT_CALL(*raw_file_, close_()).WillOnce(Return(Api::SysCallBoolResult{true, 0})); -} - } // namespace Filesystem } // namespace Envoy diff --git a/test/mocks/access_log/mocks.cc b/test/mocks/access_log/mocks.cc index d1e10758c3fb3..c4efdd76cc7f0 100644 --- a/test/mocks/access_log/mocks.cc +++ b/test/mocks/access_log/mocks.cc @@ -11,6 +11,9 @@ using testing::ReturnRef; namespace Envoy { namespace AccessLog { +MockAccessLogFile::MockAccessLogFile() {} +MockAccessLogFile::~MockAccessLogFile() {} + MockFilter::MockFilter() {} MockFilter::~MockFilter() {} diff --git a/test/mocks/access_log/mocks.h b/test/mocks/access_log/mocks.h index c96aee7c84289..3c2a55e47745e 100644 --- a/test/mocks/access_log/mocks.h +++ b/test/mocks/access_log/mocks.h @@ -5,13 +5,22 @@ #include "envoy/access_log/access_log.h" -#include "test/mocks/filesystem/mocks.h" - #include "gmock/gmock.h" namespace Envoy { namespace AccessLog { +class MockAccessLogFile : public AccessLogFile { +public: + MockAccessLogFile(); + ~MockAccessLogFile(); + + // AccessLog::AccessLogFile + MOCK_METHOD1(write, void(absl::string_view data)); + MOCK_METHOD0(reopen, void()); + MOCK_METHOD0(flush, void()); +}; + class MockFilter : public Filter { public: MockFilter(); @@ -29,9 +38,9 @@ class MockAccessLogManager : public AccessLogManager { // AccessLog::AccessLogManager MOCK_METHOD0(reopen, void()); - MOCK_METHOD1(createAccessLog, Filesystem::FileSharedPtr(const std::string& file_name)); + MOCK_METHOD1(createAccessLog, AccessLogFileSharedPtr(const std::string& file_name)); - std::shared_ptr file_{new testing::NiceMock()}; + std::shared_ptr file_{new testing::NiceMock()}; }; class MockInstance : public Instance { diff --git a/test/mocks/filesystem/mocks.cc b/test/mocks/filesystem/mocks.cc index 1f7b2383b7a9a..5fe62371c2058 100644 --- a/test/mocks/filesystem/mocks.cc +++ b/test/mocks/filesystem/mocks.cc @@ -5,10 +5,10 @@ namespace Envoy { namespace Filesystem { -MockRawFile::MockRawFile() : num_opens_(0), num_writes_(0), is_open_(false) {} -MockRawFile::~MockRawFile() {} +MockFile::MockFile() : num_opens_(0), num_writes_(0), is_open_(false) {} +MockFile::~MockFile() {} -Api::SysCallBoolResult MockRawFile::open() { +Api::SysCallBoolResult MockFile::open() { Thread::LockGuard lock(open_mutex_); const Api::SysCallBoolResult result = open_(); @@ -19,7 +19,7 @@ Api::SysCallBoolResult MockRawFile::open() { return result; } -Api::SysCallSizeResult MockRawFile::write(absl::string_view buffer) { +Api::SysCallSizeResult MockFile::write(absl::string_view buffer) { Thread::LockGuard lock(write_mutex_); if (!is_open_) { return {-1, EBADF}; @@ -32,19 +32,13 @@ Api::SysCallSizeResult MockRawFile::write(absl::string_view buffer) { return result; } -Api::SysCallBoolResult MockRawFile::close() { +Api::SysCallBoolResult MockFile::close() { const Api::SysCallBoolResult result = close_(); is_open_ = !result.rc_; return result; } -MockRawInstance::MockRawInstance() {} -MockRawInstance::~MockRawInstance() {} - -MockFile::MockFile() {} -MockFile::~MockFile() {} - MockInstance::MockInstance() {} MockInstance::~MockInstance() {} diff --git a/test/mocks/filesystem/mocks.h b/test/mocks/filesystem/mocks.h index 017aa4a5866f4..821cf2b3c17f8 100644 --- a/test/mocks/filesystem/mocks.h +++ b/test/mocks/filesystem/mocks.h @@ -4,6 +4,7 @@ #include #include "envoy/filesystem/filesystem.h" +#include "envoy/filesystem/watcher.h" #include "common/common/thread.h" @@ -12,12 +13,12 @@ namespace Envoy { namespace Filesystem { -class MockRawFile : public RawFile { +class MockFile : public File { public: - MockRawFile(); - ~MockRawFile(); + MockFile(); + ~MockFile(); - // Filesystem::RawFile + // Filesystem::File Api::SysCallBoolResult open() override; Api::SysCallSizeResult write(absl::string_view buffer) override; Api::SysCallBoolResult close() override; @@ -40,45 +41,13 @@ class MockRawFile : public RawFile { bool is_open_; }; -class MockRawInstance : public RawInstance { -public: - MockRawInstance(); - ~MockRawInstance(); - - // Filesystem::RawInstance - MOCK_METHOD1(createRawFile, RawFilePtr(const std::string&)); - MOCK_METHOD1(fileExists, bool(const std::string&)); - MOCK_METHOD1(directoryExists, bool(const std::string&)); - MOCK_METHOD1(fileSize, ssize_t(const std::string&)); - MOCK_METHOD1(fileReadToEnd, std::string(const std::string&)); - MOCK_METHOD1(canonicalPath, Api::SysCallStringResult(const std::string&)); - MOCK_METHOD1(illegalPath, bool(const std::string&)); -}; - -class MockFile : public File { -public: - MockFile(); - ~MockFile(); - - // Filesystem::File - MOCK_METHOD1(write, void(absl::string_view data)); - MOCK_METHOD0(reopen, void()); - MOCK_METHOD0(flush, void()); -}; - class MockInstance : public Instance { public: MockInstance(); ~MockInstance(); // Filesystem::Instance - MOCK_METHOD4(createFile, FileSharedPtr(const std::string&, Event::Dispatcher&, - Thread::BasicLockable&, std::chrono::milliseconds)); - MOCK_METHOD3(createFile, - FileSharedPtr(const std::string&, Event::Dispatcher&, Thread::BasicLockable&)); - - // Filesystem::RawInstance - MOCK_METHOD1(createRawFile, RawFilePtr(const std::string&)); + MOCK_METHOD1(createFile, FilePtr(const std::string&)); MOCK_METHOD1(fileExists, bool(const std::string&)); MOCK_METHOD1(directoryExists, bool(const std::string&)); MOCK_METHOD1(fileSize, ssize_t(const std::string&)); diff --git a/test/test_common/utility.cc b/test/test_common/utility.cc index e88e7a9d4e539..bcbda972c0ef2 100644 --- a/test/test_common/utility.cc +++ b/test/test_common/utility.cc @@ -408,19 +408,13 @@ class TimeSystemProvider { class TestImpl : public TimeSystemProvider, public Impl { public: - TestImpl(std::chrono::milliseconds file_flush_interval_msec, - Thread::ThreadFactory& thread_factory, Stats::Store& stats_store) - : Impl(file_flush_interval_msec, thread_factory, stats_store, global_time_system_) {} + TestImpl(Thread::ThreadFactory& thread_factory) : Impl(thread_factory, global_time_system_) {} }; -ApiPtr createApiForTest(Stats::Store& stat_store) { - return std::make_unique(std::chrono::milliseconds(1000), Thread::threadFactoryForTest(), - stat_store); -} +ApiPtr createApiForTest() { return std::make_unique(Thread::threadFactoryForTest()); } -ApiPtr createApiForTest(Stats::Store& stat_store, Event::TimeSystem& time_system) { - return std::make_unique(std::chrono::milliseconds(1000), Thread::threadFactoryForTest(), - stat_store, time_system); +ApiPtr createApiForTest(Event::TimeSystem& time_system) { + return std::make_unique(Thread::threadFactoryForTest(), time_system); } } // namespace Api From 443a17a1668139fefa5590506334cffa7f472580 Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Wed, 6 Feb 2019 16:34:03 -0500 Subject: [PATCH 08/13] wip Signed-off-by: Sam Smith --- test/common/access_log/access_log_impl_test.cc | 4 ++-- test/fuzz/BUILD | 1 - test/fuzz/main.cc | 7 ++----- test/test_common/utility.h | 4 ++-- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/test/common/access_log/access_log_impl_test.cc b/test/common/access_log/access_log_impl_test.cc index a5c13c589c2af..2e66a76ff78c8 100644 --- a/test/common/access_log/access_log_impl_test.cc +++ b/test/common/access_log/access_log_impl_test.cc @@ -50,7 +50,7 @@ envoy::config::filter::accesslog::v2::AccessLog parseAccessLogFromV2Yaml(const s class AccessLogImplTest : public TestBase { public: - AccessLogImplTest() : file_(new Filesystem::MockFile()) { + AccessLogImplTest() : file_(new MockAccessLogFile()) { ON_CALL(context_, runtime()).WillByDefault(ReturnRef(runtime_)); ON_CALL(context_, accessLogManager()).WillByDefault(ReturnRef(log_manager_)); ON_CALL(log_manager_, createAccessLog(_)).WillByDefault(Return(file_)); @@ -61,7 +61,7 @@ class AccessLogImplTest : public TestBase { Http::TestHeaderMapImpl response_headers_; Http::TestHeaderMapImpl response_trailers_; TestStreamInfo stream_info_; - std::shared_ptr file_; + std::shared_ptr file_; StringViewSaver output_; NiceMock runtime_; diff --git a/test/fuzz/BUILD b/test/fuzz/BUILD index 2ff3a101a99e6..7ef3ab9413244 100644 --- a/test/fuzz/BUILD +++ b/test/fuzz/BUILD @@ -22,7 +22,6 @@ envoy_cc_test_library( ":fuzz_runner_lib", "//source/common/common:assert_lib", "//source/common/common:minimal_logger_lib", - "//source/common/stats:isolated_store_lib", "//test/test_common:environment_lib", "//test/test_common:utility_lib", ], diff --git a/test/fuzz/main.cc b/test/fuzz/main.cc index 023a5078cc1ca..da4d76755407a 100644 --- a/test/fuzz/main.cc +++ b/test/fuzz/main.cc @@ -14,7 +14,6 @@ #include "common/common/assert.h" #include "common/common/logger.h" -#include "common/stats/isolated_store_impl.h" #include "test/fuzz/fuzz_runner.h" #include "test/test_common/environment.h" @@ -29,9 +28,8 @@ std::vector test_corpus_; class FuzzerCorpusTest : public TestBaseWithParam { protected: - FuzzerCorpusTest() : api_(Api::createApiForTest(stats_store_)) {} + FuzzerCorpusTest() : api_(Api::createApiForTest()) {} - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; }; @@ -52,8 +50,7 @@ int main(int argc, char** argv) { RELEASE_ASSERT(argc >= 2, ""); // Consider any file after the test path which doesn't have a - prefix to be a corpus entry. uint32_t input_args = 0; - Envoy::Stats::IsolatedStoreImpl stats_store; - Envoy::Api::ApiPtr api = Envoy::Api::createApiForTest(stats_store); + Envoy::Api::ApiPtr api = Envoy::Api::createApiForTest(); for (int i = 1; i < argc; ++i) { const std::string arg{argv[i]}; if (arg.empty() || arg[0] == '-') { diff --git a/test/test_common/utility.h b/test/test_common/utility.h index c61b49b57a01e..c619e79cf3fec 100644 --- a/test/test_common/utility.h +++ b/test/test_common/utility.h @@ -526,8 +526,8 @@ ThreadFactory& threadFactoryForTest(); } // namespace Thread namespace Api { -ApiPtr createApiForTest(Stats::Store& stat_store); -ApiPtr createApiForTest(Stats::Store& stat_store, Event::TimeSystem& time_system); +ApiPtr createApiForTest(); +ApiPtr createApiForTest(Event::TimeSystem& time_system); } // namespace Api MATCHER_P(HeaderMapEqualIgnoreOrder, rhs, "") { From 5db0857c77fd1a4a3455dc31ee5a265ea3c4f432 Mon Sep 17 00:00:00 2001 From: Arjun Sreedharan Date: Thu, 7 Feb 2019 14:05:03 -0500 Subject: [PATCH 09/13] rename File -> AccessLogFile and RawFile -> File Signed-off-by: Arjun Sreedharan Signed-off-by: Sam Smith --- .../access_log_manager_impl_test.cc | 4 +- test/common/config/BUILD | 1 - .../filesystem_subscription_impl_test.cc | 2 +- .../filesystem_subscription_test_harness.h | 6 +- .../config/subscription_factory_test.cc | 3 +- test/common/config/utility_test.cc | 4 +- test/common/event/BUILD | 2 - .../event/dispatched_thread_impl_test.cc | 2 +- test/common/event/dispatcher_impl_test.cc | 9 +- test/common/event/file_event_impl_test.cc | 7 +- test/common/filesystem/BUILD | 13 - .../common/filesystem/filesystem_impl_test.cc | 227 +++++++++++++++--- .../filesystem/raw_instance_impl_test.cc | 220 ----------------- test/common/filesystem/watcher_impl_test.cc | 4 +- test/common/grpc/BUILD | 1 - .../grpc/async_client_manager_impl_test.cc | 3 +- .../grpc/google_async_client_impl_test.cc | 2 +- test/common/grpc/google_grpc_creds_test.cc | 4 +- .../grpc_client_integration_test_harness.h | 2 +- test/common/http/codec_client_test.cc | 3 +- test/common/http/http1/conn_pool_test.cc | 3 +- test/common/http/http2/conn_pool_test.cc | 3 +- test/common/json/BUILD | 2 - test/common/json/config_schemas_test.cc | 4 +- test/common/json/json_loader_test.cc | 4 +- test/common/network/BUILD | 4 - test/common/network/connection_impl_test.cc | 12 +- test/common/network/dns_impl_test.cc | 6 +- test/common/network/listener_impl_test.cc | 9 +- test/common/network/udp_listener_impl_test.cc | 3 +- test/common/protobuf/BUILD | 1 - test/common/protobuf/utility_test.cc | 4 +- test/common/router/config_impl_test.cc | 3 +- test/common/runtime/runtime_impl_test.cc | 5 +- test/common/secret/sds_api_test.cc | 3 +- .../common/secret/secret_manager_impl_test.cc | 3 +- .../stats/thread_local_store_speed_test.cc | 2 +- test/common/thread_local/BUILD | 1 - .../thread_local/thread_local_impl_test.cc | 4 +- test/common/upstream/cds_api_impl_test.cc | 2 +- .../upstream/cluster_manager_impl_test.cc | 5 +- test/common/upstream/eds_test.cc | 2 +- test/common/upstream/hds_test.cc | 2 +- .../upstream/health_checker_impl_test.cc | 2 +- .../upstream/logical_dns_cluster_test.cc | 2 +- .../upstream/original_dst_cluster_test.cc | 3 +- .../upstream/outlier_detection_impl_test.cc | 2 +- test/common/upstream/upstream_impl_test.cc | 4 +- test/config_test/config_test.cc | 10 +- test/exe/main_common_test.cc | 8 +- .../json_transcoder_filter_test.cc | 3 +- test/extensions/filters/http/jwt_authn/BUILD | 1 - .../filters/http/jwt_authn/jwks_cache_test.cc | 4 +- .../proxy_protocol/proxy_protocol_test.cc | 4 +- .../client_ssl_auth/client_ssl_auth_test.cc | 2 +- .../filters/network/mongo_proxy/BUILD | 1 - .../filters/network/mongo_proxy/proxy_test.cc | 4 +- .../resource_monitors/fixed_heap/BUILD | 1 - .../fixed_heap/config_test.cc | 5 +- .../resource_monitors/injected_resource/BUILD | 2 - .../injected_resource/config_test.cc | 4 +- .../injected_resource_monitor_test.cc | 4 +- .../tls/context_impl_test.cc | 1 + .../transport_sockets/tls/ssl_certs_test.h | 3 +- .../transport_sockets/tls/ssl_socket_test.cc | 89 +++---- test/integration/fake_upstream.cc | 5 +- test/integration/integration.cc | 3 +- test/integration/integration.h | 1 - test/integration/utility.cc | 6 +- test/server/config_validation/BUILD | 1 - .../config_validation/async_client_test.cc | 3 +- .../config_validation/cluster_manager_test.cc | 2 +- .../config_validation/dispatcher_test.cc | 7 +- test/server/configuration_impl_test.cc | 3 +- test/server/guarddog_impl_test.cc | 3 +- test/server/lds_api_test.cc | 2 +- test/server/listener_manager_impl_test.cc | 3 +- test/server/overload_manager_impl_test.cc | 2 +- test/server/worker_impl_test.cc | 3 +- test/tools/router_check/router.cc | 11 +- test/tools/router_check/router.h | 4 +- test/tools/schema_validator/validator.h | 3 +- tools/BUILD | 2 - tools/bootstrap2pb.cc | 5 +- tools/v1_to_bootstrap.cc | 5 +- 85 files changed, 322 insertions(+), 517 deletions(-) delete mode 100644 test/common/filesystem/raw_instance_impl_test.cc diff --git a/test/common/access_log/access_log_manager_impl_test.cc b/test/common/access_log/access_log_manager_impl_test.cc index ad97f5e46d384..c6c6718d66ddf 100644 --- a/test/common/access_log/access_log_manager_impl_test.cc +++ b/test/common/access_log/access_log_manager_impl_test.cc @@ -291,8 +291,8 @@ TEST_F(AccessLogManagerImplTest, reopenAllFiles) { AccessLogFileSharedPtr log = access_log_manager_.createAccessLog("foo"); NiceMock* file2 = new NiceMock; - EXPECT_CALL(file_system_, createFile("bar")) - .WillOnce(Return(ByMove(std::unique_ptr>(file2)))); + EXPECT_CALL(file_system_, createFile("bar")) + .WillOnce(Return(ByMove(std::unique_ptr>(file2)))); EXPECT_CALL(*file2, open_()).Times(2).WillRepeatedly(Return(Api::SysCallBoolResult{true, 0})); AccessLogFileSharedPtr log2 = access_log_manager_.createAccessLog("bar"); diff --git a/test/common/config/BUILD b/test/common/config/BUILD index 8f2ce71b92036..f121c14a1114b 100644 --- a/test/common/config/BUILD +++ b/test/common/config/BUILD @@ -194,7 +194,6 @@ envoy_cc_test( "//source/common/stats:stats_lib", "//test/mocks/grpc:grpc_mocks", "//test/mocks/local_info:local_info_mocks", - "//test/mocks/stats:stats_mocks", "//test/mocks/upstream:upstream_mocks", "//test/test_common:environment_lib", "//test/test_common:utility_lib", diff --git a/test/common/config/filesystem_subscription_impl_test.cc b/test/common/config/filesystem_subscription_impl_test.cc index c1582b0f45574..650985bc955ef 100644 --- a/test/common/config/filesystem_subscription_impl_test.cc +++ b/test/common/config/filesystem_subscription_impl_test.cc @@ -36,7 +36,7 @@ TEST_F(FilesystemSubscriptionImplTest, InitialFile) { TEST(MiscFilesystemSubscriptionImplTest, BadWatch) { Event::MockDispatcher dispatcher; Stats::MockIsolatedStatsStore stats_store; - Api::ApiPtr api = Api::createApiForTest(stats_store); + Api::ApiPtr api = Api::createApiForTest(); SubscriptionStats stats{Utility::generateStats(stats_store)}; auto* watcher = new Filesystem::MockWatcher(); EXPECT_CALL(dispatcher, createFilesystemWatcher_()).WillOnce(Return(watcher)); diff --git a/test/common/config/filesystem_subscription_test_harness.h b/test/common/config/filesystem_subscription_test_harness.h index 22a4bfd16697a..49f6e7e1b41e7 100644 --- a/test/common/config/filesystem_subscription_test_harness.h +++ b/test/common/config/filesystem_subscription_test_harness.h @@ -29,9 +29,8 @@ typedef FilesystemSubscriptionImpl class FilesystemSubscriptionTestHarness : public SubscriptionTestHarness { public: FilesystemSubscriptionTestHarness() - : path_(TestEnvironment::temporaryPath("eds.json")), - api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_), - subscription_(dispatcher_, path_, stats_, *api_) {} + : path_(TestEnvironment::temporaryPath("eds.json")), api_(Api::createApiForTest()), + dispatcher_(*api_), subscription_(dispatcher_, path_, stats_, *api_) {} ~FilesystemSubscriptionTestHarness() { EXPECT_EQ(0, ::unlink(path_.c_str())); } @@ -97,7 +96,6 @@ class FilesystemSubscriptionTestHarness : public SubscriptionTestHarness { const std::string path_; std::string version_; - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; Event::DispatcherImpl dispatcher_; NiceMock> callbacks_; diff --git a/test/common/config/subscription_factory_test.cc b/test/common/config/subscription_factory_test.cc index 0daf82b123fca..810121a206f2c 100644 --- a/test/common/config/subscription_factory_test.cc +++ b/test/common/config/subscription_factory_test.cc @@ -28,8 +28,7 @@ namespace Config { class SubscriptionFactoryTest : public TestBase { public: - SubscriptionFactoryTest() - : http_request_(&cm_.async_client_), api_(Api::createApiForTest(stats_store_)) {} + SubscriptionFactoryTest() : http_request_(&cm_.async_client_), api_(Api::createApiForTest()) {} std::unique_ptr> subscriptionFromConfigSource(const envoy::api::v2::core::ConfigSource& config) { diff --git a/test/common/config/utility_test.cc b/test/common/config/utility_test.cc index c3ebc97e5d235..8fbf134012939 100644 --- a/test/common/config/utility_test.cc +++ b/test/common/config/utility_test.cc @@ -11,7 +11,6 @@ #include "test/mocks/grpc/mocks.h" #include "test/mocks/local_info/mocks.h" -#include "test/mocks/stats/mocks.h" #include "test/mocks/upstream/mocks.h" #include "test/test_common/environment.h" #include "test/test_common/test_base.h" @@ -208,8 +207,7 @@ TEST(UtilityTest, UnixClusterStatic) { } TEST(UtilityTest, CheckFilesystemSubscriptionBackingPath) { - Stats::MockIsolatedStatsStore stats_store; - Api::ApiPtr api = Api::createApiForTest(stats_store); + Api::ApiPtr api = Api::createApiForTest(); EXPECT_THROW_WITH_MESSAGE( Utility::checkFilesystemSubscriptionBackingPath("foo", *api), EnvoyException, diff --git a/test/common/event/BUILD b/test/common/event/BUILD index 0a5ad582e66b2..f1c95babefa04 100644 --- a/test/common/event/BUILD +++ b/test/common/event/BUILD @@ -15,7 +15,6 @@ envoy_cc_test( "//source/common/api:api_lib", "//source/common/event:dispatcher_includes", "//source/common/event:dispatcher_lib", - "//source/common/stats:isolated_store_lib", "//test/mocks:common_lib", "//test/test_common:utility_lib", ], @@ -28,7 +27,6 @@ envoy_cc_test( "//include/envoy/event:file_event_interface", "//source/common/event:dispatcher_includes", "//source/common/event:dispatcher_lib", - "//source/common/stats:isolated_store_lib", "//test/mocks:common_lib", "//test/test_common:environment_lib", "//test/test_common:utility_lib", diff --git a/test/common/event/dispatched_thread_impl_test.cc b/test/common/event/dispatched_thread_impl_test.cc index fc9ba00435fbd..0bbe17c3138a7 100644 --- a/test/common/event/dispatched_thread_impl_test.cc +++ b/test/common/event/dispatched_thread_impl_test.cc @@ -23,7 +23,7 @@ namespace Event { class DispatchedThreadTest : public TestBase { protected: DispatchedThreadTest() - : config_(1000, 1000, 1000, 1000), api_(Api::createApiForTest(fakestats_)), thread_(*api_), + : config_(1000, 1000, 1000, 1000), api_(Api::createApiForTest()), thread_(*api_), guard_dog_(fakestats_, config_, *api_) {} void SetUp() override { thread_.start(guard_dog_); } diff --git a/test/common/event/dispatcher_impl_test.cc b/test/common/event/dispatcher_impl_test.cc index 6677fbfe679d9..58873195d0403 100644 --- a/test/common/event/dispatcher_impl_test.cc +++ b/test/common/event/dispatcher_impl_test.cc @@ -5,7 +5,6 @@ #include "common/api/api_impl.h" #include "common/common/lock_guard.h" #include "common/event/dispatcher_impl.h" -#include "common/stats/isolated_store_impl.h" #include "test/mocks/common.h" #include "test/test_common/test_base.h" @@ -29,8 +28,7 @@ class TestDeferredDeletable : public DeferredDeletable { TEST(DeferredDeleteTest, DeferredDelete) { InSequence s; - Stats::IsolatedStoreImpl stats_store; - Api::ApiPtr api = Api::createApiForTest(stats_store); + Api::ApiPtr api = Api::createApiForTest(); DispatcherImpl dispatcher(*api); ReadyWatcher watcher1; @@ -62,8 +60,8 @@ TEST(DeferredDeleteTest, DeferredDelete) { class DispatcherImplTest : public TestBase { protected: DispatcherImplTest() - : api_(Api::createApiForTest(stat_store_)), - dispatcher_(std::make_unique(*api_)), work_finished_(false) { + : api_(Api::createApiForTest()), dispatcher_(std::make_unique(*api_)), + work_finished_(false) { dispatcher_thread_ = api_->threadFactory().createThread([this]() { // Must create a keepalive timer to keep the dispatcher from exiting. std::chrono::milliseconds time_interval(500); @@ -80,7 +78,6 @@ class DispatcherImplTest : public TestBase { dispatcher_thread_->join(); } - Stats::IsolatedStoreImpl stat_store_; Api::ApiPtr api_; Thread::ThreadPtr dispatcher_thread_; DispatcherPtr dispatcher_; diff --git a/test/common/event/file_event_impl_test.cc b/test/common/event/file_event_impl_test.cc index d43dbeef0bc40..0fcb8dd97a447 100644 --- a/test/common/event/file_event_impl_test.cc +++ b/test/common/event/file_event_impl_test.cc @@ -3,7 +3,6 @@ #include "envoy/event/file_event.h" #include "common/event/dispatcher_impl.h" -#include "common/stats/isolated_store_impl.h" #include "test/mocks/common.h" #include "test/test_common/environment.h" @@ -15,7 +14,7 @@ namespace Event { class FileEventImplTest : public TestBase { public: - FileEventImplTest() : api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_) {} + FileEventImplTest() : api_(Api::createApiForTest()), dispatcher_(*api_) {} void SetUp() override { int rc = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds_); @@ -32,7 +31,6 @@ class FileEventImplTest : public TestBase { protected: int fds_[2]; - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; DispatcherImpl dispatcher_; }; @@ -52,8 +50,7 @@ TEST_P(FileEventImplActivateTest, Activate) { } ASSERT_NE(-1, fd); - Stats::IsolatedStoreImpl stats_store; - Api::ApiPtr api = Api::createApiForTest(stats_store); + Api::ApiPtr api = Api::createApiForTest(); DispatcherImpl dispatcher(*api); ReadyWatcher read_event; EXPECT_CALL(read_event, ready()).Times(1); diff --git a/test/common/filesystem/BUILD b/test/common/filesystem/BUILD index 566b5d03f630e..6f385036615a6 100644 --- a/test/common/filesystem/BUILD +++ b/test/common/filesystem/BUILD @@ -13,18 +13,6 @@ envoy_cc_test( srcs = ["filesystem_impl_test.cc"], deps = [ "//source/common/filesystem:filesystem_lib", - "//source/common/stats:isolated_store_lib", - "//test/mocks/event:event_mocks", - "//test/mocks/filesystem:filesystem_mocks", - "//test/test_common:environment_lib", - ], -) - -envoy_cc_test( - name = "raw_instance_impl_test", - srcs = ["raw_instance_impl_test.cc"], - deps = [ - "//source/common/filesystem:raw_instance_lib", "//test/test_common:environment_lib", ], ) @@ -46,7 +34,6 @@ envoy_cc_test( "//source/common/event:dispatcher_includes", "//source/common/event:dispatcher_lib", "//source/common/filesystem:watcher_lib", - "//source/common/stats:isolated_store_lib", "//test/test_common:environment_lib", ], ) diff --git a/test/common/filesystem/filesystem_impl_test.cc b/test/common/filesystem/filesystem_impl_test.cc index 51f17749d1a36..7923c34bea1de 100644 --- a/test/common/filesystem/filesystem_impl_test.cc +++ b/test/common/filesystem/filesystem_impl_test.cc @@ -1,49 +1,220 @@ #include #include -#include "common/common/lock_guard.h" -#include "common/common/thread.h" -#include "common/event/dispatcher_impl.h" +#include "common/common/assert.h" #include "common/filesystem/filesystem_impl.h" -#include "common/stats/isolated_store_impl.h" -#include "test/mocks/event/mocks.h" -#include "test/mocks/filesystem/mocks.h" #include "test/test_common/environment.h" #include "test/test_common/test_base.h" -#include "test/test_common/utility.h" #include "gmock/gmock.h" - -using testing::_; -using testing::ByMove; -using testing::InSequence; -using testing::Invoke; -using testing::NiceMock; -using testing::Return; -using testing::SaveArg; -using testing::Sequence; -using testing::Throw; +#include "gtest/gtest.h" namespace Envoy { namespace Filesystem { class FileSystemImplTest : public TestBase { protected: - FileSystemImplTest() - : raw_file_(new NiceMock), - file_system_(std::chrono::milliseconds(10000), Thread::threadFactoryForTest(), stats_store_, - raw_instance_) { - EXPECT_CALL(raw_instance_, createRawFile(_)) - .WillOnce(Return(ByMove(std::unique_ptr>(raw_file_)))); + int getFd(File* file) { + auto file_impl = dynamic_cast(file); + RELEASE_ASSERT(file_impl != nullptr, "failed to cast File* to FileImpl*"); + return file_impl->fd_; } - NiceMock* raw_file_; - const std::chrono::milliseconds timeout_40ms_{40}; - Stats::IsolatedStoreImpl stats_store_; - NiceMock raw_instance_; InstanceImpl file_system_; }; +TEST_F(FileSystemImplTest, fileExists) { + EXPECT_TRUE(file_system_.fileExists("/dev/null")); + EXPECT_FALSE(file_system_.fileExists("/dev/blahblahblah")); +} + +TEST_F(FileSystemImplTest, directoryExists) { + EXPECT_TRUE(file_system_.directoryExists("/dev")); + EXPECT_FALSE(file_system_.directoryExists("/dev/null")); + EXPECT_FALSE(file_system_.directoryExists("/dev/blahblah")); +} + +TEST_F(FileSystemImplTest, fileSize) { + EXPECT_EQ(0, file_system_.fileSize("/dev/null")); + EXPECT_EQ(-1, file_system_.fileSize("/dev/blahblahblah")); + const std::string data = "test string\ntest"; + const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); + EXPECT_EQ(data.length(), file_system_.fileSize(file_path)); +} + +TEST_F(FileSystemImplTest, fileReadToEndSuccess) { + const std::string data = "test string\ntest"; + const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); + + EXPECT_EQ(data, file_system_.fileReadToEnd(file_path)); +} + +// Files are read into std::string; verify that all bytes (eg non-ascii characters) come back +// unmodified +TEST_F(FileSystemImplTest, fileReadToEndSuccessBinary) { + std::string data; + for (unsigned i = 0; i < 256; i++) { + data.push_back(i); + } + const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); + + const std::string read = file_system_.fileReadToEnd(file_path); + const std::vector binary_read(read.begin(), read.end()); + EXPECT_EQ(binary_read.size(), 256); + for (unsigned i = 0; i < 256; i++) { + EXPECT_EQ(binary_read.at(i), i); + } +} + +TEST_F(FileSystemImplTest, fileReadToEndDoesNotExist) { + unlink(TestEnvironment::temporaryPath("envoy_this_not_exist").c_str()); + EXPECT_THROW(file_system_.fileReadToEnd(TestEnvironment::temporaryPath("envoy_this_not_exist")), + EnvoyException); +} + +TEST_F(FileSystemImplTest, fileReadToEndBlacklisted) { + EXPECT_THROW(file_system_.fileReadToEnd("/dev/urandom"), EnvoyException); + EXPECT_THROW(file_system_.fileReadToEnd("/proc/cpuinfo"), EnvoyException); + EXPECT_THROW(file_system_.fileReadToEnd("/sys/block/sda/dev"), EnvoyException); +} + +TEST_F(FileSystemImplTest, CanonicalPathSuccess) { + EXPECT_EQ("/", file_system_.canonicalPath("//").rc_); +} + +TEST_F(FileSystemImplTest, CanonicalPathFail) { + const Api::SysCallStringResult result = file_system_.canonicalPath("/_some_non_existent_file"); + EXPECT_TRUE(result.rc_.empty()); + EXPECT_STREQ("No such file or directory", ::strerror(result.errno_)); +} + +TEST_F(FileSystemImplTest, IllegalPath) { + EXPECT_FALSE(file_system_.illegalPath("/")); + EXPECT_TRUE(file_system_.illegalPath("/dev")); + EXPECT_TRUE(file_system_.illegalPath("/dev/")); + EXPECT_TRUE(file_system_.illegalPath("/proc")); + EXPECT_TRUE(file_system_.illegalPath("/proc/")); + EXPECT_TRUE(file_system_.illegalPath("/sys")); + EXPECT_TRUE(file_system_.illegalPath("/sys/")); + EXPECT_TRUE(file_system_.illegalPath("/_some_non_existent_file")); +} + +TEST_F(FileSystemImplTest, ConstructedFileNotOpen) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + FilePtr file = file_system_.createFile(new_file_path); + EXPECT_FALSE(file->isOpen()); +} + +TEST_F(FileSystemImplTest, Open) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + FilePtr file = file_system_.createFile(new_file_path); + const Api::SysCallBoolResult result = file->open(); + EXPECT_TRUE(result.rc_); + EXPECT_TRUE(file->isOpen()); +} + +TEST_F(FileSystemImplTest, OpenTwice) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + FilePtr file = file_system_.createFile(new_file_path); + EXPECT_EQ(getFd(file.get()), -1); + + Api::SysCallBoolResult result = file->open(); + const int initial_fd = getFd(file.get()); + EXPECT_TRUE(result.rc_); + EXPECT_TRUE(file->isOpen()); + + // check that we don't leak a file descriptor + result = file->open(); + EXPECT_EQ(initial_fd, getFd(file.get())); + EXPECT_TRUE(result.rc_); + EXPECT_TRUE(file->isOpen()); +} + +TEST_F(FileSystemImplTest, OpenBadFilePath) { + FilePtr file = file_system_.createFile(""); + const Api::SysCallBoolResult result = file->open(); + EXPECT_FALSE(result.rc_); +} + +TEST_F(FileSystemImplTest, ExistingFile) { + const std::string file_path = + TestEnvironment::writeStringToFileForTest("test_envoy", "existing file"); + + { + FilePtr file = file_system_.createFile(file_path); + const Api::SysCallBoolResult open_result = file->open(); + EXPECT_TRUE(open_result.rc_); + std::string data(" new data"); + const Api::SysCallSizeResult result = file->write(data); + EXPECT_EQ(data.length(), result.rc_); + } + + auto contents = TestEnvironment::readFileToStringForTest(file_path); + EXPECT_EQ("existing file new data", contents); +} + +TEST_F(FileSystemImplTest, NonExistingFile) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + { + FilePtr file = file_system_.createFile(new_file_path); + const Api::SysCallBoolResult open_result = file->open(); + EXPECT_TRUE(open_result.rc_); + std::string data(" new data"); + const Api::SysCallSizeResult result = file->write(data); + EXPECT_EQ(data.length(), result.rc_); + } + + auto contents = TestEnvironment::readFileToStringForTest(new_file_path); + EXPECT_EQ(" new data", contents); +} + +TEST_F(FileSystemImplTest, Close) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + FilePtr file = file_system_.createFile(new_file_path); + const Api::SysCallBoolResult result = file->close(); + EXPECT_TRUE(result.rc_); + EXPECT_FALSE(file->isOpen()); +} + +TEST_F(FileSystemImplTest, CloseTwice) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + FilePtr file = file_system_.createFile(new_file_path); + Api::SysCallBoolResult result = file->close(); + EXPECT_TRUE(result.rc_); + EXPECT_FALSE(file->isOpen()); + + // check that closing an already closed file doesn't error + result = file->close(); + EXPECT_TRUE(result.rc_); + EXPECT_FALSE(file->isOpen()); +} + +TEST_F(FileSystemImplTest, WriteAfterClose) { + const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); + ::unlink(new_file_path.c_str()); + + FilePtr file = file_system_.createFile(new_file_path); + Api::SysCallBoolResult bool_result = file->open(); + EXPECT_TRUE(bool_result.rc_); + bool_result = file->close(); + EXPECT_TRUE(bool_result.rc_); + const Api::SysCallSizeResult result = file->write(" new data"); + EXPECT_EQ(-1, result.rc_); + EXPECT_EQ(EBADF, result.errno_); +} + } // namespace Filesystem -} // namespace Envoy +} // namespace Envoy \ No newline at end of file diff --git a/test/common/filesystem/raw_instance_impl_test.cc b/test/common/filesystem/raw_instance_impl_test.cc deleted file mode 100644 index ed442534f80bb..0000000000000 --- a/test/common/filesystem/raw_instance_impl_test.cc +++ /dev/null @@ -1,220 +0,0 @@ -#include -#include - -#include "common/common/assert.h" -#include "common/filesystem/raw_instance_impl.h" - -#include "test/test_common/environment.h" -#include "test/test_common/test_base.h" - -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -namespace Envoy { -namespace Filesystem { - -class RawInstanceImplTest : public TestBase { -protected: - int getFd(RawFile* file) { - auto file_impl = dynamic_cast(file); - RELEASE_ASSERT(file_impl != nullptr, "failed to cast RawFile* to RawFileImpl*"); - return file_impl->fd_; - } - - RawInstanceImpl raw_instance_; -}; - -TEST_F(RawInstanceImplTest, fileExists) { - EXPECT_TRUE(raw_instance_.fileExists("/dev/null")); - EXPECT_FALSE(raw_instance_.fileExists("/dev/blahblahblah")); -} - -TEST_F(RawInstanceImplTest, directoryExists) { - EXPECT_TRUE(raw_instance_.directoryExists("/dev")); - EXPECT_FALSE(raw_instance_.directoryExists("/dev/null")); - EXPECT_FALSE(raw_instance_.directoryExists("/dev/blahblah")); -} - -TEST_F(RawInstanceImplTest, fileSize) { - EXPECT_EQ(0, raw_instance_.fileSize("/dev/null")); - EXPECT_EQ(-1, raw_instance_.fileSize("/dev/blahblahblah")); - const std::string data = "test string\ntest"; - const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); - EXPECT_EQ(data.length(), raw_instance_.fileSize(file_path)); -} - -TEST_F(RawInstanceImplTest, fileReadToEndSuccess) { - const std::string data = "test string\ntest"; - const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); - - EXPECT_EQ(data, raw_instance_.fileReadToEnd(file_path)); -} - -// Files are read into std::string; verify that all bytes (eg non-ascii characters) come back -// unmodified -TEST_F(RawInstanceImplTest, fileReadToEndSuccessBinary) { - std::string data; - for (unsigned i = 0; i < 256; i++) { - data.push_back(i); - } - const std::string file_path = TestEnvironment::writeStringToFileForTest("test_envoy", data); - - const std::string read = raw_instance_.fileReadToEnd(file_path); - const std::vector binary_read(read.begin(), read.end()); - EXPECT_EQ(binary_read.size(), 256); - for (unsigned i = 0; i < 256; i++) { - EXPECT_EQ(binary_read.at(i), i); - } -} - -TEST_F(RawInstanceImplTest, fileReadToEndDoesNotExist) { - unlink(TestEnvironment::temporaryPath("envoy_this_not_exist").c_str()); - EXPECT_THROW(raw_instance_.fileReadToEnd(TestEnvironment::temporaryPath("envoy_this_not_exist")), - EnvoyException); -} - -TEST_F(RawInstanceImplTest, fileReadToEndBlacklisted) { - EXPECT_THROW(raw_instance_.fileReadToEnd("/dev/urandom"), EnvoyException); - EXPECT_THROW(raw_instance_.fileReadToEnd("/proc/cpuinfo"), EnvoyException); - EXPECT_THROW(raw_instance_.fileReadToEnd("/sys/block/sda/dev"), EnvoyException); -} - -TEST_F(RawInstanceImplTest, CanonicalPathSuccess) { - EXPECT_EQ("/", raw_instance_.canonicalPath("//").rc_); -} - -TEST_F(RawInstanceImplTest, CanonicalPathFail) { - const Api::SysCallStringResult result = raw_instance_.canonicalPath("/_some_non_existent_file"); - EXPECT_TRUE(result.rc_.empty()); - EXPECT_STREQ("No such file or directory", ::strerror(result.errno_)); -} - -TEST_F(RawInstanceImplTest, IllegalPath) { - EXPECT_FALSE(raw_instance_.illegalPath("/")); - EXPECT_TRUE(raw_instance_.illegalPath("/dev")); - EXPECT_TRUE(raw_instance_.illegalPath("/dev/")); - EXPECT_TRUE(raw_instance_.illegalPath("/proc")); - EXPECT_TRUE(raw_instance_.illegalPath("/proc/")); - EXPECT_TRUE(raw_instance_.illegalPath("/sys")); - EXPECT_TRUE(raw_instance_.illegalPath("/sys/")); - EXPECT_TRUE(raw_instance_.illegalPath("/_some_non_existent_file")); -} - -TEST_F(RawInstanceImplTest, ConstructedFileNotOpen) { - const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); - ::unlink(new_file_path.c_str()); - - RawFilePtr file = raw_instance_.createRawFile(new_file_path); - EXPECT_FALSE(file->isOpen()); -} - -TEST_F(RawInstanceImplTest, Open) { - const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); - ::unlink(new_file_path.c_str()); - - RawFilePtr file = raw_instance_.createRawFile(new_file_path); - const Api::SysCallBoolResult result = file->open(); - EXPECT_TRUE(result.rc_); - EXPECT_TRUE(file->isOpen()); -} - -TEST_F(RawInstanceImplTest, OpenTwice) { - const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); - ::unlink(new_file_path.c_str()); - - RawFilePtr file = raw_instance_.createRawFile(new_file_path); - EXPECT_EQ(getFd(file.get()), -1); - - Api::SysCallBoolResult result = file->open(); - const int initial_fd = getFd(file.get()); - EXPECT_TRUE(result.rc_); - EXPECT_TRUE(file->isOpen()); - - // check that we don't leak a file descriptor - result = file->open(); - EXPECT_EQ(initial_fd, getFd(file.get())); - EXPECT_TRUE(result.rc_); - EXPECT_TRUE(file->isOpen()); -} - -TEST_F(RawInstanceImplTest, OpenBadFilePath) { - RawFilePtr file = raw_instance_.createRawFile(""); - const Api::SysCallBoolResult result = file->open(); - EXPECT_FALSE(result.rc_); -} - -TEST_F(RawInstanceImplTest, ExistingFile) { - const std::string file_path = - TestEnvironment::writeStringToFileForTest("test_envoy", "existing file"); - - { - RawFilePtr file = raw_instance_.createRawFile(file_path); - const Api::SysCallBoolResult open_result = file->open(); - EXPECT_TRUE(open_result.rc_); - std::string data(" new data"); - const Api::SysCallSizeResult result = file->write(data); - EXPECT_EQ(data.length(), result.rc_); - } - - auto contents = TestEnvironment::readFileToStringForTest(file_path); - EXPECT_EQ("existing file new data", contents); -} - -TEST_F(RawInstanceImplTest, NonExistingFile) { - const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); - ::unlink(new_file_path.c_str()); - - { - RawFilePtr file = raw_instance_.createRawFile(new_file_path); - const Api::SysCallBoolResult open_result = file->open(); - EXPECT_TRUE(open_result.rc_); - std::string data(" new data"); - const Api::SysCallSizeResult result = file->write(data); - EXPECT_EQ(data.length(), result.rc_); - } - - auto contents = TestEnvironment::readFileToStringForTest(new_file_path); - EXPECT_EQ(" new data", contents); -} - -TEST_F(RawInstanceImplTest, Close) { - const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); - ::unlink(new_file_path.c_str()); - - RawFilePtr file = raw_instance_.createRawFile(new_file_path); - const Api::SysCallBoolResult result = file->close(); - EXPECT_TRUE(result.rc_); - EXPECT_FALSE(file->isOpen()); -} - -TEST_F(RawInstanceImplTest, CloseTwice) { - const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); - ::unlink(new_file_path.c_str()); - - RawFilePtr file = raw_instance_.createRawFile(new_file_path); - Api::SysCallBoolResult result = file->close(); - EXPECT_TRUE(result.rc_); - EXPECT_FALSE(file->isOpen()); - - // check that closing an already closed file doesn't error - result = file->close(); - EXPECT_TRUE(result.rc_); - EXPECT_FALSE(file->isOpen()); -} - -TEST_F(RawInstanceImplTest, WriteAfterClose) { - const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); - ::unlink(new_file_path.c_str()); - - RawFilePtr file = raw_instance_.createRawFile(new_file_path); - Api::SysCallBoolResult bool_result = file->open(); - EXPECT_TRUE(bool_result.rc_); - bool_result = file->close(); - EXPECT_TRUE(bool_result.rc_); - const Api::SysCallSizeResult result = file->write(" new data"); - EXPECT_EQ(-1, result.rc_); - EXPECT_EQ(EBADF, result.errno_); -} - -} // namespace Filesystem -} // namespace Envoy diff --git a/test/common/filesystem/watcher_impl_test.cc b/test/common/filesystem/watcher_impl_test.cc index da6b5fd80cddf..69024e526bf93 100644 --- a/test/common/filesystem/watcher_impl_test.cc +++ b/test/common/filesystem/watcher_impl_test.cc @@ -4,7 +4,6 @@ #include "common/common/assert.h" #include "common/event/dispatcher_impl.h" #include "common/filesystem/watcher_impl.h" -#include "common/stats/isolated_store_impl.h" #include "test/test_common/environment.h" #include "test/test_common/test_base.h" @@ -17,9 +16,8 @@ namespace Filesystem { class WatcherImplTest : public TestBase { protected: - WatcherImplTest() : api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_) {} + WatcherImplTest() : api_(Api::createApiForTest()), dispatcher_(*api_) {} - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; Event::DispatcherImpl dispatcher_; }; diff --git a/test/common/grpc/BUILD b/test/common/grpc/BUILD index 3d262d90ee43b..4f025b3d64daf 100644 --- a/test/common/grpc/BUILD +++ b/test/common/grpc/BUILD @@ -80,7 +80,6 @@ envoy_cc_test( srcs = envoy_select_google_grpc(["google_grpc_creds_test.cc"]), deps = [ ":utility_lib", - "//test/mocks/stats:stats_mocks", "//test/test_common:utility_lib", ] + envoy_select_google_grpc(["//source/common/grpc:google_grpc_creds_lib"]), ) diff --git a/test/common/grpc/async_client_manager_impl_test.cc b/test/common/grpc/async_client_manager_impl_test.cc index 8d3c15f0a9fdc..a64ea8697020e 100644 --- a/test/common/grpc/async_client_manager_impl_test.cc +++ b/test/common/grpc/async_client_manager_impl_test.cc @@ -18,11 +18,10 @@ namespace { class AsyncClientManagerImplTest : public TestBase { public: - AsyncClientManagerImplTest() : api_(Api::createApiForTest(api_stats_store_)) {} + AsyncClientManagerImplTest() : api_(Api::createApiForTest()) {} Upstream::MockClusterManager cm_; NiceMock tls_; - Stats::IsolatedStoreImpl api_stats_store_; Stats::MockStore scope_; DangerousDeprecatedTestTime test_time_; Api::ApiPtr api_; diff --git a/test/common/grpc/google_async_client_impl_test.cc b/test/common/grpc/google_async_client_impl_test.cc index 73f69db13b9de..a811d4b9fedac 100644 --- a/test/common/grpc/google_async_client_impl_test.cc +++ b/test/common/grpc/google_async_client_impl_test.cc @@ -47,7 +47,7 @@ class MockStubFactory : public GoogleStubFactory { class EnvoyGoogleAsyncClientImplTest : public TestBase { public: EnvoyGoogleAsyncClientImplTest() - : stats_store_(new Stats::IsolatedStoreImpl), api_(Api::createApiForTest(*stats_store_)), + : stats_store_(new Stats::IsolatedStoreImpl), api_(Api::createApiForTest()), dispatcher_(*api_), scope_(stats_store_), method_descriptor_(helloworld::Greeter::descriptor()->FindMethodByName("SayHello")) { envoy::api::v2::core::GrpcService config; diff --git a/test/common/grpc/google_grpc_creds_test.cc b/test/common/grpc/google_grpc_creds_test.cc index 1bbb3bd353401..1d322c3debf99 100644 --- a/test/common/grpc/google_grpc_creds_test.cc +++ b/test/common/grpc/google_grpc_creds_test.cc @@ -1,7 +1,6 @@ #include "common/grpc/google_grpc_creds_impl.h" #include "test/common/grpc/utility.h" -#include "test/mocks/stats/mocks.h" #include "test/test_common/test_base.h" #include "test/test_common/utility.h" @@ -16,9 +15,8 @@ namespace { class CredsUtilityTest : public TestBase { public: - CredsUtilityTest() : api_(Api::createApiForTest(stats_store_)) {} + CredsUtilityTest() : api_(Api::createApiForTest()) {} - Stats::MockIsolatedStatsStore stats_store_; Api::ApiPtr api_; }; diff --git a/test/common/grpc/grpc_client_integration_test_harness.h b/test/common/grpc/grpc_client_integration_test_harness.h index 950c087a163c2..5c6385f18e80a 100644 --- a/test/common/grpc/grpc_client_integration_test_harness.h +++ b/test/common/grpc/grpc_client_integration_test_harness.h @@ -218,7 +218,7 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { public: GrpcClientIntegrationTest() : method_descriptor_(helloworld::Greeter::descriptor()->FindMethodByName("SayHello")), - api_(Api::createApiForTest(*stats_store_, test_time_.timeSystem())), dispatcher_(*api_) {} + api_(Api::createApiForTest(test_time_.timeSystem())), dispatcher_(*api_) {} virtual void initialize() { if (fake_upstream_ == nullptr) { diff --git a/test/common/http/codec_client_test.cc b/test/common/http/codec_client_test.cc index 6e38d86bea355..d41dc83068087 100644 --- a/test/common/http/codec_client_test.cc +++ b/test/common/http/codec_client_test.cc @@ -259,7 +259,7 @@ TEST_F(CodecClientTest, WatermarkPassthrough) { // Test the codec getting input from a real TCP connection. class CodecNetworkTest : public TestBaseWithParam { public: - CodecNetworkTest() : api_(Api::createApiForTest(stats_store_)) { + CodecNetworkTest() : api_(Api::createApiForTest()) { dispatcher_ = std::make_unique(*api_); upstream_listener_ = dispatcher_->createListener(socket_, listener_callbacks_, true, false); Network::ClientConnectionPtr client_connection = dispatcher_->createClientConnection( @@ -326,7 +326,6 @@ class CodecNetworkTest : public TestBaseWithParam { } protected: - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; Event::DispatcherPtr dispatcher_; Network::ListenerPtr upstream_listener_; diff --git a/test/common/http/http1/conn_pool_test.cc b/test/common/http/http1/conn_pool_test.cc index ae6152f37eb7b..853b488499b84 100644 --- a/test/common/http/http1/conn_pool_test.cc +++ b/test/common/http/http1/conn_pool_test.cc @@ -46,7 +46,7 @@ class ConnPoolImplForTest : public ConnPoolImpl { NiceMock* upstream_ready_timer) : ConnPoolImpl(dispatcher, Upstream::makeTestHost(cluster, "tcp://127.0.0.1:9000"), Upstream::ResourcePriority::Default, nullptr), - api_(Api::createApiForTest(stats_store_)), mock_dispatcher_(dispatcher), + api_(Api::createApiForTest()), mock_dispatcher_(dispatcher), mock_upstream_ready_timer_(upstream_ready_timer) {} ~ConnPoolImplForTest() { @@ -111,7 +111,6 @@ class ConnPoolImplForTest : public ConnPoolImpl { EXPECT_FALSE(upstream_ready_enabled_); } - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; Event::MockDispatcher& mock_dispatcher_; NiceMock* mock_upstream_ready_timer_; diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index cd318c0fb6735..1527946c3b129 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -64,7 +64,7 @@ class Http2ConnPoolImplTest : public TestBase { }; Http2ConnPoolImplTest() - : api_(Api::createApiForTest(stats_store_)), + : api_(Api::createApiForTest()), pool_(dispatcher_, host_, Upstream::ResourcePriority::Default, nullptr) {} ~Http2ConnPoolImplTest() { @@ -116,7 +116,6 @@ class Http2ConnPoolImplTest : public TestBase { MOCK_METHOD0(onClientDestroy, void()); - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; NiceMock dispatcher_; std::shared_ptr cluster_{new NiceMock()}; diff --git a/test/common/json/BUILD b/test/common/json/BUILD index 0b78a0a51f407..aa3928a658468 100644 --- a/test/common/json/BUILD +++ b/test/common/json/BUILD @@ -17,7 +17,6 @@ envoy_cc_test( deps = [ "//source/common/json:config_schemas_lib", "//source/common/json:json_loader_lib", - "//source/common/stats:isolated_store_lib", "//test/test_common:environment_lib", "//test/test_common:utility_lib", ], @@ -28,7 +27,6 @@ envoy_cc_test( srcs = ["json_loader_test.cc"], deps = [ "//source/common/json:json_loader_lib", - "//source/common/stats:isolated_store_lib", "//test/test_common:utility_lib", ], ) diff --git a/test/common/json/config_schemas_test.cc b/test/common/json/config_schemas_test.cc index 5a4d6eba6dc8d..7b57e9dcbb4b5 100644 --- a/test/common/json/config_schemas_test.cc +++ b/test/common/json/config_schemas_test.cc @@ -4,7 +4,6 @@ #include "common/common/fmt.h" #include "common/json/config_schemas.h" #include "common/json/json_loader.h" -#include "common/stats/isolated_store_impl.h" #include "test/test_common/environment.h" #include "test/test_common/test_base.h" @@ -29,9 +28,8 @@ std::vector generateTestInputs() { class ConfigSchemasTest : public TestBaseWithParam { protected: - ConfigSchemasTest() : api_(Api::createApiForTest(stats_store_)) {} + ConfigSchemasTest() : api_(Api::createApiForTest()) {} - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; }; diff --git a/test/common/json/json_loader_test.cc b/test/common/json/json_loader_test.cc index 2846fa4f0a556..83d596886882f 100644 --- a/test/common/json/json_loader_test.cc +++ b/test/common/json/json_loader_test.cc @@ -2,7 +2,6 @@ #include #include "common/json/json_loader.h" -#include "common/stats/isolated_store_impl.h" #include "test/test_common/test_base.h" #include "test/test_common/utility.h" @@ -12,9 +11,8 @@ namespace Json { class JsonLoaderTest : public TestBase { protected: - JsonLoaderTest() : api_(Api::createApiForTest(stats_store_)) {} + JsonLoaderTest() : api_(Api::createApiForTest()) {} - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; }; diff --git a/test/common/network/BUILD b/test/common/network/BUILD index 8b356ed2c997e..30d077420e6e9 100644 --- a/test/common/network/BUILD +++ b/test/common/network/BUILD @@ -55,7 +55,6 @@ envoy_cc_test( "//source/common/network:connection_lib", "//source/common/network:listen_socket_lib", "//source/common/network:utility_lib", - "//source/common/stats:stats_lib", "//test/mocks/buffer:buffer_mocks", "//test/mocks/event:event_mocks", "//test/mocks/network:network_mocks", @@ -82,7 +81,6 @@ envoy_cc_test( "//source/common/network:dns_lib", "//source/common/network:filter_lib", "//source/common/network:listen_socket_lib", - "//source/common/stats:stats_lib", "//test/mocks/network:network_mocks", "//test/test_common:environment_lib", "//test/test_common:network_utility_lib", @@ -150,7 +148,6 @@ envoy_cc_test( "//source/common/network:address_lib", "//source/common/network:listener_lib", "//source/common/network:utility_lib", - "//source/common/stats:stats_lib", "//test/mocks/network:network_mocks", "//test/mocks/server:server_mocks", "//test/test_common:environment_lib", @@ -167,7 +164,6 @@ envoy_cc_test( "//source/common/network:address_lib", "//source/common/network:listener_lib", "//source/common/network:utility_lib", - "//source/common/stats:stats_lib", "//test/mocks/network:network_mocks", "//test/mocks/server:server_mocks", "//test/test_common:environment_lib", diff --git a/test/common/network/connection_impl_test.cc b/test/common/network/connection_impl_test.cc index f00422b5125ca..ab378a59bf4f1 100644 --- a/test/common/network/connection_impl_test.cc +++ b/test/common/network/connection_impl_test.cc @@ -78,9 +78,8 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, ConnectionImplDeathTest, TestUtility::ipTestParamsToString); TEST_P(ConnectionImplDeathTest, BadFd) { - Stats::IsolatedStoreImpl stats_store; Event::SimulatedTimeSystem time_system; - Api::ApiPtr api = Api::createApiForTest(stats_store); + Api::ApiPtr api = Api::createApiForTest(); Event::DispatcherImpl dispatcher(*api); IoHandlePtr io_handle = std::make_unique(); EXPECT_DEATH_LOG_TO_STDERR( @@ -92,7 +91,7 @@ TEST_P(ConnectionImplDeathTest, BadFd) { class ConnectionImplTest : public TestBaseWithParam { public: - ConnectionImplTest() : api_(Api::createApiForTest(stats_store_)) {} + ConnectionImplTest() : api_(Api::createApiForTest()) {} void setUpBasicConnection() { if (dispatcher_.get() == nullptr) { @@ -208,7 +207,6 @@ class ConnectionImplTest : public TestBaseWithParam { Event::SimulatedTimeSystem time_system_; Event::DispatcherPtr dispatcher_; - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; Network::TcpListenSocket socket_{Network::Test::getAnyAddress(GetParam()), nullptr, true}; Network::MockListenerCallbacks listener_callbacks_; @@ -1645,9 +1643,8 @@ TEST_P(ReadBufferLimitTest, SomeLimit) { class TcpClientConnectionImplTest : public TestBaseWithParam { protected: - TcpClientConnectionImplTest() : api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_) {} + TcpClientConnectionImplTest() : api_(Api::createApiForTest()), dispatcher_(*api_) {} - Stats::IsolatedStoreImpl stats_store_; Event::SimulatedTimeSystem time_system_; Api::ApiPtr api_; Event::DispatcherImpl dispatcher_; @@ -1689,9 +1686,8 @@ TEST_P(TcpClientConnectionImplTest, BadConnectConnRefused) { class PipeClientConnectionImplTest : public TestBase { protected: - PipeClientConnectionImplTest() : api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_) {} + PipeClientConnectionImplTest() : api_(Api::createApiForTest()), dispatcher_(*api_) {} - Stats::IsolatedStoreImpl stats_store_; Event::SimulatedTimeSystem time_system_; Api::ApiPtr api_; Event::DispatcherImpl dispatcher_; diff --git a/test/common/network/dns_impl_test.cc b/test/common/network/dns_impl_test.cc index d5c0403d592d5..b03c4f0ba304b 100644 --- a/test/common/network/dns_impl_test.cc +++ b/test/common/network/dns_impl_test.cc @@ -324,9 +324,8 @@ class DnsResolverImplPeer { class DnsImplConstructor : public TestBase { protected: - DnsImplConstructor() : api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_) {} + DnsImplConstructor() : api_(Api::createApiForTest()), dispatcher_(*api_) {} - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; Event::DispatcherImpl dispatcher_; }; @@ -404,7 +403,7 @@ TEST_F(DnsImplConstructor, BadCustomResolvers) { class DnsImplTest : public TestBaseWithParam { public: - DnsImplTest() : api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_) {} + DnsImplTest() : api_(Api::createApiForTest()), dispatcher_(*api_) {} void SetUp() override { resolver_ = dispatcher_.createDnsResolver({}); @@ -434,7 +433,6 @@ class DnsImplTest : public TestBaseWithParam { std::unique_ptr peer_; Network::MockConnectionHandler connection_handler_; Network::TcpListenSocketPtr socket_; - Stats::IsolatedStoreImpl stats_store_; std::unique_ptr listener_; Api::ApiPtr api_; Event::DispatcherImpl dispatcher_; diff --git a/test/common/network/listener_impl_test.cc b/test/common/network/listener_impl_test.cc index 05592b2072e45..f752d16ce6b28 100644 --- a/test/common/network/listener_impl_test.cc +++ b/test/common/network/listener_impl_test.cc @@ -21,8 +21,7 @@ namespace Network { static void errorCallbackTest(Address::IpVersion version) { // Force the error callback to fire by closing the socket under the listener. We run this entire // test in the forked process to avoid confusion when the fork happens. - Stats::IsolatedStoreImpl stats_store; - Api::ApiPtr api = Api::createApiForTest(stats_store); + Api::ApiPtr api = Api::createApiForTest(); Event::DispatcherImpl dispatcher(*api); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version), nullptr, @@ -77,11 +76,10 @@ class ListenerImplTest : public TestBaseWithParam { : version_(GetParam()), alt_address_(Network::Test::findOrCheckFreePort( Network::Test::getCanonicalLoopbackAddress(version_), Address::SocketType::Stream)), - api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_) {} + api_(Api::createApiForTest()), dispatcher_(*api_) {} const Address::IpVersion version_; const Address::InstanceConstSharedPtr alt_address_; - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; Event::DispatcherImpl dispatcher_; }; @@ -121,7 +119,6 @@ TEST_P(ListenerImplTest, SetListeningSocketOptionsError) { } TEST_P(ListenerImplTest, UseActualDst) { - Stats::IsolatedStoreImpl stats_store; Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(version_), nullptr, true); Network::TcpListenSocket socketDst(alt_address_, nullptr, false); @@ -158,7 +155,6 @@ TEST_P(ListenerImplTest, UseActualDst) { } TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { - Stats::IsolatedStoreImpl stats_store; Network::TcpListenSocket socket(Network::Test::getAnyAddress(version_), nullptr, true); Network::MockListenerCallbacks listener_callbacks; Network::MockConnectionHandler connection_handler; @@ -196,7 +192,6 @@ TEST_P(ListenerImplTest, WildcardListenerUseActualDst) { // local and remote addresses of the connection should be IPv4 instances, as the connection really // is an IPv4 connection. TEST_P(ListenerImplTest, WildcardListenerIpv4Compat) { - Stats::IsolatedStoreImpl stats_store; auto option = std::make_unique(); auto options = std::make_shared>(); EXPECT_CALL(*option, setOption(_, envoy::api::v2::core::SocketOption::STATE_PREBIND)) diff --git a/test/common/network/udp_listener_impl_test.cc b/test/common/network/udp_listener_impl_test.cc index ae2639c7a6c56..990336736b3da 100644 --- a/test/common/network/udp_listener_impl_test.cc +++ b/test/common/network/udp_listener_impl_test.cc @@ -42,7 +42,7 @@ class UdpListenerImplTest : public TestBaseWithParam { : version_(GetParam()), alt_address_(Network::Test::findOrCheckFreePort( Network::Test::getCanonicalLoopbackAddress(version_), Address::SocketType::Stream)), - api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_) {} + api_(Api::createApiForTest()), dispatcher_(*api_) {} SocketPtr getSocket(Address::SocketType type, const Address::InstanceConstSharedPtr& address, const Network::Socket::OptionsSharedPtr& options, bool bind) { @@ -115,7 +115,6 @@ class UdpListenerImplTest : public TestBaseWithParam { const Address::IpVersion version_; const Address::InstanceConstSharedPtr alt_address_; - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; DangerousDeprecatedTestTime test_time_; Event::DispatcherImpl dispatcher_; diff --git a/test/common/protobuf/BUILD b/test/common/protobuf/BUILD index 54e44139d97c7..0b0a3534d225f 100644 --- a/test/common/protobuf/BUILD +++ b/test/common/protobuf/BUILD @@ -14,7 +14,6 @@ envoy_cc_test( srcs = ["utility_test.cc"], deps = [ "//source/common/protobuf:utility_lib", - "//source/common/stats:isolated_store_lib", "//test/proto:deprecated_proto_cc", "//test/test_common:environment_lib", "//test/test_common:logging_lib", diff --git a/test/common/protobuf/utility_test.cc b/test/common/protobuf/utility_test.cc index 1352ecd17910b..fb09d692b2721 100644 --- a/test/common/protobuf/utility_test.cc +++ b/test/common/protobuf/utility_test.cc @@ -5,7 +5,6 @@ #include "common/protobuf/protobuf.h" #include "common/protobuf/utility.h" -#include "common/stats/isolated_store_impl.h" #include "test/proto/deprecated.pb.h" #include "test/test_common/environment.h" @@ -17,9 +16,8 @@ namespace Envoy { class ProtobufUtilityTest : public TestBase { protected: - ProtobufUtilityTest() : api_(Api::createApiForTest(stats_store_)) {} + ProtobufUtilityTest() : api_(Api::createApiForTest()) {} - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; }; diff --git a/test/common/router/config_impl_test.cc b/test/common/router/config_impl_test.cc index 37926cb9518ad..25f0dc0a738f9 100644 --- a/test/common/router/config_impl_test.cc +++ b/test/common/router/config_impl_test.cc @@ -102,11 +102,10 @@ envoy::api::v2::RouteConfiguration parseRouteConfigurationFromV2Yaml(const std:: class ConfigImplTestBase { protected: - ConfigImplTestBase() : api_(Api::createApiForTest(stats_)) { + ConfigImplTestBase() : api_(Api::createApiForTest()) { ON_CALL(factory_context_, api()).WillByDefault(ReturnRef(*api_)); } - Stats::IsolatedStoreImpl stats_; Api::ApiPtr api_; NiceMock factory_context_; }; diff --git a/test/common/runtime/runtime_impl_test.cc b/test/common/runtime/runtime_impl_test.cc index aa99434d3bef4..3da8e7c89e63e 100644 --- a/test/common/runtime/runtime_impl_test.cc +++ b/test/common/runtime/runtime_impl_test.cc @@ -65,7 +65,7 @@ TEST(UUID, sanityCheckOfUniqueness) { class DiskBackedLoaderImplTest : public TestBase { protected: - DiskBackedLoaderImplTest() : api_(Api::createApiForTest(store)) {} + DiskBackedLoaderImplTest() : api_(Api::createApiForTest()) {} static void SetUpTestSuite() { TestEnvironment::exec( @@ -262,9 +262,8 @@ TEST(LoaderImplTest, All) { class DiskLayerTest : public TestBase { protected: - DiskLayerTest() : api_(Api::createApiForTest(store_)) {} + DiskLayerTest() : api_(Api::createApiForTest()) {} - Stats::IsolatedStoreImpl store_; Api::ApiPtr api_; }; diff --git a/test/common/secret/sds_api_test.cc b/test/common/secret/sds_api_test.cc index 39808f24d432d..d3bbdad07e7cb 100644 --- a/test/common/secret/sds_api_test.cc +++ b/test/common/secret/sds_api_test.cc @@ -28,9 +28,8 @@ namespace { class SdsApiTest : public TestBase { protected: - SdsApiTest() : api_(Api::createApiForTest(stats_store_)) {} + SdsApiTest() : api_(Api::createApiForTest()) {} - Stats::MockIsolatedStatsStore stats_store_; Api::ApiPtr api_; }; diff --git a/test/common/secret/secret_manager_impl_test.cc b/test/common/secret/secret_manager_impl_test.cc index 7b3aa38238f66..71c9ea1e94c36 100644 --- a/test/common/secret/secret_manager_impl_test.cc +++ b/test/common/secret/secret_manager_impl_test.cc @@ -24,9 +24,8 @@ namespace { class SecretManagerImplTest : public TestBase { protected: - SecretManagerImplTest() : api_(Api::createApiForTest(stats_store_)) {} + SecretManagerImplTest() : api_(Api::createApiForTest()) {} - Stats::MockIsolatedStatsStore stats_store_; Api::ApiPtr api_; }; diff --git a/test/common/stats/thread_local_store_speed_test.cc b/test/common/stats/thread_local_store_speed_test.cc index 8eddd256937de..d013e9a5f8f56 100644 --- a/test/common/stats/thread_local_store_speed_test.cc +++ b/test/common/stats/thread_local_store_speed_test.cc @@ -22,7 +22,7 @@ namespace Envoy { class ThreadLocalStorePerf { public: ThreadLocalStorePerf() - : store_(options_, heap_alloc_), api_(Api::createApiForTest(store_, time_system_)) { + : store_(options_, heap_alloc_), api_(Api::createApiForTest(time_system_)) { store_.setTagProducer(std::make_unique(stats_config_)); } diff --git a/test/common/thread_local/BUILD b/test/common/thread_local/BUILD index c1d95410e5ab9..ba4b9b894d1f8 100644 --- a/test/common/thread_local/BUILD +++ b/test/common/thread_local/BUILD @@ -14,7 +14,6 @@ envoy_cc_test( deps = [ "//source/common/api:api_lib", "//source/common/event:dispatcher_lib", - "//source/common/stats:isolated_store_lib", "//source/common/thread_local:thread_local_lib", "//test/mocks/event:event_mocks", ], diff --git a/test/common/thread_local/thread_local_impl_test.cc b/test/common/thread_local/thread_local_impl_test.cc index 99ff8eaa426cf..4641b84e79359 100644 --- a/test/common/thread_local/thread_local_impl_test.cc +++ b/test/common/thread_local/thread_local_impl_test.cc @@ -1,6 +1,5 @@ #include "common/common/thread.h" #include "common/event/dispatcher_impl.h" -#include "common/stats/isolated_store_impl.h" #include "common/thread_local/thread_local_impl.h" #include "test/mocks/event/mocks.h" @@ -116,8 +115,7 @@ TEST_F(ThreadLocalInstanceImplTest, RunOnAllThreads) { TEST(ThreadLocalInstanceImplDispatcherTest, Dispatcher) { InstanceImpl tls; - Stats::IsolatedStoreImpl stats_store; - Api::ApiPtr api = Api::createApiForTest(stats_store); + Api::ApiPtr api = Api::createApiForTest(); Event::DispatcherImpl main_dispatcher(*api); Event::DispatcherImpl thread_dispatcher(*api); diff --git a/test/common/upstream/cds_api_impl_test.cc b/test/common/upstream/cds_api_impl_test.cc index 205611fb88c52..f1d80262a22ee 100644 --- a/test/common/upstream/cds_api_impl_test.cc +++ b/test/common/upstream/cds_api_impl_test.cc @@ -28,7 +28,7 @@ namespace Upstream { class CdsApiImplTest : public TestBase { protected: - CdsApiImplTest() : request_(&cm_.async_client_), api_(Api::createApiForTest(store_)) {} + CdsApiImplTest() : request_(&cm_.async_client_), api_(Api::createApiForTest()) {} void setup() { const std::string config_json = R"EOF( diff --git a/test/common/upstream/cluster_manager_impl_test.cc b/test/common/upstream/cluster_manager_impl_test.cc index ade2b7b5e399e..ba5521cdfb791 100644 --- a/test/common/upstream/cluster_manager_impl_test.cc +++ b/test/common/upstream/cluster_manager_impl_test.cc @@ -56,7 +56,7 @@ namespace { // the expectations when needed. class TestClusterManagerFactory : public ClusterManagerFactory { public: - TestClusterManagerFactory() : api_(Api::createApiForTest(stats_)) { + TestClusterManagerFactory() : api_(Api::createApiForTest()) { ON_CALL(*this, clusterFromProto_(_, _, _, _)) .WillByDefault(Invoke([&](const envoy::api::v2::Cluster& cluster, ClusterManager& cm, Outlier::EventLoggerSharedPtr outlier_event_logger, @@ -165,7 +165,7 @@ envoy::config::bootstrap::v2::Bootstrap parseBootstrapFromV2Yaml(const std::stri class ClusterManagerImplTest : public TestBase { public: - ClusterManagerImplTest() : api_(Api::createApiForTest(stats_store_)) {} + ClusterManagerImplTest() : api_(Api::createApiForTest()) {} void create(const envoy::config::bootstrap::v2::Bootstrap& bootstrap) { cluster_manager_ = std::make_unique( @@ -239,7 +239,6 @@ class ClusterManagerImplTest : public TestBase { return metadata; } - Stats::IsolatedStoreImpl stats_store_; Event::SimulatedTimeSystem time_system_; Api::ApiPtr api_; NiceMock factory_; diff --git a/test/common/upstream/eds_test.cc b/test/common/upstream/eds_test.cc index be98cdf9f97eb..2dfc7a55cfba2 100644 --- a/test/common/upstream/eds_test.cc +++ b/test/common/upstream/eds_test.cc @@ -29,7 +29,7 @@ namespace Upstream { class EdsTest : public TestBase { protected: - EdsTest() : api_(Api::createApiForTest(stats_)) { resetCluster(); } + EdsTest() : api_(Api::createApiForTest()) { resetCluster(); } void resetCluster() { resetCluster(R"EOF( diff --git a/test/common/upstream/hds_test.cc b/test/common/upstream/hds_test.cc index fc39df03d8784..5e45002506ffe 100644 --- a/test/common/upstream/hds_test.cc +++ b/test/common/upstream/hds_test.cc @@ -46,7 +46,7 @@ class HdsTest : public TestBase { protected: HdsTest() : retry_timer_(new Event::MockTimer()), server_response_timer_(new Event::MockTimer()), - async_client_(new Grpc::MockAsyncClient()), api_(Api::createApiForTest(stats_store_)), + async_client_(new Grpc::MockAsyncClient()), api_(Api::createApiForTest()), ssl_context_manager_(api_->timeSystem()) { node_.set_id("hds-node"); } diff --git a/test/common/upstream/health_checker_impl_test.cc b/test/common/upstream/health_checker_impl_test.cc index 77cf92c352370..a0f506780a139 100644 --- a/test/common/upstream/health_checker_impl_test.cc +++ b/test/common/upstream/health_checker_impl_test.cc @@ -3507,7 +3507,7 @@ TEST(Printer, HealthTransitionPrinter) { TEST(HealthCheckEventLoggerImplTest, All) { AccessLog::MockAccessLogManager log_manager; - std::shared_ptr file(new Filesystem::MockFile()); + std::shared_ptr file(new AccessLog::MockAccessLogFile()); EXPECT_CALL(log_manager, createAccessLog("foo")).WillOnce(Return(file)); std::shared_ptr host(new NiceMock()); diff --git a/test/common/upstream/logical_dns_cluster_test.cc b/test/common/upstream/logical_dns_cluster_test.cc index 9d55f81d1e5ed..e336f2f0bd4e6 100644 --- a/test/common/upstream/logical_dns_cluster_test.cc +++ b/test/common/upstream/logical_dns_cluster_test.cc @@ -37,7 +37,7 @@ enum class ConfigType { V2_YAML, V1_JSON }; class LogicalDnsClusterTest : public TestBase { protected: - LogicalDnsClusterTest() : api_(Api::createApiForTest(stats_store_)) {} + LogicalDnsClusterTest() : api_(Api::createApiForTest()) {} void setupFromV1Json(const std::string& json) { resolve_timer_ = new Event::MockTimer(&dispatcher_); diff --git a/test/common/upstream/original_dst_cluster_test.cc b/test/common/upstream/original_dst_cluster_test.cc index f052e5d56a21b..f704ffaa9bfe2 100644 --- a/test/common/upstream/original_dst_cluster_test.cc +++ b/test/common/upstream/original_dst_cluster_test.cc @@ -63,8 +63,7 @@ class OriginalDstClusterTest : public TestBase { // on it. Ownership is transferred to the cluster at the cluster constructor, so the cluster will // take care of destructing it! OriginalDstClusterTest() - : cleanup_timer_(new Event::MockTimer(&dispatcher_)), - api_(Api::createApiForTest(stats_store_)) {} + : cleanup_timer_(new Event::MockTimer(&dispatcher_)), api_(Api::createApiForTest()) {} void setupFromJson(const std::string& json) { setup(parseClusterFromJson(json)); } void setupFromYaml(const std::string& yaml) { setup(parseClusterFromV2Yaml(yaml)); } diff --git a/test/common/upstream/outlier_detection_impl_test.cc b/test/common/upstream/outlier_detection_impl_test.cc index c55da17c86190..e2c3c664759e0 100644 --- a/test/common/upstream/outlier_detection_impl_test.cc +++ b/test/common/upstream/outlier_detection_impl_test.cc @@ -772,7 +772,7 @@ TEST(DetectorHostMonitorNullImplTest, All) { TEST(OutlierDetectionEventLoggerImplTest, All) { AccessLog::MockAccessLogManager log_manager; - std::shared_ptr file(new Filesystem::MockFile()); + std::shared_ptr file(new AccessLog::MockAccessLogFile()); NiceMock cluster; std::shared_ptr host(new NiceMock()); ON_CALL(*host, cluster()).WillByDefault(ReturnRef(cluster)); diff --git a/test/common/upstream/upstream_impl_test.cc b/test/common/upstream/upstream_impl_test.cc index a84e7b834b985..40d06d40b46f9 100644 --- a/test/common/upstream/upstream_impl_test.cc +++ b/test/common/upstream/upstream_impl_test.cc @@ -45,7 +45,7 @@ namespace { class UpstreamImplTestBase { protected: - UpstreamImplTestBase() : api_(Api::createApiForTest(stats_)) {} + UpstreamImplTestBase() : api_(Api::createApiForTest()) {} NiceMock admin_; Ssl::MockContextManager ssl_context_manager_; @@ -1534,7 +1534,7 @@ TEST(PrioritySet, Extend) { class ClusterInfoImplTest : public TestBase { public: - ClusterInfoImplTest() : api_(Api::createApiForTest(stats_)) {} + ClusterInfoImplTest() : api_(Api::createApiForTest()) {} std::unique_ptr makeCluster(const std::string& yaml) { cluster_config_ = parseClusterFromV2Yaml(yaml); diff --git a/test/config_test/config_test.cc b/test/config_test/config_test.cc index e9aab4f379564..db9aca85ca90c 100644 --- a/test/config_test/config_test.cc +++ b/test/config_test/config_test.cc @@ -43,8 +43,7 @@ OptionsImpl asConfigYaml(const OptionsImpl& src, Api::Api& api) { class ConfigTest { public: - ConfigTest(const OptionsImpl& options) - : api_(Api::createApiForTest(stats_store_)), options_(options) { + ConfigTest(const OptionsImpl& options) : api_(Api::createApiForTest()), options_(options) { ON_CALL(server_, options()).WillByDefault(ReturnRef(options_)); ON_CALL(server_, random()).WillByDefault(ReturnRef(random_)); ON_CALL(server_, sslContextManager()).WillByDefault(ReturnRef(ssl_context_manager_)); @@ -98,7 +97,6 @@ class ConfigTest { server_.thread_local_.shutdownThread(); } - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; NiceMock server_; NiceMock ssl_context_manager_; @@ -114,8 +112,7 @@ class ConfigTest { }; void testMerge() { - Stats::IsolatedStoreImpl stats; - Api::ApiPtr api = Api::createApiForTest(stats); + Api::ApiPtr api = Api::createApiForTest(); const std::string overlay = "static_resources: { clusters: [{name: 'foo'}]}"; OptionsImpl options(Server::createTestOptionsImpl("google_com_proxy.v2.yaml", overlay, @@ -127,8 +124,7 @@ void testMerge() { uint32_t run(const std::string& directory) { uint32_t num_tested = 0; - Stats::IsolatedStoreImpl stats; - Api::ApiPtr api = Api::createApiForTest(stats); + Api::ApiPtr api = Api::createApiForTest(); for (const std::string& filename : TestUtility::listFiles(directory, false)) { ENVOY_LOG_MISC(info, "testing {}.\n", filename); OptionsImpl options( diff --git a/test/exe/main_common_test.cc b/test/exe/main_common_test.cc index 0040171dbe53d..8428407025629 100644 --- a/test/exe/main_common_test.cc +++ b/test/exe/main_common_test.cc @@ -234,7 +234,7 @@ class AdminRequestTest : public MainCommonTest { TEST_P(AdminRequestTest, AdminRequestGetStatsAndQuit) { startEnvoy(); started_.WaitForNotification(); - EXPECT_THAT(adminRequest("/stats", "GET"), HasSubstr("filesystem.reopen_failed")); + EXPECT_THAT(adminRequest("/stats", "GET"), HasSubstr("access_log_file.reopen_failed")); adminRequest("/quitquitquit", "POST"); EXPECT_TRUE(waitForEnvoyToExit()); } @@ -244,7 +244,7 @@ TEST_P(AdminRequestTest, AdminRequestGetStatsAndQuit) { TEST_P(AdminRequestTest, AdminRequestGetStatsAndKill) { startEnvoy(); started_.WaitForNotification(); - EXPECT_THAT(adminRequest("/stats", "GET"), HasSubstr("filesystem.reopen_failed")); + EXPECT_THAT(adminRequest("/stats", "GET"), HasSubstr("access_log_file.reopen_failed")); kill(getpid(), SIGTERM); EXPECT_TRUE(waitForEnvoyToExit()); } @@ -254,7 +254,7 @@ TEST_P(AdminRequestTest, AdminRequestGetStatsAndKill) { TEST_P(AdminRequestTest, AdminRequestGetStatsAndCtrlC) { startEnvoy(); started_.WaitForNotification(); - EXPECT_THAT(adminRequest("/stats", "GET"), HasSubstr("filesystem.reopen_failed")); + EXPECT_THAT(adminRequest("/stats", "GET"), HasSubstr("access_log_file.reopen_failed")); kill(getpid(), SIGINT); EXPECT_TRUE(waitForEnvoyToExit()); } @@ -317,7 +317,7 @@ TEST_P(AdminRequestTest, AdminRequestBeforeRun) { EXPECT_TRUE(admin_handler_was_called); // This just checks that some stat output was reported. We could pick any stat. - EXPECT_THAT(out, HasSubstr("filesystem.reopen_failed")); + EXPECT_THAT(out, HasSubstr("access_log_file.reopen_failed")); } // Class to track whether an object has been destroyed, which it does by bumping an atomic. diff --git a/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc b/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc index f5ad48329deab..7ccf851a798a0 100644 --- a/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc +++ b/test/extensions/filters/http/grpc_json_transcoder/json_transcoder_filter_test.cc @@ -44,9 +44,8 @@ namespace GrpcJsonTranscoder { class GrpcJsonTranscoderFilterTestBase { protected: - GrpcJsonTranscoderFilterTestBase() : api_(Api::createApiForTest(stats_)) {} + GrpcJsonTranscoderFilterTestBase() : api_(Api::createApiForTest()) {} - Stats::IsolatedStoreImpl stats_; Api::ApiPtr api_; }; diff --git a/test/extensions/filters/http/jwt_authn/BUILD b/test/extensions/filters/http/jwt_authn/BUILD index b225c4510ed08..72e1d19767d20 100644 --- a/test/extensions/filters/http/jwt_authn/BUILD +++ b/test/extensions/filters/http/jwt_authn/BUILD @@ -66,7 +66,6 @@ envoy_extension_cc_test( srcs = ["jwks_cache_test.cc"], extension_name = "envoy.filters.http.jwt_authn", deps = [ - "//source/common/stats:isolated_store_lib", "//source/extensions/filters/http/common:jwks_fetcher_lib", "//source/extensions/filters/http/jwt_authn:jwks_cache_lib", "//test/extensions/filters/http/jwt_authn:test_common_lib", diff --git a/test/extensions/filters/http/jwt_authn/jwks_cache_test.cc b/test/extensions/filters/http/jwt_authn/jwks_cache_test.cc index 29ce11ed0cd6e..34fe5127ef500 100644 --- a/test/extensions/filters/http/jwt_authn/jwks_cache_test.cc +++ b/test/extensions/filters/http/jwt_authn/jwks_cache_test.cc @@ -2,7 +2,6 @@ #include #include "common/protobuf/utility.h" -#include "common/stats/isolated_store_impl.h" #include "extensions/filters/http/jwt_authn/jwks_cache.h" @@ -21,7 +20,7 @@ namespace { class JwksCacheTest : public TestBase { protected: - JwksCacheTest() : api_(Api::createApiForTest(stats_)) {} + JwksCacheTest() : api_(Api::createApiForTest()) {} void SetUp() override { MessageUtil::loadFromYaml(ExampleConfig, config_); cache_ = JwksCache::create(config_, time_system_, *api_); @@ -32,7 +31,6 @@ class JwksCacheTest : public TestBase { JwtAuthentication config_; JwksCachePtr cache_; google::jwt_verify::JwksPtr jwks_; - Stats::IsolatedStoreImpl stats_; Api::ApiPtr api_; }; diff --git a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc index cdb8d7c6c126b..8ce9c06e614e3 100644 --- a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc +++ b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc @@ -49,7 +49,7 @@ class ProxyProtocolTest : public TestBaseWithParam, protected Logger::Loggable { public: ProxyProtocolTest() - : api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_), + : api_(Api::createApiForTest()), dispatcher_(*api_), socket_(Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true), connection_handler_(new Server::ConnectionHandlerImpl(ENVOY_LOGGER(), dispatcher_)), name_("proxy"), filter_chain_(Network::Test::createEmptyFilterChainWithRawBufferSockets()) { @@ -869,7 +869,7 @@ class WildcardProxyProtocolTest : public TestBaseWithParam { public: WildcardProxyProtocolTest() - : api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_), + : api_(Api::createApiForTest()), dispatcher_(*api_), socket_(Network::Test::getAnyAddress(GetParam()), nullptr, true), local_dst_address_(Network::Utility::getAddressWithPort( *Network::Test::getCanonicalLoopbackAddress(GetParam()), diff --git a/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc b/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc index 2c6a78b380ac8..07ec3d59da43b 100644 --- a/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc +++ b/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc @@ -59,7 +59,7 @@ class ClientSslAuthFilterTest : public TestBase { protected: ClientSslAuthFilterTest() : request_(&cm_.async_client_), interval_timer_(new Event::MockTimer(&dispatcher_)), - api_(Api::createApiForTest(stats_store_)) {} + api_(Api::createApiForTest()) {} ~ClientSslAuthFilterTest() { tls_.shutdownThread(); } void setup() { diff --git a/test/extensions/filters/network/mongo_proxy/BUILD b/test/extensions/filters/network/mongo_proxy/BUILD index 21ada59634012..3eb1f8fa0cf9b 100644 --- a/test/extensions/filters/network/mongo_proxy/BUILD +++ b/test/extensions/filters/network/mongo_proxy/BUILD @@ -46,7 +46,6 @@ envoy_extension_cc_test( "//test/common/stream_info:test_util", "//test/mocks/access_log:access_log_mocks", "//test/mocks/event:event_mocks", - "//test/mocks/filesystem:filesystem_mocks", "//test/mocks/network:network_mocks", "//test/mocks/runtime:runtime_mocks", ], diff --git a/test/extensions/filters/network/mongo_proxy/proxy_test.cc b/test/extensions/filters/network/mongo_proxy/proxy_test.cc index 63dddf1a4194e..78e23ee74bd7c 100644 --- a/test/extensions/filters/network/mongo_proxy/proxy_test.cc +++ b/test/extensions/filters/network/mongo_proxy/proxy_test.cc @@ -14,7 +14,6 @@ #include "test/common/stream_info/test_util.h" #include "test/mocks/access_log/mocks.h" #include "test/mocks/event/mocks.h" -#include "test/mocks/filesystem/mocks.h" #include "test/mocks/network/mocks.h" #include "test/mocks/runtime/mocks.h" #include "test/test_common/printers.h" @@ -115,7 +114,8 @@ class MongoProxyFilterTest : public TestBase { NiceMock store_; NiceMock runtime_; NiceMock dispatcher_; - std::shared_ptr file_{new NiceMock()}; + std::shared_ptr file_{ + new NiceMock()}; AccessLogSharedPtr access_log_; FaultConfigSharedPtr fault_config_; std::unique_ptr filter_; diff --git a/test/extensions/resource_monitors/fixed_heap/BUILD b/test/extensions/resource_monitors/fixed_heap/BUILD index 9f2c70e726064..3d1c8eff0ab3b 100644 --- a/test/extensions/resource_monitors/fixed_heap/BUILD +++ b/test/extensions/resource_monitors/fixed_heap/BUILD @@ -27,7 +27,6 @@ envoy_extension_cc_test( extension_name = "envoy.resource_monitors.fixed_heap", deps = [ "//include/envoy/registry", - "//source/common/stats:isolated_store_lib", "//source/extensions/resource_monitors/fixed_heap:config", "//source/server:resource_monitor_config_lib", "//test/mocks/event:event_mocks", diff --git a/test/extensions/resource_monitors/fixed_heap/config_test.cc b/test/extensions/resource_monitors/fixed_heap/config_test.cc index edc9e54d44f68..1eeede7baccd1 100644 --- a/test/extensions/resource_monitors/fixed_heap/config_test.cc +++ b/test/extensions/resource_monitors/fixed_heap/config_test.cc @@ -1,8 +1,6 @@ #include "envoy/config/resource_monitor/fixed_heap/v2alpha/fixed_heap.pb.validate.h" #include "envoy/registry/registry.h" -#include "common/stats/isolated_store_impl.h" - #include "server/resource_monitor_config_impl.h" #include "extensions/resource_monitors/fixed_heap/config.h" @@ -24,8 +22,7 @@ TEST(FixedHeapMonitorFactoryTest, CreateMonitor) { envoy::config::resource_monitor::fixed_heap::v2alpha::FixedHeapConfig config; config.set_max_heap_size_bytes(std::numeric_limits::max()); Event::MockDispatcher dispatcher; - Stats::IsolatedStoreImpl stats_store; - Api::ApiPtr api = Api::createApiForTest(stats_store); + Api::ApiPtr api = Api::createApiForTest(); Server::Configuration::ResourceMonitorFactoryContextImpl context(dispatcher, *api); auto monitor = factory->createResourceMonitor(config, context); EXPECT_NE(monitor, nullptr); diff --git a/test/extensions/resource_monitors/injected_resource/BUILD b/test/extensions/resource_monitors/injected_resource/BUILD index 51e9ef57e5637..83458f439ae88 100644 --- a/test/extensions/resource_monitors/injected_resource/BUILD +++ b/test/extensions/resource_monitors/injected_resource/BUILD @@ -17,7 +17,6 @@ envoy_cc_test( srcs = ["injected_resource_monitor_test.cc"], deps = [ "//source/common/event:dispatcher_lib", - "//source/common/stats:isolated_store_lib", "//source/extensions/resource_monitors/injected_resource:injected_resource_monitor", "//source/server:resource_monitor_config_lib", "//test/test_common:environment_lib", @@ -32,7 +31,6 @@ envoy_extension_cc_test( deps = [ "//include/envoy/registry", "//source/common/event:dispatcher_lib", - "//source/common/stats:isolated_store_lib", "//source/extensions/resource_monitors/injected_resource:config", "//source/server:resource_monitor_config_lib", "//test/test_common:environment_lib", diff --git a/test/extensions/resource_monitors/injected_resource/config_test.cc b/test/extensions/resource_monitors/injected_resource/config_test.cc index c595ee80b80c3..3e80cf9b9c91c 100644 --- a/test/extensions/resource_monitors/injected_resource/config_test.cc +++ b/test/extensions/resource_monitors/injected_resource/config_test.cc @@ -2,7 +2,6 @@ #include "envoy/registry/registry.h" #include "common/event/dispatcher_impl.h" -#include "common/stats/isolated_store_impl.h" #include "server/resource_monitor_config_impl.h" @@ -25,8 +24,7 @@ TEST(InjectedResourceMonitorFactoryTest, CreateMonitor) { envoy::config::resource_monitor::injected_resource::v2alpha::InjectedResourceConfig config; config.set_filename(TestEnvironment::temporaryPath("injected_resource")); - Stats::IsolatedStoreImpl stats_store; - Api::ApiPtr api = Api::createApiForTest(stats_store); + Api::ApiPtr api = Api::createApiForTest(); Event::DispatcherImpl dispatcher(*api); Server::Configuration::ResourceMonitorFactoryContextImpl context(dispatcher, *api); Server::ResourceMonitorPtr monitor = factory->createResourceMonitor(config, context); diff --git a/test/extensions/resource_monitors/injected_resource/injected_resource_monitor_test.cc b/test/extensions/resource_monitors/injected_resource/injected_resource_monitor_test.cc index a173600bfff2d..689d60a119313 100644 --- a/test/extensions/resource_monitors/injected_resource/injected_resource_monitor_test.cc +++ b/test/extensions/resource_monitors/injected_resource/injected_resource_monitor_test.cc @@ -1,5 +1,4 @@ #include "common/event/dispatcher_impl.h" -#include "common/stats/isolated_store_impl.h" #include "server/resource_monitor_config_impl.h" @@ -45,7 +44,7 @@ class MockedCallbacks : public Server::ResourceMonitor::Callbacks { class InjectedResourceMonitorTest : public TestBase { protected: InjectedResourceMonitorTest() - : api_(Api::createApiForTest(stats_store_)), dispatcher_(*api_), + : api_(Api::createApiForTest()), dispatcher_(*api_), resource_filename_(TestEnvironment::temporaryPath("injected_resource")), file_updater_(resource_filename_), monitor_(createMonitor()) {} @@ -64,7 +63,6 @@ class InjectedResourceMonitorTest : public TestBase { return std::make_unique(config, context); } - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; Event::DispatcherImpl dispatcher_; const std::string resource_filename_; diff --git a/test/extensions/transport_sockets/tls/context_impl_test.cc b/test/extensions/transport_sockets/tls/context_impl_test.cc index bfa059bb2a290..5e7a5cd8ff4e8 100644 --- a/test/extensions/transport_sockets/tls/context_impl_test.cc +++ b/test/extensions/transport_sockets/tls/context_impl_test.cc @@ -38,6 +38,7 @@ class SslContextImplTest : public SslCertsTest { protected: Event::SimulatedTimeSystem time_system_; ContextManagerImpl manager_{time_system_}; + Stats::IsolatedStoreImpl store_; }; TEST_F(SslContextImplTest, TestdNSNameMatching) { diff --git a/test/extensions/transport_sockets/tls/ssl_certs_test.h b/test/extensions/transport_sockets/tls/ssl_certs_test.h index 339716fe92237..2675ca4e0c5a9 100644 --- a/test/extensions/transport_sockets/tls/ssl_certs_test.h +++ b/test/extensions/transport_sockets/tls/ssl_certs_test.h @@ -15,12 +15,11 @@ class SslCertsTest : public TestBase { } protected: - SslCertsTest() : api_(Api::createApiForTest(store_)) { + SslCertsTest() : api_(Api::createApiForTest()) { ON_CALL(factory_context_, api()).WillByDefault(ReturnRef(*api_)); } testing::NiceMock factory_context_; - Stats::IsolatedStoreImpl store_; Api::ApiPtr api_; }; } // namespace Envoy diff --git a/test/extensions/transport_sockets/tls/ssl_socket_test.cc b/test/extensions/transport_sockets/tls/ssl_socket_test.cc index 0be696fe23cad..689a2250c4682 100644 --- a/test/extensions/transport_sockets/tls/ssl_socket_test.cc +++ b/test/extensions/transport_sockets/tls/ssl_socket_test.cc @@ -172,22 +172,20 @@ class TestUtilOptions : public TestUtilOptionsBase { void testUtil(const TestUtilOptions& options) { Event::SimulatedTimeSystem time_system; - Stats::IsolatedStoreImpl server_stats_store; - Api::ApiPtr server_api = Api::createApiForTest(server_stats_store); - testing::NiceMock - server_factory_context; - ON_CALL(server_factory_context, api()).WillByDefault(ReturnRef(*server_api)); + Api::ApiPtr api = Api::createApiForTest(); + testing::NiceMock factory_context; + ON_CALL(factory_context, api()).WillByDefault(ReturnRef(*api)); envoy::api::v2::auth::DownstreamTlsContext server_tls_context; MessageUtil::loadFromYaml(TestEnvironment::substitute(options.serverCtxYaml()), server_tls_context); - auto server_cfg = - std::make_unique(server_tls_context, server_factory_context); + auto server_cfg = std::make_unique(server_tls_context, factory_context); ContextManagerImpl manager(*time_system); + Stats::IsolatedStoreImpl server_stats_store; ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, server_stats_store, std::vector{}); - Event::DispatcherImpl dispatcher(*server_api); + Event::DispatcherImpl dispatcher(*api); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(options.version()), nullptr, true); Network::MockListenerCallbacks callbacks; @@ -198,14 +196,8 @@ void testUtil(const TestUtilOptions& options) { MessageUtil::loadFromYaml(TestEnvironment::substitute(options.clientCtxYaml()), client_tls_context); + auto client_cfg = std::make_unique(client_tls_context, factory_context); Stats::IsolatedStoreImpl client_stats_store; - Api::ApiPtr client_api = Api::createApiForTest(client_stats_store); - testing::NiceMock - client_factory_context; - ON_CALL(client_factory_context, api()).WillByDefault(ReturnRef(*client_api)); - - auto client_cfg = - std::make_unique(client_tls_context, client_factory_context); ClientSslSocketFactory client_ssl_socket_factory(std::move(client_cfg), manager, client_stats_store); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( @@ -402,18 +394,18 @@ const std::string testUtilV2(const TestUtilOptionsV2& options) { const auto& filter_chain = options.listener().filter_chains(0); std::vector server_names(filter_chain.filter_chain_match().server_names().begin(), filter_chain.filter_chain_match().server_names().end()); - Stats::IsolatedStoreImpl server_stats_store; - Api::ApiPtr server_api = Api::createApiForTest(server_stats_store); - testing::NiceMock - server_factory_context; - ON_CALL(server_factory_context, api()).WillByDefault(ReturnRef(*server_api)); + Api::ApiPtr api = Api::createApiForTest(); + testing::NiceMock factory_context; + ON_CALL(factory_context, api()).WillByDefault(ReturnRef(*api)); + + Stats::IsolatedStoreImpl server_stats_store; auto server_cfg = - std::make_unique(filter_chain.tls_context(), server_factory_context); + std::make_unique(filter_chain.tls_context(), factory_context); ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, server_stats_store, server_names); - Event::DispatcherImpl dispatcher(*server_api); + Event::DispatcherImpl dispatcher(*api); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(options.version()), nullptr, true); NiceMock callbacks; @@ -421,13 +413,8 @@ const std::string testUtilV2(const TestUtilOptionsV2& options) { Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true, false); Stats::IsolatedStoreImpl client_stats_store; - Api::ApiPtr client_api = Api::createApiForTest(client_stats_store); - testing::NiceMock - client_factory_context; - ON_CALL(client_factory_context, api()).WillByDefault(ReturnRef(*client_api)); - auto client_cfg = - std::make_unique(options.clientCtxProto(), client_factory_context); + std::make_unique(options.clientCtxProto(), factory_context); ClientSslSocketFactory client_ssl_socket_factory(std::move(client_cfg), manager, client_stats_store); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( @@ -2105,21 +2092,20 @@ void testTicketSessionResumption(const std::string& server_ctx_yaml1, Event::SimulatedTimeSystem time_system; ContextManagerImpl manager(*time_system); - Stats::IsolatedStoreImpl server_stats_store; - Api::ApiPtr server_api = Api::createApiForTest(server_stats_store); - testing::NiceMock - server_factory_context; - ON_CALL(server_factory_context, api()).WillByDefault(ReturnRef(*server_api)); + Api::ApiPtr api = Api::createApiForTest(); + testing::NiceMock factory_context; + ON_CALL(factory_context, api()).WillByDefault(ReturnRef(*api)); envoy::api::v2::auth::DownstreamTlsContext server_tls_context1; MessageUtil::loadFromYaml(TestEnvironment::substitute(server_ctx_yaml1), server_tls_context1); auto server_cfg1 = - std::make_unique(server_tls_context1, server_factory_context); + std::make_unique(server_tls_context1, factory_context); envoy::api::v2::auth::DownstreamTlsContext server_tls_context2; MessageUtil::loadFromYaml(TestEnvironment::substitute(server_ctx_yaml2), server_tls_context2); auto server_cfg2 = - std::make_unique(server_tls_context2, server_factory_context); + std::make_unique(server_tls_context2, factory_context); + Stats::IsolatedStoreImpl server_stats_store; ServerSslSocketFactory server_ssl_socket_factory1(std::move(server_cfg1), manager, server_stats_store, server_names1); ServerSslSocketFactory server_ssl_socket_factory2(std::move(server_cfg2), manager, @@ -2131,7 +2117,7 @@ void testTicketSessionResumption(const std::string& server_ctx_yaml1, true); NiceMock callbacks; Network::MockConnectionHandler connection_handler; - Event::DispatcherImpl dispatcher(*server_api); + Event::DispatcherImpl dispatcher(*api); Network::ListenerPtr listener1 = dispatcher.createListener(socket1, callbacks, true, false); Network::ListenerPtr listener2 = dispatcher.createListener(socket2, callbacks, true, false); @@ -2139,13 +2125,7 @@ void testTicketSessionResumption(const std::string& server_ctx_yaml1, MessageUtil::loadFromYaml(TestEnvironment::substitute(client_ctx_yaml), client_tls_context); Stats::IsolatedStoreImpl client_stats_store; - Api::ApiPtr client_api = Api::createApiForTest(client_stats_store); - testing::NiceMock - client_factory_context; - ON_CALL(client_factory_context, api()).WillByDefault(ReturnRef(*client_api)); - - auto client_cfg = - std::make_unique(client_tls_context, client_factory_context); + auto client_cfg = std::make_unique(client_tls_context, factory_context); ClientSslSocketFactory ssl_socket_factory(std::move(client_cfg), manager, client_stats_store); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( socket1.localAddress(), Network::Address::InstanceConstSharedPtr(), @@ -2636,16 +2616,14 @@ void SslSocketTest::testClientSessionResumption(const std::string& server_ctx_ya ContextManagerImpl manager(time_system_); - Stats::IsolatedStoreImpl server_stats_store; - Api::ApiPtr server_api = Api::createApiForTest(server_stats_store); - testing::NiceMock - server_factory_context; - ON_CALL(server_factory_context, api()).WillByDefault(ReturnRef(*server_api)); + Api::ApiPtr api = Api::createApiForTest(); + testing::NiceMock factory_context; + ON_CALL(factory_context, api()).WillByDefault(ReturnRef(*api)); envoy::api::v2::auth::DownstreamTlsContext server_ctx_proto; MessageUtil::loadFromYaml(TestEnvironment::substitute(server_ctx_yaml), server_ctx_proto); - auto server_cfg = - std::make_unique(server_ctx_proto, server_factory_context); + auto server_cfg = std::make_unique(server_ctx_proto, factory_context); + Stats::IsolatedStoreImpl server_stats_store; ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, server_stats_store, std::vector{}); @@ -2653,8 +2631,7 @@ void SslSocketTest::testClientSessionResumption(const std::string& server_ctx_ya true); NiceMock callbacks; Network::MockConnectionHandler connection_handler; - Api::ApiPtr api = Api::createApiForTest(server_stats_store); - Event::DispatcherImpl dispatcher(*server_api); + Event::DispatcherImpl dispatcher(*api); Network::ListenerPtr listener = dispatcher.createListener(socket, callbacks, true, false); Network::ConnectionPtr server_connection; @@ -2663,14 +2640,8 @@ void SslSocketTest::testClientSessionResumption(const std::string& server_ctx_ya envoy::api::v2::auth::UpstreamTlsContext client_ctx_proto; MessageUtil::loadFromYaml(TestEnvironment::substitute(client_ctx_yaml), client_ctx_proto); + auto client_cfg = std::make_unique(client_ctx_proto, factory_context); Stats::IsolatedStoreImpl client_stats_store; - Api::ApiPtr client_api = Api::createApiForTest(client_stats_store); - testing::NiceMock - client_factory_context; - ON_CALL(client_factory_context, api()).WillByDefault(ReturnRef(*client_api)); - - auto client_cfg = - std::make_unique(client_ctx_proto, client_factory_context); ClientSslSocketFactory client_ssl_socket_factory(std::move(client_cfg), manager, client_stats_store); Network::ClientConnectionPtr client_connection = dispatcher.createClientConnection( diff --git a/test/integration/fake_upstream.cc b/test/integration/fake_upstream.cc index 2e9bc4786411b..afffccaf26aa0 100644 --- a/test/integration/fake_upstream.cc +++ b/test/integration/fake_upstream.cc @@ -372,9 +372,8 @@ FakeUpstream::FakeUpstream(Network::TransportSocketFactoryPtr&& transport_socket FakeUpstream::FakeUpstream(Network::TransportSocketFactoryPtr&& transport_socket_factory, Network::SocketPtr&& listen_socket, FakeHttpConnection::Type type, Event::TestTimeSystem& time_system, bool enable_half_close) - : http_type_(type), socket_(std::move(listen_socket)), - api_(Api::createApiForTest(stats_store_)), time_system_(time_system), - dispatcher_(api_->allocateDispatcher()), + : http_type_(type), socket_(std::move(listen_socket)), api_(Api::createApiForTest()), + time_system_(time_system), dispatcher_(api_->allocateDispatcher()), handler_(new Server::ConnectionHandlerImpl(ENVOY_LOGGER(), *dispatcher_)), allow_unexpected_disconnects_(false), enable_half_close_(enable_half_close), listener_(*this), filter_chain_(Network::Test::createEmptyFilterChain(std::move(transport_socket_factory))) { diff --git a/test/integration/integration.cc b/test/integration/integration.cc index 6147978f30887..26f1abf1ba693 100644 --- a/test/integration/integration.cc +++ b/test/integration/integration.cc @@ -228,8 +228,7 @@ void IntegrationTcpClient::ConnectionCallbacks::onEvent(Network::ConnectionEvent BaseIntegrationTest::BaseIntegrationTest(Network::Address::IpVersion version, const std::string& config) - : api_(Api::createApiForTest(stats_store_)), - mock_buffer_factory_(new NiceMock), + : api_(Api::createApiForTest()), mock_buffer_factory_(new NiceMock), dispatcher_( new Event::DispatcherImpl(Buffer::WatermarkFactoryPtr{mock_buffer_factory_}, *api_)), version_(version), config_helper_(version, *api_, config), diff --git a/test/integration/integration.h b/test/integration/integration.h index 15a77c66d0b67..f827d3753011f 100644 --- a/test/integration/integration.h +++ b/test/integration/integration.h @@ -179,7 +179,6 @@ class BaseIntegrationTest : Logger::Loggable { Event::TestTimeSystem& timeSystem() { return time_system_; } - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; MockBufferFactory* mock_buffer_factory_; // Will point to the dispatcher's factory. diff --git a/test/integration/utility.cc b/test/integration/utility.cc index f7d46289ceece..1579318572e04 100644 --- a/test/integration/utility.cc +++ b/test/integration/utility.cc @@ -60,10 +60,8 @@ IntegrationUtil::makeSingleRequest(const Network::Address::InstanceConstSharedPt const std::string& body, Http::CodecClient::Type type, const std::string& host, const std::string& content_type) { - NiceMock mock_stats_store; Event::GlobalTimeSystem time_system; - Api::Impl api(std::chrono::milliseconds(9000), Thread::threadFactoryForTest(), mock_stats_store, - time_system); + Api::Impl api(Thread::threadFactoryForTest(), time_system); Event::DispatcherPtr dispatcher(api.allocateDispatcher()); std::shared_ptr cluster{new NiceMock()}; Upstream::HostDescriptionConstSharedPtr host_description{ @@ -111,7 +109,7 @@ IntegrationUtil::makeSingleRequest(uint32_t port, const std::string& method, con RawConnectionDriver::RawConnectionDriver(uint32_t port, Buffer::Instance& initial_data, ReadCallback data_callback, Network::Address::IpVersion version) { - api_ = Api::createApiForTest(stats_store_); + api_ = Api::createApiForTest(); Event::GlobalTimeSystem time_system; dispatcher_ = api_->allocateDispatcher(); callbacks_ = std::make_unique(); diff --git a/test/server/config_validation/BUILD b/test/server/config_validation/BUILD index a1e274b2ebd9b..1cf2f27f45b8a 100644 --- a/test/server/config_validation/BUILD +++ b/test/server/config_validation/BUILD @@ -72,7 +72,6 @@ envoy_cc_test( srcs = ["dispatcher_test.cc"], deps = [ "//source/common/event:libevent_lib", - "//source/common/stats:isolated_store_lib", "//source/server/config_validation:api_lib", "//source/server/config_validation:dns_lib", "//test/test_common:environment_lib", diff --git a/test/server/config_validation/async_client_test.cc b/test/server/config_validation/async_client_test.cc index dceb4dafafb3e..21ef295efacc2 100644 --- a/test/server/config_validation/async_client_test.cc +++ b/test/server/config_validation/async_client_test.cc @@ -15,8 +15,7 @@ TEST(ValidationAsyncClientTest, MockedMethods) { MockAsyncClientCallbacks callbacks; MockAsyncClientStreamCallbacks stream_callbacks; - Stats::IsolatedStoreImpl stats_store; - Api::ApiPtr api = Api::createApiForTest(stats_store); + Api::ApiPtr api = Api::createApiForTest(); ValidationAsyncClient client(*api); EXPECT_EQ(nullptr, client.send(std::move(message), callbacks, AsyncClient::RequestOptions())); EXPECT_EQ(nullptr, client.start(stream_callbacks, AsyncClient::StreamOptions())); diff --git a/test/server/config_validation/cluster_manager_test.cc b/test/server/config_validation/cluster_manager_test.cc index 3b976a80f8271..8f6dd6ef3a1cf 100644 --- a/test/server/config_validation/cluster_manager_test.cc +++ b/test/server/config_validation/cluster_manager_test.cc @@ -26,7 +26,7 @@ namespace Upstream { TEST(ValidationClusterManagerTest, MockedMethods) { Stats::IsolatedStoreImpl stats_store; - Api::ApiPtr api(Api::createApiForTest(stats_store)); + Api::ApiPtr api(Api::createApiForTest()); NiceMock runtime; NiceMock tls; NiceMock random; diff --git a/test/server/config_validation/dispatcher_test.cc b/test/server/config_validation/dispatcher_test.cc index db5e41dfcce5f..8c2bce323f1a8 100644 --- a/test/server/config_validation/dispatcher_test.cc +++ b/test/server/config_validation/dispatcher_test.cc @@ -5,7 +5,6 @@ #include "common/event/libevent.h" #include "common/network/address_impl.h" #include "common/network/utility.h" -#include "common/stats/isolated_store_impl.h" #include "server/config_validation/api.h" @@ -24,15 +23,13 @@ class ConfigValidation : public TestBaseWithParam { ConfigValidation() { Event::Libevent::Global::initialize(); - validation_ = std::make_unique(std::chrono::milliseconds(1000), - Thread::threadFactoryForTest(), - stats_store_, test_time_.timeSystem()); + validation_ = std::make_unique(Thread::threadFactoryForTest(), + test_time_.timeSystem()); dispatcher_ = validation_->allocateDispatcher(); } DangerousDeprecatedTestTime test_time_; Event::DispatcherPtr dispatcher_; - Stats::IsolatedStoreImpl stats_store_; private: // Using config validation API. diff --git a/test/server/configuration_impl_test.cc b/test/server/configuration_impl_test.cc index 2b6b6217bee9b..5a566b52271f7 100644 --- a/test/server/configuration_impl_test.cc +++ b/test/server/configuration_impl_test.cc @@ -53,14 +53,13 @@ TEST(FilterChainUtility, buildFilterChainFailWithBadFilters) { class ConfigurationImplTest : public TestBase { protected: ConfigurationImplTest() - : api_(Api::createApiForTest(stats_store_)), + : api_(Api::createApiForTest()), cluster_manager_factory_( server_.admin(), server_.runtime(), server_.stats(), server_.threadLocal(), server_.random(), server_.dnsResolver(), server_.sslContextManager(), server_.dispatcher(), server_.localInfo(), server_.secretManager(), *api_, server_.httpContext(), server_.accessLogManager(), server_.singletonManager()) {} - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; NiceMock server_; Upstream::ProdClusterManagerFactory cluster_manager_factory_; diff --git a/test/server/guarddog_impl_test.cc b/test/server/guarddog_impl_test.cc index c61ac7946f347..30e6bc4226974 100644 --- a/test/server/guarddog_impl_test.cc +++ b/test/server/guarddog_impl_test.cc @@ -26,10 +26,9 @@ namespace Server { class GuardDogTestBase : public TestBase { protected: - GuardDogTestBase() : api_(Api::createApiForTest(stats_store_, time_system_)) {} + GuardDogTestBase() : api_(Api::createApiForTest(time_system_)) {} Event::SimulatedTimeSystem time_system_; - Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; }; diff --git a/test/server/lds_api_test.cc b/test/server/lds_api_test.cc index 73a092984c555..66080bec0e017 100644 --- a/test/server/lds_api_test.cc +++ b/test/server/lds_api_test.cc @@ -24,7 +24,7 @@ namespace Server { class LdsApiTest : public TestBase { public: - LdsApiTest() : request_(&cluster_manager_.async_client_), api_(Api::createApiForTest(store_)) {} + LdsApiTest() : request_(&cluster_manager_.async_client_), api_(Api::createApiForTest()) {} void setup() { const std::string config_json = R"EOF( diff --git a/test/server/listener_manager_impl_test.cc b/test/server/listener_manager_impl_test.cc index 616b29e36a53c..e2006ec2b127a 100644 --- a/test/server/listener_manager_impl_test.cc +++ b/test/server/listener_manager_impl_test.cc @@ -57,7 +57,7 @@ class ListenerHandle { class ListenerManagerImplTest : public TestBase { protected: - ListenerManagerImplTest() : api_(Api::createApiForTest(stats_)) { + ListenerManagerImplTest() : api_(Api::createApiForTest()) { ON_CALL(server_, api()).WillByDefault(ReturnRef(*api_)); EXPECT_CALL(worker_factory_, createWorker_()).WillOnce(Return(worker_)); manager_ = std::make_unique(server_, listener_factory_, worker_factory_); @@ -122,7 +122,6 @@ class ListenerManagerImplTest : public TestBase { std::unique_ptr manager_; NiceMock guard_dog_; Event::SimulatedTimeSystem time_system_; - Stats::IsolatedStoreImpl stats_; Api::ApiPtr api_; }; diff --git a/test/server/overload_manager_impl_test.cc b/test/server/overload_manager_impl_test.cc index f79598a43ec24..24ef2dca65ba9 100644 --- a/test/server/overload_manager_impl_test.cc +++ b/test/server/overload_manager_impl_test.cc @@ -74,7 +74,7 @@ class OverloadManagerImplTest : public TestBase { OverloadManagerImplTest() : factory1_("envoy.resource_monitors.fake_resource1"), factory2_("envoy.resource_monitors.fake_resource2"), register_factory1_(factory1_), - register_factory2_(factory2_), api_(Api::createApiForTest(stats_)) {} + register_factory2_(factory2_), api_(Api::createApiForTest()) {} void setDispatcherExpectation() { timer_ = new NiceMock(); diff --git a/test/server/worker_impl_test.cc b/test/server/worker_impl_test.cc index 06775542ab02d..dd56ad2317a82 100644 --- a/test/server/worker_impl_test.cc +++ b/test/server/worker_impl_test.cc @@ -22,13 +22,12 @@ namespace Server { class WorkerImplTest : public TestBase { public: - WorkerImplTest() : api_(Api::createApiForTest(stats_store_)) { + WorkerImplTest() : api_(Api::createApiForTest()) { // In the real worker the watchdog has timers that prevent exit. Here we need to prevent event // loop exit since we use mock timers. no_exit_timer_->enableTimer(std::chrono::hours(1)); } - Stats::IsolatedStoreImpl stats_store_; NiceMock tls_; Network::MockConnectionHandler* handler_ = new Network::MockConnectionHandler(); NiceMock guard_dog_; diff --git a/test/tools/router_check/router.cc b/test/tools/router_check/router.cc index 8f4cf575b5e97..0178ab4943500 100644 --- a/test/tools/router_check/router.cc +++ b/test/tools/router_check/router.cc @@ -44,23 +44,20 @@ ToolConfig::ToolConfig(std::unique_ptr headers, int ran RouterCheckTool RouterCheckTool::create(const std::string& router_config_file) { // TODO(hennna): Allow users to load a full config and extract the route configuration from it. envoy::api::v2::RouteConfiguration route_config; - auto stats = std::make_unique(); - auto api = Api::createApiForTest(*stats); + Api::ApiPtr api = Api::createApiForTest(); MessageUtil::loadFromFile(router_config_file, route_config, *api); auto factory_context = std::make_unique>(); auto config = std::make_unique(route_config, *factory_context, false); - return RouterCheckTool(std::move(factory_context), std::move(config), std::move(stats), - std::move(api)); + return RouterCheckTool(std::move(factory_context), std::move(config), std::move(api)); } RouterCheckTool::RouterCheckTool( std::unique_ptr> factory_context, - std::unique_ptr config, std::unique_ptr stats, - Api::ApiPtr api) + std::unique_ptr config, Api::ApiPtr api) : factory_context_(std::move(factory_context)), config_(std::move(config)), - stats_(std::move(stats)), api_(std::move(api)) {} + api_(std::move(api)) {} bool RouterCheckTool::compareEntriesInJson(const std::string& expected_route_json) { Json::ObjectSharedPtr loader = Json::Factory::loadFromFile(expected_route_json, *api_); diff --git a/test/tools/router_check/router.h b/test/tools/router_check/router.h index 64283e11cd57a..f2d849db025aa 100644 --- a/test/tools/router_check/router.h +++ b/test/tools/router_check/router.h @@ -67,8 +67,7 @@ class RouterCheckTool : Logger::Loggable { private: RouterCheckTool( std::unique_ptr> factory_context, - std::unique_ptr config, std::unique_ptr stats, - Api::ApiPtr api); + std::unique_ptr config, Api::ApiPtr api); bool compareCluster(ToolConfig& tool_config, const std::string& expected); bool compareVirtualCluster(ToolConfig& tool_config, const std::string& expected); @@ -95,7 +94,6 @@ class RouterCheckTool : Logger::Loggable { // TODO(hennna): Switch away from mocks following work done by @rlazarus in github issue #499. std::unique_ptr> factory_context_; std::unique_ptr config_; - std::unique_ptr stats_; Api::ApiPtr api_; }; } // namespace Envoy diff --git a/test/tools/schema_validator/validator.h b/test/tools/schema_validator/validator.h index abcee1069940b..ed50d676fe1f3 100644 --- a/test/tools/schema_validator/validator.h +++ b/test/tools/schema_validator/validator.h @@ -58,7 +58,7 @@ class Options { */ class Validator { public: - Validator() : api_(Api::createApiForTest(stats_)) {} + Validator() : api_(Api::createApiForTest()) {} /** * Validates the JSON at config_path against schema_type. * An EnvoyException is thrown in several cases: @@ -70,7 +70,6 @@ class Validator { void validate(const std::string& json_path, Schema::Type schema_type); private: - Stats::IsolatedStoreImpl stats_; Api::ApiPtr api_; }; diff --git a/tools/BUILD b/tools/BUILD index e504a8889e703..d3c3e8c19cbb6 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -31,7 +31,6 @@ envoy_cc_binary( deps = [ "//source/common/api:api_lib", "//source/common/common:assert_lib", - "//source/common/stats:isolated_store_lib", "//source/common/protobuf:utility_lib", "@envoy_api//envoy/config/bootstrap/v2:bootstrap_cc", ] + envoy_cc_platform_dep("//source/exe:platform_impl_lib"), @@ -46,7 +45,6 @@ envoy_cc_binary( "//source/common/json:json_loader_lib", "//source/common/protobuf:utility_lib", "//source/common/stats:stats_options_lib", - "//source/common/stats:isolated_store_lib", "@envoy_api//envoy/config/bootstrap/v2:bootstrap_cc", ] + envoy_cc_platform_dep("//source/exe:platform_impl_lib"), ) diff --git a/tools/bootstrap2pb.cc b/tools/bootstrap2pb.cc index 8b298b3da8c49..951a3122b9cc5 100644 --- a/tools/bootstrap2pb.cc +++ b/tools/bootstrap2pb.cc @@ -15,7 +15,6 @@ #include "common/common/assert.h" #include "common/event/real_time_system.h" #include "common/protobuf/utility.h" -#include "common/stats/isolated_store_impl.h" #include "exe/platform_impl.h" @@ -28,10 +27,8 @@ int main(int argc, char** argv) { } Envoy::PlatformImpl platform_impl_; - Envoy::Stats::IsolatedStoreImpl stats_store; Envoy::Event::RealTimeSystem time_system; // NO_CHECK_FORMAT(real_time) - Envoy::Api::Impl api(std::chrono::milliseconds(1000), platform_impl_.threadFactory(), stats_store, - time_system); + Envoy::Api::Impl api(platform_impl_.threadFactory(), time_system); envoy::config::bootstrap::v2::Bootstrap bootstrap; Envoy::MessageUtil::loadFromFile(argv[1], bootstrap, api); diff --git a/tools/v1_to_bootstrap.cc b/tools/v1_to_bootstrap.cc index 48f8861552898..7174b3338dfd1 100644 --- a/tools/v1_to_bootstrap.cc +++ b/tools/v1_to_bootstrap.cc @@ -15,7 +15,6 @@ #include "common/event/real_time_system.h" #include "common/json/json_loader.h" #include "common/protobuf/utility.h" -#include "common/stats/isolated_store_impl.h" #include "common/stats/stats_options_impl.h" #include "exe/platform_impl.h" @@ -28,10 +27,8 @@ int main(int argc, char** argv) { } Envoy::PlatformImpl platform_impl_; - Envoy::Stats::IsolatedStoreImpl stats_store; Envoy::Event::RealTimeSystem time_system; // NO_CHECK_FORMAT(real_time) - Envoy::Api::Impl api(std::chrono::milliseconds(1000), platform_impl_.threadFactory(), stats_store, - time_system); + Envoy::Api::Impl api(platform_impl_.threadFactory(), time_system); envoy::config::bootstrap::v2::Bootstrap bootstrap; auto config_json = Envoy::Json::Factory::loadFromFile(argv[1], api); From 05862aac0f68d22ae32b33d7353f75f423cabf0a Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Mon, 11 Feb 2019 08:47:35 -0500 Subject: [PATCH 10/13] update todo Signed-off-by: Sam Smith --- include/envoy/filesystem/filesystem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/envoy/filesystem/filesystem.h b/include/envoy/filesystem/filesystem.h index 938d16df8fd76..194a5a6376600 100644 --- a/include/envoy/filesystem/filesystem.h +++ b/include/envoy/filesystem/filesystem.h @@ -53,7 +53,7 @@ class File { /** * @return string a human-readable string describing the error code - * TODO(sesmith177) Abstract this method so it isn't dependant on integer error codes + * TODO(sesmith177) Use the IOError class after #5829 merges */ virtual std::string errorToString(int error) PURE; }; From 1b62da44b64e81948c325b1dc8d6967f44562ac6 Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Mon, 11 Feb 2019 11:12:55 -0500 Subject: [PATCH 11/13] add Stats::Store& back to Api ctor Signed-off-by: Sam Smith Signed-off-by: Arjun Sreedharan --- source/common/api/api_impl.cc | 2 +- source/common/api/api_impl.h | 2 +- source/server/config_validation/api.cc | 4 ++-- source/server/config_validation/api.h | 3 ++- source/server/config_validation/server.cc | 2 +- source/server/server.cc | 2 +- test/integration/utility.cc | 4 ++-- test/server/config_validation/dispatcher_test.cc | 4 +++- test/test_common/utility.cc | 9 ++++++--- tools/BUILD | 2 ++ tools/bootstrap2pb.cc | 4 +++- tools/v1_to_bootstrap.cc | 4 +++- 12 files changed, 27 insertions(+), 15 deletions(-) diff --git a/source/common/api/api_impl.cc b/source/common/api/api_impl.cc index ee4feb56b4f15..e3417452612cf 100644 --- a/source/common/api/api_impl.cc +++ b/source/common/api/api_impl.cc @@ -9,7 +9,7 @@ namespace Envoy { namespace Api { -Impl::Impl(Thread::ThreadFactory& thread_factory, Event::TimeSystem& time_system) +Impl::Impl(Thread::ThreadFactory& thread_factory, Stats::Store&, Event::TimeSystem& time_system) : thread_factory_(thread_factory), time_system_(time_system) {} Event::DispatcherPtr Impl::allocateDispatcher() { diff --git a/source/common/api/api_impl.h b/source/common/api/api_impl.h index 0fcf7076e8307..a6a3de0c1b9dd 100644 --- a/source/common/api/api_impl.h +++ b/source/common/api/api_impl.h @@ -18,7 +18,7 @@ namespace Api { */ class Impl : public Api { public: - Impl(Thread::ThreadFactory& thread_factory, Event::TimeSystem& time_system); + Impl(Thread::ThreadFactory& thread_factory, Stats::Store&, Event::TimeSystem& time_system); // Api::Api Event::DispatcherPtr allocateDispatcher() override; diff --git a/source/server/config_validation/api.cc b/source/server/config_validation/api.cc index becc0eb9da58f..73c4ccebcc37c 100644 --- a/source/server/config_validation/api.cc +++ b/source/server/config_validation/api.cc @@ -5,9 +5,9 @@ namespace Envoy { namespace Api { -ValidationImpl::ValidationImpl(Thread::ThreadFactory& thread_factory, +ValidationImpl::ValidationImpl(Thread::ThreadFactory& thread_factory, Stats::Store& stats_store, Event::TimeSystem& time_system) - : Impl(thread_factory, time_system) {} + : Impl(thread_factory, stats_store, time_system) {} Event::DispatcherPtr ValidationImpl::allocateDispatcher() { return Event::DispatcherPtr{new Event::ValidationDispatcher(*this)}; diff --git a/source/server/config_validation/api.h b/source/server/config_validation/api.h index 375d2ec0d6917..93efece33486e 100644 --- a/source/server/config_validation/api.h +++ b/source/server/config_validation/api.h @@ -15,7 +15,8 @@ namespace Api { */ class ValidationImpl : public Impl { public: - ValidationImpl(Thread::ThreadFactory& thread_factory, Event::TimeSystem& time_system); + ValidationImpl(Thread::ThreadFactory& thread_factory, Stats::Store& stats_store, + Event::TimeSystem& time_system); Event::DispatcherPtr allocateDispatcher() override; }; diff --git a/source/server/config_validation/server.cc b/source/server/config_validation/server.cc index e5f7e79720874..9e13ab37d59d3 100644 --- a/source/server/config_validation/server.cc +++ b/source/server/config_validation/server.cc @@ -41,7 +41,7 @@ ValidationInstance::ValidationInstance(const Options& options, Event::TimeSystem ComponentFactory& component_factory, Thread::ThreadFactory& thread_factory) : options_(options), stats_store_(store), - api_(new Api::ValidationImpl(thread_factory, time_system)), + api_(new Api::ValidationImpl(thread_factory, store, time_system)), dispatcher_(api_->allocateDispatcher()), singleton_manager_(new Singleton::ManagerImpl(api_->threadFactory().currentThreadId())), access_log_manager_(options.fileFlushIntervalMsec(), *api_, *dispatcher_, access_log_lock, diff --git a/source/server/server.cc b/source/server/server.cc index 13b9fc6496f76..91b7ab47553e6 100644 --- a/source/server/server.cc +++ b/source/server/server.cc @@ -54,7 +54,7 @@ InstanceImpl::InstanceImpl(const Options& options, Event::TimeSystem& time_syste ThreadLocal::Instance& tls, Thread::ThreadFactory& thread_factory) : shutdown_(false), options_(options), time_source_(time_system), restarter_(restarter), start_time_(time(nullptr)), original_start_time_(start_time_), stats_store_(store), - thread_local_(tls), api_(new Api::Impl(thread_factory, time_system)), + thread_local_(tls), api_(new Api::Impl(thread_factory, store, time_system)), secret_manager_(std::make_unique()), dispatcher_(api_->allocateDispatcher()), singleton_manager_(new Singleton::ManagerImpl(api_->threadFactory().currentThreadId())), diff --git a/test/integration/utility.cc b/test/integration/utility.cc index 1579318572e04..b9b3758fc4e0a 100644 --- a/test/integration/utility.cc +++ b/test/integration/utility.cc @@ -61,8 +61,8 @@ IntegrationUtil::makeSingleRequest(const Network::Address::InstanceConstSharedPt const std::string& host, const std::string& content_type) { Event::GlobalTimeSystem time_system; - Api::Impl api(Thread::threadFactoryForTest(), time_system); - Event::DispatcherPtr dispatcher(api.allocateDispatcher()); + Api::ApiPtr api = Api::createApiForTest(time_system); + Event::DispatcherPtr dispatcher(api->allocateDispatcher()); std::shared_ptr cluster{new NiceMock()}; Upstream::HostDescriptionConstSharedPtr host_description{ Upstream::makeTestHostDescription(cluster, "tcp://127.0.0.1:80")}; diff --git a/test/server/config_validation/dispatcher_test.cc b/test/server/config_validation/dispatcher_test.cc index 8c2bce323f1a8..0698f3d49337a 100644 --- a/test/server/config_validation/dispatcher_test.cc +++ b/test/server/config_validation/dispatcher_test.cc @@ -8,6 +8,7 @@ #include "server/config_validation/api.h" +#include "test/mocks/stats/mocks.h" #include "test/test_common/environment.h" #include "test/test_common/network_utility.h" #include "test/test_common/test_time.h" @@ -24,10 +25,11 @@ class ConfigValidation : public TestBaseWithParam { Event::Libevent::Global::initialize(); validation_ = std::make_unique(Thread::threadFactoryForTest(), - test_time_.timeSystem()); + stats_store_, test_time_.timeSystem()); dispatcher_ = validation_->allocateDispatcher(); } + testing::NiceMock stats_store_; DangerousDeprecatedTestTime test_time_; Event::DispatcherPtr dispatcher_; diff --git a/test/test_common/utility.cc b/test/test_common/utility.cc index dc602c5d9b555..adb0583dd68ab 100644 --- a/test/test_common/utility.cc +++ b/test/test_common/utility.cc @@ -405,17 +405,20 @@ namespace Api { class TestImplProvider { protected: Event::GlobalTimeSystem global_time_system_; + testing::NiceMock default_stats_store_; }; class TestImpl : public TestImplProvider, public Impl { public: - TestImpl(Thread::ThreadFactory& thread_factory) : Impl(thread_factory, global_time_system_) {} + TestImpl() : Impl(Thread::threadFactoryForTest(), default_stats_store_, global_time_system_) {} + TestImpl(Event::TimeSystem& time_system) + : Impl(Thread::threadFactoryForTest(), default_stats_store_, time_system) {} }; -ApiPtr createApiForTest() { return std::make_unique(Thread::threadFactoryForTest()); } +ApiPtr createApiForTest() { return std::make_unique(); } ApiPtr createApiForTest(Event::TimeSystem& time_system) { - return std::make_unique(Thread::threadFactoryForTest(), time_system); + return std::make_unique(time_system); } } // namespace Api diff --git a/tools/BUILD b/tools/BUILD index d3c3e8c19cbb6..ab8452c075a78 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -32,6 +32,7 @@ envoy_cc_binary( "//source/common/api:api_lib", "//source/common/common:assert_lib", "//source/common/protobuf:utility_lib", + "//source/common/stats:isolated_store_lib", "@envoy_api//envoy/config/bootstrap/v2:bootstrap_cc", ] + envoy_cc_platform_dep("//source/exe:platform_impl_lib"), ) @@ -44,6 +45,7 @@ envoy_cc_binary( "//source/common/config:bootstrap_json_lib", "//source/common/json:json_loader_lib", "//source/common/protobuf:utility_lib", + "//source/common/stats:isolated_store_lib", "//source/common/stats:stats_options_lib", "@envoy_api//envoy/config/bootstrap/v2:bootstrap_cc", ] + envoy_cc_platform_dep("//source/exe:platform_impl_lib"), diff --git a/tools/bootstrap2pb.cc b/tools/bootstrap2pb.cc index 951a3122b9cc5..6ca6eee145d5e 100644 --- a/tools/bootstrap2pb.cc +++ b/tools/bootstrap2pb.cc @@ -15,6 +15,7 @@ #include "common/common/assert.h" #include "common/event/real_time_system.h" #include "common/protobuf/utility.h" +#include "common/stats/isolated_store_impl.h" #include "exe/platform_impl.h" @@ -27,8 +28,9 @@ int main(int argc, char** argv) { } Envoy::PlatformImpl platform_impl_; + Envoy::Stats::IsolatedStoreImpl stats_store; Envoy::Event::RealTimeSystem time_system; // NO_CHECK_FORMAT(real_time) - Envoy::Api::Impl api(platform_impl_.threadFactory(), time_system); + Envoy::Api::Impl api(platform_impl_.threadFactory(), stats_store, time_system); envoy::config::bootstrap::v2::Bootstrap bootstrap; Envoy::MessageUtil::loadFromFile(argv[1], bootstrap, api); diff --git a/tools/v1_to_bootstrap.cc b/tools/v1_to_bootstrap.cc index 7174b3338dfd1..76a2cecaf4e8f 100644 --- a/tools/v1_to_bootstrap.cc +++ b/tools/v1_to_bootstrap.cc @@ -15,6 +15,7 @@ #include "common/event/real_time_system.h" #include "common/json/json_loader.h" #include "common/protobuf/utility.h" +#include "common/stats/isolated_store_impl.h" #include "common/stats/stats_options_impl.h" #include "exe/platform_impl.h" @@ -27,8 +28,9 @@ int main(int argc, char** argv) { } Envoy::PlatformImpl platform_impl_; + Envoy::Stats::IsolatedStoreImpl stats_store; Envoy::Event::RealTimeSystem time_system; // NO_CHECK_FORMAT(real_time) - Envoy::Api::Impl api(platform_impl_.threadFactory(), time_system); + Envoy::Api::Impl api(platform_impl_.threadFactory(), stats_store, time_system); envoy::config::bootstrap::v2::Bootstrap bootstrap; auto config_json = Envoy::Json::Factory::loadFromFile(argv[1], api); From f8e155d7858047b2d9062532b90865c7f822293e Mon Sep 17 00:00:00 2001 From: Yael Harel Date: Wed, 13 Feb 2019 10:50:02 -0500 Subject: [PATCH 12/13] Revert createApiForTest Signed-off-by: Yael Harel Signed-off-by: Sam Smith --- test/common/config/BUILD | 1 + .../filesystem_subscription_impl_test.cc | 2 +- .../filesystem_subscription_test_harness.h | 7 +- .../config/subscription_factory_test.cc | 3 +- test/common/config/utility_test.cc | 1 + test/common/event/BUILD | 2 + .../event/dispatched_thread_impl_test.cc | 2 +- test/common/event/dispatcher_impl_test.cc | 1 + test/common/event/file_event_impl_test.cc | 1 + test/common/grpc/BUILD | 1 + .../grpc/google_async_client_impl_test.cc | 2 +- test/common/grpc/google_grpc_creds_test.cc | 1 + .../grpc_client_integration_test_harness.h | 2 +- test/common/http/http2/conn_pool_test.cc | 3 +- test/common/json/BUILD | 2 + test/common/json/config_schemas_test.cc | 1 + test/common/json/json_loader_test.cc | 1 + test/common/network/BUILD | 4 + test/common/runtime/runtime_impl_test.cc | 2 +- .../stats/thread_local_store_speed_test.cc | 2 +- test/common/thread_local/BUILD | 1 + .../thread_local/thread_local_impl_test.cc | 1 + test/common/upstream/cds_api_impl_test.cc | 2 +- .../upstream/cluster_manager_impl_test.cc | 2 +- test/common/upstream/eds_test.cc | 2 +- test/common/upstream/hds_test.cc | 2 +- .../upstream/logical_dns_cluster_test.cc | 2 +- .../upstream/original_dst_cluster_test.cc | 3 +- test/common/upstream/upstream_impl_test.cc | 4 +- test/extensions/filters/http/jwt_authn/BUILD | 1 + .../filters/http/jwt_authn/jwks_cache_test.cc | 1 + .../proxy_protocol/proxy_protocol_test.cc | 4 +- .../client_ssl_auth/client_ssl_auth_test.cc | 2 +- .../resource_monitors/fixed_heap/BUILD | 1 + .../resource_monitors/injected_resource/BUILD | 2 + .../injected_resource_monitor_test.cc | 1 + .../tls/context_impl_test.cc | 1 - .../transport_sockets/tls/ssl_certs_test.h | 3 +- .../transport_sockets/tls/ssl_socket_test.cc | 89 ++++++++++++------- test/fuzz/BUILD | 1 + test/integration/fake_upstream.cc | 5 +- test/integration/integration.cc | 3 +- test/integration/integration.h | 1 + test/integration/utility.cc | 7 +- test/server/config_validation/BUILD | 1 + .../config_validation/cluster_manager_test.cc | 2 +- .../config_validation/dispatcher_test.cc | 4 +- test/server/guarddog_impl_test.cc | 4 +- test/server/lds_api_test.cc | 2 +- test/server/overload_manager_impl_test.cc | 2 +- test/test_common/utility.cc | 21 +++-- test/test_common/utility.h | 2 + test/tools/router_check/router.cc | 11 ++- test/tools/router_check/router.h | 4 +- test/tools/schema_validator/validator.h | 3 +- 55 files changed, 160 insertions(+), 78 deletions(-) diff --git a/test/common/config/BUILD b/test/common/config/BUILD index f121c14a1114b..8f2ce71b92036 100644 --- a/test/common/config/BUILD +++ b/test/common/config/BUILD @@ -194,6 +194,7 @@ envoy_cc_test( "//source/common/stats:stats_lib", "//test/mocks/grpc:grpc_mocks", "//test/mocks/local_info:local_info_mocks", + "//test/mocks/stats:stats_mocks", "//test/mocks/upstream:upstream_mocks", "//test/test_common:environment_lib", "//test/test_common:utility_lib", diff --git a/test/common/config/filesystem_subscription_impl_test.cc b/test/common/config/filesystem_subscription_impl_test.cc index 5670ac147e9ca..c088e2329a70e 100644 --- a/test/common/config/filesystem_subscription_impl_test.cc +++ b/test/common/config/filesystem_subscription_impl_test.cc @@ -36,7 +36,7 @@ TEST_F(FilesystemSubscriptionImplTest, InitialFile) { TEST(MiscFilesystemSubscriptionImplTest, BadWatch) { Event::MockDispatcher dispatcher; Stats::MockIsolatedStatsStore stats_store; - Api::ApiPtr api = Api::createApiForTest(); + Api::ApiPtr api = Api::createApiForTest(stats_store); SubscriptionStats stats{Utility::generateStats(stats_store)}; auto* watcher = new Filesystem::MockWatcher(); EXPECT_CALL(dispatcher, createFilesystemWatcher_()).WillOnce(Return(watcher)); diff --git a/test/common/config/filesystem_subscription_test_harness.h b/test/common/config/filesystem_subscription_test_harness.h index 76effb488f61e..b59c79eb95b90 100644 --- a/test/common/config/filesystem_subscription_test_harness.h +++ b/test/common/config/filesystem_subscription_test_harness.h @@ -29,9 +29,9 @@ typedef FilesystemSubscriptionImpl class FilesystemSubscriptionTestHarness : public SubscriptionTestHarness { public: FilesystemSubscriptionTestHarness() - : path_(TestEnvironment::temporaryPath("eds.json")), api_(Api::createApiForTest()), - dispatcher_(api_->allocateDispatcher()), subscription_(*dispatcher_, path_, stats_, *api_) { - } + : path_(TestEnvironment::temporaryPath("eds.json")), + api_(Api::createApiForTest(stats_store_)), dispatcher_(api_->allocateDispatcher()), + subscription_(*dispatcher_, path_, stats_, *api_) {} ~FilesystemSubscriptionTestHarness() { EXPECT_EQ(0, ::unlink(path_.c_str())); } @@ -97,6 +97,7 @@ class FilesystemSubscriptionTestHarness : public SubscriptionTestHarness { const std::string path_; std::string version_; + Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; Event::DispatcherPtr dispatcher_; NiceMock> callbacks_; diff --git a/test/common/config/subscription_factory_test.cc b/test/common/config/subscription_factory_test.cc index 0395d4bf773b5..680bd125a1d76 100644 --- a/test/common/config/subscription_factory_test.cc +++ b/test/common/config/subscription_factory_test.cc @@ -28,7 +28,8 @@ namespace Config { class SubscriptionFactoryTest : public TestBase { public: - SubscriptionFactoryTest() : http_request_(&cm_.async_client_), api_(Api::createApiForTest()) {} + SubscriptionFactoryTest() + : http_request_(&cm_.async_client_), api_(Api::createApiForTest(stats_store_)) {} std::unique_ptr> subscriptionFromConfigSource(const envoy::api::v2::core::ConfigSource& config) { diff --git a/test/common/config/utility_test.cc b/test/common/config/utility_test.cc index 274605aa4fb7e..64fc6092858db 100644 --- a/test/common/config/utility_test.cc +++ b/test/common/config/utility_test.cc @@ -11,6 +11,7 @@ #include "test/mocks/grpc/mocks.h" #include "test/mocks/local_info/mocks.h" +#include "test/mocks/stats/mocks.h" #include "test/mocks/upstream/mocks.h" #include "test/test_common/environment.h" #include "test/test_common/test_base.h" diff --git a/test/common/event/BUILD b/test/common/event/BUILD index f1c95babefa04..0a5ad582e66b2 100644 --- a/test/common/event/BUILD +++ b/test/common/event/BUILD @@ -15,6 +15,7 @@ envoy_cc_test( "//source/common/api:api_lib", "//source/common/event:dispatcher_includes", "//source/common/event:dispatcher_lib", + "//source/common/stats:isolated_store_lib", "//test/mocks:common_lib", "//test/test_common:utility_lib", ], @@ -27,6 +28,7 @@ envoy_cc_test( "//include/envoy/event:file_event_interface", "//source/common/event:dispatcher_includes", "//source/common/event:dispatcher_lib", + "//source/common/stats:isolated_store_lib", "//test/mocks:common_lib", "//test/test_common:environment_lib", "//test/test_common:utility_lib", diff --git a/test/common/event/dispatched_thread_impl_test.cc b/test/common/event/dispatched_thread_impl_test.cc index 0bbe17c3138a7..fc9ba00435fbd 100644 --- a/test/common/event/dispatched_thread_impl_test.cc +++ b/test/common/event/dispatched_thread_impl_test.cc @@ -23,7 +23,7 @@ namespace Event { class DispatchedThreadTest : public TestBase { protected: DispatchedThreadTest() - : config_(1000, 1000, 1000, 1000), api_(Api::createApiForTest()), thread_(*api_), + : config_(1000, 1000, 1000, 1000), api_(Api::createApiForTest(fakestats_)), thread_(*api_), guard_dog_(fakestats_, config_, *api_) {} void SetUp() override { thread_.start(guard_dog_); } diff --git a/test/common/event/dispatcher_impl_test.cc b/test/common/event/dispatcher_impl_test.cc index d55cf8847c5ba..2d807c2cc24ad 100644 --- a/test/common/event/dispatcher_impl_test.cc +++ b/test/common/event/dispatcher_impl_test.cc @@ -5,6 +5,7 @@ #include "common/api/api_impl.h" #include "common/common/lock_guard.h" #include "common/event/dispatcher_impl.h" +#include "common/stats/isolated_store_impl.h" #include "test/mocks/common.h" #include "test/test_common/test_base.h" diff --git a/test/common/event/file_event_impl_test.cc b/test/common/event/file_event_impl_test.cc index bd4e6854e2e10..832dab2dfa64c 100644 --- a/test/common/event/file_event_impl_test.cc +++ b/test/common/event/file_event_impl_test.cc @@ -3,6 +3,7 @@ #include "envoy/event/file_event.h" #include "common/event/dispatcher_impl.h" +#include "common/stats/isolated_store_impl.h" #include "test/mocks/common.h" #include "test/test_common/environment.h" diff --git a/test/common/grpc/BUILD b/test/common/grpc/BUILD index 4f025b3d64daf..3d262d90ee43b 100644 --- a/test/common/grpc/BUILD +++ b/test/common/grpc/BUILD @@ -80,6 +80,7 @@ envoy_cc_test( srcs = envoy_select_google_grpc(["google_grpc_creds_test.cc"]), deps = [ ":utility_lib", + "//test/mocks/stats:stats_mocks", "//test/test_common:utility_lib", ] + envoy_select_google_grpc(["//source/common/grpc:google_grpc_creds_lib"]), ) diff --git a/test/common/grpc/google_async_client_impl_test.cc b/test/common/grpc/google_async_client_impl_test.cc index 560155c9a9e3e..10dda16e87ff7 100644 --- a/test/common/grpc/google_async_client_impl_test.cc +++ b/test/common/grpc/google_async_client_impl_test.cc @@ -47,7 +47,7 @@ class MockStubFactory : public GoogleStubFactory { class EnvoyGoogleAsyncClientImplTest : public TestBase { public: EnvoyGoogleAsyncClientImplTest() - : stats_store_(new Stats::IsolatedStoreImpl), api_(Api::createApiForTest()), + : stats_store_(new Stats::IsolatedStoreImpl), api_(Api::createApiForTest(*stats_store_)), dispatcher_(api_->allocateDispatcher()), scope_(stats_store_), method_descriptor_(helloworld::Greeter::descriptor()->FindMethodByName("SayHello")) { envoy::api::v2::core::GrpcService config; diff --git a/test/common/grpc/google_grpc_creds_test.cc b/test/common/grpc/google_grpc_creds_test.cc index 1d322c3debf99..7ba5c677636ba 100644 --- a/test/common/grpc/google_grpc_creds_test.cc +++ b/test/common/grpc/google_grpc_creds_test.cc @@ -1,6 +1,7 @@ #include "common/grpc/google_grpc_creds_impl.h" #include "test/common/grpc/utility.h" +#include "test/mocks/stats/mocks.h" #include "test/test_common/test_base.h" #include "test/test_common/utility.h" diff --git a/test/common/grpc/grpc_client_integration_test_harness.h b/test/common/grpc/grpc_client_integration_test_harness.h index 2acf7dabafc55..9e1b8e1570dbd 100644 --- a/test/common/grpc/grpc_client_integration_test_harness.h +++ b/test/common/grpc/grpc_client_integration_test_harness.h @@ -218,7 +218,7 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { public: GrpcClientIntegrationTest() : method_descriptor_(helloworld::Greeter::descriptor()->FindMethodByName("SayHello")), - api_(Api::createApiForTest(test_time_.timeSystem())), + api_(Api::createApiForTest(*stats_store_, test_time_.timeSystem())), dispatcher_(api_->allocateDispatcher()) {} virtual void initialize() { diff --git a/test/common/http/http2/conn_pool_test.cc b/test/common/http/http2/conn_pool_test.cc index 7e9deb02e97bc..8c735ac6296a7 100644 --- a/test/common/http/http2/conn_pool_test.cc +++ b/test/common/http/http2/conn_pool_test.cc @@ -64,7 +64,7 @@ class Http2ConnPoolImplTest : public TestBase { }; Http2ConnPoolImplTest() - : api_(Api::createApiForTest()), + : api_(Api::createApiForTest(stats_store_)), pool_(dispatcher_, host_, Upstream::ResourcePriority::Default, nullptr) {} ~Http2ConnPoolImplTest() { @@ -116,6 +116,7 @@ class Http2ConnPoolImplTest : public TestBase { MOCK_METHOD0(onClientDestroy, void()); + Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; NiceMock dispatcher_; std::shared_ptr cluster_{new NiceMock()}; diff --git a/test/common/json/BUILD b/test/common/json/BUILD index aa3928a658468..0b78a0a51f407 100644 --- a/test/common/json/BUILD +++ b/test/common/json/BUILD @@ -17,6 +17,7 @@ envoy_cc_test( deps = [ "//source/common/json:config_schemas_lib", "//source/common/json:json_loader_lib", + "//source/common/stats:isolated_store_lib", "//test/test_common:environment_lib", "//test/test_common:utility_lib", ], @@ -27,6 +28,7 @@ envoy_cc_test( srcs = ["json_loader_test.cc"], deps = [ "//source/common/json:json_loader_lib", + "//source/common/stats:isolated_store_lib", "//test/test_common:utility_lib", ], ) diff --git a/test/common/json/config_schemas_test.cc b/test/common/json/config_schemas_test.cc index 7b57e9dcbb4b5..20da497190938 100644 --- a/test/common/json/config_schemas_test.cc +++ b/test/common/json/config_schemas_test.cc @@ -4,6 +4,7 @@ #include "common/common/fmt.h" #include "common/json/config_schemas.h" #include "common/json/json_loader.h" +#include "common/stats/isolated_store_impl.h" #include "test/test_common/environment.h" #include "test/test_common/test_base.h" diff --git a/test/common/json/json_loader_test.cc b/test/common/json/json_loader_test.cc index 83d596886882f..9fc615e5cc3c3 100644 --- a/test/common/json/json_loader_test.cc +++ b/test/common/json/json_loader_test.cc @@ -2,6 +2,7 @@ #include #include "common/json/json_loader.h" +#include "common/stats/isolated_store_impl.h" #include "test/test_common/test_base.h" #include "test/test_common/utility.h" diff --git a/test/common/network/BUILD b/test/common/network/BUILD index 70bbb20d546a5..24c585dd02819 100644 --- a/test/common/network/BUILD +++ b/test/common/network/BUILD @@ -72,6 +72,7 @@ envoy_cc_test( "//source/common/network:connection_lib", "//source/common/network:listen_socket_lib", "//source/common/network:utility_lib", + "//source/common/stats:stats_lib", "//test/mocks/buffer:buffer_mocks", "//test/mocks/event:event_mocks", "//test/mocks/network:network_mocks", @@ -98,6 +99,7 @@ envoy_cc_test( "//source/common/network:dns_lib", "//source/common/network:filter_lib", "//source/common/network:listen_socket_lib", + "//source/common/stats:stats_lib", "//test/mocks/network:network_mocks", "//test/test_common:environment_lib", "//test/test_common:network_utility_lib", @@ -165,6 +167,7 @@ envoy_cc_test( "//source/common/network:address_lib", "//source/common/network:listener_lib", "//source/common/network:utility_lib", + "//source/common/stats:stats_lib", "//test/common/network:listener_impl_test_base_lib", "//test/mocks/network:network_mocks", "//test/mocks/server:server_mocks", @@ -182,6 +185,7 @@ envoy_cc_test( "//source/common/network:address_lib", "//source/common/network:listener_lib", "//source/common/network:utility_lib", + "//source/common/stats:stats_lib", "//test/common/network:listener_impl_test_base_lib", "//test/mocks/network:network_mocks", "//test/mocks/server:server_mocks", diff --git a/test/common/runtime/runtime_impl_test.cc b/test/common/runtime/runtime_impl_test.cc index 2110ca8d17738..06651402f2811 100644 --- a/test/common/runtime/runtime_impl_test.cc +++ b/test/common/runtime/runtime_impl_test.cc @@ -65,7 +65,7 @@ TEST(UUID, sanityCheckOfUniqueness) { class DiskBackedLoaderImplTest : public TestBase { protected: - DiskBackedLoaderImplTest() : api_(Api::createApiForTest()) {} + DiskBackedLoaderImplTest() : api_(Api::createApiForTest(store)) {} static void SetUpTestSuite() { TestEnvironment::exec( diff --git a/test/common/stats/thread_local_store_speed_test.cc b/test/common/stats/thread_local_store_speed_test.cc index 11b2e91f1057a..88090b6dc44c1 100644 --- a/test/common/stats/thread_local_store_speed_test.cc +++ b/test/common/stats/thread_local_store_speed_test.cc @@ -22,7 +22,7 @@ namespace Envoy { class ThreadLocalStorePerf { public: ThreadLocalStorePerf() - : store_(options_, heap_alloc_), api_(Api::createApiForTest(time_system_)) { + : store_(options_, heap_alloc_), api_(Api::createApiForTest(store_, time_system_)) { store_.setTagProducer(std::make_unique(stats_config_)); } diff --git a/test/common/thread_local/BUILD b/test/common/thread_local/BUILD index ba4b9b894d1f8..c1d95410e5ab9 100644 --- a/test/common/thread_local/BUILD +++ b/test/common/thread_local/BUILD @@ -14,6 +14,7 @@ envoy_cc_test( deps = [ "//source/common/api:api_lib", "//source/common/event:dispatcher_lib", + "//source/common/stats:isolated_store_lib", "//source/common/thread_local:thread_local_lib", "//test/mocks/event:event_mocks", ], diff --git a/test/common/thread_local/thread_local_impl_test.cc b/test/common/thread_local/thread_local_impl_test.cc index 847d4ff590bf7..f5cee2442f056 100644 --- a/test/common/thread_local/thread_local_impl_test.cc +++ b/test/common/thread_local/thread_local_impl_test.cc @@ -1,5 +1,6 @@ #include "common/common/thread.h" #include "common/event/dispatcher_impl.h" +#include "common/stats/isolated_store_impl.h" #include "common/thread_local/thread_local_impl.h" #include "test/mocks/event/mocks.h" diff --git a/test/common/upstream/cds_api_impl_test.cc b/test/common/upstream/cds_api_impl_test.cc index 8a6ef87e8af4e..1e610f53a02a3 100644 --- a/test/common/upstream/cds_api_impl_test.cc +++ b/test/common/upstream/cds_api_impl_test.cc @@ -28,7 +28,7 @@ namespace Upstream { class CdsApiImplTest : public TestBase { protected: - CdsApiImplTest() : request_(&cm_.async_client_), api_(Api::createApiForTest()) {} + CdsApiImplTest() : request_(&cm_.async_client_), api_(Api::createApiForTest(store_)) {} void setup() { const std::string config_json = R"EOF( diff --git a/test/common/upstream/cluster_manager_impl_test.cc b/test/common/upstream/cluster_manager_impl_test.cc index 28c98f367aee0..f16dadecd7dd1 100644 --- a/test/common/upstream/cluster_manager_impl_test.cc +++ b/test/common/upstream/cluster_manager_impl_test.cc @@ -56,7 +56,7 @@ namespace { // the expectations when needed. class TestClusterManagerFactory : public ClusterManagerFactory { public: - TestClusterManagerFactory() : api_(Api::createApiForTest()) { + TestClusterManagerFactory() : api_(Api::createApiForTest(stats_)) { ON_CALL(*this, clusterFromProto_(_, _, _, _)) .WillByDefault(Invoke([&](const envoy::api::v2::Cluster& cluster, ClusterManager& cm, Outlier::EventLoggerSharedPtr outlier_event_logger, diff --git a/test/common/upstream/eds_test.cc b/test/common/upstream/eds_test.cc index e76652cbb5c93..50176b0237cd0 100644 --- a/test/common/upstream/eds_test.cc +++ b/test/common/upstream/eds_test.cc @@ -29,7 +29,7 @@ namespace Upstream { class EdsTest : public TestBase { protected: - EdsTest() : api_(Api::createApiForTest()) { resetCluster(); } + EdsTest() : api_(Api::createApiForTest(stats_)) { resetCluster(); } void resetCluster() { resetCluster(R"EOF( diff --git a/test/common/upstream/hds_test.cc b/test/common/upstream/hds_test.cc index 86893793fba17..b14be2c84d72f 100644 --- a/test/common/upstream/hds_test.cc +++ b/test/common/upstream/hds_test.cc @@ -46,7 +46,7 @@ class HdsTest : public TestBase { protected: HdsTest() : retry_timer_(new Event::MockTimer()), server_response_timer_(new Event::MockTimer()), - async_client_(new Grpc::MockAsyncClient()), api_(Api::createApiForTest()), + async_client_(new Grpc::MockAsyncClient()), api_(Api::createApiForTest(stats_store_)), ssl_context_manager_(api_->timeSource()) { node_.set_id("hds-node"); } diff --git a/test/common/upstream/logical_dns_cluster_test.cc b/test/common/upstream/logical_dns_cluster_test.cc index e336f2f0bd4e6..9d55f81d1e5ed 100644 --- a/test/common/upstream/logical_dns_cluster_test.cc +++ b/test/common/upstream/logical_dns_cluster_test.cc @@ -37,7 +37,7 @@ enum class ConfigType { V2_YAML, V1_JSON }; class LogicalDnsClusterTest : public TestBase { protected: - LogicalDnsClusterTest() : api_(Api::createApiForTest()) {} + LogicalDnsClusterTest() : api_(Api::createApiForTest(stats_store_)) {} void setupFromV1Json(const std::string& json) { resolve_timer_ = new Event::MockTimer(&dispatcher_); diff --git a/test/common/upstream/original_dst_cluster_test.cc b/test/common/upstream/original_dst_cluster_test.cc index d8031ac2f1d28..a3eec32502ef6 100644 --- a/test/common/upstream/original_dst_cluster_test.cc +++ b/test/common/upstream/original_dst_cluster_test.cc @@ -63,7 +63,8 @@ class OriginalDstClusterTest : public TestBase { // on it. Ownership is transferred to the cluster at the cluster constructor, so the cluster will // take care of destructing it! OriginalDstClusterTest() - : cleanup_timer_(new Event::MockTimer(&dispatcher_)), api_(Api::createApiForTest()) {} + : cleanup_timer_(new Event::MockTimer(&dispatcher_)), + api_(Api::createApiForTest(stats_store_)) {} void setupFromJson(const std::string& json) { setup(parseClusterFromJson(json)); } void setupFromYaml(const std::string& yaml) { setup(parseClusterFromV2Yaml(yaml)); } diff --git a/test/common/upstream/upstream_impl_test.cc b/test/common/upstream/upstream_impl_test.cc index a11067eac60a4..11c23287a2a96 100644 --- a/test/common/upstream/upstream_impl_test.cc +++ b/test/common/upstream/upstream_impl_test.cc @@ -45,7 +45,7 @@ namespace { class UpstreamImplTestBase { protected: - UpstreamImplTestBase() : api_(Api::createApiForTest()) {} + UpstreamImplTestBase() : api_(Api::createApiForTest(stats_)) {} NiceMock admin_; Ssl::MockContextManager ssl_context_manager_; @@ -1592,7 +1592,7 @@ TEST(PrioritySet, Extend) { class ClusterInfoImplTest : public TestBase { public: - ClusterInfoImplTest() : api_(Api::createApiForTest()) {} + ClusterInfoImplTest() : api_(Api::createApiForTest(stats_)) {} std::unique_ptr makeCluster(const std::string& yaml) { cluster_config_ = parseClusterFromV2Yaml(yaml); diff --git a/test/extensions/filters/http/jwt_authn/BUILD b/test/extensions/filters/http/jwt_authn/BUILD index 72e1d19767d20..b225c4510ed08 100644 --- a/test/extensions/filters/http/jwt_authn/BUILD +++ b/test/extensions/filters/http/jwt_authn/BUILD @@ -66,6 +66,7 @@ envoy_extension_cc_test( srcs = ["jwks_cache_test.cc"], extension_name = "envoy.filters.http.jwt_authn", deps = [ + "//source/common/stats:isolated_store_lib", "//source/extensions/filters/http/common:jwks_fetcher_lib", "//source/extensions/filters/http/jwt_authn:jwks_cache_lib", "//test/extensions/filters/http/jwt_authn:test_common_lib", diff --git a/test/extensions/filters/http/jwt_authn/jwks_cache_test.cc b/test/extensions/filters/http/jwt_authn/jwks_cache_test.cc index 34fe5127ef500..2c27434572c75 100644 --- a/test/extensions/filters/http/jwt_authn/jwks_cache_test.cc +++ b/test/extensions/filters/http/jwt_authn/jwks_cache_test.cc @@ -2,6 +2,7 @@ #include #include "common/protobuf/utility.h" +#include "common/stats/isolated_store_impl.h" #include "extensions/filters/http/jwt_authn/jwks_cache.h" diff --git a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc index d60a9446c3d07..48e36bb387d7e 100644 --- a/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc +++ b/test/extensions/filters/listener/proxy_protocol/proxy_protocol_test.cc @@ -49,7 +49,7 @@ class ProxyProtocolTest : public TestBaseWithParam, protected Logger::Loggable { public: ProxyProtocolTest() - : api_(Api::createApiForTest()), dispatcher_(api_->allocateDispatcher()), + : api_(Api::createApiForTest(stats_store_)), dispatcher_(api_->allocateDispatcher()), socket_(Network::Test::getCanonicalLoopbackAddress(GetParam()), nullptr, true), connection_handler_(new Server::ConnectionHandlerImpl(ENVOY_LOGGER(), *dispatcher_)), name_("proxy"), filter_chain_(Network::Test::createEmptyFilterChainWithRawBufferSockets()) { @@ -869,7 +869,7 @@ class WildcardProxyProtocolTest : public TestBaseWithParam { public: WildcardProxyProtocolTest() - : api_(Api::createApiForTest()), dispatcher_(api_->allocateDispatcher()), + : api_(Api::createApiForTest(stats_store_)), dispatcher_(api_->allocateDispatcher()), socket_(Network::Test::getAnyAddress(GetParam()), nullptr, true), local_dst_address_(Network::Utility::getAddressWithPort( *Network::Test::getCanonicalLoopbackAddress(GetParam()), diff --git a/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc b/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc index 07ec3d59da43b..2c6a78b380ac8 100644 --- a/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc +++ b/test/extensions/filters/network/client_ssl_auth/client_ssl_auth_test.cc @@ -59,7 +59,7 @@ class ClientSslAuthFilterTest : public TestBase { protected: ClientSslAuthFilterTest() : request_(&cm_.async_client_), interval_timer_(new Event::MockTimer(&dispatcher_)), - api_(Api::createApiForTest()) {} + api_(Api::createApiForTest(stats_store_)) {} ~ClientSslAuthFilterTest() { tls_.shutdownThread(); } void setup() { diff --git a/test/extensions/resource_monitors/fixed_heap/BUILD b/test/extensions/resource_monitors/fixed_heap/BUILD index 3d1c8eff0ab3b..9f2c70e726064 100644 --- a/test/extensions/resource_monitors/fixed_heap/BUILD +++ b/test/extensions/resource_monitors/fixed_heap/BUILD @@ -27,6 +27,7 @@ envoy_extension_cc_test( extension_name = "envoy.resource_monitors.fixed_heap", deps = [ "//include/envoy/registry", + "//source/common/stats:isolated_store_lib", "//source/extensions/resource_monitors/fixed_heap:config", "//source/server:resource_monitor_config_lib", "//test/mocks/event:event_mocks", diff --git a/test/extensions/resource_monitors/injected_resource/BUILD b/test/extensions/resource_monitors/injected_resource/BUILD index 83458f439ae88..51e9ef57e5637 100644 --- a/test/extensions/resource_monitors/injected_resource/BUILD +++ b/test/extensions/resource_monitors/injected_resource/BUILD @@ -17,6 +17,7 @@ envoy_cc_test( srcs = ["injected_resource_monitor_test.cc"], deps = [ "//source/common/event:dispatcher_lib", + "//source/common/stats:isolated_store_lib", "//source/extensions/resource_monitors/injected_resource:injected_resource_monitor", "//source/server:resource_monitor_config_lib", "//test/test_common:environment_lib", @@ -31,6 +32,7 @@ envoy_extension_cc_test( deps = [ "//include/envoy/registry", "//source/common/event:dispatcher_lib", + "//source/common/stats:isolated_store_lib", "//source/extensions/resource_monitors/injected_resource:config", "//source/server:resource_monitor_config_lib", "//test/test_common:environment_lib", diff --git a/test/extensions/resource_monitors/injected_resource/injected_resource_monitor_test.cc b/test/extensions/resource_monitors/injected_resource/injected_resource_monitor_test.cc index a35c6eb705ea8..20dad3e497d9f 100644 --- a/test/extensions/resource_monitors/injected_resource/injected_resource_monitor_test.cc +++ b/test/extensions/resource_monitors/injected_resource/injected_resource_monitor_test.cc @@ -1,4 +1,5 @@ #include "common/event/dispatcher_impl.h" +#include "common/stats/isolated_store_impl.h" #include "server/resource_monitor_config_impl.h" diff --git a/test/extensions/transport_sockets/tls/context_impl_test.cc b/test/extensions/transport_sockets/tls/context_impl_test.cc index 5e7a5cd8ff4e8..bfa059bb2a290 100644 --- a/test/extensions/transport_sockets/tls/context_impl_test.cc +++ b/test/extensions/transport_sockets/tls/context_impl_test.cc @@ -38,7 +38,6 @@ class SslContextImplTest : public SslCertsTest { protected: Event::SimulatedTimeSystem time_system_; ContextManagerImpl manager_{time_system_}; - Stats::IsolatedStoreImpl store_; }; TEST_F(SslContextImplTest, TestdNSNameMatching) { diff --git a/test/extensions/transport_sockets/tls/ssl_certs_test.h b/test/extensions/transport_sockets/tls/ssl_certs_test.h index 77bffc6238de5..b9bd3a2597306 100644 --- a/test/extensions/transport_sockets/tls/ssl_certs_test.h +++ b/test/extensions/transport_sockets/tls/ssl_certs_test.h @@ -16,12 +16,13 @@ class SslCertsTest : public TestBase { } protected: - SslCertsTest() : api_(Api::createApiForTest(time_system_)) { + SslCertsTest() : api_(Api::createApiForTest(store_, time_system_)) { ON_CALL(factory_context_, api()).WillByDefault(ReturnRef(*api_)); } Event::SimulatedTimeSystem time_system_; testing::NiceMock factory_context_; + Stats::IsolatedStoreImpl store_; Api::ApiPtr api_; }; } // namespace Envoy diff --git a/test/extensions/transport_sockets/tls/ssl_socket_test.cc b/test/extensions/transport_sockets/tls/ssl_socket_test.cc index 0d8f79facf221..bdd9ee1393a89 100644 --- a/test/extensions/transport_sockets/tls/ssl_socket_test.cc +++ b/test/extensions/transport_sockets/tls/ssl_socket_test.cc @@ -199,20 +199,22 @@ class TestUtilOptions : public TestUtilOptionsBase { void testUtil(const TestUtilOptions& options) { Event::SimulatedTimeSystem time_system; - Api::ApiPtr api = Api::createApiForTest(time_system); - testing::NiceMock factory_context; - ON_CALL(factory_context, api()).WillByDefault(ReturnRef(*api)); + Stats::IsolatedStoreImpl server_stats_store; + Api::ApiPtr server_api = Api::createApiForTest(server_stats_store, time_system); + testing::NiceMock + server_factory_context; + ON_CALL(server_factory_context, api()).WillByDefault(ReturnRef(*server_api)); envoy::api::v2::auth::DownstreamTlsContext server_tls_context; MessageUtil::loadFromYaml(TestEnvironment::substitute(options.serverCtxYaml()), server_tls_context); - auto server_cfg = std::make_unique(server_tls_context, factory_context); + auto server_cfg = + std::make_unique(server_tls_context, server_factory_context); ContextManagerImpl manager(*time_system); - Stats::IsolatedStoreImpl server_stats_store; ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, server_stats_store, std::vector{}); - Event::DispatcherPtr dispatcher = api->allocateDispatcher(); + Event::DispatcherPtr dispatcher = server_api->allocateDispatcher(); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(options.version()), nullptr, true); Network::MockListenerCallbacks callbacks; @@ -223,8 +225,14 @@ void testUtil(const TestUtilOptions& options) { MessageUtil::loadFromYaml(TestEnvironment::substitute(options.clientCtxYaml()), client_tls_context); - auto client_cfg = std::make_unique(client_tls_context, factory_context); Stats::IsolatedStoreImpl client_stats_store; + Api::ApiPtr client_api = Api::createApiForTest(client_stats_store, time_system); + testing::NiceMock + client_factory_context; + ON_CALL(client_factory_context, api()).WillByDefault(ReturnRef(*client_api)); + + auto client_cfg = + std::make_unique(client_tls_context, client_factory_context); ClientSslSocketFactory client_ssl_socket_factory(std::move(client_cfg), manager, client_stats_store); Network::ClientConnectionPtr client_connection = dispatcher->createClientConnection( @@ -441,18 +449,18 @@ const std::string testUtilV2(const TestUtilOptionsV2& options) { const auto& filter_chain = options.listener().filter_chains(0); std::vector server_names(filter_chain.filter_chain_match().server_names().begin(), filter_chain.filter_chain_match().server_names().end()); - - Api::ApiPtr api = Api::createApiForTest(time_system); - testing::NiceMock factory_context; - ON_CALL(factory_context, api()).WillByDefault(ReturnRef(*api)); - Stats::IsolatedStoreImpl server_stats_store; + Api::ApiPtr server_api = Api::createApiForTest(server_stats_store, time_system); + testing::NiceMock + server_factory_context; + ON_CALL(server_factory_context, api()).WillByDefault(ReturnRef(*server_api)); + auto server_cfg = - std::make_unique(filter_chain.tls_context(), factory_context); + std::make_unique(filter_chain.tls_context(), server_factory_context); ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, server_stats_store, server_names); - Event::DispatcherPtr dispatcher(api->allocateDispatcher()); + Event::DispatcherPtr dispatcher(server_api->allocateDispatcher()); Network::TcpListenSocket socket(Network::Test::getCanonicalLoopbackAddress(options.version()), nullptr, true); NiceMock callbacks; @@ -460,8 +468,13 @@ const std::string testUtilV2(const TestUtilOptionsV2& options) { Network::ListenerPtr listener = dispatcher->createListener(socket, callbacks, true, false); Stats::IsolatedStoreImpl client_stats_store; + Api::ApiPtr client_api = Api::createApiForTest(client_stats_store, time_system); + testing::NiceMock + client_factory_context; + ON_CALL(client_factory_context, api()).WillByDefault(ReturnRef(*client_api)); + auto client_cfg = - std::make_unique(options.clientCtxProto(), factory_context); + std::make_unique(options.clientCtxProto(), client_factory_context); ClientSslSocketFactory client_ssl_socket_factory(std::move(client_cfg), manager, client_stats_store); Network::ClientConnectionPtr client_connection = dispatcher->createClientConnection( @@ -2166,20 +2179,21 @@ void testTicketSessionResumption(const std::string& server_ctx_yaml1, Event::SimulatedTimeSystem time_system; ContextManagerImpl manager(*time_system); - Api::ApiPtr api = Api::createApiForTest(time_system); - testing::NiceMock factory_context; - ON_CALL(factory_context, api()).WillByDefault(ReturnRef(*api)); + Stats::IsolatedStoreImpl server_stats_store; + Api::ApiPtr server_api = Api::createApiForTest(server_stats_store, time_system); + testing::NiceMock + server_factory_context; + ON_CALL(server_factory_context, api()).WillByDefault(ReturnRef(*server_api)); envoy::api::v2::auth::DownstreamTlsContext server_tls_context1; MessageUtil::loadFromYaml(TestEnvironment::substitute(server_ctx_yaml1), server_tls_context1); auto server_cfg1 = - std::make_unique(server_tls_context1, factory_context); + std::make_unique(server_tls_context1, server_factory_context); envoy::api::v2::auth::DownstreamTlsContext server_tls_context2; MessageUtil::loadFromYaml(TestEnvironment::substitute(server_ctx_yaml2), server_tls_context2); auto server_cfg2 = - std::make_unique(server_tls_context2, factory_context); - Stats::IsolatedStoreImpl server_stats_store; + std::make_unique(server_tls_context2, server_factory_context); ServerSslSocketFactory server_ssl_socket_factory1(std::move(server_cfg1), manager, server_stats_store, server_names1); ServerSslSocketFactory server_ssl_socket_factory2(std::move(server_cfg2), manager, @@ -2191,7 +2205,7 @@ void testTicketSessionResumption(const std::string& server_ctx_yaml1, true); NiceMock callbacks; Network::MockConnectionHandler connection_handler; - Event::DispatcherPtr dispatcher(api->allocateDispatcher()); + Event::DispatcherPtr dispatcher(server_api->allocateDispatcher()); Network::ListenerPtr listener1 = dispatcher->createListener(socket1, callbacks, true, false); Network::ListenerPtr listener2 = dispatcher->createListener(socket2, callbacks, true, false); @@ -2199,7 +2213,13 @@ void testTicketSessionResumption(const std::string& server_ctx_yaml1, MessageUtil::loadFromYaml(TestEnvironment::substitute(client_ctx_yaml), client_tls_context); Stats::IsolatedStoreImpl client_stats_store; - auto client_cfg = std::make_unique(client_tls_context, factory_context); + Api::ApiPtr client_api = Api::createApiForTest(client_stats_store, time_system); + testing::NiceMock + client_factory_context; + ON_CALL(client_factory_context, api()).WillByDefault(ReturnRef(*client_api)); + + auto client_cfg = + std::make_unique(client_tls_context, client_factory_context); ClientSslSocketFactory ssl_socket_factory(std::move(client_cfg), manager, client_stats_store); Network::ClientConnectionPtr client_connection = dispatcher->createClientConnection( socket1.localAddress(), Network::Address::InstanceConstSharedPtr(), @@ -2690,14 +2710,16 @@ void SslSocketTest::testClientSessionResumption(const std::string& server_ctx_ya ContextManagerImpl manager(time_system_); - Api::ApiPtr api = Api::createApiForTest(time_system_); - testing::NiceMock factory_context; - ON_CALL(factory_context, api()).WillByDefault(ReturnRef(*api)); + Stats::IsolatedStoreImpl server_stats_store; + Api::ApiPtr server_api = Api::createApiForTest(server_stats_store, time_system_); + testing::NiceMock + server_factory_context; + ON_CALL(server_factory_context, api()).WillByDefault(ReturnRef(*server_api)); envoy::api::v2::auth::DownstreamTlsContext server_ctx_proto; MessageUtil::loadFromYaml(TestEnvironment::substitute(server_ctx_yaml), server_ctx_proto); - auto server_cfg = std::make_unique(server_ctx_proto, factory_context); - Stats::IsolatedStoreImpl server_stats_store; + auto server_cfg = + std::make_unique(server_ctx_proto, server_factory_context); ServerSslSocketFactory server_ssl_socket_factory(std::move(server_cfg), manager, server_stats_store, std::vector{}); @@ -2705,7 +2727,8 @@ void SslSocketTest::testClientSessionResumption(const std::string& server_ctx_ya true); NiceMock callbacks; Network::MockConnectionHandler connection_handler; - Event::DispatcherPtr dispatcher(api->allocateDispatcher()); + Api::ApiPtr api = Api::createApiForTest(server_stats_store, time_system_); + Event::DispatcherPtr dispatcher(server_api->allocateDispatcher()); Network::ListenerPtr listener = dispatcher->createListener(socket, callbacks, true, false); Network::ConnectionPtr server_connection; @@ -2714,8 +2737,14 @@ void SslSocketTest::testClientSessionResumption(const std::string& server_ctx_ya envoy::api::v2::auth::UpstreamTlsContext client_ctx_proto; MessageUtil::loadFromYaml(TestEnvironment::substitute(client_ctx_yaml), client_ctx_proto); - auto client_cfg = std::make_unique(client_ctx_proto, factory_context); Stats::IsolatedStoreImpl client_stats_store; + Api::ApiPtr client_api = Api::createApiForTest(client_stats_store, time_system_); + testing::NiceMock + client_factory_context; + ON_CALL(client_factory_context, api()).WillByDefault(ReturnRef(*client_api)); + + auto client_cfg = + std::make_unique(client_ctx_proto, client_factory_context); ClientSslSocketFactory client_ssl_socket_factory(std::move(client_cfg), manager, client_stats_store); Network::ClientConnectionPtr client_connection = dispatcher->createClientConnection( diff --git a/test/fuzz/BUILD b/test/fuzz/BUILD index 7ef3ab9413244..2ff3a101a99e6 100644 --- a/test/fuzz/BUILD +++ b/test/fuzz/BUILD @@ -22,6 +22,7 @@ envoy_cc_test_library( ":fuzz_runner_lib", "//source/common/common:assert_lib", "//source/common/common:minimal_logger_lib", + "//source/common/stats:isolated_store_lib", "//test/test_common:environment_lib", "//test/test_common:utility_lib", ], diff --git a/test/integration/fake_upstream.cc b/test/integration/fake_upstream.cc index afffccaf26aa0..2e9bc4786411b 100644 --- a/test/integration/fake_upstream.cc +++ b/test/integration/fake_upstream.cc @@ -372,8 +372,9 @@ FakeUpstream::FakeUpstream(Network::TransportSocketFactoryPtr&& transport_socket FakeUpstream::FakeUpstream(Network::TransportSocketFactoryPtr&& transport_socket_factory, Network::SocketPtr&& listen_socket, FakeHttpConnection::Type type, Event::TestTimeSystem& time_system, bool enable_half_close) - : http_type_(type), socket_(std::move(listen_socket)), api_(Api::createApiForTest()), - time_system_(time_system), dispatcher_(api_->allocateDispatcher()), + : http_type_(type), socket_(std::move(listen_socket)), + api_(Api::createApiForTest(stats_store_)), time_system_(time_system), + dispatcher_(api_->allocateDispatcher()), handler_(new Server::ConnectionHandlerImpl(ENVOY_LOGGER(), *dispatcher_)), allow_unexpected_disconnects_(false), enable_half_close_(enable_half_close), listener_(*this), filter_chain_(Network::Test::createEmptyFilterChain(std::move(transport_socket_factory))) { diff --git a/test/integration/integration.cc b/test/integration/integration.cc index b45d3b7b85162..117453616cc57 100644 --- a/test/integration/integration.cc +++ b/test/integration/integration.cc @@ -228,7 +228,8 @@ void IntegrationTcpClient::ConnectionCallbacks::onEvent(Network::ConnectionEvent BaseIntegrationTest::BaseIntegrationTest(Network::Address::IpVersion version, const std::string& config) - : api_(Api::createApiForTest()), mock_buffer_factory_(new NiceMock), + : api_(Api::createApiForTest(stats_store_)), + mock_buffer_factory_(new NiceMock), dispatcher_(api_->allocateDispatcher(Buffer::WatermarkFactoryPtr{mock_buffer_factory_})), version_(version), config_helper_(version, *api_, config), default_log_level_(TestEnvironment::getOptions().logLevel()) { diff --git a/test/integration/integration.h b/test/integration/integration.h index d7bde275adfa3..85cf2acaf168a 100644 --- a/test/integration/integration.h +++ b/test/integration/integration.h @@ -179,6 +179,7 @@ class BaseIntegrationTest : Logger::Loggable { Event::TestTimeSystem& timeSystem() { return time_system_; } + Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; MockBufferFactory* mock_buffer_factory_; // Will point to the dispatcher's factory. diff --git a/test/integration/utility.cc b/test/integration/utility.cc index b9b3758fc4e0a..76fc69623a202 100644 --- a/test/integration/utility.cc +++ b/test/integration/utility.cc @@ -60,9 +60,10 @@ IntegrationUtil::makeSingleRequest(const Network::Address::InstanceConstSharedPt const std::string& body, Http::CodecClient::Type type, const std::string& host, const std::string& content_type) { + NiceMock mock_stats_store; Event::GlobalTimeSystem time_system; - Api::ApiPtr api = Api::createApiForTest(time_system); - Event::DispatcherPtr dispatcher(api->allocateDispatcher()); + Api::Impl api(Thread::threadFactoryForTest(), mock_stats_store, time_system); + Event::DispatcherPtr dispatcher(api.allocateDispatcher()); std::shared_ptr cluster{new NiceMock()}; Upstream::HostDescriptionConstSharedPtr host_description{ Upstream::makeTestHostDescription(cluster, "tcp://127.0.0.1:80")}; @@ -109,7 +110,7 @@ IntegrationUtil::makeSingleRequest(uint32_t port, const std::string& method, con RawConnectionDriver::RawConnectionDriver(uint32_t port, Buffer::Instance& initial_data, ReadCallback data_callback, Network::Address::IpVersion version) { - api_ = Api::createApiForTest(); + api_ = Api::createApiForTest(stats_store_); Event::GlobalTimeSystem time_system; dispatcher_ = api_->allocateDispatcher(); callbacks_ = std::make_unique(); diff --git a/test/server/config_validation/BUILD b/test/server/config_validation/BUILD index 431a0ec8ca28f..30e8e8f2f976b 100644 --- a/test/server/config_validation/BUILD +++ b/test/server/config_validation/BUILD @@ -73,6 +73,7 @@ envoy_cc_test( srcs = ["dispatcher_test.cc"], deps = [ "//source/common/event:libevent_lib", + "//source/common/stats:isolated_store_lib", "//source/server/config_validation:api_lib", "//source/server/config_validation:dns_lib", "//test/test_common:environment_lib", diff --git a/test/server/config_validation/cluster_manager_test.cc b/test/server/config_validation/cluster_manager_test.cc index 0c71edc932124..ddace5e3d03c6 100644 --- a/test/server/config_validation/cluster_manager_test.cc +++ b/test/server/config_validation/cluster_manager_test.cc @@ -28,7 +28,7 @@ namespace Upstream { TEST(ValidationClusterManagerTest, MockedMethods) { Stats::IsolatedStoreImpl stats_store; Event::SimulatedTimeSystem time_system; - Api::ApiPtr api(Api::createApiForTest(time_system)); + Api::ApiPtr api(Api::createApiForTest(stats_store, time_system)); NiceMock runtime; NiceMock tls; NiceMock random; diff --git a/test/server/config_validation/dispatcher_test.cc b/test/server/config_validation/dispatcher_test.cc index 0698f3d49337a..d34d7f403203a 100644 --- a/test/server/config_validation/dispatcher_test.cc +++ b/test/server/config_validation/dispatcher_test.cc @@ -5,10 +5,10 @@ #include "common/event/libevent.h" #include "common/network/address_impl.h" #include "common/network/utility.h" +#include "common/stats/isolated_store_impl.h" #include "server/config_validation/api.h" -#include "test/mocks/stats/mocks.h" #include "test/test_common/environment.h" #include "test/test_common/network_utility.h" #include "test/test_common/test_time.h" @@ -29,9 +29,9 @@ class ConfigValidation : public TestBaseWithParam { dispatcher_ = validation_->allocateDispatcher(); } - testing::NiceMock stats_store_; DangerousDeprecatedTestTime test_time_; Event::DispatcherPtr dispatcher_; + Stats::IsolatedStoreImpl stats_store_; private: // Using config validation API. diff --git a/test/server/guarddog_impl_test.cc b/test/server/guarddog_impl_test.cc index 30e6bc4226974..170e034dcad3e 100644 --- a/test/server/guarddog_impl_test.cc +++ b/test/server/guarddog_impl_test.cc @@ -26,9 +26,10 @@ namespace Server { class GuardDogTestBase : public TestBase { protected: - GuardDogTestBase() : api_(Api::createApiForTest(time_system_)) {} + GuardDogTestBase() : api_(Api::createApiForTest(stats_store_, time_system_)) {} Event::SimulatedTimeSystem time_system_; + Stats::IsolatedStoreImpl stats_store_; Api::ApiPtr api_; }; @@ -139,7 +140,6 @@ class GuardDogMissTest : public GuardDogTestBase { NiceMock config_miss_; NiceMock config_mega_; - Stats::IsolatedStoreImpl stats_store_; }; TEST_F(GuardDogMissTest, MissTest) { diff --git a/test/server/lds_api_test.cc b/test/server/lds_api_test.cc index db68fddd99903..6c83b329bad55 100644 --- a/test/server/lds_api_test.cc +++ b/test/server/lds_api_test.cc @@ -24,7 +24,7 @@ namespace Server { class LdsApiTest : public TestBase { public: - LdsApiTest() : request_(&cluster_manager_.async_client_), api_(Api::createApiForTest()) {} + LdsApiTest() : request_(&cluster_manager_.async_client_), api_(Api::createApiForTest(store_)) {} void setup() { const std::string config_json = R"EOF( diff --git a/test/server/overload_manager_impl_test.cc b/test/server/overload_manager_impl_test.cc index 24ef2dca65ba9..f79598a43ec24 100644 --- a/test/server/overload_manager_impl_test.cc +++ b/test/server/overload_manager_impl_test.cc @@ -74,7 +74,7 @@ class OverloadManagerImplTest : public TestBase { OverloadManagerImplTest() : factory1_("envoy.resource_monitors.fake_resource1"), factory2_("envoy.resource_monitors.fake_resource2"), register_factory1_(factory1_), - register_factory2_(factory2_), api_(Api::createApiForTest()) {} + register_factory2_(factory2_), api_(Api::createApiForTest(stats_)) {} void setDispatcherExpectation() { timer_ = new NiceMock(); diff --git a/test/test_common/utility.cc b/test/test_common/utility.cc index adb0583dd68ab..fd4afa8d656c1 100644 --- a/test/test_common/utility.cc +++ b/test/test_common/utility.cc @@ -410,15 +410,26 @@ class TestImplProvider { class TestImpl : public TestImplProvider, public Impl { public: - TestImpl() : Impl(Thread::threadFactoryForTest(), default_stats_store_, global_time_system_) {} - TestImpl(Event::TimeSystem& time_system) - : Impl(Thread::threadFactoryForTest(), default_stats_store_, time_system) {} + TestImpl(Thread::ThreadFactory& thread_factory, Stats::Store& stats_store) + : Impl(thread_factory, stats_store, global_time_system_) {} + TestImpl(Thread::ThreadFactory& thread_factory, Event::TimeSystem& time_system) + : Impl(thread_factory, default_stats_store_, time_system) {} + TestImpl(Thread::ThreadFactory& thread_factory) + : Impl(thread_factory, default_stats_store_, global_time_system_) {} }; -ApiPtr createApiForTest() { return std::make_unique(); } +ApiPtr createApiForTest() { return std::make_unique(Thread::threadFactoryForTest()); } + +ApiPtr createApiForTest(Stats::Store& stat_store) { + return std::make_unique(Thread::threadFactoryForTest(), stat_store); +} ApiPtr createApiForTest(Event::TimeSystem& time_system) { - return std::make_unique(time_system); + return std::make_unique(Thread::threadFactoryForTest(), time_system); +} + +ApiPtr createApiForTest(Stats::Store& stat_store, Event::TimeSystem& time_system) { + return std::make_unique(Thread::threadFactoryForTest(), stat_store, time_system); } } // namespace Api diff --git a/test/test_common/utility.h b/test/test_common/utility.h index c619e79cf3fec..8f04750068c22 100644 --- a/test/test_common/utility.h +++ b/test/test_common/utility.h @@ -527,7 +527,9 @@ ThreadFactory& threadFactoryForTest(); namespace Api { ApiPtr createApiForTest(); +ApiPtr createApiForTest(Stats::Store& stat_store); ApiPtr createApiForTest(Event::TimeSystem& time_system); +ApiPtr createApiForTest(Stats::Store& stat_store, Event::TimeSystem& time_system); } // namespace Api MATCHER_P(HeaderMapEqualIgnoreOrder, rhs, "") { diff --git a/test/tools/router_check/router.cc b/test/tools/router_check/router.cc index d68738fc239fa..043fcbe55480a 100644 --- a/test/tools/router_check/router.cc +++ b/test/tools/router_check/router.cc @@ -44,20 +44,23 @@ ToolConfig::ToolConfig(std::unique_ptr headers, int ran RouterCheckTool RouterCheckTool::create(const std::string& router_config_file) { // TODO(hennna): Allow users to load a full config and extract the route configuration from it. envoy::api::v2::RouteConfiguration route_config; - Api::ApiPtr api = Api::createApiForTest(); + auto stats = std::make_unique(); + auto api = Api::createApiForTest(*stats); MessageUtil::loadFromFile(router_config_file, route_config, *api); auto factory_context = std::make_unique>(); auto config = std::make_unique(route_config, *factory_context, false); - return RouterCheckTool(std::move(factory_context), std::move(config), std::move(api)); + return RouterCheckTool(std::move(factory_context), std::move(config), std::move(stats), + std::move(api)); } RouterCheckTool::RouterCheckTool( std::unique_ptr> factory_context, - std::unique_ptr config, Api::ApiPtr api) + std::unique_ptr config, std::unique_ptr stats, + Api::ApiPtr api) : factory_context_(std::move(factory_context)), config_(std::move(config)), - api_(std::move(api)) {} + stats_(std::move(stats)), api_(std::move(api)) {} bool RouterCheckTool::compareEntriesInJson(const std::string& expected_route_json) { Json::ObjectSharedPtr loader = Json::Factory::loadFromFile(expected_route_json, *api_); diff --git a/test/tools/router_check/router.h b/test/tools/router_check/router.h index f2d849db025aa..64283e11cd57a 100644 --- a/test/tools/router_check/router.h +++ b/test/tools/router_check/router.h @@ -67,7 +67,8 @@ class RouterCheckTool : Logger::Loggable { private: RouterCheckTool( std::unique_ptr> factory_context, - std::unique_ptr config, Api::ApiPtr api); + std::unique_ptr config, std::unique_ptr stats, + Api::ApiPtr api); bool compareCluster(ToolConfig& tool_config, const std::string& expected); bool compareVirtualCluster(ToolConfig& tool_config, const std::string& expected); @@ -94,6 +95,7 @@ class RouterCheckTool : Logger::Loggable { // TODO(hennna): Switch away from mocks following work done by @rlazarus in github issue #499. std::unique_ptr> factory_context_; std::unique_ptr config_; + std::unique_ptr stats_; Api::ApiPtr api_; }; } // namespace Envoy diff --git a/test/tools/schema_validator/validator.h b/test/tools/schema_validator/validator.h index ed50d676fe1f3..abcee1069940b 100644 --- a/test/tools/schema_validator/validator.h +++ b/test/tools/schema_validator/validator.h @@ -58,7 +58,7 @@ class Options { */ class Validator { public: - Validator() : api_(Api::createApiForTest()) {} + Validator() : api_(Api::createApiForTest(stats_)) {} /** * Validates the JSON at config_path against schema_type. * An EnvoyException is thrown in several cases: @@ -70,6 +70,7 @@ class Validator { void validate(const std::string& json_path, Schema::Type schema_type); private: + Stats::IsolatedStoreImpl stats_; Api::ApiPtr api_; }; From 85458c48eb8454882a62083f74cea76901c5d9de Mon Sep 17 00:00:00 2001 From: Sam Smith Date: Thu, 21 Feb 2019 08:49:52 -0500 Subject: [PATCH 13/13] only close open files Signed-off-by: Yael Harel Signed-off-by: Sam Smith --- source/common/filesystem/filesystem_impl.cc | 10 +++++----- test/common/filesystem/filesystem_impl_test.cc | 15 ++------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/source/common/filesystem/filesystem_impl.cc b/source/common/filesystem/filesystem_impl.cc index 420d3273e5203..a940c12f6fae9 100644 --- a/source/common/filesystem/filesystem_impl.cc +++ b/source/common/filesystem/filesystem_impl.cc @@ -25,8 +25,10 @@ namespace Filesystem { FileImpl::FileImpl(const std::string& path) : fd_(-1), path_(path) {} FileImpl::~FileImpl() { - const Api::SysCallBoolResult result = close(); - ASSERT(result.rc_); + if (isOpen()) { + const Api::SysCallBoolResult result = close(); + ASSERT(result.rc_); + } } Api::SysCallBoolResult FileImpl::open() { @@ -50,9 +52,7 @@ Api::SysCallSizeResult FileImpl::write(absl::string_view buffer) { } Api::SysCallBoolResult FileImpl::close() { - if (!isOpen()) { - return {true, 0}; - } + ASSERT(isOpen()); const int rc = ::close(fd_); if (rc == -1) { diff --git a/test/common/filesystem/filesystem_impl_test.cc b/test/common/filesystem/filesystem_impl_test.cc index 940c76d28ca87..cc7bb2cdff8e5 100644 --- a/test/common/filesystem/filesystem_impl_test.cc +++ b/test/common/filesystem/filesystem_impl_test.cc @@ -181,21 +181,10 @@ TEST_F(FileSystemImplTest, Close) { ::unlink(new_file_path.c_str()); FilePtr file = file_system_.createFile(new_file_path); - const Api::SysCallBoolResult result = file->close(); - EXPECT_TRUE(result.rc_); - EXPECT_FALSE(file->isOpen()); -} - -TEST_F(FileSystemImplTest, CloseTwice) { - const std::string new_file_path = TestEnvironment::temporaryPath("envoy_this_not_exist"); - ::unlink(new_file_path.c_str()); - - FilePtr file = file_system_.createFile(new_file_path); - Api::SysCallBoolResult result = file->close(); + Api::SysCallBoolResult result = file->open(); EXPECT_TRUE(result.rc_); - EXPECT_FALSE(file->isOpen()); + EXPECT_TRUE(file->isOpen()); - // check that closing an already closed file doesn't error result = file->close(); EXPECT_TRUE(result.rc_); EXPECT_FALSE(file->isOpen());