1 /*
2 * Copyright (C) 2025 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 <filesystem>
17 #include <fstream>
18
19 #include <gtest/gtest.h>
20 #include "fs_atomicfile.h"
21
22 namespace OHOS::FileManagement::ModuleFileIO::Test {
23 using namespace std;
24 namespace fs = std::filesystem;
25
26 string g_filePath = "/data/test/FsAtomicfileTest.txt";
27 string g_deleteFile = "/data/test/FsAtomicfileDelTest.txt";
28
29 class FsAtomicfileTest : public testing::Test {
30 public:
31 static void SetUpTestCase(void);
32 static void TearDownTestCase(void);
33 void SetUp();
34 void TearDown();
35 };
36
SetUpTestCase(void)37 void FsAtomicfileTest::SetUpTestCase(void)
38 {
39 ofstream tempfile(g_filePath);
40 tempfile << "hello world";
41 tempfile.close();
42 GTEST_LOG_(INFO) << "SetUpTestCase";
43 }
44
TearDownTestCase(void)45 void FsAtomicfileTest::TearDownTestCase(void)
46 {
47 filesystem::remove(g_filePath);
48 GTEST_LOG_(INFO) << "TearDownTestCase";
49 }
50
SetUp(void)51 void FsAtomicfileTest::SetUp(void)
52 {
53 GTEST_LOG_(INFO) << "SetUp";
54 }
55
TearDown(void)56 void FsAtomicfileTest::TearDown(void)
57 {
58 GTEST_LOG_(INFO) << "TearDown";
59 }
60
61 /**
62 * @tc.name: FsAtomicfileTest_GetPath_001
63 * @tc.desc: Test function of FsAtomicFile::GetPath interface for succ.
64 * @tc.size: MEDIUM
65 * @tc.type: FUNC
66 * @tc.level Level 1
67 */
68 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_GetPath_001, testing::ext::TestSize.Level1)
69 {
70 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_GetPath_001";
71
72 auto ret = FsAtomicFile::Constructor(g_filePath);
73 ASSERT_TRUE(ret.IsSuccess());
74
75 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
76 string path = stream->GetPath();
77 EXPECT_EQ(path, g_filePath);
78
79 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_GetPath_001";
80 }
81
82 /**
83 * @tc.name: FsAtomicfileTest_GetBaseFile_001
84 * @tc.desc: Test function of FsAtomicFile::GetBaseFile interface for succ.
85 * @tc.size: MEDIUM
86 * @tc.type: FUNC
87 * @tc.level Level 1
88 */
89 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_GetBaseFile_001, testing::ext::TestSize.Level1)
90 {
91 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_GetBaseFile_001";
92
93 auto ret = FsAtomicFile::Constructor(g_filePath);
94 ASSERT_TRUE(ret.IsSuccess());
95
96 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
97 auto retFl = stream->GetBaseFile();
98 EXPECT_TRUE(retFl.IsSuccess());
99
100 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_GetBaseFile_001";
101 }
102
103 /**
104 * @tc.name: FsAtomicfileTest_GetBaseFile_002
105 * @tc.desc: Test function of FsAtomicFile::GetBaseFile interface for path > PATH_MAX.
106 * @tc.size: MEDIUM
107 * @tc.type: FUNC
108 * @tc.level Level 1
109 */
110 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_GetBaseFile_002, testing::ext::TestSize.Level1)
111 {
112 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_GetBaseFile_002";
113
114 size_t largeLength = static_cast<size_t>(PATH_MAX) + 1;
115 char text = 'a';
116 string largeString(largeLength, text);
117
118 auto ret = FsAtomicFile::Constructor(largeString);
119 ASSERT_TRUE(ret.IsSuccess());
120
121 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
122 auto retFl = stream->GetBaseFile();
123 EXPECT_FALSE(retFl.IsSuccess());
124
125 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_GetBaseFile_002";
126 }
127
128 /**
129 * @tc.name: FsAtomicfileTest_GetBaseFile_003
130 * @tc.desc: Test function of FsAtomicFile::GetBaseFile interface for failed realpath.
131 * @tc.size: MEDIUM
132 * @tc.type: FUNC
133 * @tc.level Level 1
134 */
135 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_GetBaseFile_003, testing::ext::TestSize.Level1)
136 {
137 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_GetBaseFile_003";
138
139 string path = "FsAtomicfileTest_GetBaseFile_003_aaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
140
141 auto ret = FsAtomicFile::Constructor(path);
142 ASSERT_TRUE(ret.IsSuccess());
143
144 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
145 auto retFl = stream->GetBaseFile();
146 EXPECT_FALSE(retFl.IsSuccess());
147
148 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_GetBaseFile_003";
149 }
150
151 /**
152 * @tc.name: FsAtomicfileTest_GetBaseFile_004
153 * @tc.desc: Test function of FsAtomicFile::GetBaseFile interface for failed open.
154 * @tc.size: MEDIUM
155 * @tc.type: FUNC
156 * @tc.level Level 1
157 */
158 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_GetBaseFile_004, testing::ext::TestSize.Level1)
159 {
160 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_GetBaseFile_004";
161
162 string path = "/data/test/FsAtomicfileTest_GetBaseFile_004_aaaaaaaaaa.txt";
163
164 auto ret = FsAtomicFile::Constructor(path);
165 ASSERT_TRUE(ret.IsSuccess());
166
167 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
168 auto retFl = stream->GetBaseFile();
169 EXPECT_FALSE(retFl.IsSuccess());
170
171 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_GetBaseFile_004";
172 }
173
174 /**
175 * @tc.name: FsAtomicfileTest_StartWrite_001
176 * @tc.desc: Test function of FsAtomicFile::StartWrite interface for succ.
177 * @tc.size: MEDIUM
178 * @tc.type: FUNC
179 * @tc.level Level 1
180 */
181 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_StartWrite_001, testing::ext::TestSize.Level1)
182 {
183 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_StartWrite_001";
184
185 auto ret = FsAtomicFile::Constructor(g_filePath);
186 ASSERT_TRUE(ret.IsSuccess());
187
188 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
189 auto retFl = stream->StartWrite();
190 EXPECT_TRUE(retFl.IsSuccess());
191
192 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_StartWrite_001";
193 }
194
195 /**
196 * @tc.name: FsAtomicfileTest_StartWrite_002
197 * @tc.desc: Test function of FsAtomicFile::StartWrite interface for no parent dir.
198 * @tc.size: MEDIUM
199 * @tc.type: FUNC
200 * @tc.level Level 1
201 */
202 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_StartWrite_002, testing::ext::TestSize.Level1)
203 {
204 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_StartWrite_002";
205
206 string path = "/data/local/tmp/test/test/test/FsAtomicfileTest_StartWrite_002_test.txt";
207
208 auto ret = FsAtomicFile::Constructor(path);
209 ASSERT_TRUE(ret.IsSuccess());
210
211 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
212 auto retFl = stream->StartWrite();
213 EXPECT_FALSE(retFl.IsSuccess());
214
215 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_StartWrite_002";
216 }
217
218 /**
219 * @tc.name: FsAtomicfileTest_StartWrite_003
220 * @tc.desc: Test function of FsAtomicFile::StartWrite interface for no permission.
221 * @tc.size: MEDIUM
222 * @tc.type: FUNC
223 * @tc.level Level 1
224 */
225 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_StartWrite_003, testing::ext::TestSize.Level1)
226 {
227 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_StartWrite_003";
228
229 string path = "/sys/kernel/address_bits";
230
231 auto ret = FsAtomicFile::Constructor(path);
232 ASSERT_TRUE(ret.IsSuccess());
233
234 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
235 auto retFl = stream->StartWrite();
236 EXPECT_FALSE(retFl.IsSuccess());
237
238 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_StartWrite_003";
239 }
240
241 /**
242 * @tc.name: FsAtomicfileTest_FinishWrite_001
243 * @tc.desc: Test function of FsAtomicFile::FinishWrite interface for succ.
244 * @tc.size: MEDIUM
245 * @tc.type: FUNC
246 * @tc.level Level 1
247 */
248 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_FinishWrite_001, testing::ext::TestSize.Level1)
249 {
250 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_FinishWrite_001";
251
252 auto ret = FsAtomicFile::Constructor(g_filePath);
253 ASSERT_TRUE(ret.IsSuccess());
254
255 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
256 auto retFl = stream->StartWrite();
257 ASSERT_TRUE(retFl.IsSuccess());
258 string newPath = retFl.GetData().value();
259 ofstream tempfile(newPath);
260 tempfile << "hello world";
261 tempfile.close();
262
263 auto retFW = stream->FinishWrite();
264 EXPECT_TRUE(retFW.IsSuccess());
265
266 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_FinishWrite_001";
267 }
268
269 /**
270 * @tc.name: FsAtomicfileTest_FailWrite_001
271 * @tc.desc: Test function of FsAtomicFile::FailWrite interface for succ.
272 * @tc.size: MEDIUM
273 * @tc.type: FUNC
274 * @tc.level Level 1
275 */
276 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_FailWrite_001, testing::ext::TestSize.Level1)
277 {
278 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_FailWrite_001";
279
280 auto ret = FsAtomicFile::Constructor(g_filePath);
281 ASSERT_TRUE(ret.IsSuccess());
282
283 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
284 auto retFl = stream->StartWrite();
285 ASSERT_TRUE(retFl.IsSuccess());
286 string newPath = retFl.GetData().value();
287 ofstream tempfile(newPath);
288 tempfile << "hello world";
289 tempfile.close();
290
291 auto retFW = stream->FailWrite();
292 EXPECT_TRUE(retFW.IsSuccess());
293
294 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_FailWrite_001";
295 }
296
297 /**
298 * @tc.name: FsAtomicfileTest_Delete_001
299 * @tc.desc: Test function of FsAtomicFile::Delete interface for succ.
300 * @tc.size: MEDIUM
301 * @tc.type: FUNC
302 * @tc.level Level 1
303 */
304 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_Delete_001, testing::ext::TestSize.Level1)
305 {
306 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_Delete_001";
307
308 auto ret = FsAtomicFile::Constructor(g_deleteFile);
309 ASSERT_TRUE(ret.IsSuccess());
310
311 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
312 auto retFl = stream->StartWrite();
313 ASSERT_TRUE(retFl.IsSuccess());
314 string newPath = retFl.GetData().value();
315 ofstream tempfile(newPath);
316 tempfile << "hello world";
317 tempfile.close();
318
319 auto retFW = stream->Delete();
320 EXPECT_TRUE(retFW.IsSuccess());
321
322 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_Delete_001";
323 }
324
325 /**
326 * @tc.name: FsAtomicfileTest_ReadFully_001
327 * @tc.desc: Test function of FsAtomicFile::ReadFully interface for succ.
328 * @tc.size: MEDIUM
329 * @tc.type: FUNC
330 * @tc.level Level 1
331 */
332 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_ReadFully_001, testing::ext::TestSize.Level1)
333 {
334 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_ReadFully_001";
335
336 auto ret = FsAtomicFile::Constructor(g_filePath);
337 ASSERT_TRUE(ret.IsSuccess());
338
339 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
340 auto result = stream->ReadFully();
341 ASSERT_TRUE(result.IsSuccess());
342
343 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_ReadFully_001";
344 }
345
346 /**
347 * @tc.name: FsAtomicfileTest_ReadFully_002
348 * @tc.desc: Test function of FsAtomicFile::ReadFully interface for valied path.
349 * @tc.size: MEDIUM
350 * @tc.type: FUNC
351 * @tc.level Level 1
352 */
353 HWTEST_F(FsAtomicfileTest, FsAtomicfileTest_ReadFully_002, testing::ext::TestSize.Level1)
354 {
355 GTEST_LOG_(INFO) << "FsAtomicfileTest-begin FsAtomicfileTest_ReadFully_002";
356
357 auto ret = FsAtomicFile::Constructor("aaaaaaaaaaaaaaaa");
358 ASSERT_TRUE(ret.IsSuccess());
359
360 shared_ptr<FsAtomicFile> stream(move(ret.GetData().value()));
361 auto result = stream->ReadFully();
362 ASSERT_FALSE(result.IsSuccess());
363
364 GTEST_LOG_(INFO) << "FsAtomicfileTest-end FsAtomicfileTest_ReadFully_002";
365 }
366
367 } // namespace OHOS::FileManagement::ModuleFileIO::Test