1/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 *     Copyright 2016 Couchbase, Inc.
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 */
17
18#include <gtest/gtest.h>
19#include <platform/compress.h>
20#include <strings.h>
21
22TEST(Compression, DetectInvalidAlgoritm) {
23    cb::compression::Buffer buffer;
24    EXPECT_THROW(cb::compression::inflate(
25                     (cb::compression::Algorithm)5, {}, buffer),
26                 std::invalid_argument);
27    EXPECT_THROW(cb::compression::deflate(
28                     (cb::compression::Algorithm)5, {}, buffer),
29                 std::invalid_argument);
30}
31
32TEST(Compression, TestSnappyCompression) {
33    cb::compression::Buffer input;
34    cb::compression::Buffer output(cb::compression::Allocator{
35            cb::compression::Allocator::Mode::Malloc});
36
37    input.resize(8192);
38    memset(input.data(), 'a', 8192);
39
40    EXPECT_TRUE(cb::compression::deflate(
41            cb::compression::Algorithm::Snappy, input.data(), output));
42    EXPECT_LT(output.size(), 8192u);
43    EXPECT_NE(nullptr, output.data());
44
45    cb::compression::Buffer back;
46    EXPECT_TRUE(cb::compression::inflate(
47            cb::compression::Algorithm::Snappy, output, back));
48    EXPECT_EQ(8192u, back.size());
49    EXPECT_NE(nullptr, back.data());
50    EXPECT_EQ(0, memcmp(input.data(), back.data(), input.size()));
51
52    // Verify that we don't exceed the max size:
53    EXPECT_FALSE(cb::compression::inflate(
54            cb::compression::Algorithm::Snappy, output, back, 4096));
55}
56
57TEST(Compression, TestIllegalSnappyInflate) {
58    cb::compression::Buffer input;
59    cb::compression::Buffer output;
60
61    input.resize(8192);
62    memset(input.data(), 'a', 8192);
63
64    EXPECT_FALSE(cb::compression::inflate(
65            cb::compression::Algorithm::Snappy, input, output));
66}
67
68TEST(Compression, ToString) {
69    EXPECT_EQ("Snappy", to_string(cb::compression::Algorithm::Snappy));
70    EXPECT_EQ("LZ4", to_string(cb::compression::Algorithm::LZ4));
71}
72
73TEST(Compression, ToAlgorithm) {
74    using namespace cb::compression;
75    EXPECT_EQ(Algorithm::Snappy, to_algorithm("SnApPy"));
76    EXPECT_EQ(Algorithm::LZ4, to_algorithm("lz4"));
77    EXPECT_THROW(to_algorithm("foo"), std::invalid_argument);
78}
79
80TEST(Compression, TestGetUncompressedLength) {
81    cb::compression::Buffer input;
82    cb::compression::Buffer output;
83
84    input.resize(8192);
85    memset(input.data(), 'a', 8192);
86    EXPECT_TRUE(cb::compression::deflate(cb::compression::Algorithm::Snappy,
87                                         {input.data(), input.size()},
88                                         output));
89    EXPECT_LT(output.size(), 8192u);
90    EXPECT_NE(nullptr, output.data());
91
92    EXPECT_EQ(8192u,
93              cb::compression::get_uncompressed_length(
94                      cb::compression::Algorithm::Snappy,
95                      {output.data(), output.size()}));
96}
97
98#ifdef CB_LZ4_SUPPORT
99TEST(Compression, TestLZ4Compression) {
100    cb::compression::Buffer input;
101    cb::compression::Buffer output;
102
103    input.resize(8192);
104    memset(input.data(), 'a', 8192);
105
106    EXPECT_TRUE(cb::compression::deflate(
107            cb::compression::Algorithm::LZ4, input, output));
108    EXPECT_LT(output.size(), 8192u);
109    EXPECT_NE(nullptr, output.data());
110
111    cb::compression::Buffer back;
112    EXPECT_TRUE(cb::compression::inflate(
113            cb::compression::Algorithm::LZ4, output, back));
114    EXPECT_EQ(8192u, back.size());
115    EXPECT_NE(nullptr, back.data());
116    EXPECT_EQ(0, memcmp(input.data(), back.data(), input.size()));
117}
118
119TEST(Compression, TestIllegalLZ4Inflate) {
120    cb::compression::Buffer input;
121    cb::compression::Buffer output;
122
123    input.resize(8192);
124    memset(input.data(), 'a', 8192);
125    *reinterpret_cast<uint32_t*>(input.data()) = 512;
126
127    EXPECT_FALSE(cb::compression::inflate(
128            cb::compression::Algorithm::LZ4, input, output));
129}
130
131TEST(Compression, TestLZ4GetUncompressedLength) {
132    cb::compression::Buffer input;
133    cb::compression::Buffer output;
134
135    input.resize(8192);
136    memset(input.data(), 'a', 8192);
137
138    EXPECT_TRUE(cb::compression::deflate(cb::compression::Algorithm::LZ4,
139                                         {input.data(), input.size()},
140                                         output));
141    EXPECT_LT(output.size(), 8192u);
142    EXPECT_NE(nullptr, output.data());
143
144    EXPECT_EQ(8192u,
145              cb::compression::get_uncompressed_length(
146                      cb::compression::Algorithm::LZ4,
147                      {output.data(), output.size()}));
148}
149
150#endif
151