1 /*
2 * Copyright (C) 2024 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 "gtest/gtest.h"
17 #include <cstdint>
18 #include <cstdlib>
19 #include <ctime>
20 #include <fstream>
21 #include <iostream>
22 #include <memory>
23 #include <sstream>
24 #include <string>
25 #include <unordered_map>
26
27 #include <csetjmp>
28 #include <csignal>
29 #include <cstring>
30 #include <dirent.h>
31 #include <execinfo.h>
32 #include <fcntl.h>
33 #include <pwd.h>
34 #include <sys/stat.h>
35 #include <unistd.h>
36
37 #include <gmock/gmock-actions.h>
38 #include <gmock/gmock-cardinalities.h>
39 #include <gmock/gmock-spec-builders.h>
40 #include <gmock/gmock.h>
41 #include <gtest/gtest.h>
42
43 #include "metadata_stream.h"
44 #include "buffer_metadata_stream.h"
45 #include "file_metadata_stream.h"
46 #include "data_buf.h"
47
48 using namespace testing::ext;
49 using namespace testing;
50 using namespace OHOS::Media;
51
52 namespace OHOS {
53 namespace Media {
54 const int SIZE_1024 = 1024;
55 const int SIZE_512 = 512;
56 const int SIZE_255 = 255;
57 const int SIZE_20 = 20;
58 const int SIZE_10 = 10;
59 const int TEST_DIR_PERMISSIONS = 0777;
60
61 class MemoryCheck {
62 public:
Start()63 void Start()
64 {
65 startVmSize = GetVmSize();
66 startVmRSS = GetVmRSS();
67 startFdCount = CountOpenFileDescriptors();
68 }
69
End()70 void End()
71 {
72 endVmSize = GetVmSize();
73 endVmRSS = GetVmRSS();
74 endFdCount = CountOpenFileDescriptors();
75 }
76
77 bool check = true;
78
Compare() const79 bool Compare() const
80 {
81 if (check) {
82 if (startVmSize != endVmSize || startVmRSS != endVmRSS || startFdCount != endFdCount) {
83 std::cout << "Difference in VmSize: " << endVmSize - startVmSize << std::endl;
84 std::cout << "Difference in VmRSS: " << endVmRSS - startVmRSS << std::endl;
85 std::cout << "Difference in File Descriptors: " << endFdCount - startFdCount << std::endl;
86 return false;
87 }
88 }
89 return true;
90 }
91
92 private:
GetVmSize() const93 long GetVmSize() const
94 {
95 return GetMemoryInfo("VmSize:");
96 }
97
GetVmRSS() const98 long GetVmRSS() const
99 {
100 return GetMemoryInfo("VmRSS:");
101 }
102
CountOpenFileDescriptors() const103 int CountOpenFileDescriptors() const
104 {
105 DIR *dir;
106 int fdCount = 0;
107 std::string dirPath = "/proc/" + std::to_string(getpid()) + "/fd/";
108 if ((dir = opendir(dirPath.c_str())) != nullptr) {
109 while (readdir(dir) != nullptr) {
110 fdCount++;
111 }
112 closedir(dir);
113 } else {
114 std::cerr << "Could not open " << dirPath << std::endl;
115 }
116
117 return fdCount;
118 }
119
GetMemoryInfo(const std::string & name) const120 long GetMemoryInfo(const std::string &name) const
121 {
122 std::string line;
123 std::ifstream statusFile("/proc/self/status");
124
125 while (std::getline(statusFile, line)) {
126 if (line.find(name) != std::string::npos) {
127 return std::stol(line.substr(name.length()));
128 }
129 }
130
131 return 0;
132 }
133
134 long startVmSize = 0;
135 long startVmRSS = 0;
136 long endVmSize = 0;
137 long endVmRSS = 0;
138 int startFdCount = 0;
139 int endFdCount = 0;
140 };
141
CountOpenFileDescriptors()142 int CountOpenFileDescriptors()
143 {
144 DIR *dir;
145 int fdCount = 0;
146 std::string dirPath = "/proc/" + std::to_string(getpid()) + "/fd/";
147 if ((dir = opendir(dirPath.c_str())) != nullptr) {
148 while (readdir(dir) != nullptr) {
149 fdCount++;
150 }
151 closedir(dir);
152 } else {
153 std::cerr << "Could not open " << dirPath << std::endl;
154 }
155
156 return fdCount;
157 }
158
159
RemoveFile(const std::string & filePath)160 void RemoveFile(const std::string &filePath)
161 {
162 int result = remove(filePath.c_str());
163 if (result != 0) {
164 char errstr[METADATA_STREAM_ERROR_BUFFER_SIZE];
165 strerror_r(errno, errstr, sizeof(errstr));
166 }
167 }
168
CreateIfNotExit(const std::string & filePath)169 std::string CreateIfNotExit(const std::string &filePath)
170 {
171 struct stat buffer;
172 if (stat(filePath.c_str(), &buffer) != 0) { // 文件不存在
173 std::ofstream file(filePath);
174 if (!file) {
175 std::cerr << "Failed to create file: " << filePath << std::endl;
176 } else {
177 file.close();
178 }
179 }
180 return filePath;
181 }
182
183 class MetadataStreamTest : public testing::Test {
184 public:
MetadataStreamTest()185 MetadataStreamTest() {}
~MetadataStreamTest()186 ~MetadataStreamTest() override {}
187 std::string filePath = "/data/local/tmp/image/testfile.txt";
188 std::string filePathSource = "/data/local/tmp/image/test_exif_test.jpg";
189 std::string filePathDest = "/data/local/tmp/image/testfile_dest.png";
190 std::string backupFilePathSource = "/data/local/tmp/image/test_exif.jpg";
191 const ssize_t testSize[4] = {
192 1,
193 METADATA_STREAM_PAGE_SIZE + 1,
194 METADATA_STREAM_PAGE_SIZE,
195 METADATA_STREAM_PAGE_SIZE - 1
196 };
197 MemoryCheck memoryCheck;
198
SetUp()199 void SetUp() override
200 {
201 // Create the directory
202 std::string dirPath = "/data/local/tmp/image";
203 if (access(dirPath.c_str(), F_OK) != 0) {
204 int ret = mkdir(dirPath.c_str(), TEST_DIR_PERMISSIONS);
205 if (ret != 0) {
206 char buf[METADATA_STREAM_ERROR_BUFFER_SIZE];
207 strerror_r(errno, buf, sizeof(buf));
208 GTEST_LOG_(ERROR) << "Failed to create directory: " << dirPath << ", error: " << buf;
209 }
210 }
211
212 // Backup the files
213 std::filesystem::copy(backupFilePathSource, filePathSource, std::filesystem::copy_options::overwrite_existing);
214 memoryCheck.check = true;
215 memoryCheck.Start();
216 }
217
218 const static std::string tmpDirectory;
219 static bool alreadyExist;
220
TearDown()221 void TearDown() override
222 {
223 memoryCheck.End();
224 memoryCheck.check = false;
225 if (!memoryCheck.Compare()) {
226 GTEST_LOG_(INFO) << "Memory leak detected";
227 }
228 RemoveFile(filePath.c_str());
229 RemoveFile(filePathDest.c_str());
230 }
231
SetUpTestCase()232 static void SetUpTestCase()
233 {
234 // Create the directory
235 if (access(tmpDirectory.c_str(), F_OK) != 0) {
236 int ret = mkdir(tmpDirectory.c_str(), TEST_DIR_PERMISSIONS);
237 if (ret != 0) {
238 char buf[METADATA_STREAM_ERROR_BUFFER_SIZE];
239 strerror_r(errno, buf, sizeof(buf));
240 GTEST_LOG_(ERROR) << "Failed to create directory: " << tmpDirectory << ", error: " << buf;
241 }
242 alreadyExist = false;
243 } else {
244 alreadyExist = true;
245 }
246 }
TearDownTestCase()247 static void TearDownTestCase()
248 {
249 if (!alreadyExist) {
250 rmdir(tmpDirectory.c_str());
251 }
252 }
253 };
254
255 bool MetadataStreamTest::alreadyExist = false;
256 const std::string MetadataStreamTest::tmpDirectory = "/data/local/tmp/image";
257
258 class MockFileWrapper : public FileWrapper {
259 public:
260 MOCK_METHOD(ssize_t, FWrite, (const void *src, size_t size, ssize_t nmemb, FILE *file), (override));
261 MOCK_METHOD(ssize_t, FRead, (void *destv, size_t size, ssize_t nmemb, FILE *file), (override));
262
MockFileWrapper()263 MockFileWrapper()
264 {
265 // Set the default behavior of write to call the system's write function
266 ON_CALL(*this, FWrite(_, _, _, _))
267 .WillByDefault(Invoke([](const void *src, size_t size, ssize_t nmemb, FILE *file) {
268 size_t result = ::fwrite(src, size, nmemb, file);
269 if (result != static_cast<size_t>(nmemb)) {
270 char errstr[METADATA_STREAM_ERROR_BUFFER_SIZE];
271 strerror_r(errno, errstr, sizeof(errstr));
272 std::cerr << "Failed to write to the file: " << errstr << std::endl;
273 }
274 return result;
275 }));
276 // Set the default behavior of read to call the system's read function
277 ON_CALL(*this, FRead(_, _, _, _)).WillByDefault(Invoke([](void *destv, size_t size, ssize_t nmemb, FILE *file) {
278 size_t result = ::fread(destv, size, nmemb, file);
279 if (result != static_cast<size_t>(nmemb)) {
280 char errstr[METADATA_STREAM_ERROR_BUFFER_SIZE];
281 strerror_r(errno, errstr, sizeof(errstr));
282 std::cerr << "Failed to read from the file: " << errstr << std::endl;
283 }
284 return result;
285 }));
286 }
287 };
288
289 /**
290 * @tc.name: FileMetadataStream_Write001
291 * @tc.desc: Test the Write function of FileMetadataStream, whether it can write
292 * normally and verify the written data
293 * @tc.type: FUNC
294 */
295 HWTEST_F(MetadataStreamTest, FileMetadataStream_Write001, TestSize.Level3)
296 {
297 // Create a FileMetadataStream object
298 FileMetadataStream stream(CreateIfNotExit(filePath));
299
300 // Open the file
301 ASSERT_TRUE(stream.Open(OpenMode::ReadWrite));
302
303 // Create some data to write
304 byte data[SIZE_10] = {0};
305
306 ASSERT_EQ(stream.Tell(), 0);
307
308 // Write the data to the file
309 size_t bytesWritten = stream.Write(data, sizeof(data));
310
311 // Check that the correct number of bytes were written
312 ASSERT_EQ(bytesWritten, sizeof(data));
313
314 // Flush the file
315 stream.Flush();
316
317 // Open the file again
318 int fileDescriptor = open(filePath.c_str(), O_RDONLY);
319 ASSERT_NE(fileDescriptor, -1);
320
321 // Read the data from the file
322 byte buffer[SIZE_10];
323 ssize_t bytesRead = read(fileDescriptor, buffer, sizeof(buffer));
324
325 // Check that the correct number of bytes were read
326 ASSERT_EQ(bytesRead, sizeof(data));
327
328 // Check that the data read is the same as the data written
329 ASSERT_EQ(memcmp(data, buffer, sizeof(data)), 0);
330
331 // Close the file
332 close(fileDescriptor);
333 }
334
335 /**
336 * @tc.name: FileMetadataStream_Write002
337 * @tc.desc: Test the Write function of FileMetadataStream when the file is not
338 * open
339 * @tc.type: FUNC
340 */
341 HWTEST_F(MetadataStreamTest, FileMetadataStream_Write002, TestSize.Level3)
342 {
343 FileMetadataStream stream(filePath);
344 byte data[SIZE_10] = {0};
345 ASSERT_EQ(stream.Write(data, sizeof(data)), -1);
346 }
347
348 /**
349 * @tc.name: FileMetadataStream_Write003
350 * @tc.desc: Test the Write function of FileMetadataStream when the amount of data
351 * written exceeds the remaining space in the file system
352 * @tc.type: FUNC
353 */
354 HWTEST_F(MetadataStreamTest, FileMetadataStream_Write003, TestSize.Level3)
355 {
356 // This test case requires an MetadataStream object that can simulate a read
357 // failure, so mock technology may be needed in actual testing
358 auto mockFileWrapper = std::make_unique<MockFileWrapper>();
359 // Set the behavior of the write function to always return -1, simulating a
360 // write failure
361 EXPECT_CALL(*mockFileWrapper.get(), FWrite(_, _, _, _)).WillOnce(Return(-1));
362
363 FileMetadataStream stream(CreateIfNotExit(filePath), std::move(mockFileWrapper));
364
365 // Test the Write function
366 byte buffer[SIZE_1024];
367 stream.Open(OpenMode::ReadWrite);
368 EXPECT_EQ(stream.Write(buffer, sizeof(buffer)), -1);
369 }
370
371 /**
372 * @tc.name: FileMetadataStream_Write004
373 * @tc.desc: Test the Write function of FileMetadataStream when all data from the
374 * source image stream has been read
375 * @tc.type: FUNC
376 */
377 HWTEST_F(MetadataStreamTest, FileMetadataStream_Write004, TestSize.Level3)
378 {
379 FileMetadataStream stream1(filePathSource);
380 FileMetadataStream stream2(CreateIfNotExit(filePathDest));
381 ASSERT_TRUE(stream1.Open(OpenMode::ReadWrite));
382 ASSERT_TRUE(stream2.Open(OpenMode::ReadWrite));
383 // Read all data from stream1
384 byte buffer[METADATA_STREAM_PAGE_SIZE];
385 while (stream1.Read(buffer, sizeof(buffer)) > 0) {
386 }
387 // At this point, all data from stream1 has been read, so the write should
388 // return 0
389 byte *buf = new byte[stream1.GetSize()];
390 stream1.Read(buf, stream1.GetSize());
391 ASSERT_EQ(stream2.Write(buf, stream1.GetSize()), stream1.GetSize());
392 stream1.Flush();
393 stream2.Flush();
394 delete[] buf;
395 }
396
397 /**
398 * @tc.name: FileMetadataStream_Write005
399 * @tc.desc: Test the Write function of FileMetadataStream when reading data from
400 * the source image stream fails
401 * @tc.type: FUNC
402 */
403 HWTEST_F(MetadataStreamTest, FileMetadataStream_Write005, TestSize.Level3)
404 {
405 // This test case requires an MetadataStream object that can simulate a read
406 // failure, so mock technology may be needed in actual testing
407 auto mockSourceFileWrapper = std::make_unique<MockFileWrapper>();
408 auto mockDestFileWrapper = std::make_unique<MockFileWrapper>();
409
410 // Set the behavior of the write function to always return -1, simulating a
411 // write failure
412 EXPECT_CALL(*mockDestFileWrapper.get(), FWrite(_, _, _, _)).Times(Exactly(0));
413 EXPECT_CALL(*mockSourceFileWrapper.get(), FRead(_, _, _, _)).WillOnce(Return(-1));
414
415 FileMetadataStream sourceStream(filePathSource, std::move(mockSourceFileWrapper));
416 FileMetadataStream destStream(filePath, std::move(mockDestFileWrapper));
417
418 // Test the Write function
419 sourceStream.Open();
420 destStream.Open();
421 byte *buf = new byte[sourceStream.GetSize()];
422 EXPECT_EQ(sourceStream.Read(buf, sourceStream.GetSize()), -1);
423 delete[] buf;
424 }
425
426 /**
427 * @tc.name: FileMetadataStream_Write006
428 * @tc.desc: Test the Write function of FileMetadataStream when the amount of data
429 * written exceeds the remaining space in the file system
430 * @tc.type: FUNC
431 */
432 HWTEST_F(MetadataStreamTest, FileMetadataStream_Write006, TestSize.Level3)
433 {
434 // This test case requires a nearly full file system, so it may be difficult
435 // to implement in actual testing
436 auto mockFileWrapper = std::make_unique<MockFileWrapper>();
437 FileMetadataStream stream(filePath, std::move(mockFileWrapper));
438 }
439
440 /**
441 * @tc.name: FileMetadataStream_Write001
442 * @tc.desc: Test the Write function of FileMetadataStream, whether it can write
443 * normally and verify the written data
444 * @tc.type: FUNC
445 */
446 HWTEST_F(MetadataStreamTest, FileMetadataStream_Write007, TestSize.Level3)
447 {
448 // Create a FileMetadataStream object
449 FileMetadataStream stream(CreateIfNotExit(filePath));
450
451 // Open the file
452 ASSERT_TRUE(stream.Open(OpenMode::ReadWrite));
453
454 // Create some data to write
455 std::string data = "1Hello, world!";
456
457 ASSERT_EQ(stream.Seek(0, SeekPos::BEGIN), 0);
458 ASSERT_EQ(stream.Tell(), 0);
459 // Write the data to the file
460 ASSERT_EQ(stream.Write((byte *)data.c_str(), data.size()), data.size());
461 ASSERT_EQ(stream.Tell(), data.size());
462 // Flush the file
463 stream.Flush();
464
465 // Open the file again
466 int fileDescriptor = open(filePath.c_str(), O_RDONLY);
467 ASSERT_NE(fileDescriptor, -1);
468
469 // Read the data from the file
470 byte buffer[SIZE_20];
471 read(fileDescriptor, buffer, sizeof(buffer));
472
473 // Check that the data read is the same as the data written
474 ASSERT_EQ(memcmp(data.c_str(), buffer, data.size()), 0);
475
476 // Close the file
477 close(fileDescriptor);
478 }
479
480 HWTEST_F(MetadataStreamTest, FileMetadataStream_Write008, TestSize.Level3)
481 {
482 for (ssize_t size : testSize) {
483 RemoveFile(filePath);
484 FileMetadataStream stream(CreateIfNotExit(filePath));
485 ASSERT_TRUE(stream.Open());
486 byte *buf = new byte[size](); // Dynamically allocate the buffer with the current test size
487 ASSERT_EQ(stream.Write(buf, size), size);
488 ASSERT_EQ(stream.Flush(), true);
489 ASSERT_EQ(stream.GetSize(), size);
490
491 // Open the file in binary mode and move the file pointer to the end to get the file size
492 std::ifstream file(filePath, std::ios::binary | std::ios::ate);
493 ASSERT_TRUE(file.is_open());
494
495 // Get the file size
496 std::streamsize fileSize = file.tellg();
497 file.close();
498
499 // Compare the file size with the current test size
500 ASSERT_EQ(fileSize, size);
501
502 delete[] buf; // Don't forget to delete the dynamically allocated buffer
503 }
504 }
505
506 /**
507 * @tc.name: FileMetadataStream_Open001
508 * @tc.desc: Test the Open function of FileMetadataStream when the file path does
509 * not exist
510 * @tc.type: FUNC
511 */
512 HWTEST_F(MetadataStreamTest, FileMetadataStream_Open001, TestSize.Level3)
513 {
514 // Test the case where the file path does not exist
515 std::string nonExistFilePath = "/data/local/tmp/image/non_exist_file.txt";
516 RemoveFile(nonExistFilePath.c_str());
517 FileMetadataStream stream1(CreateIfNotExit(nonExistFilePath));
518 ASSERT_TRUE(stream1.Open());
519 std::string sourceData = "Hello, world!";
520 stream1.Write((byte *)sourceData.c_str(), sourceData.size());
521 // Read data from stream1
522 byte buffer[SIZE_255];
523 stream1.Seek(0, SeekPos::BEGIN);
524 ssize_t bytesRead = stream1.Read(buffer, sourceData.size());
525 ASSERT_EQ(bytesRead, sourceData.size());
526 buffer[bytesRead] = '\0'; // Add string termination character
527 // Check if the read data is the same as the written data
528 ASSERT_STREQ((char *)buffer, sourceData.c_str());
529 ASSERT_TRUE(stream1.Flush());
530 RemoveFile(nonExistFilePath.c_str());
531 }
532
533 /**
534 * @tc.name: FileMetadataStream_Open002
535 * @tc.desc: Test the Open function of FileMetadataStream when the file path exists
536 * but is not writable
537 * @tc.type: FUNC
538 */
539 HWTEST_F(MetadataStreamTest, FileMetadataStream_Open002, TestSize.Level3)
540 {
541 // Get the username of the current user
542 uid_t uid = getuid();
543 struct passwd *passwordEntry = getpwuid(uid);
544 if (passwordEntry == nullptr) {
545 perror("getpwuid");
546 return;
547 }
548 std::string username(passwordEntry->pw_name);
549
550 // Test the case where the file path exists but is not writable
551 std::string nonWritableFilePath = "/data/local/tmp/image/non_writable_file.txt";
552 close(open(nonWritableFilePath.c_str(), O_CREAT, S_IRUSR));
553 FileMetadataStream stream2(nonWritableFilePath);
554 if (username == "root") {
555 // If the current user is root, then it can be opened successfully
556 ASSERT_TRUE(stream2.Open());
557 } else {
558 // If the current user is not root, then it cannot be opened
559 ASSERT_FALSE(stream2.Open());
560 }
561 RemoveFile(nonWritableFilePath.c_str());
562 }
563
564 /**
565 * @tc.name: FileMetadataStream_Open003
566 * @tc.desc: Test the Open function of FileMetadataStream when the file is already
567 * open
568 * @tc.type: FUNC
569 */
570 HWTEST_F(MetadataStreamTest, FileMetadataStream_Open003, TestSize.Level3)
571 {
572 // Test the case where the file is already open
573 FileMetadataStream stream3(CreateIfNotExit(filePath));
574 ASSERT_TRUE(stream3.Open());
575 ASSERT_TRUE(stream3.Open());
576 ASSERT_TRUE(stream3.Flush());
577 }
578
579 /**
580 * @tc.name: FileMetadataStream_Open004
581 * @tc.desc: Test the Open function of FileMetadataStream when the file does not
582 * exist
583 * @tc.type: FUNC
584 */
585 HWTEST_F(MetadataStreamTest, FileMetadataStream_Open004, TestSize.Level3)
586 {
587 // Test the case where the file does not exist
588 const char *nonExistentFilePath = "/path/to/nonexistent/file";
589 FileMetadataStream stream(nonExistentFilePath);
590 ASSERT_FALSE(stream.Open(OpenMode::Read));
591 }
592
593 /**
594 * @tc.name: FileMetadataStream_Open005
595 * @tc.desc: Test the Open twice
596 * @tc.type: FUNC
597 */
598 HWTEST_F(MetadataStreamTest, FileMetadataStream_Open005, TestSize.Level3)
599 {
600 FileMetadataStream stream(filePathSource);
601 ASSERT_TRUE(stream.Open(OpenMode::Read));
602 ASSERT_TRUE(stream.Open(OpenMode::Read));
603 }
604
605 /**
606 * @tc.name: FileMetadataStream_Read001
607 * @tc.desc: Test the Read function of FileMetadataStream, reading 512 bytes
608 * @tc.type: FUNC
609 */
610 HWTEST_F(MetadataStreamTest, FileMetadataStream_Read001, TestSize.Level3)
611 {
612 FileMetadataStream stream(filePathSource);
613 byte buffer[SIZE_1024];
614 stream.Open(OpenMode::ReadWrite);
615 // Simulate reading 512 bytes
616 ssize_t bytesRead = stream.Read(buffer, SIZE_512);
617 EXPECT_EQ(SIZE_512, bytesRead);
618 }
619
620 /**
621 * @tc.name: FileMetadataStream_Read002
622 * @tc.desc: Test the Read function of FileMetadataStream, trying to read from a
623 * file that has not been opened
624 * @tc.type: FUNC
625 */
626 HWTEST_F(MetadataStreamTest, FileMetadataStream_Read002, TestSize.Level3)
627 {
628 FileMetadataStream stream(filePathSource);
629 byte buffer[SIZE_1024];
630 // Flush the stream to simulate an unopened file
631 ASSERT_FALSE(stream.Flush());
632 ssize_t bytesRead = stream.Read(buffer, SIZE_512);
633 EXPECT_EQ(-1, bytesRead);
634 }
635
636 // Define a global jmp_buf variable
637 static sigjmp_buf g_jmpBuf;
638
639 // Define a signal handler function
HandleSigsegv(int sig)640 static void HandleSigsegv(int sig)
641 {
642 siglongjmp(g_jmpBuf, 1);
643 }
644
645 /**
646 * @tc.name: FileMetadataStream_MMap001
647 * @tc.desc: Test the MMap function of FileMetadataStream, trying to write to a
648 * memory-mapped file that is not writable
649 * @tc.type: FUNC
650 */
651 HWTEST_F(MetadataStreamTest, FileMetadataStream_MMap001, TestSize.Level3)
652 {
653 memoryCheck.check = false; // This test is expected to crash, so memory leak
654 // check is not needed
655 // Assume there is an appropriate way to create or obtain the resources
656 // needed for the test YourResource test_resource; Test the behavior of the
657 // MMap function when isWriteable is false
658 FileMetadataStream stream(filePathSource);
659 byte *result = stream.GetAddr(false);
660 // Assume that checking whether result is not nullptr, or there is another
661 // appropriate verification method
662 ASSERT_EQ(result, nullptr);
663 stream.Open(OpenMode::ReadWrite);
664 result = stream.GetAddr(false);
665 ASSERT_NE(result, nullptr);
666
667 // Set the signal handler function
668 signal(SIGSEGV, HandleSigsegv);
669
670 // Try to write data
671 if (sigsetjmp(g_jmpBuf, 1) == 0) {
672 result[0] = 0;
673 // If no segmentation fault is triggered, then this is an error
674 FAIL() << "Expected a segmentation fault";
675 }
676 }
677
678 /**
679 * @tc.name: FileMetadataStream_MMap002
680 * @tc.desc: Test the MMap function of FileMetadataStream, trying to write to a
681 * memory-mapped file that is writable
682 * @tc.type: FUNC
683 */
684 HWTEST_F(MetadataStreamTest, FileMetadataStream_MMap002, TestSize.Level3)
685 {
686 // Test the behavior of the MMap function when isWriteable is true
687 FileMetadataStream stream(filePathSource);
688 ASSERT_TRUE(stream.Open(OpenMode::ReadWrite));
689 byte *result = stream.GetAddr(true);
690 ASSERT_NE(result, nullptr);
691 // Try to write data
692 result[0] = 123;
693
694 // Read the data and check if it is the same as the written data
695 ASSERT_EQ(result[0], 123);
696 }
697
698 /**
699 * @tc.name: FileMetadataStream_MMap003
700 * @tc.desc: Test whether the MMap function of FileMetadataStream can actually
701 * modify the content of the file
702 * @tc.type: FUNC
703 */
704 HWTEST_F(MetadataStreamTest, FileMetadataStream_MMap003, TestSize.Level3)
705 {
706 // Test whether MMap can actually modify the content of the file
707 FileMetadataStream stream(filePathSource);
708 ASSERT_TRUE(stream.Open(OpenMode::ReadWrite));
709 byte *result = stream.GetAddr(true);
710 ASSERT_NE(result, nullptr);
711
712 // Try to write data
713 result[0] = 123;
714
715 stream.Seek(0, SeekPos::BEGIN);
716 byte buffer[1];
717 ASSERT_EQ(stream.Read(buffer, 1), 1);
718 ASSERT_EQ(buffer[0], 123);
719
720 // Flush stream
721 ASSERT_TRUE(stream.Flush());
722 FileMetadataStream checkStream(filePathSource);
723 checkStream.Open(OpenMode::ReadWrite);
724 byte checkBuffer[1];
725 ASSERT_EQ(checkStream.Read(checkBuffer, 1), 1);
726
727 // Check if the data in the file is the same as the data written
728 ASSERT_EQ(checkBuffer[0], 123);
729 }
730
731 /**
732 * @tc.name: FileMetadataStream_CopyFrom001
733 * @tc.desc: Test the CopyFrom function of FileMetadataStream, copying data from
734 * one stream to another
735 * @tc.type: FUNC
736 */
737 HWTEST_F(MetadataStreamTest, FileMetadataStream_CopyFrom001, TestSize.Level3)
738 {
739 FileMetadataStream src(filePathSource);
740 FileMetadataStream dest(CreateIfNotExit(filePathDest));
741
742 src.Open();
743 // Write some known data to src
744 std::string data = "Hello, world!";
745 ASSERT_EQ(src.Tell(), 0);
746 ASSERT_GE(src.Write((byte *)data.c_str(), data.size()), 0);
747 ASSERT_TRUE(src.Flush());
748 // Call the Transfer function to transfer data from src to dest
749 dest.Open();
750 ASSERT_TRUE(dest.CopyFrom(src));
751 // Read data from dest and verify that it is the same as the data written to
752 // src
753 byte buffer[SIZE_255] = {0};
754
755 ASSERT_EQ(dest.Seek(0, SeekPos::BEGIN), 0);
756 ASSERT_EQ(dest.Read(buffer, data.size()), data.size());
757 ASSERT_EQ(std::string(buffer, buffer + data.size()), data);
758
759 // Verify that src is empty
760 ASSERT_EQ(dest.GetSize(), src.GetSize());
761 }
762
763 HWTEST_F(MetadataStreamTest, FileMetadataStream_CopyFrom002, TestSize.Level3)
764 {
765 BufferMetadataStream src;
766 FileMetadataStream dest(CreateIfNotExit(filePathDest));
767 ASSERT_TRUE(src.Open());
768 ASSERT_EQ(dest.Open(), true);
769 src.Write((byte *)"Hello, world!", 13);
770 char bufSrc[14] = {0};
771 src.Seek(0, SeekPos::BEGIN);
772 src.Read((byte *)bufSrc, 13);
773 ASSERT_STREQ(bufSrc, "Hello, world!");
774 ASSERT_TRUE(dest.CopyFrom(src));
775 dest.Seek(0, SeekPos::BEGIN);
776 char buf[14] = {0};
777 dest.Read((byte *)buf, 13);
778 ASSERT_STREQ(buf, "Hello, world!");
779 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), 13), 0);
780 }
781
782 HWTEST_F(MetadataStreamTest, FileMetadataStream_CopyFrom003, TestSize.Level3)
783 {
784 BufferMetadataStream src;
785 FileMetadataStream dest(CreateIfNotExit(filePathDest));
786 src.Open();
787 dest.Open();
788 char buff[METADATA_STREAM_PAGE_SIZE + 1] = {0};
789 src.Write((byte *)buff, sizeof(buff));
790 ASSERT_TRUE(dest.CopyFrom(src));
791 ASSERT_EQ(src.GetSize(), dest.GetSize());
792 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), 4097), 0);
793 }
794
795 HWTEST_F(MetadataStreamTest, FileMetadataStream_CopyFrom004, TestSize.Level3)
796 {
797 BufferMetadataStream src;
798 FileMetadataStream dest(CreateIfNotExit(filePathDest));
799 src.Open();
800 dest.Open();
801 char buff[METADATA_STREAM_PAGE_SIZE - 1] = {0};
802 src.Write((byte *)buff, sizeof(buff));
803 ASSERT_TRUE(dest.CopyFrom(src));
804 ASSERT_EQ(src.GetSize(), dest.GetSize());
805 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), src.GetSize()), 0);
806 }
807
808 HWTEST_F(MetadataStreamTest, FileMetadataStream_CopyFrom005, TestSize.Level3)
809 {
810 RemoveFile(filePath.c_str());
811 FileMetadataStream src(CreateIfNotExit(filePathDest));
812 BufferMetadataStream dest;
813 src.Open();
814 dest.Open();
815 char buff[METADATA_STREAM_PAGE_SIZE - 1] = {0};
816 ASSERT_EQ(src.Write((byte *)buff, sizeof(buff)), sizeof(buff));
817 ASSERT_TRUE(src.Flush());
818 ASSERT_EQ(src.Tell(), sizeof(buff));
819 ASSERT_EQ(src.GetSize(), sizeof(buff));
820 ASSERT_TRUE(dest.CopyFrom(src));
821 ASSERT_EQ(src.GetSize(), dest.GetSize());
822 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), src.GetSize()), 0);
823 }
824
825 HWTEST_F(MetadataStreamTest, FileMetadataStream_CopyFrom006, TestSize.Level3)
826 {
827 for (ssize_t size : testSize) {
828 RemoveFile(filePathDest.c_str());
829 FileMetadataStream src(CreateIfNotExit(filePathDest));
830 BufferMetadataStream dest;
831 src.Open();
832 dest.Open();
833 byte *buf = new byte[size]();
834 ASSERT_EQ(src.Write(buf, size), size);
835 ASSERT_TRUE(src.Flush());
836 ASSERT_EQ(src.Tell(), size);
837 ASSERT_EQ(src.GetSize(), size);
838 ASSERT_TRUE(dest.CopyFrom(src));
839 ASSERT_EQ(src.GetSize(), dest.GetSize());
840 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), src.GetSize()), 0);
841 delete[] buf;
842 }
843 }
844
845 HWTEST_F(MetadataStreamTest, FileMetadataStream_CopyFrom007, TestSize.Level3)
846 {
847 for (ssize_t size : testSize) {
848 RemoveFile(filePath.c_str());
849 FileMetadataStream dest(CreateIfNotExit(filePathDest));
850 BufferMetadataStream src;
851 src.Open();
852 dest.Open();
853 byte *buf = new byte[size]();
854 ASSERT_EQ(src.Write(buf, size), size);
855 ASSERT_TRUE(src.Flush());
856 ASSERT_EQ(src.Tell(), size);
857 ASSERT_EQ(src.GetSize(), size);
858 ASSERT_TRUE(dest.CopyFrom(src));
859 ASSERT_EQ(src.GetSize(), dest.GetSize());
860 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), src.GetSize()), 0);
861 delete[] buf;
862 }
863 }
864
865 HWTEST_F(MetadataStreamTest, FileMetadataStream_CopyFrom008, TestSize.Level3)
866 {
867 for (ssize_t size : testSize) {
868 RemoveFile(filePathDest.c_str());
869 RemoveFile(filePathSource.c_str());
870 FileMetadataStream src(CreateIfNotExit(filePathSource));
871 FileMetadataStream dest(CreateIfNotExit(filePathDest));
872 src.Open();
873 dest.Open();
874 byte *buf = new byte[size]();
875 ASSERT_EQ(src.Write(buf, size), size);
876 ASSERT_TRUE(src.Flush());
877 ASSERT_EQ(src.Tell(), size);
878 ASSERT_EQ(src.GetSize(), size);
879 ASSERT_TRUE(dest.CopyFrom(src));
880 ASSERT_EQ(src.GetSize(), dest.GetSize());
881 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), src.GetSize()), 0);
882 delete[] buf;
883 }
884 }
885
886 HWTEST_F(MetadataStreamTest, FileMetadataStream_CopyFrom009, TestSize.Level3)
887 {
888 for (ssize_t size : testSize) {
889 RemoveFile(filePath.c_str());
890 BufferMetadataStream src;
891 BufferMetadataStream dest;
892 src.Open();
893 dest.Open();
894 byte *buf = new byte[size]();
895 ASSERT_EQ(src.Write(buf, size), size);
896 ASSERT_TRUE(src.Flush());
897 ASSERT_EQ(src.Tell(), size);
898 ASSERT_EQ(src.GetSize(), size);
899 ASSERT_TRUE(dest.CopyFrom(src));
900 ASSERT_EQ(src.GetSize(), dest.GetSize());
901 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), src.GetSize()), 0);
902 delete[] buf;
903 }
904 }
905
906 HWTEST_F(MetadataStreamTest, FileMetadataStream_CopyFrom010, TestSize.Level3)
907 {
908 for (ssize_t size : testSize) {
909 RemoveFile(filePathDest.c_str());
910 std::filesystem::copy(backupFilePathSource, filePathSource, std::filesystem::copy_options::overwrite_existing);
911 FileMetadataStream src(CreateIfNotExit(filePathDest));
912 FileMetadataStream dest(CreateIfNotExit(filePathSource));
913 src.Open();
914 dest.Open();
915 byte *buf = new byte[size]();
916 ASSERT_EQ(src.Write(buf, size), size);
917 ASSERT_TRUE(src.Flush());
918 ASSERT_EQ(src.Tell(), size);
919 ASSERT_EQ(src.GetSize(), size);
920 ASSERT_TRUE(dest.CopyFrom(src));
921 ASSERT_EQ(src.GetSize(), dest.GetSize());
922 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), src.GetSize()), 0);
923 delete[] buf;
924 }
925 }
926
927 HWTEST_F(MetadataStreamTest, FileMetadataStream_IsEof001, TestSize.Level3)
928 {
929 FileMetadataStream src(filePathSource);
930 src.Open();
931 byte buffer[1];
932 ASSERT_EQ(src.Seek(0, SeekPos::BEGIN), 0);
933 src.Read(buffer, sizeof(buffer));
934 ASSERT_FALSE(src.IsEof());
935 ASSERT_EQ(src.Seek(0, SeekPos::END), src.GetSize());
936 src.Read(buffer, sizeof(buffer));
937 ASSERT_TRUE(src.IsEof());
938 }
939
940 /**
941 * @tc.name: FileMetadataStream_ReadByte001
942 * @tc.desc: Test the ReadByte function of FileMetadataStream, comparing its output
943 * with the Read function
944 * @tc.type: FUNC
945 */
946 HWTEST_F(MetadataStreamTest, FileMetadataStream_ReadByte001, TestSize.Level3)
947 {
948 FileMetadataStream stream(filePathSource);
949 stream.Open(OpenMode::ReadWrite);
950
951 // Read 10 bytes using Read function
952 byte buffer[SIZE_10];
953 stream.Read(buffer, SIZE_10);
954
955 // Reset the file offset
956 stream.Seek(0, SeekPos::BEGIN);
957
958 // Read 10 bytes using ReadByte function
959 byte byteBuffer[SIZE_10];
960 for (int i = 0; i < SIZE_10; i++) {
961 byteBuffer[i] = stream.ReadByte();
962 }
963
964 // Compare the results
965 for (int i = 0; i < SIZE_10; i++) {
966 EXPECT_EQ(buffer[i], byteBuffer[i]);
967 }
968 }
969
970 /**
971 * @tc.name: FileMetadataStream_ReadByte002
972 * @tc.desc: Test the ReadByte function of FileMetadataStream, trying to read
973 * beyond the end of the file
974 * @tc.type: FUNC
975 */
976 HWTEST_F(MetadataStreamTest, FileMetadataStream_ReadByte002, TestSize.Level3)
977 {
978 FileMetadataStream stream(filePathSource);
979 stream.Open(OpenMode::ReadWrite);
980
981 // Set the file offset to the end of the file
982 EXPECT_EQ(stream.Seek(0, SeekPos::END), stream.GetSize());
983
984 // Try to read one more byte
985 int result = stream.ReadByte();
986
987 // Check if the result is -1
988 EXPECT_EQ(result, -1);
989 }
990
991 /**
992 * @tc.name: FileMetadataStream_CONSTRUCTOR001
993 * @tc.desc: Test the constructor of FileMetadataStream, checking if it can
994 * correctly initialize a stream from an existing file pointer
995 * @tc.type: FUNC
996 */
997 HWTEST_F(MetadataStreamTest, FileMetadataStream_CONSTRUCTOR001, TestSize.Level3)
998 {
999 FileMetadataStream stream(CreateIfNotExit(filePath));
1000 ASSERT_TRUE(stream.Open(OpenMode::ReadWrite));
1001 std::string sourceData = "Hello, world!";
1002 ASSERT_EQ(stream.Seek(5, SeekPos::BEGIN), 5);
1003 ASSERT_EQ(stream.Write((byte *)sourceData.c_str(), sourceData.size()), sourceData.size());
1004
1005 FileMetadataStream cloneStream(fileno(stream.fp_));
1006 ASSERT_TRUE(stream.Flush());
1007 ASSERT_TRUE(cloneStream.Open(OpenMode::ReadWrite));
1008 // Read the data from cloneStream
1009 byte buffer[SIZE_255];
1010 cloneStream.Seek(5, SeekPos::BEGIN);
1011 ssize_t bytesRead = cloneStream.Read(buffer, sourceData.size());
1012 ASSERT_EQ(bytesRead, sourceData.size());
1013 buffer[bytesRead] = '\0'; // Add string termination character
1014
1015 // Check if the read data is the same as the data in the source file
1016 ASSERT_STREQ((char *)buffer, sourceData.c_str());
1017
1018 // Write some new data to cloneStream
1019 std::string newData = "New data";
1020 cloneStream.Write((byte *)newData.c_str(), newData.size());
1021
1022 // Read the data from cloneStream again
1023 cloneStream.Seek(0, SeekPos::BEGIN);
1024 bytesRead = cloneStream.Read(buffer, sizeof(buffer) - 1);
1025 buffer[bytesRead] = '\0'; // Add string termination character
1026
1027 // Check if the read data contains the new data
1028 ASSERT_STRNE((char *)buffer, newData.c_str());
1029 }
1030
1031 /**
1032 * @tc.name: FileMetadataStream_CONSTRUCTOR002
1033 * @tc.desc: Test the constructor of FileMetadataStream, checking if it can
1034 * correctly initialize a stream from an existing file descriptor
1035 * @tc.type: FUNC
1036 */
1037 HWTEST_F(MetadataStreamTest, FileMetadataStream_CONSTRUCTOR002, TestSize.Level3)
1038 {
1039 // Create and open a temporary file
1040 std::string tempFile = tmpDirectory + "/testfile";
1041 int fileDescription = open(tempFile.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
1042 ASSERT_NE(fileDescription, -1);
1043
1044 // Use the file descriptor to create a new FileMetadataStream object
1045 FileMetadataStream stream(fileDescription);
1046 ASSERT_TRUE(stream.Open(OpenMode::ReadWrite));
1047 ASSERT_NE(stream.dupFD_, -1);
1048 // Check the state of the FileMetadataStream object
1049 ASSERT_TRUE(stream.fp_ != nullptr);
1050 ASSERT_EQ(stream.mappedMemory_, nullptr);
1051 ASSERT_EQ(stream.Tell(), 0);
1052
1053 // Write data
1054 byte writeData[SIZE_10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
1055 ssize_t bytesWritten = stream.Write(writeData, sizeof(writeData));
1056 ASSERT_EQ(bytesWritten, sizeof(writeData));
1057
1058 // Reset the file pointer to the beginning of the file
1059 stream.Seek(0, SeekPos::BEGIN);
1060
1061 // Read data
1062 byte readData[SIZE_10] = {0};
1063 ssize_t bytesRead = stream.Read(readData, sizeof(readData));
1064 ASSERT_EQ(bytesRead, sizeof(readData));
1065
1066 // Check if the read data is the same as the written data
1067 for (size_t i = 0; i < sizeof(writeData); ++i) {
1068 ASSERT_EQ(writeData[i], readData[i]);
1069 }
1070
1071 // Close the file
1072 close(fileDescription);
1073 RemoveFile(tempFile.c_str());
1074 }
1075
1076 /**
1077 * @tc.name: FileMetadataStream_CONSTRUCTOR003
1078 * @tc.desc: Test the constructor of FileMetadataStream, checking if it can
1079 * correctly initialize a stream from an existing file descriptor and handle
1080 * file operations
1081 * @tc.type: FUNC
1082 */
1083 HWTEST_F(MetadataStreamTest, FileMetadataStream_CONSTRUCTOR003, TestSize.Level3)
1084 {
1085 int fdCount = CountOpenFileDescriptors();
1086 std::string tempFile = tmpDirectory + "/testfile";
1087 int fileDescriptor = open(tempFile.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
1088 ASSERT_EQ(fdCount + 1, CountOpenFileDescriptors());
1089 int dupFD = dup(fileDescriptor);
1090 ASSERT_EQ(fdCount + 2, CountOpenFileDescriptors());
1091 ASSERT_NE(fileDescriptor, -1);
1092 FILE *fileStream = fdopen(dupFD, "r+"); // Change "rb" to "wb" for writing in binary mode
1093 ASSERT_EQ(fdCount + 2, CountOpenFileDescriptors());
1094 ;
1095 ASSERT_NE(fileStream, nullptr);
1096 std::string text = "Hello, world!";
1097 ssize_t result = fwrite(text.c_str(), sizeof(char), text.size(),
1098 fileStream); // Use sizeof(char) as the second argument
1099 ASSERT_EQ(ferror(fileStream), 0);
1100 ASSERT_EQ(result, text.size());
1101
1102 // Reset the file pointer to the beginning of the file
1103 rewind(fileStream);
1104
1105 ASSERT_EQ(fdCount + 2, CountOpenFileDescriptors());
1106 fileno(fileStream);
1107 ASSERT_EQ(fdCount + 2, CountOpenFileDescriptors());
1108
1109 // Read and verify the data
1110 char buffer[SIZE_255];
1111 result = fread(buffer, sizeof(char), text.size(), fileStream);
1112 ASSERT_EQ(result, text.size());
1113 buffer[result] = '\0'; // Add string termination character
1114 ASSERT_STREQ(buffer, text.c_str());
1115
1116 fclose(fileStream);
1117 ASSERT_EQ(fdCount + 1, CountOpenFileDescriptors());
1118 close(fileDescriptor);
1119 ASSERT_EQ(fdCount, CountOpenFileDescriptors());
1120 }
1121
1122 /**
1123 * @tc.name: FileMetadataStream_CONSTRUCTOR004
1124 * @tc.desc: Test the constructor of FileMetadataStream, checking if it can
1125 * correctly initialize a stream from an existing file descriptor and handle
1126 * file operations using the stream's file pointer
1127 * @tc.type: FUNC
1128 */
1129 HWTEST_F(MetadataStreamTest, FileMetadataStream_CONSTRUCTOR004, TestSize.Level3)
1130 {
1131 std::string tempFile = tmpDirectory + "/testfile";
1132 int fileDescriptor = open(tempFile.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
1133 FileMetadataStream stream(fileDescriptor);
1134 int dupFD = stream.dupFD_;
1135 ASSERT_NE(fileDescriptor, -1);
1136 ASSERT_TRUE(stream.Open(OpenMode::ReadWrite));
1137 FILE *fileStream = stream.fp_; // Change "rb" to "wb" for writing in binary mode
1138 // binary mode
1139 ASSERT_NE(fileStream, nullptr);
1140 std::string text = "Hello, world!";
1141 ssize_t result = fwrite(text.c_str(), sizeof(char), text.size(),
1142 fileStream); // Use sizeof(char) as the second argument
1143 ASSERT_EQ(ferror(fileStream), 0);
1144 ASSERT_EQ(result, text.size());
1145
1146 // Reset the file pointer to the beginning of the file
1147 rewind(fileStream);
1148
1149 // Read and verify the data
1150 char buffer[SIZE_255];
1151 result = fread(buffer, sizeof(char), text.size(), fileStream);
1152 ASSERT_EQ(result, text.size());
1153 buffer[result] = '\0'; // Add string termination character
1154 ASSERT_STREQ(buffer, text.c_str());
1155
1156 fclose(fileStream);
1157 close(dupFD);
1158 close(fileDescriptor);
1159 }
1160
1161 HWTEST_F(MetadataStreamTest, FileMetadataStream_CONSTRUCTOR005, TestSize.Level3)
1162 {
1163 int fileDescriptor = open(filePathSource.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
1164 FileMetadataStream *stream = new FileMetadataStream(fileDescriptor);
1165 ASSERT_FALSE(stream->IsOpen());
1166 ASSERT_TRUE(stream->Open());
1167 delete stream;
1168 stream = new FileMetadataStream(fileDescriptor);
1169 ASSERT_TRUE(stream->Open());
1170 delete stream;
1171 }
1172
1173 /**
1174 * @tc.name: FileMetadataStream_DESTRUCTOR001
1175 * @tc.desc: Test the destructor of FileMetadataStream, checking if it can
1176 * correctly handle the deletion of a non-existing file
1177 * @tc.type: FUNC
1178 */
1179 HWTEST_F(MetadataStreamTest, FileMetadataStream_DESTRUCTOR001, TestSize.Level3)
1180 {
1181 FileMetadataStream *stream = new FileMetadataStream("/data/fileNotExist");
1182 ASSERT_FALSE(stream->Open());
1183 ASSERT_EQ(stream->Write((byte *)"Hello, the world", 16), -1);
1184 stream->GetAddr();
1185 ASSERT_FALSE(stream->Flush());
1186 delete stream;
1187 }
1188
1189 /**
1190 * @tc.name: FileMetadataStream_Seek001
1191 * @tc.desc: Test the Seek function of FileMetadataStream, checking if it can
1192 * correctly change the position of the file pointer
1193 * @tc.type: FUNC
1194 */
1195 HWTEST_F(MetadataStreamTest, FileMetadataStream_Seek001, TestSize.Level3)
1196 {
1197 RemoveFile(filePath.c_str());
1198 FileMetadataStream stream(CreateIfNotExit(filePath));
1199 stream.Open(OpenMode::ReadWrite);
1200 std::string sourceData = "Hello, world!";
1201 ASSERT_EQ(stream.Tell(), 0);
1202 stream.Write((byte *)sourceData.c_str(), sourceData.size());
1203 ASSERT_EQ(stream.Tell(), sourceData.size());
1204 stream.Seek(2, SeekPos::BEGIN);
1205 ASSERT_EQ(stream.Tell(), 2);
1206 byte buffer[SIZE_255];
1207 ssize_t bytesRead = stream.Read(buffer, 1);
1208 buffer[bytesRead] = '\0'; // Add string termination character
1209 ASSERT_STREQ((char *)buffer, "l");
1210 ASSERT_EQ(stream.Tell(), 3);
1211 stream.Seek(3, SeekPos::CURRENT);
1212 ASSERT_EQ(stream.Tell(), 6);
1213 bytesRead = stream.Read(buffer, 1);
1214 buffer[bytesRead] = '\0'; // Add string termination character
1215 ASSERT_STREQ((char *)buffer, " ");
1216 stream.Seek(0, SeekPos::END);
1217 ASSERT_EQ(stream.Tell(), sourceData.size());
1218 }
1219
1220 /**
1221 * @tc.name: BufferMetadataStream_Open001
1222 * @tc.desc: Test the Open function of BufferMetadataStream, checking if it can
1223 * correctly open a stream
1224 * @tc.type: FUNC
1225 */
1226 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Open001, TestSize.Level3)
1227 {
1228 BufferMetadataStream stream;
1229 ASSERT_TRUE(stream.Open(OpenMode::ReadWrite));
1230 }
1231
1232 /**
1233 * @tc.name: BufferMetadataStream_Read001
1234 * @tc.desc: Test the Read function of BufferMetadataStream, checking if it can
1235 * correctly read data from the stream
1236 * @tc.type: FUNC
1237 */
1238 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Read001, TestSize.Level3)
1239 {
1240 BufferMetadataStream stream;
1241 ASSERT_TRUE(stream.Open(OpenMode::ReadWrite));
1242
1243 // Write a string
1244 std::string sourceData = "Hello, world!";
1245 ASSERT_EQ(stream.Tell(), 0);
1246 stream.Write((byte *)sourceData.c_str(), sourceData.size());
1247
1248 // Read the string
1249 byte buffer[SIZE_255];
1250 stream.Seek(0, SeekPos::BEGIN);
1251 size_t bytesRead = stream.Read(buffer, sourceData.size());
1252 buffer[bytesRead] = '\0'; // Add string termination character
1253
1254 // Compare the read string with the written string
1255 ASSERT_STREQ((char *)buffer, sourceData.c_str());
1256 }
1257
1258 /**
1259 * @tc.name: BufferMetadataStream_Write001
1260 * @tc.desc: Test the Write function of BufferMetadataStream, checking if it can
1261 * correctly write data to the stream
1262 * @tc.type: FUNC
1263 */
1264 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Write001, TestSize.Level3)
1265 {
1266 BufferMetadataStream stream;
1267 byte data[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
1268 stream.Open(OpenMode::ReadWrite);
1269 size_t size = sizeof(data) / sizeof(data[0]);
1270 int offset = 0;
1271 stream.Seek(0, SeekPos::BEGIN);
1272 ssize_t bytesWritten = stream.Write(data, size);
1273 ASSERT_EQ(bytesWritten, size);
1274 offset = stream.Tell();
1275 ASSERT_EQ(stream.Tell(), size);
1276 ASSERT_NE(offset, 0);
1277 byte readData[10] = {0};
1278 stream.Seek(0, SeekPos::BEGIN);
1279 ASSERT_EQ(stream.Tell(), 0);
1280 ssize_t bytesRead = stream.Read(readData, size);
1281 ASSERT_EQ(bytesRead, size);
1282
1283 for (size_t i = 0; i < size; ++i) {
1284 ASSERT_EQ(data[i], readData[i]);
1285 }
1286 }
1287
1288 /**
1289 * @tc.name: BufferMetadataStream_Write002
1290 * @tc.desc: Test the Write function of BufferMetadataStream, checking if it can
1291 * correctly write a string to the stream
1292 * @tc.type: FUNC
1293 */
1294 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Write002, TestSize.Level3)
1295 {
1296 BufferMetadataStream stream;
1297 stream.Open(OpenMode::ReadWrite);
1298 stream.Write((byte *)"Hello, world!", 13);
1299 ASSERT_EQ(stream.capacity_, METADATA_STREAM_PAGE_SIZE);
1300 ASSERT_EQ(stream.Tell(), 13);
1301 }
1302
1303 /**
1304 * @tc.name: BufferMetadataStream_Write003
1305 * @tc.desc: Test the Write function of BufferMetadataStream, checking if it can
1306 * correctly handle large data
1307 * @tc.type: FUNC
1308 */
1309 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Write003, TestSize.Level3)
1310 {
1311 BufferMetadataStream stream;
1312 stream.Open(OpenMode::ReadWrite);
1313 byte data[METADATA_STREAM_PAGE_SIZE + 1] = {0}; // Create a 4097-byte data
1314 stream.Write(data, METADATA_STREAM_PAGE_SIZE + 1); // Write 4097 bytes of data
1315 ASSERT_GE(stream.capacity_,
1316 METADATA_STREAM_PAGE_SIZE + 1); // Check if the buffer capacity is at least 4097
1317 ASSERT_EQ(stream.Tell(), METADATA_STREAM_PAGE_SIZE + 1); // Check if the write position is correct
1318 }
1319
1320 /**
1321 * @tc.name: BufferImageStream_Write004
1322 * @tc.desc: Test the Write function of BufferImageStream, checking if it can
1323 * correctly handle data of the exact buffer capacity
1324 * @tc.type: FUNC
1325 */
1326 HWTEST_F(MetadataStreamTest, BufferImageStream_Write004, TestSize.Level3)
1327 {
1328 BufferMetadataStream stream;
1329 stream.Open();
1330
1331 byte data[METADATA_STREAM_PAGE_SIZE] = {0}; // Create a 4096-byte data
1332 stream.Write(data, METADATA_STREAM_PAGE_SIZE); // Write 4096 bytes of data
1333 ASSERT_EQ(stream.capacity_,
1334 METADATA_STREAM_PAGE_SIZE); // Check if the buffer capacity is 4096
1335 ASSERT_EQ(stream.Tell(),
1336 METADATA_STREAM_PAGE_SIZE); // Check if the write position is correct
1337 }
1338
1339 /**
1340 * @tc.name: BufferImageStream_Write005
1341 * @tc.desc: Test the Write function of BufferImageStream, checking if it can
1342 * correctly handle fixed buffer size
1343 * @tc.type: FUNC
1344 */
1345 HWTEST_F(MetadataStreamTest, BufferImageStream_Write005, TestSize.Level3)
1346 {
1347 char text[] = "Hello, world!";
1348 BufferMetadataStream stream((byte *)text, sizeof(text), BufferMetadataStream::Fix);
1349 ASSERT_TRUE(stream.Open());
1350 ASSERT_EQ(stream.Write((byte *)"Hi", 2), 2);
1351 ASSERT_EQ(stream.Tell(), 2);
1352 ASSERT_STREQ(text, "Hillo, world!");
1353 ASSERT_EQ(stream.Write((byte *)"this is a very long text", 24), -1);
1354 ASSERT_STREQ(text, "Hillo, world!");
1355 }
1356
1357 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Write006, TestSize.Level3)
1358 {
1359 for (ssize_t size : testSize) {
1360 BufferMetadataStream stream;
1361 ASSERT_TRUE(stream.Open());
1362 byte *buf = new byte[size](); // Dynamically allocate the buffer with the current test size
1363 ASSERT_EQ(stream.Write(buf, size), size);
1364 ASSERT_EQ(stream.GetSize(), size);
1365
1366 delete[] buf; // Don't forget to delete the dynamically allocated buffer
1367 }
1368 }
1369
1370 /**
1371 * @tc.name: BufferImageStream_Write006
1372 * @tc.desc: Test the Write function of BufferImageStream, checking if it can
1373 * correctly handle dynamic buffer size
1374 * @tc.type: FUNC
1375 */
1376 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Write007, TestSize.Level3)
1377 {
1378 char text[] = "Hello, world!";
1379 BufferMetadataStream stream((byte *)text, sizeof(text), BufferMetadataStream::Dynamic);
1380 ASSERT_TRUE(stream.Open());
1381 ASSERT_EQ(stream.Write((byte *)"Hi", 2), 2);
1382 ASSERT_EQ(stream.Tell(), 2);
1383 ASSERT_STREQ(text, "Hillo, world!");
1384 stream.Seek(0, SeekPos::BEGIN);
1385 ASSERT_EQ(stream.Write((byte *)"this is a very long text", 25), 25);
1386 ASSERT_STREQ((char *)stream.GetAddr(false), "this is a very long text");
1387 }
1388
1389 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Write008, TestSize.Level3)
1390 {
1391 BufferMetadataStream stream;
1392 byte *buf = new byte[13];
1393 ASSERT_TRUE(stream.Open());
1394 stream.Write((uint8_t *)"Hello, world!", 13);
1395 stream.Seek(4, SeekPos::BEGIN);
1396 stream.Write((uint8_t *)"a", 1);
1397 stream.Write((uint8_t *)"b", 1);
1398 stream.Seek(0, SeekPos::BEGIN);
1399 stream.Read(buf, 13);
1400 ASSERT_STREQ((char *)buf, "Hellab world!");
1401 delete[] buf;
1402 }
1403
1404 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Write009, TestSize.Level3)
1405 {
1406 BufferMetadataStream stream;
1407 byte *buf = new byte[2000];
1408 byte *buf2 = new byte[500];
1409 ASSERT_TRUE(stream.Open());
1410 stream.Write(buf, 2000);
1411 stream.Write(buf2, 500);
1412 stream.Write(buf2, 500);
1413 ASSERT_EQ(stream.GetSize(), 3000);
1414 ASSERT_EQ(stream.capacity_, 32768);
1415 delete[] buf;
1416 delete[] buf2;
1417 }
1418
1419 /**
1420 * @tc.name: BufferMetadataStream_Close001
1421 * @tc.desc: Test the Close function of BufferMetadataStream with an empty stream
1422 * @tc.type: FUNC
1423 */
1424 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Close001, TestSize.Level3)
1425 {
1426 BufferMetadataStream stream;
1427 }
1428
1429 /**
1430 * @tc.name: BufferMetadataStream_Close002
1431 * @tc.desc: Test the Close function of BufferMetadataStream after writing to the
1432 * stream
1433 * @tc.type: FUNC
1434 */
1435 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Close002, TestSize.Level3)
1436 {
1437 BufferMetadataStream stream;
1438 stream.Write((byte *)"Hello, world!", 13);
1439 }
1440
1441 /**
1442 * @tc.name: BufferImageStream_Close003
1443 * @tc.desc: Test the Close function of BufferImageStream after releasing the
1444 * stream
1445 * @tc.type: FUNC
1446 */
1447 HWTEST_F(MetadataStreamTest, BufferImageStream_Close003, TestSize.Level3)
1448 {
1449 BufferMetadataStream stream;
1450 stream.Write((byte *)"Hello, world!", 13);
1451 delete[] stream.Release();
1452 }
1453
1454 /**
1455 * @tc.name: BufferMetadataStream_Close004
1456 * @tc.desc: Test the Close function of BufferMetadataStream after closing the
1457 * stream
1458 * @tc.type: FUNC
1459 */
1460 HWTEST_F(MetadataStreamTest, BufferMetadataStream_Close004, TestSize.Level3)
1461 {
1462 BufferMetadataStream stream;
1463 stream.Write((byte *)"Hello, world!", 13);
1464 stream.Close();
1465 }
1466
1467 /**
1468 * @tc.name: BufferImageStream_Close005
1469 * @tc.desc: Test the Close function of BufferImageStream with a fixed size
1470 * buffer
1471 * @tc.type: FUNC
1472 */
1473 HWTEST_F(MetadataStreamTest, BufferImageStream_Close005, TestSize.Level3)
1474 {
1475 char text[] = "Hello, world!";
1476 BufferMetadataStream stream((byte *)text, sizeof(text), BufferMetadataStream::Fix);
1477 }
1478
1479 /**
1480 * @tc.name: BufferImageStream_Close006
1481 * @tc.desc: Test the Close function of BufferImageStream with a fixed size
1482 * buffer after releasing the stream
1483 * @tc.type: FUNC
1484 */
1485 HWTEST_F(MetadataStreamTest, BufferImageStream_Close006, TestSize.Level3)
1486 {
1487 char text[] = "Hello, world!";
1488 BufferMetadataStream stream((byte *)text, sizeof(text), BufferMetadataStream::Fix);
1489 stream.Release();
1490 }
1491
1492 /**
1493 * @tc.name: BufferImageStream_Close007
1494 * @tc.desc: Test the Close function of BufferImageStream with a dynamic size
1495 * buffer after writing and releasing the stream
1496 * @tc.type: FUNC
1497 */
1498 HWTEST_F(MetadataStreamTest, BufferImageStream_Close007, TestSize.Level3)
1499 {
1500 char text[] = "Hello, world!";
1501 BufferMetadataStream stream((byte *)text, sizeof(text), BufferMetadataStream::Dynamic);
1502 stream.Write((byte *)"this is a very very long text", 28);
1503 delete[] stream.Release();
1504
1505 DataBuf dataBuf(10);
1506 dataBuf.WriteUInt8(0, 123);
1507 EXPECT_EQ(dataBuf.ReadUInt8(0), 123);
1508 }
1509
1510 HWTEST_F(MetadataStreamTest, BufferMetadataStream_CopyFrom001, TestSize.Level3)
1511 {
1512 FileMetadataStream src(filePathSource);
1513 BufferMetadataStream dest;
1514 src.Open();
1515 dest.Open();
1516 ASSERT_TRUE(dest.CopyFrom(src));
1517 ASSERT_EQ(src.GetSize(), dest.GetSize());
1518 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), src.GetSize()), 0);
1519 }
1520
1521 HWTEST_F(MetadataStreamTest, BufferMetadataStream_CopyFrom002, TestSize.Level3)
1522 {
1523 BufferMetadataStream src;
1524 BufferMetadataStream dest;
1525 src.Open();
1526 dest.Open();
1527 src.Write((byte *)"Hello, world!", 13);
1528 ASSERT_TRUE(dest.CopyFrom(src));
1529 ASSERT_EQ(src.GetSize(), dest.GetSize());
1530 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), src.GetSize()), 0);
1531 }
1532
1533 HWTEST_F(MetadataStreamTest, BufferMetadataStream_CopyFrom003, TestSize.Level3)
1534 {
1535 BufferMetadataStream src;
1536 BufferMetadataStream dest;
1537 src.Open();
1538 dest.Open();
1539 char buff[METADATA_STREAM_PAGE_SIZE + 1] = {0};
1540 src.Write((byte *)buff, METADATA_STREAM_PAGE_SIZE + 1);
1541 ASSERT_TRUE(dest.CopyFrom(src));
1542 ASSERT_EQ(src.GetSize(), dest.GetSize());
1543 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), src.GetSize()), 0);
1544 }
1545
1546 HWTEST_F(MetadataStreamTest, BufferMetadataStream_CopyFrom004, TestSize.Level3)
1547 {
1548 BufferMetadataStream src;
1549 BufferMetadataStream dest;
1550 src.Open();
1551 dest.Open();
1552 char buff[METADATA_STREAM_PAGE_SIZE - 1] = {0};
1553 src.Write((byte *)buff, METADATA_STREAM_PAGE_SIZE - 1);
1554 ASSERT_TRUE(dest.CopyFrom(src));
1555 ASSERT_EQ(src.GetSize(), dest.GetSize());
1556 ASSERT_EQ(memcmp(src.GetAddr(), dest.GetAddr(), src.GetSize()), 0);
1557 }
1558
1559 HWTEST_F(MetadataStreamTest, BufferMetadataStream_CopyFrom005, TestSize.Level3)
1560 {
1561 BufferMetadataStream temp;
1562 temp.Open();
1563 temp.Write((uint8_t*)"Hello, world", 13);
1564 BufferMetadataStream src(temp.GetAddr(), temp.GetSize(), BufferMetadataStream::Dynamic);
1565 FileMetadataStream dest(filePathSource);
1566 src.Open();
1567 dest.Open();
1568 src.CopyFrom(dest);
1569 }
1570
1571 } // namespace Media
1572 } // namespace OHOS