lz_ut.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #include "lz.h"
  2. #include <library/cpp/testing/unittest/registar.h>
  3. #include <library/cpp/resource/resource.h>
  4. #include <util/stream/file.h>
  5. #include <util/generic/vector.h>
  6. #include <util/system/tempfile.h>
  7. #include <util/generic/singleton.h>
  8. #define LDATA "./ldata"
  9. #define LDATA_RANDOM "./ldata.random"
  10. static const TString data = "aa aaa aa aaa aa aaa bb bbb bb bbb bb bbb";
  11. namespace {
  12. /**
  13. * Produces well-formed random crap
  14. **/
  15. TString RandomString(size_t size) {
  16. TString entropy(NResource::Find("/random.data"));
  17. TString result;
  18. size_t seed = 1;
  19. size_t j = 0;
  20. for (size_t i = 0; i < size; ++i) {
  21. seed *= 3;
  22. char sym;
  23. do {
  24. sym = char((seed ^ i) % 256);
  25. if (!sym) {
  26. seed += 1;
  27. }
  28. } while (!sym);
  29. Y_ASSERT(sym);
  30. j = (j + 1) % entropy.size();
  31. result += char(sym + entropy[j]);
  32. }
  33. return result;
  34. }
  35. TVector<TString> InitRandomData() {
  36. static const TVector<size_t> sizes = {
  37. 0,
  38. 1,
  39. 127,
  40. 2017,
  41. 32767,
  42. };
  43. TVector<TString> result;
  44. for (auto size : sizes) {
  45. result.push_back(RandomString(size));
  46. }
  47. result.push_back(NResource::Find("/request.data"));
  48. return result;
  49. }
  50. TString TestFileName(const TString& d, size_t bufferSize) {
  51. return LDATA_RANDOM + TString(".") + ToString(d.size()) + TString(".") + ToString(bufferSize);
  52. }
  53. struct TRandomData: public TVector<TString> {
  54. inline TRandomData() {
  55. InitRandomData().swap(*this);
  56. }
  57. };
  58. }
  59. static const TVector<size_t> bufferSizes = {
  60. 127,
  61. 1024,
  62. 32768,
  63. };
  64. #ifndef OPENSOURCE
  65. namespace {
  66. template <TLzqCompress::EVersion Ver, int Level, TLzqCompress::EMode Mode>
  67. struct TLzqCompressX: public TLzqCompress {
  68. inline TLzqCompressX(IOutputStream* out, size_t bufLen)
  69. : TLzqCompress(out, bufLen, Ver, Level, Mode)
  70. {
  71. }
  72. };
  73. }
  74. #endif
  75. template <class C>
  76. static inline void TestGoodDataCompress() {
  77. TFixedBufferFileOutput o(LDATA);
  78. C c(&o, 1024);
  79. TString d = data;
  80. for (size_t i = 0; i < 10; ++i) {
  81. c.Write(d.data(), d.size());
  82. c << Endl;
  83. d = d + d;
  84. }
  85. c.Finish();
  86. o.Finish();
  87. }
  88. template <class C>
  89. static inline void TestIncompressibleDataCompress(const TString& d, size_t bufferSize) {
  90. TString testFileName = TestFileName(d, bufferSize);
  91. TFixedBufferFileOutput o(testFileName);
  92. C c(&o, bufferSize);
  93. c.Write(d.data(), d.size());
  94. c.Finish();
  95. o.Finish();
  96. }
  97. template <class C>
  98. static inline void TestCompress() {
  99. TestGoodDataCompress<C>();
  100. for (auto bufferSize : bufferSizes) {
  101. for (auto rd : *Singleton<TRandomData>()) {
  102. TestIncompressibleDataCompress<C>(rd, bufferSize);
  103. }
  104. }
  105. }
  106. template <class D>
  107. static inline void TestGoodDataDecompress() {
  108. TTempFile tmpFile(LDATA);
  109. {
  110. TFileInput i1(LDATA);
  111. D ld(&i1);
  112. TString d = data;
  113. for (size_t i2 = 0; i2 < 10; ++i2) {
  114. UNIT_ASSERT_EQUAL(ld.ReadLine(), d);
  115. d = d + d;
  116. }
  117. }
  118. }
  119. template <class D>
  120. static inline void TestIncompressibleDataDecompress(const TString& d, size_t bufferSize) {
  121. TString testFileName = TestFileName(d, bufferSize);
  122. TTempFile tmpFile(testFileName);
  123. {
  124. TFileInput i(testFileName);
  125. D ld(&i);
  126. UNIT_ASSERT_EQUAL(ld.ReadAll(), d);
  127. }
  128. }
  129. template <class D>
  130. static inline void TestDecompress() {
  131. TestGoodDataDecompress<D>();
  132. for (auto bufferSize : bufferSizes) {
  133. for (auto rd : *Singleton<TRandomData>()) {
  134. TestIncompressibleDataDecompress<D>(rd, bufferSize);
  135. }
  136. }
  137. }
  138. class TMixedDecompress: public IInputStream {
  139. public:
  140. TMixedDecompress(IInputStream* input)
  141. : Slave_(OpenLzDecompressor(input).Release())
  142. {
  143. }
  144. private:
  145. size_t DoRead(void* buf, size_t len) override {
  146. return Slave_->Read(buf, len);
  147. }
  148. private:
  149. THolder<IInputStream> Slave_;
  150. };
  151. template <class C>
  152. static inline void TestMixedDecompress() {
  153. TestCompress<C>();
  154. TestDecompress<TMixedDecompress>();
  155. }
  156. template <class D, class C>
  157. static inline void TestDecompressError() {
  158. TestCompress<C>();
  159. UNIT_ASSERT_EXCEPTION(TestDecompress<D>(), TDecompressorError);
  160. }
  161. Y_UNIT_TEST_SUITE(TLzTest) {
  162. #ifndef OPENSOURCE
  163. Y_UNIT_TEST(TestLzo) {
  164. TestCompress<TLzoCompress>();
  165. TestDecompress<TLzoDecompress>();
  166. }
  167. #endif
  168. Y_UNIT_TEST(TestLzf) {
  169. TestCompress<TLzfCompress>();
  170. TestDecompress<TLzfDecompress>();
  171. }
  172. #ifndef OPENSOURCE
  173. Y_UNIT_TEST(TestLzq) {
  174. TestCompress<TLzqCompress>();
  175. TestDecompress<TLzqDecompress>();
  176. }
  177. Y_UNIT_TEST(TestLzq151_1) {
  178. TestCompress<TLzqCompressX<TLzqCompress::V_1_51, 1, TLzqCompress::M_0>>();
  179. TestDecompress<TLzqDecompress>();
  180. }
  181. Y_UNIT_TEST(TestLzq151_2) {
  182. TestCompress<TLzqCompressX<TLzqCompress::V_1_51, 2, TLzqCompress::M_100000>>();
  183. TestDecompress<TLzqDecompress>();
  184. }
  185. Y_UNIT_TEST(TestLzq151_3) {
  186. TestCompress<TLzqCompressX<TLzqCompress::V_1_51, 3, TLzqCompress::M_1000000>>();
  187. TestDecompress<TLzqDecompress>();
  188. }
  189. Y_UNIT_TEST(TestLzq140_1) {
  190. TestCompress<TLzqCompressX<TLzqCompress::V_1_40, 1, TLzqCompress::M_0>>();
  191. TestDecompress<TLzqDecompress>();
  192. }
  193. Y_UNIT_TEST(TestLzq140_2) {
  194. TestCompress<TLzqCompressX<TLzqCompress::V_1_40, 2, TLzqCompress::M_100000>>();
  195. TestDecompress<TLzqDecompress>();
  196. }
  197. Y_UNIT_TEST(TestLzq140_3) {
  198. TestCompress<TLzqCompressX<TLzqCompress::V_1_40, 3, TLzqCompress::M_1000000>>();
  199. TestDecompress<TLzqDecompress>();
  200. }
  201. #endif
  202. Y_UNIT_TEST(TestLz4) {
  203. TestCompress<TLz4Compress>();
  204. TestDecompress<TLz4Decompress>();
  205. }
  206. Y_UNIT_TEST(TestSnappy) {
  207. TestCompress<TSnappyCompress>();
  208. TestDecompress<TSnappyDecompress>();
  209. }
  210. Y_UNIT_TEST(TestGeneric) {
  211. #ifndef OPENSOURCE
  212. TestMixedDecompress<TLzoCompress>();
  213. #endif
  214. TestMixedDecompress<TLzfCompress>();
  215. #ifndef OPENSOURCE
  216. TestMixedDecompress<TLzqCompress>();
  217. #endif
  218. TestMixedDecompress<TLz4Compress>();
  219. TestMixedDecompress<TSnappyCompress>();
  220. }
  221. Y_UNIT_TEST(TestDecompressorError) {
  222. #ifndef OPENSOURCE
  223. TestDecompressError<TLzoDecompress, TLzfCompress>();
  224. TestDecompressError<TLzfDecompress, TLzqCompress>();
  225. TestDecompressError<TLzqDecompress, TLz4Compress>();
  226. #endif
  227. TestDecompressError<TLz4Decompress, TSnappyCompress>();
  228. TestDecompressError<TSnappyDecompress, TBufferedOutput>();
  229. TestDecompressError<TMixedDecompress, TBufferedOutput>();
  230. }
  231. Y_UNIT_TEST(TestFactory) {
  232. TStringStream ss;
  233. {
  234. TLz4Compress c(&ss);
  235. c.Write("123456789", 9);
  236. c.Finish();
  237. }
  238. TAutoPtr<IInputStream> is(OpenOwnedLzDecompressor(new TStringInput(ss.Str())));
  239. UNIT_ASSERT_EQUAL(is->ReadAll(), "123456789");
  240. }
  241. Y_UNIT_TEST(TestYQ609) {
  242. auto data = NResource::Find("/yq_609.data");
  243. TMemoryInput input(data.Data(), data.Size());
  244. TLz4Decompress d(&input);
  245. UNIT_ASSERT_EXCEPTION(d.ReadAll(), TDecompressorError);
  246. }
  247. }