1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
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  *     http://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 
16 #include <benchmark/benchmark.h>
17 #include "unique_fd.h"
18 #include <fstream>
19 #include <iostream>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <fcntl.h>
23 #include "benchmark_log.h"
24 #include "benchmark_assert.h"
25 using namespace std;
26 
27 namespace OHOS {
28 namespace {
29 
30 static const char *TEST_FILE_NAME = "testfilename.test";
31 
32 class BenchmarkUniqueFd : public benchmark::Fixture {
33 public:
BenchmarkUniqueFd()34     BenchmarkUniqueFd()
35     {
36         Iterations(iterations);
37         Repetitions(repetitions);
38         ReportAggregatesOnly();
39     }
40 
41     ~BenchmarkUniqueFd() override = default;
SetUp(const::benchmark::State & state)42     void SetUp(const ::benchmark::State& state) override
43     {
44         ofstream outfile;
45         outfile.open(TEST_FILE_NAME, ios::out | ios::trunc);
46         outfile << "testdata\n"
47                 << std::endl;
48         outfile.close();
49     }
50 
TearDown(::benchmark::State & state)51     void TearDown(::benchmark::State& state) override
52     {
53         ifstream inputfile;
54         inputfile.open(TEST_FILE_NAME, ios::in);
55         std::string testStr;
56         inputfile >> testStr;
57         inputfile.close();
58         AssertEqual(remove(TEST_FILE_NAME), 0, "remove(TEST_FILE_NAME) did not equal 0 as expected.", state);
59     }
60 
61 protected:
62     const int32_t repetitions = 3;
63     const int32_t iterations = 1000;
64 };
65 
66 const int FILE_PERMISSION_READ_WRITE = 0666;
67 const int MIN_VALID_FD = 0;
68 const int MAX_VALID_FD = 1000000;
69 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFd)70 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFd)(benchmark::State& state)
71 {
72     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFd start.");
73     const int expectedValue = -1;
74     while (state.KeepRunning()) {
75         int fd = open("NOTHISFILE", O_RDWR, FILE_PERMISSION_READ_WRITE);
76 
77         UniqueFd ufd2(fd);
78         AssertEqual(ufd2, expectedValue, "ufd2 did not equal expectedValue as expected.", state);
79     }
80     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFd end.");
81 }
82 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueCtroFromInt)83 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueCtroFromInt)(benchmark::State& state)
84 {
85     BENCHMARK_LOGD("UniqueFd testUtilsUniqueCtroFromInt start.");
86     const int expectedValue = -1;
87     while (state.KeepRunning()) {
88         UniqueFd ufd2(open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE));
89         AssertUnequal(ufd2, expectedValue, "ufd2 was not different from expectedValue as expected.", state);
90     }
91     BENCHMARK_LOGD("UniqueFd testUtilsUniqueCtroFromInt end.");
92 }
93 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdeqcompare)94 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdeqcompare)(benchmark::State& state)
95 {
96     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompare start.");
97     while (state.KeepRunning()) {
98         int fd = open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE);
99         UniqueFd ufd2(fd);
100         AssertEqual(fd, ufd2, "fd did not equal ufd2 as expected.", state);
101         AssertEqual(ufd2, fd, "ufd2 did not equal fd as expected.", state);
102     }
103     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompare end.");
104 }
105 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdeqcompareNl)106 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdeqcompareNl)(benchmark::State& state)
107 {
108     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompareNl start.");
109     while (state.KeepRunning()) {
110         int fd = open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE);
111         UniqueFd ufd2(fd);
112         AssertGreaterThanOrEqual(ufd2, 0, "ufd2 >= 0 did not equal true as expected.", state);
113         AssertLessThanOrEqual(0, ufd2, "0 <= ufd2 did not equal true as expected.", state);
114     }
115     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompareNl end.");
116 }
117 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdeqcompareBg)118 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdeqcompareBg)(benchmark::State& state)
119 {
120     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompareBg start.");
121     while (state.KeepRunning()) {
122         int fd = open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE);
123         UniqueFd ufd2(fd);
124         AssertGreaterThan(ufd2, MIN_VALID_FD, "ufd2 > MIN_VALID_FD did not equal true as expected.", state);
125         AssertLessThan(MIN_VALID_FD, ufd2, "MIN_VALID_FD < ufd2 did not equal true as expected.", state);
126     }
127     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompareBg end.");
128 }
129 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdeqcompareNb)130 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdeqcompareNb)(benchmark::State& state)
131 {
132     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompareNb start.");
133     while (state.KeepRunning()) {
134         int fd = open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE);
135         UniqueFd ufd2(fd);
136         AssertLessThanOrEqual(ufd2, MAX_VALID_FD, "ufd2 <= MAX_VALID_FD did not equal true as expected.", state);
137         AssertGreaterThanOrEqual(MAX_VALID_FD, ufd2, "MAX_VALID_FD >= ufd2 did not equal true as expected.", state);
138     }
139     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompareNb end.");
140 }
141 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdeqcompareLess)142 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdeqcompareLess)(benchmark::State& state)
143 {
144     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompareLess start.");
145     while (state.KeepRunning()) {
146         int fd = open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE);
147         UniqueFd ufd2(fd);
148         AssertLessThan(ufd2, MAX_VALID_FD, "ufd2 < MAX_VALID_FD did not equal true as expected.", state);
149         AssertGreaterThan(MAX_VALID_FD, ufd2, "MAX_VALID_FD > ufd2 did not equal true as expected.", state);
150     }
151     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompareLess end.");
152 }
153 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdeqcompareNeq)154 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdeqcompareNeq)(benchmark::State& state)
155 {
156     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompareNeq start.");
157     while (state.KeepRunning()) {
158         int fd = open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE);
159         UniqueFd ufd2(fd);
160         AssertUnequal(ufd2, MAX_VALID_FD, "ufd2 != MAX_VALID_FD did not equal true as expected.", state);
161         AssertUnequal(MAX_VALID_FD, ufd2, "MAX_VALID_FD != ufd2 did not equal true as expected.", state);
162     }
163     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdeqcompareNeq end.");
164 }
165 
166 class NewDeleter {
167 public:
168     static int iflag;
Close(int fd)169     static void Close(int fd)
170     {
171         BENCHMARK_LOGD("UniqueFd static void Close is called.");
172 
173         iflag = 10; // give the expected fd an arbitrary value other than 0.
174         close(fd);
175     }
176 };
177 
178 int NewDeleter::iflag = 0;
179 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdDefineDeletor)180 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdDefineDeletor)(benchmark::State& state)
181 {
182     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdDefineDeletor start.");
183     const int initialFlagValue = 0;
184     const int expectedFlagValueAfterDelete = 10;
185     const int invalidFileDescriptor = -1;
186     while (state.KeepRunning()) {
187         NewDeleter::iflag = 0;
188         int fd = open(TEST_FILE_NAME, O_RDWR);
189 
190         {
191             UniqueFdAddDeletor<NewDeleter> ufd2(fd);
192             AssertEqual(NewDeleter::iflag, initialFlagValue,
193                 "NewDeleter::iflag did not equal 0 as expected.", state);
194             BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdDefineDeletor NewDeleter::iflag: %{public}d", NewDeleter::iflag);
195             AssertUnequal(ufd2, invalidFileDescriptor, "open test.h error", state);
196         }
197         AssertEqual(NewDeleter::iflag, expectedFlagValueAfterDelete,
198             "NewDeleter::iflag did not equal expectedFlagValueAfterDelete as expected.", state);
199     }
200     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdDefineDeletor end.");
201 }
202 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdDefineDeletorCloseStatus)203 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdDefineDeletorCloseStatus)(benchmark::State& state)
204 {
205     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdDefineDeletorCloseStatus start.");
206     const int errorReturn = -1;
207     while (state.KeepRunning()) {
208         int fd = open(TEST_FILE_NAME, O_RDWR);
209 
210         {
211             UniqueFdAddDeletor<NewDeleter> ufd2(fd);
212         }
213 
214         char buf[] = "test";
215         int ret = write(fd, buf, sizeof(buf));
216         AssertEqual(ret, errorReturn, "ret did not equal errorReturn as expected.", state);
217     }
218     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdDefineDeletorCloseStatus end.");
219 }
220 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdRelease)221 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdRelease)(benchmark::State& state)
222 {
223     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdRelease start.");
224     const int expectedValue = -1;
225     while (state.KeepRunning()) {
226         UniqueFd ufd(open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE));
227         AssertUnequal(ufd, expectedValue, "ufd was not different from expectedValue as expected.", state);
228 
229         int fd = ufd.Release();
230         AssertUnequal(fd, expectedValue, "fd was not different from expectedValue as expected.", state);
231         DefaultDeleter::Close(fd);
232     }
233     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdRelease end.");
234 }
235 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdOperatorInt)236 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdOperatorInt)(benchmark::State& state)
237 {
238     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdOperatorInt start.");
239     const int expectedValue = -1;
240     while (state.KeepRunning()) {
241         UniqueFd ufd(open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE));
242         AssertUnequal(ufd, expectedValue, "ufd was not different from expectedValue as expected.", state);
243 
244         int fd = ufd;
245         AssertEqual(fd, ufd, "fd did not equal ufd as expected.", state);
246     }
247     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdOperatorInt end.");
248 }
249 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdGet)250 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdGet)(benchmark::State& state)
251 {
252     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdGet start.");
253     const int expectedValue = -1;
254     while (state.KeepRunning()) {
255         UniqueFd ufd(open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE));
256         AssertUnequal(ufd, expectedValue, "ufd was not different from expectedValue as expected.", state);
257 
258         int fd = ufd.Get();
259         AssertEqual(fd, ufd, "fd did not equal ufd as expected.", state);
260     }
261     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdGet end.");
262 }
263 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdMoveConstructor)264 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdMoveConstructor)(benchmark::State& state)
265 {
266     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdMoveConstructor start.");
267     const int expectedValue = -1;
268     while (state.KeepRunning()) {
269         UniqueFd ufd(open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE));
270         AssertUnequal(ufd, expectedValue, "ufd was not different from expectedValue as expected.", state);
271 
272         UniqueFd ufd1(std::move(ufd));
273         AssertEqual(ufd, expectedValue, "ufd did not equal expectedValue as expected.", state);
274         AssertUnequal(ufd1, expectedValue, "ufd1 was not different from expectedValue as expected.", state);
275     }
276     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdMoveConstructor end.");
277 }
278 
BENCHMARK_F(BenchmarkUniqueFd,testUtilsUniqueFdMoveAssignment)279 BENCHMARK_F(BenchmarkUniqueFd, testUtilsUniqueFdMoveAssignment)(benchmark::State& state)
280 {
281     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdMoveAssignment start.");
282     const int expectedValue = -1;
283     while (state.KeepRunning()) {
284         UniqueFd ufd(open(TEST_FILE_NAME, O_RDWR, FILE_PERMISSION_READ_WRITE));
285         AssertUnequal(ufd, expectedValue, "ufd was not different from expectedValue as expected.", state);
286 
287         UniqueFd ufd1;
288         ufd1 = std::move(ufd);
289         AssertEqual(ufd, expectedValue, "ufd did not equal expectedValue as expected.", state);
290         AssertUnequal(ufd1, expectedValue, "ufd1 was not different from expectedValue as expected.", state);
291     }
292     BENCHMARK_LOGD("UniqueFd testUtilsUniqueFdMoveAssignment end.");
293 }
294 }  // namespace
295 }  // namespace OHOS
296 // Run the benchmark
297 BENCHMARK_MAIN();