xref: /aosp_15_r20/external/sandboxed-api/contrib/brotli/test/brotli_test.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1*ec63e07aSXin Li // Copyright 2022 Google LLC
2*ec63e07aSXin Li //
3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License");
4*ec63e07aSXin Li // you may not use this file except in compliance with the License.
5*ec63e07aSXin Li // You may obtain a copy of the License at
6*ec63e07aSXin Li //
7*ec63e07aSXin Li //     https://www.apache.org/licenses/LICENSE-2.0
8*ec63e07aSXin Li //
9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software
10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS,
11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*ec63e07aSXin Li // See the License for the specific language governing permissions and
13*ec63e07aSXin Li // limitations under the License.
14*ec63e07aSXin Li 
15*ec63e07aSXin Li #include <fcntl.h>
16*ec63e07aSXin Li 
17*ec63e07aSXin Li #include <fstream>
18*ec63e07aSXin Li 
19*ec63e07aSXin Li #include "contrib/brotli/sandboxed.h"
20*ec63e07aSXin Li #include "contrib/brotli/utils/utils_brotli.h"
21*ec63e07aSXin Li #include "contrib/brotli/utils/utils_brotli_dec.h"
22*ec63e07aSXin Li #include "contrib/brotli/utils/utils_brotli_enc.h"
23*ec63e07aSXin Li #include "sandboxed_api/util/path.h"
24*ec63e07aSXin Li #include "sandboxed_api/util/status_matchers.h"
25*ec63e07aSXin Li 
26*ec63e07aSXin Li namespace {
27*ec63e07aSXin Li 
28*ec63e07aSXin Li using ::sapi::IsOk;
29*ec63e07aSXin Li 
30*ec63e07aSXin Li class BrotliBase : public testing::Test {
31*ec63e07aSXin Li  protected:
GetTestFilePath(const std::string & filename)32*ec63e07aSXin Li   std::string GetTestFilePath(const std::string& filename) {
33*ec63e07aSXin Li     return sapi::file::JoinPath(test_dir_, filename);
34*ec63e07aSXin Li   }
35*ec63e07aSXin Li 
36*ec63e07aSXin Li   void SetUp() override;
37*ec63e07aSXin Li 
38*ec63e07aSXin Li   std::unique_ptr<BrotliSandbox> sandbox_;
39*ec63e07aSXin Li   std::unique_ptr<BrotliEncoder> enc_;
40*ec63e07aSXin Li   std::unique_ptr<BrotliDecoder> dec_;
41*ec63e07aSXin Li   const char* test_dir_;
42*ec63e07aSXin Li };
43*ec63e07aSXin Li 
44*ec63e07aSXin Li class BrotliMultiFile : public BrotliBase,
45*ec63e07aSXin Li                         public testing::WithParamInterface<std::string> {};
46*ec63e07aSXin Li 
SetUp()47*ec63e07aSXin Li void BrotliBase::SetUp() {
48*ec63e07aSXin Li   sandbox_ = std::make_unique<BrotliSapiSandbox>();
49*ec63e07aSXin Li   ASSERT_THAT(sandbox_.get()->Init(), IsOk());
50*ec63e07aSXin Li 
51*ec63e07aSXin Li   enc_ = std::make_unique<BrotliEncoder>(sandbox_.get());
52*ec63e07aSXin Li   ASSERT_TRUE(enc_.get()->IsInit());
53*ec63e07aSXin Li 
54*ec63e07aSXin Li   dec_ = std::make_unique<BrotliDecoder>(sandbox_.get());
55*ec63e07aSXin Li   ASSERT_TRUE(dec_.get()->IsInit());
56*ec63e07aSXin Li 
57*ec63e07aSXin Li   test_dir_ = getenv("TEST_FILES_DIR");
58*ec63e07aSXin Li   ASSERT_NE(test_dir_, nullptr);
59*ec63e07aSXin Li }
60*ec63e07aSXin Li 
TEST_F(BrotliBase,SetParamEnc)61*ec63e07aSXin Li TEST_F(BrotliBase, SetParamEnc) {
62*ec63e07aSXin Li   ASSERT_THAT(enc_.get()->SetParameter(BROTLI_PARAM_QUALITY, 5), IsOk());
63*ec63e07aSXin Li }
64*ec63e07aSXin Li 
TEST_F(BrotliBase,SetParamDec)65*ec63e07aSXin Li TEST_F(BrotliBase, SetParamDec) {
66*ec63e07aSXin Li   ASSERT_THAT(dec_.get()->SetParameter(
67*ec63e07aSXin Li                   BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION, 100),
68*ec63e07aSXin Li               IsOk());
69*ec63e07aSXin Li }
70*ec63e07aSXin Li 
TEST_F(BrotliBase,Compress)71*ec63e07aSXin Li TEST_F(BrotliBase, Compress) {
72*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufin,
73*ec63e07aSXin Li                             ReadFile(GetTestFilePath("text")));
74*ec63e07aSXin Li 
75*ec63e07aSXin Li   ASSERT_THAT(enc_.get()->Compress(bufin), IsOk());
76*ec63e07aSXin Li 
77*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufout,
78*ec63e07aSXin Li                             enc_.get()->TakeOutput());
79*ec63e07aSXin Li   ASSERT_LT(bufout.size(), bufin.size());
80*ec63e07aSXin Li }
81*ec63e07aSXin Li 
TEST_F(BrotliBase,CompressDecompress)82*ec63e07aSXin Li TEST_F(BrotliBase, CompressDecompress) {
83*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufin,
84*ec63e07aSXin Li                             ReadFile(GetTestFilePath("text")));
85*ec63e07aSXin Li 
86*ec63e07aSXin Li   ASSERT_THAT(enc_.get()->Compress(bufin), IsOk());
87*ec63e07aSXin Li 
88*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufcomp,
89*ec63e07aSXin Li                             enc_.get()->TakeOutput());
90*ec63e07aSXin Li   ASSERT_LT(bufcomp.size(), bufin.size());
91*ec63e07aSXin Li 
92*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(BrotliDecoderResult result,
93*ec63e07aSXin Li                             dec_.get()->Decompress(bufcomp));
94*ec63e07aSXin Li   ASSERT_THAT(result, BROTLI_DECODER_RESULT_SUCCESS);
95*ec63e07aSXin Li 
96*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufout,
97*ec63e07aSXin Li                             dec_.get()->TakeOutput());
98*ec63e07aSXin Li   ASSERT_EQ(bufin, bufout);
99*ec63e07aSXin Li }
100*ec63e07aSXin Li 
TEST_F(BrotliBase,CompressStreamDecompress)101*ec63e07aSXin Li TEST_F(BrotliBase, CompressStreamDecompress) {
102*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> buforig,
103*ec63e07aSXin Li                             ReadFile(GetTestFilePath("text")));
104*ec63e07aSXin Li 
105*ec63e07aSXin Li   for (auto it = buforig.begin(); it != buforig.end();) {
106*ec63e07aSXin Li     int nsize = std::min<size_t>(512, buforig.end() - it);
107*ec63e07aSXin Li     BrotliEncoderOperation op = BROTLI_OPERATION_PROCESS;
108*ec63e07aSXin Li     if (it + nsize == buforig.end()) {
109*ec63e07aSXin Li       op = BROTLI_OPERATION_FINISH;
110*ec63e07aSXin Li     }
111*ec63e07aSXin Li     std::vector<uint8_t> bufin(it, it + nsize);
112*ec63e07aSXin Li 
113*ec63e07aSXin Li     ASSERT_THAT(enc_.get()->Compress(bufin, op), IsOk());
114*ec63e07aSXin Li     it += nsize;
115*ec63e07aSXin Li   }
116*ec63e07aSXin Li 
117*ec63e07aSXin Li   bool empty = false;
118*ec63e07aSXin Li   std::vector<uint8_t> bufcomp;
119*ec63e07aSXin Li   while (!empty) {
120*ec63e07aSXin Li     SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> takebuf,
121*ec63e07aSXin Li                               enc_.get()->TakeOutput());
122*ec63e07aSXin Li     empty = takebuf.empty();
123*ec63e07aSXin Li     if (!empty) {
124*ec63e07aSXin Li       bufcomp.insert(bufcomp.end(), takebuf.begin(), takebuf.end());
125*ec63e07aSXin Li     }
126*ec63e07aSXin Li   }
127*ec63e07aSXin Li 
128*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(BrotliDecoderResult result,
129*ec63e07aSXin Li                             dec_.get()->Decompress(bufcomp));
130*ec63e07aSXin Li   ASSERT_THAT(result, BROTLI_DECODER_RESULT_SUCCESS);
131*ec63e07aSXin Li 
132*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufout,
133*ec63e07aSXin Li                             dec_.get()->TakeOutput());
134*ec63e07aSXin Li   ASSERT_EQ(buforig, bufout);
135*ec63e07aSXin Li }
136*ec63e07aSXin Li 
TEST_P(BrotliMultiFile,Decompress)137*ec63e07aSXin Li TEST_P(BrotliMultiFile, Decompress) {
138*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> buforig,
139*ec63e07aSXin Li                             ReadFile(GetTestFilePath("text")));
140*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufin,
141*ec63e07aSXin Li                             ReadFile(GetTestFilePath(GetParam())));
142*ec63e07aSXin Li 
143*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(BrotliDecoderResult result,
144*ec63e07aSXin Li                             dec_.get()->Decompress(bufin));
145*ec63e07aSXin Li   ASSERT_THAT(result, BROTLI_DECODER_RESULT_SUCCESS);
146*ec63e07aSXin Li 
147*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufout,
148*ec63e07aSXin Li                             dec_.get()->TakeOutput());
149*ec63e07aSXin Li   ASSERT_EQ(buforig, bufout);
150*ec63e07aSXin Li }
151*ec63e07aSXin Li 
TEST_P(BrotliMultiFile,DecompressCharStream)152*ec63e07aSXin Li TEST_P(BrotliMultiFile, DecompressCharStream) {
153*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> buforig,
154*ec63e07aSXin Li                             ReadFile(GetTestFilePath("text")));
155*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufcomp,
156*ec63e07aSXin Li                             ReadFile(GetTestFilePath(GetParam())));
157*ec63e07aSXin Li 
158*ec63e07aSXin Li   BrotliDecoderResult result;
159*ec63e07aSXin Li   std::vector<uint8_t> bufout;
160*ec63e07aSXin Li 
161*ec63e07aSXin Li   for (auto it = bufcomp.begin(); it != bufcomp.end(); ++it) {
162*ec63e07aSXin Li     std::vector<uint8_t> tmp(it, it + 1);
163*ec63e07aSXin Li 
164*ec63e07aSXin Li     SAPI_ASSERT_OK_AND_ASSIGN(result, dec_.get()->Decompress(tmp));
165*ec63e07aSXin Li     if (result == BROTLI_DECODER_RESULT_SUCCESS) {
166*ec63e07aSXin Li       SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufuncomptmp,
167*ec63e07aSXin Li                                 dec_.get()->TakeOutput());
168*ec63e07aSXin Li       bufout.insert(bufout.end(), bufuncomptmp.begin(), bufuncomptmp.end());
169*ec63e07aSXin Li     }
170*ec63e07aSXin Li   }
171*ec63e07aSXin Li   ASSERT_THAT(result, BROTLI_DECODER_RESULT_SUCCESS);
172*ec63e07aSXin Li 
173*ec63e07aSXin Li   ASSERT_EQ(buforig, bufout);
174*ec63e07aSXin Li }
175*ec63e07aSXin Li 
TEST_P(BrotliMultiFile,DecompressChunksStream)176*ec63e07aSXin Li TEST_P(BrotliMultiFile, DecompressChunksStream) {
177*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> buforig,
178*ec63e07aSXin Li                             ReadFile(GetTestFilePath("text")));
179*ec63e07aSXin Li   SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufcomp,
180*ec63e07aSXin Li                             ReadFile(GetTestFilePath(GetParam())));
181*ec63e07aSXin Li 
182*ec63e07aSXin Li   std::vector<size_t> chunks = {128, 256, 13, 37, 99, 10, 42};
183*ec63e07aSXin Li 
184*ec63e07aSXin Li   BrotliDecoderResult result;
185*ec63e07aSXin Li   std::vector<uint8_t> bufout;
186*ec63e07aSXin Li   std::vector<uint8_t>::iterator it = bufcomp.begin();
187*ec63e07aSXin Li 
188*ec63e07aSXin Li   for (int i = 0; it != bufcomp.end(); ++i) {
189*ec63e07aSXin Li     size_t nsize =
190*ec63e07aSXin Li         std::min<size_t>(bufcomp.end() - it, chunks[i % chunks.size()]);
191*ec63e07aSXin Li     std::vector<uint8_t> tmp(it, it + nsize);
192*ec63e07aSXin Li     it += nsize;
193*ec63e07aSXin Li 
194*ec63e07aSXin Li     SAPI_ASSERT_OK_AND_ASSIGN(result, dec_.get()->Decompress(tmp));
195*ec63e07aSXin Li     if (result == BROTLI_DECODER_RESULT_SUCCESS) {
196*ec63e07aSXin Li       SAPI_ASSERT_OK_AND_ASSIGN(std::vector<uint8_t> bufuncomptmp,
197*ec63e07aSXin Li                                 dec_.get()->TakeOutput());
198*ec63e07aSXin Li       bufout.insert(bufout.end(), bufuncomptmp.begin(), bufuncomptmp.end());
199*ec63e07aSXin Li     }
200*ec63e07aSXin Li   }
201*ec63e07aSXin Li 
202*ec63e07aSXin Li   ASSERT_THAT(result, BROTLI_DECODER_RESULT_SUCCESS);
203*ec63e07aSXin Li   ASSERT_EQ(buforig, bufout);
204*ec63e07aSXin Li }
205*ec63e07aSXin Li 
206*ec63e07aSXin Li INSTANTIATE_TEST_SUITE_P(BrotliBase, BrotliMultiFile,
207*ec63e07aSXin Li                          testing::Values("text.full.brotli",
208*ec63e07aSXin Li                                          "text.chunk.brotli"));
209*ec63e07aSXin Li }  // namespace
210