xref: /aosp_15_r20/external/sandboxed-api/contrib/c-blosc/test/test_blosc.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <fstream>
16 
17 #include "contrib/c-blosc/sandboxed.h"
18 #include "contrib/c-blosc/utils/utils_blosc.h"
19 #include "sandboxed_api/util/path.h"
20 #include "sandboxed_api/util/status_matchers.h"
21 #include "sandboxed_api/util/temp_file.h"
22 
23 namespace {
24 
25 using ::sapi::IsOk;
26 
27 constexpr size_t kDefaultBlockSize = 19059;
28 
CompareFiles(const std::string & name1,const std::string & name2)29 bool CompareFiles(const std::string& name1, const std::string& name2) {
30   std::ifstream f1(name1, std::ios::binary);
31   if (!f1.is_open()) {
32     return false;
33   }
34 
35   std::ifstream f2(name2, std::ios::binary);
36   if (!f2.is_open()) {
37     return false;
38   }
39 
40   while (!f1.eof() && !f2.eof()) {
41     char buf1[128];
42     char buf2[128];
43 
44     f1.read(buf1, sizeof(buf1));
45     f2.read(buf2, sizeof(buf2));
46 
47     if (f1.gcount() != f2.gcount()) {
48       return false;
49     }
50     if (memcmp(&buf1, &buf2, f2.gcount()) != 0) {
51       return false;
52     }
53   }
54 
55   return f1.eof() == f2.eof();
56 }
57 
GetTestFilePath(const std::string & filename)58 std::string GetTestFilePath(const std::string& filename) {
59   return sapi::file::JoinPath(getenv("TEST_FILES_DIR"), filename);
60 }
61 
GetTemporaryFile(const std::string & filename)62 std::string GetTemporaryFile(const std::string& filename) {
63   absl::StatusOr<std::string> tmp_file =
64       sapi::CreateNamedTempFileAndClose(filename);
65   if (!tmp_file.ok()) {
66     return "";
67   }
68 
69   return sapi::file::JoinPath(sapi::file_util::fileops::GetCWD(), *tmp_file);
70 }
71 
GetStreamSize(std::ifstream & stream)72 std::streamsize GetStreamSize(std::ifstream& stream) {
73   stream.seekg(0, std::ios_base::end);
74   std::streamsize ssize = stream.tellg();
75   stream.seekg(0, std::ios_base::beg);
76 
77   return ssize;
78 }
79 
80 class TestText : public testing::TestWithParam<std::string> {};
81 
TEST(SandboxTest,CheckInit)82 TEST(SandboxTest, CheckInit) {
83   CbloscSapiSandbox sandbox;
84   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
85   CbloscApi api = CbloscApi(&sandbox);
86 
87   ASSERT_THAT(api.blosc_init(), IsOk());
88 }
89 
TEST(SandboxTest,CheckDestroy)90 TEST(SandboxTest, CheckDestroy) {
91   CbloscSapiSandbox sandbox;
92   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
93   CbloscApi api = CbloscApi(&sandbox);
94 
95   ASSERT_THAT(api.blosc_init(), IsOk());
96   ASSERT_THAT(api.blosc_destroy(), IsOk());
97 }
98 
TEST(SandboxTest,CheckGetNThreads)99 TEST(SandboxTest, CheckGetNThreads) {
100   CbloscSapiSandbox sandbox;
101   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
102   CbloscApi api = CbloscApi(&sandbox);
103 
104   SAPI_ASSERT_OK_AND_ASSIGN(int nthreads, api.blosc_get_nthreads());
105 
106   ASSERT_GT(nthreads, 0);
107 }
108 
TEST(SandboxTest,CheckSetNThreads)109 TEST(SandboxTest, CheckSetNThreads) {
110   CbloscSapiSandbox sandbox;
111   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
112   CbloscApi api = CbloscApi(&sandbox);
113 
114   int nthreads;
115   SAPI_ASSERT_OK_AND_ASSIGN(nthreads, api.blosc_get_nthreads());
116   ASSERT_NE(nthreads, 3);
117   ASSERT_THAT(api.blosc_set_nthreads(3), IsOk());
118   SAPI_ASSERT_OK_AND_ASSIGN(nthreads, api.blosc_get_nthreads());
119   ASSERT_EQ(nthreads, 3);
120 }
121 
TEST(SandboxTest,CheckGetBlocksize)122 TEST(SandboxTest, CheckGetBlocksize) {
123   CbloscSapiSandbox sandbox;
124   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
125   CbloscApi api = CbloscApi(&sandbox);
126 
127   SAPI_ASSERT_OK_AND_ASSIGN(size_t blocksize, api.blosc_get_blocksize());
128   ASSERT_NE(blocksize, kDefaultBlockSize);
129 }
130 
TEST(SandboxTest,CheckSetBlocksize)131 TEST(SandboxTest, CheckSetBlocksize) {
132   CbloscSapiSandbox sandbox;
133   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
134   CbloscApi api = CbloscApi(&sandbox);
135 
136   size_t blocksize;
137   SAPI_ASSERT_OK_AND_ASSIGN(blocksize, api.blosc_get_blocksize());
138   ASSERT_NE(blocksize, 1337);
139   ASSERT_THAT(api.blosc_set_blocksize(1337), IsOk());
140   SAPI_ASSERT_OK_AND_ASSIGN(blocksize, api.blosc_get_blocksize());
141   ASSERT_EQ(blocksize, 1337);
142 }
143 
TEST_P(TestText,CheckSizes)144 TEST_P(TestText, CheckSizes) {
145   absl::Status status;
146   CbloscSapiSandbox sandbox;
147   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
148   CbloscApi api = CbloscApi(&sandbox);
149 
150   std::string compressor(GetParam());
151 
152   std::string origfile_s = GetTestFilePath("text");
153   std::string infile_s = GetTestFilePath(absl::StrCat("text.", compressor));
154 
155   std::ifstream origfile(origfile_s, std::ios::binary);
156   ASSERT_TRUE(origfile.is_open());
157   ssize_t origsize = GetStreamSize(origfile);
158 
159   std::ifstream infile(infile_s, std::ios::binary);
160   ASSERT_TRUE(infile.is_open());
161 
162   std::streamsize insize = GetStreamSize(infile);
163   sapi::v::Array<uint8_t> inbuf(insize);
164   infile.read(reinterpret_cast<char*>(inbuf.GetData()), insize);
165 
166   sapi::v::IntBase<size_t> nbytes;
167   sapi::v::IntBase<size_t> cbytes;
168   sapi::v::IntBase<size_t> blocksize;
169 
170   ASSERT_THAT(api.blosc_cbuffer_sizes(inbuf.PtrBefore(), nbytes.PtrAfter(),
171                                       cbytes.PtrAfter(), blocksize.PtrAfter()),
172               IsOk());
173 
174   ASSERT_EQ(nbytes.GetValue(), origsize);
175   ASSERT_EQ(cbytes.GetValue(), insize);
176   ASSERT_EQ(blocksize.GetValue(), kDefaultBlockSize);
177 }
178 
TEST_P(TestText,CheckValidate)179 TEST_P(TestText, CheckValidate) {
180   absl::Status status;
181   CbloscSapiSandbox sandbox;
182   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
183   CbloscApi api = CbloscApi(&sandbox);
184 
185   std::string compressor(GetParam());
186 
187   std::string origfile_s = GetTestFilePath("text");
188   std::string infile_s = GetTestFilePath(absl::StrCat("text.", compressor));
189 
190   std::ifstream origfile(origfile_s, std::ios::binary);
191   ASSERT_TRUE(origfile.is_open());
192   ssize_t origsize = GetStreamSize(origfile);
193 
194   std::ifstream infile(infile_s, std::ios::binary);
195   ASSERT_TRUE(infile.is_open());
196 
197   std::streamsize insize = GetStreamSize(infile);
198   sapi::v::Array<uint8_t> inbuf(insize);
199   infile.read(reinterpret_cast<char*>(inbuf.GetData()), insize);
200 
201   sapi::v::IntBase<size_t> nbytes;
202 
203   SAPI_ASSERT_OK_AND_ASSIGN(
204       int ret, api.blosc_cbuffer_validate(inbuf.PtrBefore(), inbuf.GetSize(),
205                                           nbytes.PtrAfter()));
206 
207   ASSERT_GE(ret, 0);
208   ASSERT_EQ(nbytes.GetValue(), origsize);
209 }
210 
TEST_P(TestText,SetCompress)211 TEST_P(TestText, SetCompress) {
212   CbloscSapiSandbox sandbox;
213   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
214   CbloscApi api = CbloscApi(&sandbox);
215 
216   std::string compressor(GetParam());
217   SAPI_ASSERT_OK_AND_ASSIGN(
218       int ret, api.blosc_set_compressor(
219                    sapi::v::ConstCStr(compressor.c_str()).PtrBefore()));
220   ASSERT_GE(ret, 0);
221 
222   SAPI_ASSERT_OK_AND_ASSIGN(char* c_compressor_ret, api.blosc_get_compressor());
223   SAPI_ASSERT_OK_AND_ASSIGN(
224       std::string compressor_ret,
225       api.GetSandbox()->GetCString(sapi::v::RemotePtr(c_compressor_ret)));
226 
227   EXPECT_EQ(compressor_ret, compressor);
228 }
229 
TEST_P(TestText,Compress)230 TEST_P(TestText, Compress) {
231   CbloscSapiSandbox sandbox;
232   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
233   CbloscApi api = CbloscApi(&sandbox);
234 
235   std::string compressor(GetParam());
236 
237   std::string infile_s = GetTestFilePath("text");
238   std::string outfile_s = GetTemporaryFile(absl::StrCat("out", compressor));
239   ASSERT_FALSE(outfile_s.empty());
240 
241   std::ifstream infile(infile_s, std::ios::binary);
242   ASSERT_TRUE(infile.is_open());
243 
244   std::ofstream outfile(outfile_s, std::ios::binary);
245   ASSERT_TRUE(outfile.is_open());
246 
247   absl::Status status = Compress(api, infile, outfile, 5, compressor, 5);
248   ASSERT_THAT(status, IsOk()) << "Unable to compress file";
249 
250   ASSERT_LT(outfile.tellp(), infile.tellg());
251 }
252 
TEST_P(TestText,Decompress)253 TEST_P(TestText, Decompress) {
254   absl::Status status;
255   CbloscSapiSandbox sandbox;
256   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
257   CbloscApi api = CbloscApi(&sandbox);
258 
259   std::string compressor(GetParam());
260 
261   std::string origfile_s = GetTestFilePath("text");
262   std::string infile_s = GetTestFilePath(absl::StrCat("text.", compressor));
263   std::string outfile_s = GetTemporaryFile(absl::StrCat("middle", compressor));
264   ASSERT_FALSE(outfile_s.empty());
265 
266   std::ifstream infile(infile_s, std::ios::binary);
267   ASSERT_TRUE(infile.is_open());
268 
269   std::ofstream outfile(outfile_s, std::ios::binary);
270   ASSERT_TRUE(outfile.is_open());
271 
272   status = Decompress(api, infile, outfile, 5);
273   ASSERT_THAT(status, IsOk()) << "Unable to compress file";
274 
275   ASSERT_GT(outfile.tellp(), infile.tellg());
276 
277   ASSERT_TRUE(CompareFiles(origfile_s, outfile_s));
278 }
279 
TEST_P(TestText,CompressDecompress)280 TEST_P(TestText, CompressDecompress) {
281   absl::Status status;
282   CbloscSapiSandbox sandbox;
283   ASSERT_THAT(sandbox.Init(), IsOk()) << "Couldn't initialize Sandboxed API";
284   CbloscApi api = CbloscApi(&sandbox);
285 
286   std::string compressor(GetParam());
287 
288   std::string infile_s = GetTestFilePath("text");
289   std::string middlefile_s =
290       GetTemporaryFile(absl::StrCat("middle", compressor));
291   ASSERT_FALSE(middlefile_s.empty());
292 
293   std::ifstream infile(infile_s, std::ios::binary);
294   ASSERT_TRUE(infile.is_open());
295 
296   std::ofstream outmiddlefile(middlefile_s, std::ios::binary);
297   ASSERT_TRUE(outmiddlefile.is_open());
298 
299   status = Compress(api, infile, outmiddlefile, 5, compressor, 5);
300   ASSERT_THAT(status, IsOk()) << "Unable to compress file";
301 
302   ASSERT_LT(outmiddlefile.tellp(), infile.tellg());
303 
304   std::string outfile_s = GetTemporaryFile(absl::StrCat("out", compressor));
305   ASSERT_FALSE(outfile_s.empty());
306 
307   std::ifstream inmiddlefile(middlefile_s, std::ios::binary);
308   ASSERT_TRUE(inmiddlefile.is_open());
309 
310   std::ofstream outfile(outfile_s, std::ios::binary);
311   ASSERT_TRUE(outfile.is_open());
312 
313   status = Decompress(api, inmiddlefile, outfile, 5);
314   ASSERT_THAT(status, IsOk()) << "Unable to compress file";
315 
316   ASSERT_GT(outfile.tellp(), inmiddlefile.tellg());
317 
318   ASSERT_TRUE(CompareFiles(infile_s, outfile_s));
319 }
320 
321 INSTANTIATE_TEST_SUITE_P(SandboxTest, TestText,
322                          testing::Values("blosclz", "lz4", "lz4hc", "zlib",
323                                          "zstd"));
324 
325 }  // namespace
326