snappy-test.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. // Copyright 2011 Google Inc. All Rights Reserved.
  2. //
  3. // Redistribution and use in source and binary forms, with or without
  4. // modification, are permitted provided that the following conditions are
  5. // met:
  6. //
  7. // * Redistributions of source code must retain the above copyright
  8. // notice, this list of conditions and the following disclaimer.
  9. // * Redistributions in binary form must reproduce the above
  10. // copyright notice, this list of conditions and the following disclaimer
  11. // in the documentation and/or other materials provided with the
  12. // distribution.
  13. // * Neither the name of Google Inc. nor the names of its
  14. // contributors may be used to endorse or promote products derived from
  15. // this software without specific prior written permission.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  20. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  21. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  22. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  23. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. //
  29. // Various stubs for the unit tests for the open-source version of Snappy.
  30. #ifndef THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_
  31. #define THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_
  32. #include <iostream>
  33. #include <string>
  34. #include "snappy-stubs-internal.h"
  35. #include <stdio.h>
  36. #include <stdarg.h>
  37. #ifdef HAVE_SYS_MMAN_H
  38. #include <sys/mman.h>
  39. #endif
  40. #ifdef HAVE_SYS_RESOURCE_H
  41. #include <sys/resource.h>
  42. #endif
  43. #ifdef HAVE_SYS_TIME_H
  44. #include <sys/time.h>
  45. #endif
  46. #ifdef HAVE_WINDOWS_H
  47. #include <windows.h>
  48. #endif
  49. #include <string>
  50. #ifdef HAVE_GTEST
  51. #include <gtest/gtest.h>
  52. #undef TYPED_TEST
  53. #define TYPED_TEST TEST
  54. #define INIT_GTEST(argc, argv) ::testing::InitGoogleTest(argc, *argv)
  55. #else
  56. // Stubs for if the user doesn't have Google Test installed.
  57. #define TEST(test_case, test_subcase) \
  58. void Test_ ## test_case ## _ ## test_subcase()
  59. #define INIT_GTEST(argc, argv)
  60. #define TYPED_TEST TEST
  61. #define EXPECT_EQ CHECK_EQ
  62. #define EXPECT_NE CHECK_NE
  63. #define EXPECT_FALSE(cond) CHECK(!(cond))
  64. #endif
  65. #ifdef HAVE_GFLAGS
  66. #include <gflags/gflags.h>
  67. // This is tricky; both gflags and Google Test want to look at the command line
  68. // arguments. Google Test seems to be the most happy with unknown arguments,
  69. // though, so we call it first and hope for the best.
  70. #define InitGoogle(argv0, argc, argv, remove_flags) \
  71. INIT_GTEST(argc, argv); \
  72. google::ParseCommandLineFlags(argc, argv, remove_flags);
  73. #else
  74. // If we don't have the gflags package installed, these can only be
  75. // changed at compile time.
  76. #define DEFINE_int32(flag_name, default_value, description) \
  77. static int FLAGS_ ## flag_name = default_value;
  78. #define InitGoogle(argv0, argc, argv, remove_flags) \
  79. INIT_GTEST(argc, argv)
  80. #endif
  81. #ifdef HAVE_LIBZ
  82. #include "zlib.h"
  83. #endif
  84. #ifdef HAVE_LIBLZO2
  85. #include "lzo/lzo1x.h"
  86. #endif
  87. #ifdef HAVE_LIBLZF
  88. extern "C" {
  89. #include "lzf.h"
  90. }
  91. #endif
  92. #ifdef HAVE_LIBFASTLZ
  93. #include "fastlz.h"
  94. #endif
  95. #ifdef HAVE_LIBQUICKLZ
  96. #include "quicklz.h"
  97. #endif
  98. namespace {
  99. namespace file {
  100. int Defaults() { return 0; }
  101. class DummyStatus {
  102. public:
  103. void CheckSuccess() { }
  104. };
  105. DummyStatus GetContents(
  106. const std::string& filename, std::string* data, int unused) {
  107. FILE* fp = fopen(filename.c_str(), "rb");
  108. if (fp == NULL) {
  109. perror(filename.c_str());
  110. exit(1);
  111. }
  112. data->clear();
  113. while (!feof(fp)) {
  114. char buf[4096];
  115. size_t ret = fread(buf, 1, 4096, fp);
  116. if (ret == 0 && ferror(fp)) {
  117. perror("fread");
  118. exit(1);
  119. }
  120. data->append(std::string(buf, ret));
  121. }
  122. fclose(fp);
  123. return DummyStatus();
  124. }
  125. inline DummyStatus SetContents(
  126. const std::string& filename, const std::string& str, int unused) {
  127. FILE* fp = fopen(filename.c_str(), "wb");
  128. if (fp == NULL) {
  129. perror(filename.c_str());
  130. exit(1);
  131. }
  132. int ret = fwrite(str.data(), str.size(), 1, fp);
  133. if (ret != 1) {
  134. perror("fwrite");
  135. exit(1);
  136. }
  137. fclose(fp);
  138. return DummyStatus();
  139. }
  140. } // namespace file
  141. } // namespace
  142. namespace snappy {
  143. #define FLAGS_test_random_seed 301
  144. typedef string TypeParam;
  145. void Test_CorruptedTest_VerifyCorrupted();
  146. void Test_Snappy_SimpleTests();
  147. void Test_Snappy_MaxBlowup();
  148. void Test_Snappy_RandomData();
  149. void Test_Snappy_FourByteOffset();
  150. void Test_SnappyCorruption_TruncatedVarint();
  151. void Test_SnappyCorruption_UnterminatedVarint();
  152. void Test_SnappyCorruption_OverflowingVarint();
  153. void Test_Snappy_ReadPastEndOfBuffer();
  154. void Test_Snappy_FindMatchLength();
  155. void Test_Snappy_FindMatchLengthRandom();
  156. string ReadTestDataFile(const string& base, size_t size_limit);
  157. string ReadTestDataFile(const string& base);
  158. // A sprintf() variant that returns a std::string.
  159. // Not safe for general use due to truncation issues.
  160. string StringPrintf(const char* format, ...);
  161. // A simple, non-cryptographically-secure random generator.
  162. class ACMRandom {
  163. public:
  164. explicit ACMRandom(uint32 seed) : seed_(seed) {}
  165. int32 Next();
  166. int32 Uniform(int32 n) {
  167. return Next() % n;
  168. }
  169. uint8 Rand8() {
  170. return static_cast<uint8>((Next() >> 1) & 0x000000ff);
  171. }
  172. bool OneIn(int X) { return Uniform(X) == 0; }
  173. // Skewed: pick "base" uniformly from range [0,max_log] and then
  174. // return "base" random bits. The effect is to pick a number in the
  175. // range [0,2^max_log-1] with bias towards smaller numbers.
  176. int32 Skewed(int max_log);
  177. private:
  178. static const uint32 M = 2147483647L; // 2^31-1
  179. uint32 seed_;
  180. };
  181. inline int32 ACMRandom::Next() {
  182. static const uint64 A = 16807; // bits 14, 8, 7, 5, 2, 1, 0
  183. // We are computing
  184. // seed_ = (seed_ * A) % M, where M = 2^31-1
  185. //
  186. // seed_ must not be zero or M, or else all subsequent computed values
  187. // will be zero or M respectively. For all other values, seed_ will end
  188. // up cycling through every number in [1,M-1]
  189. uint64 product = seed_ * A;
  190. // Compute (product % M) using the fact that ((x << 31) % M) == x.
  191. seed_ = (product >> 31) + (product & M);
  192. // The first reduction may overflow by 1 bit, so we may need to repeat.
  193. // mod == M is not possible; using > allows the faster sign-bit-based test.
  194. if (seed_ > M) {
  195. seed_ -= M;
  196. }
  197. return seed_;
  198. }
  199. inline int32 ACMRandom::Skewed(int max_log) {
  200. const int32 base = (Next() - 1) % (max_log+1);
  201. return (Next() - 1) & ((1u << base)-1);
  202. }
  203. // A wall-time clock. This stub is not super-accurate, nor resistant to the
  204. // system time changing.
  205. class CycleTimer {
  206. public:
  207. CycleTimer() : real_time_us_(0) {}
  208. void Start() {
  209. #ifdef WIN32
  210. QueryPerformanceCounter(&start_);
  211. #else
  212. gettimeofday(&start_, NULL);
  213. #endif
  214. }
  215. void Stop() {
  216. #ifdef WIN32
  217. LARGE_INTEGER stop;
  218. LARGE_INTEGER frequency;
  219. QueryPerformanceCounter(&stop);
  220. QueryPerformanceFrequency(&frequency);
  221. double elapsed = static_cast<double>(stop.QuadPart - start_.QuadPart) /
  222. frequency.QuadPart;
  223. real_time_us_ += elapsed * 1e6 + 0.5;
  224. #else
  225. struct timeval stop;
  226. gettimeofday(&stop, NULL);
  227. real_time_us_ += 1000000 * (stop.tv_sec - start_.tv_sec);
  228. real_time_us_ += (stop.tv_usec - start_.tv_usec);
  229. #endif
  230. }
  231. double Get() {
  232. return real_time_us_ * 1e-6;
  233. }
  234. private:
  235. int64 real_time_us_;
  236. #ifdef WIN32
  237. LARGE_INTEGER start_;
  238. #else
  239. struct timeval start_;
  240. #endif
  241. };
  242. // Minimalistic microbenchmark framework.
  243. typedef void (*BenchmarkFunction)(int, int);
  244. class Benchmark {
  245. public:
  246. Benchmark(const string& name, BenchmarkFunction function) :
  247. name_(name), function_(function) {}
  248. Benchmark* DenseRange(int start, int stop) {
  249. start_ = start;
  250. stop_ = stop;
  251. return this;
  252. }
  253. void Run();
  254. private:
  255. const string name_;
  256. const BenchmarkFunction function_;
  257. int start_, stop_;
  258. };
  259. #define BENCHMARK(benchmark_name) \
  260. Benchmark* Benchmark_ ## benchmark_name = \
  261. (new Benchmark(#benchmark_name, benchmark_name))
  262. extern Benchmark* Benchmark_BM_UFlat;
  263. extern Benchmark* Benchmark_BM_UIOVec;
  264. extern Benchmark* Benchmark_BM_UValidate;
  265. extern Benchmark* Benchmark_BM_ZFlat;
  266. void ResetBenchmarkTiming();
  267. void StartBenchmarkTiming();
  268. void StopBenchmarkTiming();
  269. void SetBenchmarkLabel(const string& str);
  270. void SetBenchmarkBytesProcessed(int64 bytes);
  271. #ifdef HAVE_LIBZ
  272. // Object-oriented wrapper around zlib.
  273. class ZLib {
  274. public:
  275. ZLib();
  276. ~ZLib();
  277. // Wipe a ZLib object to a virgin state. This differs from Reset()
  278. // in that it also breaks any state.
  279. void Reinit();
  280. // Call this to make a zlib buffer as good as new. Here's the only
  281. // case where they differ:
  282. // CompressChunk(a); CompressChunk(b); CompressChunkDone(); vs
  283. // CompressChunk(a); Reset(); CompressChunk(b); CompressChunkDone();
  284. // You'll want to use Reset(), then, when you interrupt a compress
  285. // (or uncompress) in the middle of a chunk and want to start over.
  286. void Reset();
  287. // According to the zlib manual, when you Compress, the destination
  288. // buffer must have size at least src + .1%*src + 12. This function
  289. // helps you calculate that. Augment this to account for a potential
  290. // gzip header and footer, plus a few bytes of slack.
  291. static int MinCompressbufSize(int uncompress_size) {
  292. return uncompress_size + uncompress_size/1000 + 40;
  293. }
  294. // Compresses the source buffer into the destination buffer.
  295. // sourceLen is the byte length of the source buffer.
  296. // Upon entry, destLen is the total size of the destination buffer,
  297. // which must be of size at least MinCompressbufSize(sourceLen).
  298. // Upon exit, destLen is the actual size of the compressed buffer.
  299. //
  300. // This function can be used to compress a whole file at once if the
  301. // input file is mmap'ed.
  302. //
  303. // Returns Z_OK if success, Z_MEM_ERROR if there was not
  304. // enough memory, Z_BUF_ERROR if there was not enough room in the
  305. // output buffer. Note that if the output buffer is exactly the same
  306. // size as the compressed result, we still return Z_BUF_ERROR.
  307. // (check CL#1936076)
  308. int Compress(Bytef *dest, uLongf *destLen,
  309. const Bytef *source, uLong sourceLen);
  310. // Uncompresses the source buffer into the destination buffer.
  311. // The destination buffer must be long enough to hold the entire
  312. // decompressed contents.
  313. //
  314. // Returns Z_OK on success, otherwise, it returns a zlib error code.
  315. int Uncompress(Bytef *dest, uLongf *destLen,
  316. const Bytef *source, uLong sourceLen);
  317. // Uncompress data one chunk at a time -- ie you can call this
  318. // more than once. To get this to work you need to call per-chunk
  319. // and "done" routines.
  320. //
  321. // Returns Z_OK if success, Z_MEM_ERROR if there was not
  322. // enough memory, Z_BUF_ERROR if there was not enough room in the
  323. // output buffer.
  324. int UncompressAtMost(Bytef *dest, uLongf *destLen,
  325. const Bytef *source, uLong *sourceLen);
  326. // Checks gzip footer information, as needed. Mostly this just
  327. // makes sure the checksums match. Whenever you call this, it
  328. // will assume the last 8 bytes from the previous UncompressChunk
  329. // call are the footer. Returns true iff everything looks ok.
  330. bool UncompressChunkDone();
  331. private:
  332. int InflateInit(); // sets up the zlib inflate structure
  333. int DeflateInit(); // sets up the zlib deflate structure
  334. // These init the zlib data structures for compressing/uncompressing
  335. int CompressInit(Bytef *dest, uLongf *destLen,
  336. const Bytef *source, uLong *sourceLen);
  337. int UncompressInit(Bytef *dest, uLongf *destLen,
  338. const Bytef *source, uLong *sourceLen);
  339. // Initialization method to be called if we hit an error while
  340. // uncompressing. On hitting an error, call this method before
  341. // returning the error.
  342. void UncompressErrorInit();
  343. // Helper function for Compress
  344. int CompressChunkOrAll(Bytef *dest, uLongf *destLen,
  345. const Bytef *source, uLong sourceLen,
  346. int flush_mode);
  347. int CompressAtMostOrAll(Bytef *dest, uLongf *destLen,
  348. const Bytef *source, uLong *sourceLen,
  349. int flush_mode);
  350. // Likewise for UncompressAndUncompressChunk
  351. int UncompressChunkOrAll(Bytef *dest, uLongf *destLen,
  352. const Bytef *source, uLong sourceLen,
  353. int flush_mode);
  354. int UncompressAtMostOrAll(Bytef *dest, uLongf *destLen,
  355. const Bytef *source, uLong *sourceLen,
  356. int flush_mode);
  357. // Initialization method to be called if we hit an error while
  358. // compressing. On hitting an error, call this method before
  359. // returning the error.
  360. void CompressErrorInit();
  361. int compression_level_; // compression level
  362. int window_bits_; // log base 2 of the window size used in compression
  363. int mem_level_; // specifies the amount of memory to be used by
  364. // compressor (1-9)
  365. z_stream comp_stream_; // Zlib stream data structure
  366. bool comp_init_; // True if we have initialized comp_stream_
  367. z_stream uncomp_stream_; // Zlib stream data structure
  368. bool uncomp_init_; // True if we have initialized uncomp_stream_
  369. // These are used only with chunked compression.
  370. bool first_chunk_; // true if we need to emit headers with this chunk
  371. };
  372. #endif // HAVE_LIBZ
  373. } // namespace snappy
  374. DECLARE_bool(run_microbenchmarks);
  375. static inline void RunSpecifiedBenchmarks() {
  376. if (!FLAGS_run_microbenchmarks) {
  377. return;
  378. }
  379. fprintf(stderr, "Running microbenchmarks.\n");
  380. #ifndef NDEBUG
  381. fprintf(stderr, "WARNING: Compiled with assertions enabled, will be slow.\n");
  382. #endif
  383. #ifndef __OPTIMIZE__
  384. fprintf(stderr, "WARNING: Compiled without optimization, will be slow.\n");
  385. #endif
  386. fprintf(stderr, "Benchmark Time(ns) CPU(ns) Iterations\n");
  387. fprintf(stderr, "---------------------------------------------------\n");
  388. snappy::Benchmark_BM_UFlat->Run();
  389. snappy::Benchmark_BM_UIOVec->Run();
  390. snappy::Benchmark_BM_UValidate->Run();
  391. snappy::Benchmark_BM_ZFlat->Run();
  392. fprintf(stderr, "\n");
  393. }
  394. #ifndef HAVE_GTEST
  395. static inline int RUN_ALL_TESTS() {
  396. fprintf(stderr, "Running correctness tests.\n");
  397. snappy::Test_CorruptedTest_VerifyCorrupted();
  398. snappy::Test_Snappy_SimpleTests();
  399. snappy::Test_Snappy_MaxBlowup();
  400. snappy::Test_Snappy_RandomData();
  401. snappy::Test_Snappy_FourByteOffset();
  402. snappy::Test_SnappyCorruption_TruncatedVarint();
  403. snappy::Test_SnappyCorruption_UnterminatedVarint();
  404. snappy::Test_SnappyCorruption_OverflowingVarint();
  405. snappy::Test_Snappy_ReadPastEndOfBuffer();
  406. snappy::Test_Snappy_FindMatchLength();
  407. snappy::Test_Snappy_FindMatchLengthRandom();
  408. fprintf(stderr, "All tests passed.\n");
  409. return 0;
  410. }
  411. #endif // HAVE_GTEST
  412. // For main().
  413. namespace snappy {
  414. // Logging.
  415. #define LOG(level) LogMessage()
  416. #define VLOG(level) true ? (void)0 : \
  417. snappy::LogMessageVoidify() & snappy::LogMessage()
  418. class LogMessage {
  419. public:
  420. LogMessage() { }
  421. ~LogMessage() {
  422. std::cerr << std::endl;
  423. }
  424. LogMessage& operator<<(const std::string& msg) {
  425. std::cerr << msg;
  426. return *this;
  427. }
  428. LogMessage& operator<<(int x) {
  429. std::cerr << x;
  430. return *this;
  431. }
  432. };
  433. // Asserts, both versions activated in debug mode only,
  434. // and ones that are always active.
  435. #define CRASH_UNLESS(condition) \
  436. PREDICT_TRUE(condition) ? (void)0 : \
  437. snappy::LogMessageVoidify() & snappy::LogMessageCrash()
  438. #ifdef _MSC_VER
  439. // ~LogMessageCrash calls abort() and therefore never exits. This is by design
  440. // so temporarily disable warning C4722.
  441. #pragma warning(push)
  442. #pragma warning(disable:4722)
  443. #endif
  444. class LogMessageCrash : public LogMessage {
  445. public:
  446. LogMessageCrash() { }
  447. ~LogMessageCrash() {
  448. std::cerr << std::endl;
  449. abort();
  450. }
  451. };
  452. #ifdef _MSC_VER
  453. #pragma warning(pop)
  454. #endif
  455. // This class is used to explicitly ignore values in the conditional
  456. // logging macros. This avoids compiler warnings like "value computed
  457. // is not used" and "statement has no effect".
  458. class LogMessageVoidify {
  459. public:
  460. LogMessageVoidify() { }
  461. // This has to be an operator with a precedence lower than << but
  462. // higher than ?:
  463. void operator&(const LogMessage&) { }
  464. };
  465. #define CHECK(cond) CRASH_UNLESS(cond)
  466. #define CHECK_LE(a, b) CRASH_UNLESS((a) <= (b))
  467. #define CHECK_GE(a, b) CRASH_UNLESS((a) >= (b))
  468. #define CHECK_EQ(a, b) CRASH_UNLESS((a) == (b))
  469. #define CHECK_NE(a, b) CRASH_UNLESS((a) != (b))
  470. #define CHECK_LT(a, b) CRASH_UNLESS((a) < (b))
  471. #define CHECK_GT(a, b) CRASH_UNLESS((a) > (b))
  472. #define CHECK_OK(cond) (cond).CheckSuccess()
  473. } // namespace snappy
  474. #endif // THIRD_PARTY_SNAPPY_OPENSOURCE_SNAPPY_TEST_H_