1*ec63e07aSXin Li // Copyright 2020 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 #include <sys/stat.h>
17*ec63e07aSXin Li #include <sys/types.h>
18*ec63e07aSXin Li #include <syscall.h>
19*ec63e07aSXin Li
20*ec63e07aSXin Li #include <algorithm>
21*ec63e07aSXin Li #include <fstream>
22*ec63e07aSXin Li #include <memory>
23*ec63e07aSXin Li #include <sstream>
24*ec63e07aSXin Li
25*ec63e07aSXin Li #include "guetzli_sandbox.h" // NOLINT(build/include)
26*ec63e07aSXin Li #include "gtest/gtest.h"
27*ec63e07aSXin Li #include "absl/status/statusor.h"
28*ec63e07aSXin Li #include "sandboxed_api/vars.h"
29*ec63e07aSXin Li
30*ec63e07aSXin Li namespace guetzli::sandbox::tests {
31*ec63e07aSXin Li
32*ec63e07aSXin Li namespace {
33*ec63e07aSXin Li
34*ec63e07aSXin Li constexpr absl::string_view kInPngFilename = "bees.png";
35*ec63e07aSXin Li constexpr absl::string_view kInJpegFilename = "nature.jpg";
36*ec63e07aSXin Li constexpr absl::string_view kPngReferenceFilename = "bees_reference.jpg";
37*ec63e07aSXin Li constexpr absl::string_view kJpegReferenceFIlename = "nature_reference.jpg";
38*ec63e07aSXin Li
39*ec63e07aSXin Li constexpr int kDefaultQualityTarget = 95;
40*ec63e07aSXin Li constexpr int kDefaultMemlimitMb = 6000;
41*ec63e07aSXin Li
42*ec63e07aSXin Li constexpr absl::string_view kRelativePathToTestdata =
43*ec63e07aSXin Li "/guetzli_sandboxed/testdata/";
44*ec63e07aSXin Li
GetPathToInputFile(absl::string_view filename)45*ec63e07aSXin Li std::string GetPathToInputFile(absl::string_view filename) {
46*ec63e07aSXin Li return absl::StrCat(getenv("TEST_SRCDIR"), kRelativePathToTestdata, filename);
47*ec63e07aSXin Li }
48*ec63e07aSXin Li
ReadFromFile(const std::string & filename)49*ec63e07aSXin Li std::string ReadFromFile(const std::string& filename) {
50*ec63e07aSXin Li std::ifstream stream(filename, std::ios::binary);
51*ec63e07aSXin Li
52*ec63e07aSXin Li if (!stream.is_open()) {
53*ec63e07aSXin Li return "";
54*ec63e07aSXin Li }
55*ec63e07aSXin Li
56*ec63e07aSXin Li std::stringstream result;
57*ec63e07aSXin Li result << stream.rdbuf();
58*ec63e07aSXin Li return result.str();
59*ec63e07aSXin Li }
60*ec63e07aSXin Li
61*ec63e07aSXin Li } // namespace
62*ec63e07aSXin Li
63*ec63e07aSXin Li class GuetzliSapiTest : public ::testing::Test {
64*ec63e07aSXin Li protected:
SetUp()65*ec63e07aSXin Li void SetUp() override {
66*ec63e07aSXin Li sandbox_ = std::make_unique<GuetzliSapiSandbox>();
67*ec63e07aSXin Li ASSERT_EQ(sandbox_->Init(), absl::OkStatus());
68*ec63e07aSXin Li api_ = std::make_unique<GuetzliApi>(sandbox_.get());
69*ec63e07aSXin Li }
70*ec63e07aSXin Li
71*ec63e07aSXin Li std::unique_ptr<GuetzliSapiSandbox> sandbox_;
72*ec63e07aSXin Li std::unique_ptr<GuetzliApi> api_;
73*ec63e07aSXin Li };
74*ec63e07aSXin Li
75*ec63e07aSXin Li // This test can take up to few minutes depending on your hardware
TEST_F(GuetzliSapiTest,ProcessRGB)76*ec63e07aSXin Li TEST_F(GuetzliSapiTest, ProcessRGB) {
77*ec63e07aSXin Li sapi::v::Fd in_fd(open(GetPathToInputFile(kInPngFilename).c_str(), O_RDONLY));
78*ec63e07aSXin Li ASSERT_TRUE(in_fd.GetValue() != -1) << "Error opening input file";
79*ec63e07aSXin Li ASSERT_EQ(api_->sandbox()->TransferToSandboxee(&in_fd), absl::OkStatus())
80*ec63e07aSXin Li << "Error transfering fd to sandbox";
81*ec63e07aSXin Li ASSERT_TRUE(in_fd.GetRemoteFd() != -1) << "Error opening remote fd";
82*ec63e07aSXin Li sapi::v::Struct<ProcessingParams> processing_params;
83*ec63e07aSXin Li *processing_params.mutable_data() = {
84*ec63e07aSXin Li in_fd.GetRemoteFd(), 0, kDefaultQualityTarget, kDefaultMemlimitMb};
85*ec63e07aSXin Li sapi::v::LenVal output(0);
86*ec63e07aSXin Li absl::StatusOr<bool> processing_result =
87*ec63e07aSXin Li api_->ProcessRgb(processing_params.PtrBefore(), output.PtrBoth());
88*ec63e07aSXin Li ASSERT_TRUE(processing_result.value_or(false)) << "Error processing rgb data";
89*ec63e07aSXin Li std::string reference_data =
90*ec63e07aSXin Li ReadFromFile(GetPathToInputFile(kPngReferenceFilename));
91*ec63e07aSXin Li ASSERT_EQ(output.GetDataSize(), reference_data.size())
92*ec63e07aSXin Li << "Incorrect result data size";
93*ec63e07aSXin Li ASSERT_EQ(
94*ec63e07aSXin Li std::string(output.GetData(), output.GetData() + output.GetDataSize()),
95*ec63e07aSXin Li reference_data)
96*ec63e07aSXin Li << "Processed data doesn't match reference output";
97*ec63e07aSXin Li }
98*ec63e07aSXin Li
99*ec63e07aSXin Li // This test can take up to few minutes depending on your hardware
TEST_F(GuetzliSapiTest,ProcessJpeg)100*ec63e07aSXin Li TEST_F(GuetzliSapiTest, ProcessJpeg) {
101*ec63e07aSXin Li sapi::v::Fd in_fd(
102*ec63e07aSXin Li open(GetPathToInputFile(kInJpegFilename).c_str(), O_RDONLY));
103*ec63e07aSXin Li ASSERT_TRUE(in_fd.GetValue() != -1) << "Error opening input file";
104*ec63e07aSXin Li ASSERT_EQ(api_->sandbox()->TransferToSandboxee(&in_fd), absl::OkStatus())
105*ec63e07aSXin Li << "Error transfering fd to sandbox";
106*ec63e07aSXin Li ASSERT_TRUE(in_fd.GetRemoteFd() != -1) << "Error opening remote fd";
107*ec63e07aSXin Li sapi::v::Struct<ProcessingParams> processing_params;
108*ec63e07aSXin Li *processing_params.mutable_data() = {
109*ec63e07aSXin Li in_fd.GetRemoteFd(), 0, kDefaultQualityTarget, kDefaultMemlimitMb};
110*ec63e07aSXin Li sapi::v::LenVal output(0);
111*ec63e07aSXin Li absl::StatusOr<bool> processing_result =
112*ec63e07aSXin Li api_->ProcessJpeg(processing_params.PtrBefore(), output.PtrBoth());
113*ec63e07aSXin Li ASSERT_TRUE(processing_result.value_or(false)) << "Error processing jpg data";
114*ec63e07aSXin Li std::string reference_data =
115*ec63e07aSXin Li ReadFromFile(GetPathToInputFile(kJpegReferenceFIlename));
116*ec63e07aSXin Li ASSERT_EQ(output.GetDataSize(), reference_data.size())
117*ec63e07aSXin Li << "Incorrect result data size";
118*ec63e07aSXin Li ASSERT_EQ(
119*ec63e07aSXin Li std::string(output.GetData(), output.GetData() + output.GetDataSize()),
120*ec63e07aSXin Li reference_data)
121*ec63e07aSXin Li << "Processed data doesn't match reference output";
122*ec63e07aSXin Li }
123*ec63e07aSXin Li
124*ec63e07aSXin Li } // namespace guetzli::sandbox::tests
125