PzstdTest.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Copyright (c) Meta Platforms, Inc. and affiliates.
  3. * All rights reserved.
  4. *
  5. * This source code is licensed under both the BSD-style license (found in the
  6. * LICENSE file in the root directory of this source tree) and the GPLv2 (found
  7. * in the COPYING file in the root directory of this source tree).
  8. */
  9. #include "Pzstd.h"
  10. extern "C" {
  11. #include "datagen.h"
  12. }
  13. #include "test/RoundTrip.h"
  14. #include "utils/ScopeGuard.h"
  15. #include <cstddef>
  16. #include <cstdio>
  17. #include <gtest/gtest.h>
  18. #include <memory>
  19. #include <random>
  20. using namespace std;
  21. using namespace pzstd;
  22. TEST(Pzstd, SmallSizes) {
  23. unsigned seed = std::random_device{}();
  24. std::fprintf(stderr, "Pzstd.SmallSizes seed: %u\n", seed);
  25. std::mt19937 gen(seed);
  26. for (unsigned len = 1; len < 256; ++len) {
  27. if (len % 16 == 0) {
  28. std::fprintf(stderr, "%u / 16\n", len / 16);
  29. }
  30. std::string inputFile = std::tmpnam(nullptr);
  31. auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); });
  32. {
  33. static uint8_t buf[256];
  34. RDG_genBuffer(buf, len, 0.5, 0.0, gen());
  35. auto fd = std::fopen(inputFile.c_str(), "wb");
  36. auto written = std::fwrite(buf, 1, len, fd);
  37. std::fclose(fd);
  38. ASSERT_EQ(written, len);
  39. }
  40. for (unsigned numThreads = 1; numThreads <= 2; ++numThreads) {
  41. for (unsigned level = 1; level <= 4; level *= 4) {
  42. auto errorGuard = makeScopeGuard([&] {
  43. std::fprintf(stderr, "# threads: %u\n", numThreads);
  44. std::fprintf(stderr, "compression level: %u\n", level);
  45. });
  46. Options options;
  47. options.overwrite = true;
  48. options.inputFiles = {inputFile};
  49. options.numThreads = numThreads;
  50. options.compressionLevel = level;
  51. options.verbosity = 1;
  52. ASSERT_TRUE(roundTrip(options));
  53. errorGuard.dismiss();
  54. }
  55. }
  56. }
  57. }
  58. TEST(Pzstd, LargeSizes) {
  59. unsigned seed = std::random_device{}();
  60. std::fprintf(stderr, "Pzstd.LargeSizes seed: %u\n", seed);
  61. std::mt19937 gen(seed);
  62. for (unsigned len = 1 << 20; len <= (1 << 24); len *= 2) {
  63. std::string inputFile = std::tmpnam(nullptr);
  64. auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); });
  65. {
  66. std::unique_ptr<uint8_t[]> buf(new uint8_t[len]);
  67. RDG_genBuffer(buf.get(), len, 0.5, 0.0, gen());
  68. auto fd = std::fopen(inputFile.c_str(), "wb");
  69. auto written = std::fwrite(buf.get(), 1, len, fd);
  70. std::fclose(fd);
  71. ASSERT_EQ(written, len);
  72. }
  73. for (unsigned numThreads = 1; numThreads <= 16; numThreads *= 4) {
  74. for (unsigned level = 1; level <= 4; level *= 4) {
  75. auto errorGuard = makeScopeGuard([&] {
  76. std::fprintf(stderr, "# threads: %u\n", numThreads);
  77. std::fprintf(stderr, "compression level: %u\n", level);
  78. });
  79. Options options;
  80. options.overwrite = true;
  81. options.inputFiles = {inputFile};
  82. options.numThreads = std::min(numThreads, options.numThreads);
  83. options.compressionLevel = level;
  84. options.verbosity = 1;
  85. ASSERT_TRUE(roundTrip(options));
  86. errorGuard.dismiss();
  87. }
  88. }
  89. }
  90. }
  91. TEST(Pzstd, DISABLED_ExtremelyLargeSize) {
  92. unsigned seed = std::random_device{}();
  93. std::fprintf(stderr, "Pzstd.ExtremelyLargeSize seed: %u\n", seed);
  94. std::mt19937 gen(seed);
  95. std::string inputFile = std::tmpnam(nullptr);
  96. auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); });
  97. {
  98. // Write 4GB + 64 MB
  99. constexpr size_t kLength = 1 << 26;
  100. std::unique_ptr<uint8_t[]> buf(new uint8_t[kLength]);
  101. auto fd = std::fopen(inputFile.c_str(), "wb");
  102. auto closeGuard = makeScopeGuard([&] { std::fclose(fd); });
  103. for (size_t i = 0; i < (1 << 6) + 1; ++i) {
  104. RDG_genBuffer(buf.get(), kLength, 0.5, 0.0, gen());
  105. auto written = std::fwrite(buf.get(), 1, kLength, fd);
  106. if (written != kLength) {
  107. std::fprintf(stderr, "Failed to write file, skipping test\n");
  108. return;
  109. }
  110. }
  111. }
  112. Options options;
  113. options.overwrite = true;
  114. options.inputFiles = {inputFile};
  115. options.compressionLevel = 1;
  116. if (options.numThreads == 0) {
  117. options.numThreads = 1;
  118. }
  119. ASSERT_TRUE(roundTrip(options));
  120. }
  121. TEST(Pzstd, ExtremelyCompressible) {
  122. std::string inputFile = std::tmpnam(nullptr);
  123. auto guard = makeScopeGuard([&] { std::remove(inputFile.c_str()); });
  124. {
  125. std::unique_ptr<uint8_t[]> buf(new uint8_t[10000]);
  126. std::memset(buf.get(), 'a', 10000);
  127. auto fd = std::fopen(inputFile.c_str(), "wb");
  128. auto written = std::fwrite(buf.get(), 1, 10000, fd);
  129. std::fclose(fd);
  130. ASSERT_EQ(written, 10000);
  131. }
  132. Options options;
  133. options.overwrite = true;
  134. options.inputFiles = {inputFile};
  135. options.numThreads = 1;
  136. options.compressionLevel = 1;
  137. ASSERT_TRUE(roundTrip(options));
  138. }