Test stub improvements.

PiperOrigin-RevId: 347736380
This commit is contained in:
Victor Costan 2020-12-16 02:56:14 +00:00
parent 402d88812c
commit ac55f842f7
2 changed files with 102 additions and 112 deletions

View File

@ -28,20 +28,14 @@
// //
// Various stubs for the unit tests for the open-source version of Snappy. // Various stubs for the unit tests for the open-source version of Snappy.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_WINDOWS_H
// Needed to be able to use std::max without workarounds in the source code.
// https://support.microsoft.com/en-us/help/143208/prb-using-stl-in-windows-program-can-cause-min-max-conflicts
#define NOMINMAX
#include <windows.h>
#endif
#include "snappy-test.h" #include "snappy-test.h"
#include <algorithm> #include <algorithm>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <string>
DEFINE_bool(run_microbenchmarks, true, DEFINE_bool(run_microbenchmarks, true,
"Run microbenchmarks before doing anything else."); "Run microbenchmarks before doing anything else.");
@ -65,7 +59,7 @@ bool StatusStub::ok() { return true; }
StatusStub GetContents(const std::string &filename, std::string *output, StatusStub GetContents(const std::string &filename, std::string *output,
const OptionsStub & /* options */) { const OptionsStub & /* options */) {
FILE *fp = std::fopen(filename.c_str(), "rb"); std::FILE *fp = std::fopen(filename.c_str(), "rb");
if (fp == nullptr) { if (fp == nullptr) {
std::perror(filename.c_str()); std::perror(filename.c_str());
std::exit(1); std::exit(1);
@ -88,7 +82,7 @@ StatusStub GetContents(const std::string &filename, std::string *output,
StatusStub SetContents(const std::string &file_name, const std::string &content, StatusStub SetContents(const std::string &file_name, const std::string &content,
const OptionsStub & /* options */) { const OptionsStub & /* options */) {
FILE *fp = std::fopen(file_name.c_str(), "wb"); std::FILE *fp = std::fopen(file_name.c_str(), "wb");
if (fp == nullptr) { if (fp == nullptr) {
std::perror(file_name.c_str()); std::perror(file_name.c_str());
std::exit(1); std::exit(1);
@ -123,19 +117,43 @@ std::string ReadTestDataFile(const std::string& base, size_t size_limit) {
return contents; return contents;
} }
std::string ReadTestDataFile(const std::string& base) {
return ReadTestDataFile(base, 0);
}
std::string StrFormat(const char* format, ...) { std::string StrFormat(const char* format, ...) {
char buf[4096]; char buffer[4096];
std::va_list ap; std::va_list ap;
va_start(ap, format); va_start(ap, format);
std::vsnprintf(buf, sizeof(buf), format, ap); std::vsnprintf(buffer, sizeof(buffer), format, ap);
va_end(ap); va_end(ap);
return buf; return buffer;
} }
LogMessage::~LogMessage() { std::cerr << std::endl; }
LogMessage &LogMessage::operator<<(const std::string &message) {
std::cerr << message;
return *this;
}
LogMessage &LogMessage::operator<<(int number) {
std::cerr << number;
return *this;
}
#ifdef _MSC_VER
// ~LogMessageCrash calls std::abort() and therefore never exits. This is by
// design, so temporarily disable warning C4722.
#pragma warning(push)
#pragma warning(disable : 4722)
#endif
LogMessageCrash::~LogMessageCrash() {
std::cerr << std::endl;
std::abort();
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
ZLib::ZLib() ZLib::ZLib()

View File

@ -31,10 +31,9 @@
#ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_ #ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_
#define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_ #define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_
#include <cstdarg> #ifdef HAVE_CONFIG_H
#include <cstdio> #include "config.h"
#include <iostream> #endif
#include <string>
#include "snappy-stubs-internal.h" #include "snappy-stubs-internal.h"
@ -135,8 +134,6 @@ namespace snappy {
std::string ReadTestDataFile(const std::string& base, size_t size_limit); std::string ReadTestDataFile(const std::string& base, size_t size_limit);
std::string ReadTestDataFile(const std::string& base);
// A std::sprintf() variant that returns a std::string. // A std::sprintf() variant that returns a std::string.
// Not safe for general use due to truncation issues. // Not safe for general use due to truncation issues.
std::string StrFormat(const char* format, ...); std::string StrFormat(const char* format, ...);
@ -145,17 +142,18 @@ std::string StrFormat(const char* format, ...);
// system time changing. // system time changing.
class CycleTimer { class CycleTimer {
public: public:
CycleTimer() : real_time_us_(0) {} inline CycleTimer() : real_time_us_(0) {}
inline ~CycleTimer() = default;
void Start() { inline void Start() {
#ifdef WIN32 #ifdef WIN32
QueryPerformanceCounter(&start_); QueryPerformanceCounter(&start_);
#else #else
gettimeofday(&start_, NULL); ::gettimeofday(&start_, nullptr);
#endif #endif
} }
void Stop() { inline void Stop() {
#ifdef WIN32 #ifdef WIN32
LARGE_INTEGER stop; LARGE_INTEGER stop;
LARGE_INTEGER frequency; LARGE_INTEGER frequency;
@ -166,27 +164,77 @@ class CycleTimer {
frequency.QuadPart; frequency.QuadPart;
real_time_us_ += elapsed * 1e6 + 0.5; real_time_us_ += elapsed * 1e6 + 0.5;
#else #else
struct timeval stop; struct ::timeval stop;
gettimeofday(&stop, NULL); ::gettimeofday(&stop, nullptr);
real_time_us_ += 1000000 * (stop.tv_sec - start_.tv_sec); real_time_us_ += 1000000 * (stop.tv_sec - start_.tv_sec);
real_time_us_ += (stop.tv_usec - start_.tv_usec); real_time_us_ += (stop.tv_usec - start_.tv_usec);
#endif #endif
} }
double Get() { inline double Get() { return real_time_us_ * 1e-6; }
return real_time_us_ * 1e-6;
}
private: private:
int64_t real_time_us_; int64_t real_time_us_;
#ifdef WIN32 #ifdef WIN32
LARGE_INTEGER start_; LARGE_INTEGER start_;
#else #else
struct timeval start_; struct ::timeval start_;
#endif #endif
}; };
// Logging.
class LogMessage {
public:
inline LogMessage() = default;
~LogMessage();
LogMessage &operator<<(const std::string &message);
LogMessage &operator<<(int number);
};
class LogMessageCrash : public LogMessage {
public:
inline LogMessageCrash() = default;
~LogMessageCrash();
};
// This class is used to explicitly ignore values in the conditional
// logging macros. This avoids compiler warnings like "value computed
// is not used" and "statement has no effect".
class LogMessageVoidify {
public:
inline LogMessageVoidify() = default;
inline ~LogMessageVoidify() = default;
// This has to be an operator with a precedence lower than << but
// higher than ?:
inline void operator&(const LogMessage &) {}
};
// Asserts, both versions activated in debug mode only,
// and ones that are always active.
#define CRASH_UNLESS(condition) \
SNAPPY_PREDICT_TRUE(condition) \
? (void)0 \
: snappy::LogMessageVoidify() & snappy::LogMessageCrash()
#define LOG(level) LogMessage()
#define VLOG(level) \
true ? (void)0 : snappy::LogMessageVoidify() & snappy::LogMessage()
#define CHECK(cond) CRASH_UNLESS(cond)
#define CHECK_LE(a, b) CRASH_UNLESS((a) <= (b))
#define CHECK_GE(a, b) CRASH_UNLESS((a) >= (b))
#define CHECK_EQ(a, b) CRASH_UNLESS((a) == (b))
#define CHECK_NE(a, b) CRASH_UNLESS((a) != (b))
#define CHECK_LT(a, b) CRASH_UNLESS((a) < (b))
#define CHECK_GT(a, b) CRASH_UNLESS((a) > (b))
#define CHECK_OK(cond) (cond).ok()
#ifdef HAVE_LIBZ #ifdef HAVE_LIBZ
// Object-oriented wrapper around zlib. // Object-oriented wrapper around zlib.
@ -310,80 +358,4 @@ class ZLib {
} // namespace snappy } // namespace snappy
// For main().
namespace snappy {
// Logging.
#define LOG(level) LogMessage()
#define VLOG(level) true ? (void)0 : \
snappy::LogMessageVoidify() & snappy::LogMessage()
class LogMessage {
public:
LogMessage() { }
~LogMessage() {
std::cerr << std::endl;
}
LogMessage& operator<<(const std::string& msg) {
std::cerr << msg;
return *this;
}
LogMessage& operator<<(int x) {
std::cerr << x;
return *this;
}
};
// Asserts, both versions activated in debug mode only,
// and ones that are always active.
#define CRASH_UNLESS(condition) \
SNAPPY_PREDICT_TRUE(condition) ? (void)0 : \
snappy::LogMessageVoidify() & snappy::LogMessageCrash()
#ifdef _MSC_VER
// ~LogMessageCrash calls std::abort() and therefore never exits. This is by
// design, so temporarily disable warning C4722.
#pragma warning(push)
#pragma warning(disable:4722)
#endif
class LogMessageCrash : public LogMessage {
public:
LogMessageCrash() { }
~LogMessageCrash() {
std::cerr << std::endl;
std::abort();
}
};
#ifdef _MSC_VER
#pragma warning(pop)
#endif
// This class is used to explicitly ignore values in the conditional
// logging macros. This avoids compiler warnings like "value computed
// is not used" and "statement has no effect".
class LogMessageVoidify {
public:
LogMessageVoidify() { }
// This has to be an operator with a precedence lower than << but
// higher than ?:
void operator&(const LogMessage&) { }
};
#define CHECK(cond) CRASH_UNLESS(cond)
#define CHECK_LE(a, b) CRASH_UNLESS((a) <= (b))
#define CHECK_GE(a, b) CRASH_UNLESS((a) >= (b))
#define CHECK_EQ(a, b) CRASH_UNLESS((a) == (b))
#define CHECK_NE(a, b) CRASH_UNLESS((a) != (b))
#define CHECK_LT(a, b) CRASH_UNLESS((a) < (b))
#define CHECK_GT(a, b) CRASH_UNLESS((a) > (b))
#define CHECK_OK(cond) (cond).ok()
} // namespace snappy
#endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_ #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_