From 03300444dfed98f9541cfd2594f67df6bf00f832 Mon Sep 17 00:00:00 2001 From: peilixia Date: Tue, 30 May 2023 20:39:22 +0800 Subject: [PATCH] Provides Rust interfaces based on C++ interop File and Directory. 1. Added file_ex and directory_ex modules and their examples for the Rust side c_utils. 2. Removed redundant testcases. Issue:I7BW8O Test:unittest Signed-off-by: peilixia --- base/BUILD.gn | 3 + base/include/directory_ex.h | 17 +- base/include/file_ex.h | 14 + base/src/directory_ex.cpp | 69 +- base/src/file_ex.cpp | 74 +++ base/src/rust/directory_ex.rs | 97 +++ base/src/rust/file_ex.rs | 26 + base/src/rust/lib.rs | 5 +- base/test/unittest/common/utils_file_test.cpp | 51 +- base/test/unittest/rust/BUILD.gn | 24 +- .../rust/utils_rust_directory_test.rs | 274 ++++++++ .../unittest/rust/utils_rust_file_test.rs | 603 ++++++++++++++++++ 12 files changed, 1205 insertions(+), 52 deletions(-) create mode 100644 base/src/rust/directory_ex.rs create mode 100644 base/test/unittest/rust/utils_rust_directory_test.rs create mode 100644 base/test/unittest/rust/utils_rust_file_test.rs diff --git a/base/BUILD.gn b/base/BUILD.gn index 89f1fd7..e4ae351 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn @@ -181,6 +181,7 @@ ohos_shared_library("utils") { rust_cxx("cxx_rust_gen") { sources = [ "src/rust/ashmem.rs", + "src/rust/directory_ex.rs", "src/rust/file_ex.rs", ] } @@ -188,6 +189,7 @@ rust_cxx("cxx_rust_gen") { ohos_static_library("utils_static_cxx_rust") { sources = [ "src/ashmem.cpp", + "src/directory_ex.cpp", "src/file_ex.cpp", "src/refbase.cpp", ] @@ -211,6 +213,7 @@ ohos_static_library("utils_static_cxx_rust") { ohos_rust_shared_library("utils_rust") { sources = [ "src/rust/ashmem.rs", + "src/rust/directory_ex.rs", "src/rust/file_ex.rs", "src/rust/lib.rs", ] diff --git a/base/include/directory_ex.h b/base/include/directory_ex.h index dc3e410..a7c685c 100644 --- a/base/include/directory_ex.h +++ b/base/include/directory_ex.h @@ -19,9 +19,24 @@ #include #include #include +#ifdef UTILS_CXX_RUST +#include "cxx.h" +#endif namespace OHOS { +#ifdef UTILS_CXX_RUST +rust::String RustGetCurrentProcFullFileName(); +rust::String RustGetCurrentProcPath(); +rust::String RustExtractFilePath(const rust::String& fileFullName); +rust::String RustExtractFileName(const rust::String& fileFullName); +rust::String RustExtractFileExt(const rust::String& fileName); +rust::String RustExcludeTrailingPathDelimiter(const rust::String& path); +rust::String RustIncludeTrailingPathDelimiter(const rust::String& path); +bool RustPathToRealPath(const rust::String& path, rust::String& realPath); +void RustGetDirFiles(const rust::String& path, rust::vec& files); +#endif + /** * @brief Get the full absolute path to the current program. * @@ -149,4 +164,4 @@ bool PathToRealPath(const std::string& path, std::string& realPath); std::string TransformFileName(const std::string& fileName); #endif } // OHOS -#endif +#endif \ No newline at end of file diff --git a/base/include/file_ex.h b/base/include/file_ex.h index e1d1f3d..9d672c9 100644 --- a/base/include/file_ex.h +++ b/base/include/file_ex.h @@ -31,8 +31,22 @@ #include #include +#ifdef UTILS_CXX_RUST +#include "cxx.h" +#endif namespace OHOS { +#ifdef UTILS_CXX_RUST +bool RustLoadStringFromFile(const rust::String& filePath, rust::String& content); +bool RustLoadStringFromFd(int fd, rust::String& content); +bool RustLoadBufferFromFile(const rust::String& filePath, rust::vec& content); +bool RustSaveBufferToFile(const rust::String& filePath, const rust::vec& content, bool truncated); +bool RustSaveStringToFile(const rust::String& filePath, const rust::String& content, bool truncated); +bool RustSaveStringToFd(int fd, const rust::String& content); +bool RustFileExists(const rust::String& fileName); +bool RustStringExistsInFile(const rust::String& fileName, const rust::String& subStr, bool caseSensitive); +int RustCountStrInFile(const rust::String& fileName, const rust::String& subStr, bool caseSensitive); +#endif /** * @ingroup FileReadWrite * @brief Read contents as a string from the specified file. diff --git a/base/src/directory_ex.cpp b/base/src/directory_ex.cpp index 82c4c12..dd8e6f7 100644 --- a/base/src/directory_ex.cpp +++ b/base/src/directory_ex.cpp @@ -23,6 +23,69 @@ using namespace std; namespace OHOS { +#ifdef UTILS_CXX_RUST +rust::String RustGetCurrentProcFullFileName() +{ + return rust::String(GetCurrentProcFullFileName()); +} + +rust::String RustGetCurrentProcPath() +{ + return rust::String(GetCurrentProcPath()); +} + +rust::String RustExtractFilePath(const rust::String& fileFullName) +{ + std::string tmpName = std::string(fileFullName); + return rust::String(ExtractFilePath(tmpName)); +} + +rust::String RustExtractFileName(const rust::String& fileFullName) +{ + std::string tmpName = std::string(fileFullName); + return rust::String(ExtractFileName(tmpName)); +} + +rust::String RustExtractFileExt(const rust::String& fileName) +{ + std::string tmpName = std::string(fileName); + return rust::String(ExtractFileExt(tmpName)); +} + +rust::String RustExcludeTrailingPathDelimiter(const rust::String& path) +{ + std::string tmpPath = std::string(path); + return rust::String(ExcludeTrailingPathDelimiter(tmpPath)); +} + +rust::String RustIncludeTrailingPathDelimiter(const rust::String& path) +{ + std::string tmpPath = std::string(path); + return rust::String(IncludeTrailingPathDelimiter(tmpPath)); +} + +bool RustPathToRealPath(const rust::String& path, rust::String& realPath) +{ + std::string tmpPath = std::string(path); + std::string tmpResolved; + + if (PathToRealPath(tmpPath, tmpResolved)) { + realPath = tmpResolved; + return true; + } + + return false; +} + +void RustGetDirFiles(const rust::String& path, rust::vec& files) +{ + std::string tmpPath(path); + std::vector tmpFiles(files.begin(), files.end()); + GetDirFiles(tmpPath, tmpFiles); + std::copy(tmpFiles.begin(), tmpFiles.end(), std::back_inserter(files)); +} +#endif + string GetCurrentProcFullFileName() { char procFile[PATH_MAX + 1] = {0}; @@ -96,7 +159,7 @@ void GetDirFiles(const string& path, vector& files) break; } - // current dir OR parent dir + // current dir or parent dir if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) { continue; } else if (ptr->d_type == DT_DIR) { @@ -146,7 +209,7 @@ bool ForceRemoveDirectory(const string& path) break; } - // current dir OR parent dir + // current dir or parent dir if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) { continue; } @@ -235,7 +298,7 @@ bool ChangeModeDirectory(const string& path, const mode_t& mode) break; } - // current dir OR parent dir + // current dir or parent dir if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) { continue; } diff --git a/base/src/file_ex.cpp b/base/src/file_ex.cpp index 578b1be..5ad682c 100644 --- a/base/src/file_ex.cpp +++ b/base/src/file_ex.cpp @@ -32,6 +32,80 @@ using namespace std; const int MAX_FILE_LENGTH = 32 * 1024 * 1024; namespace OHOS { +#ifdef UTILS_CXX_RUST +bool RustLoadStringFromFile(const rust::String& filePath, rust::String& content) +{ + std::string tmpPath(filePath); + std::string tmpcontent(content); + if (LoadStringFromFile(tmpPath,tmpcontent)) { + content = tmpcontent; + return true; + } + return false; +} + +bool RustLoadStringFromFd(int fd, rust::String& content) +{ + std::string tmpcontent(content); + if (LoadStringFromFd(fd, tmpcontent)) { + content = tmpcontent; + return true; + } + return false; +} + +bool RustLoadBufferFromFile(const rust::String& filePath, rust::vec& content) +{ + std::string tmpPath(filePath); + std::vector tmpcontent(content.begin(), content.end()); + if(LoadBufferFromFile(tmpPath, tmpcontent)) { + std::copy(tmpcontent.begin(), tmpcontent.end(), std::back_inserter(content)); + return true; + } + return false; +} + +bool RustSaveBufferToFile(const rust::String& filePath, const rust::vec& content, bool truncated) +{ + std::string tmpPath(filePath); + std::vector tmpcontent(content.begin(), content.end()); + return SaveBufferToFile(tmpPath, tmpcontent, truncated); +} + +bool RustSaveStringToFile(const rust::String& filePath, const rust::String& content, bool truncated) +{ + std::string tmpPath(filePath); + std::string tmpcontent(content); + return SaveStringToFile(tmpPath, tmpcontent, truncated); +} + +bool RustSaveStringToFd(int fd, const rust::String& content) +{ + std::string tmpcontent(content); + return SaveStringToFd(fd, tmpcontent); +} + +bool RustFileExists(const rust::String& fileName) +{ + std::string tmpname(fileName); + return FileExists(tmpname); +} + +bool RustStringExistsInFile(const rust::String& fileName, const rust::String& subStr, bool caseSensitive) +{ + std::string tmpname(fileName); + std::string tmpstr(subStr); + return StringExistsInFile(tmpname, tmpstr, caseSensitive); +} + +int RustCountStrInFile(const rust::String& fileName, const rust::String& subStr, bool caseSensitive) +{ + std::string tmpname(fileName); + std::string tmpstr(subStr); + return CountStrInFile(tmpname, tmpstr, caseSensitive); +} + +#endif bool LoadStringFromFile(const string& filePath, string& content) { diff --git a/base/src/rust/directory_ex.rs b/base/src/rust/directory_ex.rs new file mode 100644 index 0000000..6b1c45f --- /dev/null +++ b/base/src/rust/directory_ex.rs @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*! + * Directory_ex provides an enhanced interface for some file and path related operations. + */ + +/// File permissions for the owner of the file (user) - Read, write, and execute. +pub const S_IRWXU: u32 = 0o700; + +/// File permissions for the group - Read, write, and execute. +pub const S_IRWXG: u32 = 0o070; + +/// File permissions for others (non-owner/non-group members) - Read, write, and execute. +pub const S_IRWXO: u32 = 0o007; + +/// File permission for the owner to read. +pub const S_IRUSR: u32 = 0o400; + +/// File permission for the group to read. +pub const S_IRGRP: u32 = 0o040; + +/// File permission for others (non-owner/non-group members) to read. +pub const S_IROTH: u32 = 0o004; + +/// Maximum length of a file path in characters +pub const PATH_MAX: usize = 4096; + +#[cxx::bridge(namespace = "OHOS")] +/// Module directory_ex::ffi. Includes interfaces which will call c++ counterparts via FFI. +pub mod ffi { + #[allow(dead_code)] + unsafe extern "C++" { + include!("commonlibrary/c_utils/base/include/directory_ex.h"); + /// Get the full absolute path to the current program. + pub fn RustGetCurrentProcFullFileName() -> String; + + /// Get the absolute path of the current program. + pub fn RustGetCurrentProcPath() -> String; + + /// Obtain the path to the corresponding file by the full path. + pub fn RustExtractFilePath(fileFullName: &String) -> String; + + /// Obtain the name to the corresponding file by the full path. + pub fn RustExtractFileName(fileFullName: &String) -> String; + + /// Obtain the filename extension to the corresponding file by the full path. + pub fn RustExtractFileExt(fileName: &String) -> String; + + /// Determine whether the path has ended with '/', and returns the path + /// after removing '/', otherwise returns the path directly. + pub fn RustExcludeTrailingPathDelimiter(path: &String) -> String; + + /// Determine whether the path has ended with "/", and returns the path + /// after adding '/', otherwise returns the path directly. + pub fn RustIncludeTrailingPathDelimiter(path: &String) -> String; + + /// Get names of all files under `path` recursively. + pub fn RustGetDirFiles(path: &String, files: &mut Vec); + + /// Judge if the path is empty. + pub fn IsEmptyFolder(path: &CxxString) -> bool; + + /// If there are problems such as 'Permission Denied', the creation may also fail. + pub fn ForceCreateDirectory(path: &CxxString) -> bool; + + /// Delete the specified dir. + pub fn ForceRemoveDirectory(path: &CxxString) -> bool; + + /// Remove the file specified by fileName. + pub fn RemoveFile(fileName: &CxxString) -> bool; + + /// Get the folder size(bytes). + pub fn GetFolderSize(path: &CxxString) -> u64; + + /// Change the file authority. + pub fn ChangeModeFile(fileName: &CxxString, mode: &u32) -> bool; + + /// Change authority of the directory specified by path and all of its subdirectories. + pub fn ChangeModeDirectory(path: &CxxString, mode: &u32) -> bool; + + /// Get real path from relative path. + pub fn RustPathToRealPath(path: &String, realPath: &mut String) -> bool; + } +} \ No newline at end of file diff --git a/base/src/rust/file_ex.rs b/base/src/rust/file_ex.rs index c468551..8a00459 100644 --- a/base/src/rust/file_ex.rs +++ b/base/src/rust/file_ex.rs @@ -22,5 +22,31 @@ pub mod ffi { #[allow(dead_code)] unsafe extern "C++" { include!("commonlibrary/c_utils/base/include/file_ex.h"); + /// Read contents as a string from the specified file. + pub fn RustLoadStringFromFile(filePath: &String, content: &mut String) -> bool; + + /// Write contents of a string to the specified file. + pub fn RustSaveStringToFile(filePath: &String, content: &String, truncated: bool) -> bool; + + /// Read contents as a string from the file specified by its fd. + pub fn RustLoadStringFromFd(fd: i32, content: &mut String) -> bool; + + /// Write contents of a string to the file specified by its fd. + pub fn RustSaveStringToFd(fd: i32, content: &String) -> bool; + + /// Read contents as a vector from the specified file. + pub fn RustLoadBufferFromFile(filePath: &String, content: &mut Vec) -> bool; + + /// Write contents of a vector to the specified file. + pub fn RustSaveBufferToFile(filePath: &String, content: &Vec, truncated: bool) -> bool; + + /// Check if the specified file exists. + pub fn RustFileExists(fileName: &String) -> bool; + + /// Check if the file contains specified contents in string. + pub fn RustStringExistsInFile(fileName: &String, subStr: &String, caseSensitive: bool) -> bool; + + /// Get amount of the specified string in the file. + pub fn RustCountStrInFile(fileName: &String, subStr: &String, caseSensitive: bool) -> i32; } } diff --git a/base/src/rust/lib.rs b/base/src/rust/lib.rs index c47720a..0a9b3e0 100644 --- a/base/src/rust/lib.rs +++ b/base/src/rust/lib.rs @@ -21,4 +21,7 @@ pub mod ashmem; /// Module File_ex. Provides interfaces to operate on file. /// Includes reading from or writting to files and searching for specified strings. -pub mod file_ex; \ No newline at end of file +pub mod file_ex; + +/// Module Directory_ex. Provides interfaces to operate on directory. +pub mod directory_ex; \ No newline at end of file diff --git a/base/test/unittest/common/utils_file_test.cpp b/base/test/unittest/common/utils_file_test.cpp index 95401b8..21c9c73 100644 --- a/base/test/unittest/common/utils_file_test.cpp +++ b/base/test/unittest/common/utils_file_test.cpp @@ -303,30 +303,9 @@ HWTEST_F(UtilsFileTest, testSaveStringToFile002, TestSize.Level0) /* * @tc.name: testSaveStringToFile003 - * @tc.desc: Test writting a string to a file in truncate mode - */ -HWTEST_F(UtilsFileTest, testSaveStringToFile003, TestSize.Level0) -{ - string path = FILE_PATH; - string content = "Before truncated!"; - CreateTestFile(path, content); - - string newContent = CONTENT_STR; - bool ret = SaveStringToFile(path, newContent, true); - EXPECT_EQ(ret, true); - - string loadResult; - ret = LoadStringFromFile(path, loadResult); - RemoveTestFile(path); - EXPECT_EQ(ret, true); - EXPECT_STREQ(loadResult.c_str(), newContent.c_str()); -} - -/* - * @tc.name: testSaveStringToFile004 * @tc.desc: Test writting an empty string to a file in truncate mode */ -HWTEST_F(UtilsFileTest, testSaveStringToFile004, TestSize.Level0) +HWTEST_F(UtilsFileTest, testSaveStringToFile003, TestSize.Level0) { string path = FILE_PATH; string content = "Before truncated!"; @@ -344,10 +323,10 @@ HWTEST_F(UtilsFileTest, testSaveStringToFile004, TestSize.Level0) } /* - * @tc.name: testSaveStringToFile005 + * @tc.name: testSaveStringToFile004 * @tc.desc: Test writting an empty string to a file in append mode */ -HWTEST_F(UtilsFileTest, testSaveStringToFile005, TestSize.Level0) +HWTEST_F(UtilsFileTest, testSaveStringToFile004, TestSize.Level0) { string newContent; string path = FILE_PATH; @@ -364,10 +343,10 @@ HWTEST_F(UtilsFileTest, testSaveStringToFile005, TestSize.Level0) } /* - * @tc.name: testSaveStringToFile006 + * @tc.name: testSaveStringToFile005 * @tc.desc: Test writting a string to a file in append mode */ -HWTEST_F(UtilsFileTest, testSaveStringToFile006, TestSize.Level0) +HWTEST_F(UtilsFileTest, testSaveStringToFile005, TestSize.Level0) { string path = FILE_PATH; string content = "Before appended!"; @@ -579,26 +558,6 @@ HWTEST_F(UtilsFileTest, testSaveBufferToFile002, TestSize.Level0) * @tc.desc: singleton template */ HWTEST_F(UtilsFileTest, testSaveBufferToFile003, TestSize.Level0) -{ - vector buff; - string path = FILE_PATH; - string content = "ttxx"; - CreateTestFile(path, content); - bool ret = SaveBufferToFile(path, buff, false); - EXPECT_EQ(ret, true); - - string loadResult; - ret = LoadStringFromFile(path, loadResult); - RemoveTestFile(path); - EXPECT_EQ(ret, true); - EXPECT_EQ(loadResult, content); -} - -/* - * @tc.name: testSaveBufferToFile004 - * @tc.desc: singleton template - */ -HWTEST_F(UtilsFileTest, testSaveBufferToFile004, TestSize.Level0) { string path = FILE_PATH; string content = "ttxx"; diff --git a/base/test/unittest/rust/BUILD.gn b/base/test/unittest/rust/BUILD.gn index a44d0db..723fa08 100644 --- a/base/test/unittest/rust/BUILD.gn +++ b/base/test/unittest/rust/BUILD.gn @@ -24,7 +24,11 @@ group("unittest") { testonly = true deps = [] - deps += [ ":utils_rust_ashmem_test" ] + deps += [ + ":utils_rust_ashmem_test", + ":utils_rust_directory_test", + ":utils_rust_file_test", + ] } ohos_rust_unittest("utils_rust_ashmem_test") { @@ -33,3 +37,21 @@ ohos_rust_unittest("utils_rust_ashmem_test") { configs = [ ":module_private_config" ] deps = [ "../../../../base:utils_rust" ] } + +ohos_rust_unittest("utils_rust_file_test") { + module_out_path = "utils/base/rust" + sources = [ "utils_rust_file_test.rs" ] + deps = [ + "//commonlibrary/c_utils/base:utils_rust", + "//third_party/rust/crates/cxx:lib", + ] +} + +ohos_rust_unittest("utils_rust_directory_test") { + module_out_path = "utils/base/rust" + sources = [ "utils_rust_directory_test.rs" ] + deps = [ + "//commonlibrary/c_utils/base:utils_rust", + "//third_party/rust/crates/cxx:lib", + ] +} diff --git a/base/test/unittest/rust/utils_rust_directory_test.rs b/base/test/unittest/rust/utils_rust_directory_test.rs new file mode 100644 index 0000000..0fea0e0 --- /dev/null +++ b/base/test/unittest/rust/utils_rust_directory_test.rs @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use utils_rust::directory_ex; +use cxx::let_cxx_string; +use std::fs; +use std::fs::File; + +// This code is converted from 22 functions of the utils_directory_test.cpp. + +#[test] +fn test_get_current_proc_full_file_name_001() +{ + let str_base_name = "/data/test/utils_rust_directory_test"; + let str_filename = directory_ex::ffi::RustGetCurrentProcFullFileName(); + assert_eq!(str_base_name, str_filename); +} + +#[test] +fn test_get_current_proc_path_001() +{ + let str_path_name = "/data/test/"; + let str_cur_path_name = directory_ex::ffi::RustGetCurrentProcPath(); + assert_eq!(str_path_name, str_cur_path_name); +} + +#[test] +fn test_extract_file_path_001() +{ + let str_file_path = "/data/test/"; + let str_path = directory_ex::ffi::RustExtractFilePath(&directory_ex::ffi::RustGetCurrentProcFullFileName()); + assert_eq!(str_file_path, str_path); +} + +#[test] +fn test_extract_file_name_001() +{ + let str_base_name = "utils_rust_directory_test"; + let str_name = directory_ex::ffi::RustExtractFileName(&directory_ex::ffi::RustGetCurrentProcFullFileName()); + assert_eq!(str_base_name, str_name); +} + +#[test] +fn test_extract_file_ext_001() +{ + let str_base_name = "test/test.txt"; + let str_type_name = directory_ex::ffi::RustExtractFileExt(&str_base_name.to_string()); + assert_eq!(str_type_name, "txt"); +} + +#[test] +fn test_extract_file_ext_002() +{ + let str_base_name = "test/test_txt"; + let str_type_name = directory_ex::ffi::RustExtractFileExt(&str_base_name.to_string()); + assert_eq!(str_type_name, ""); +} + +#[test] +fn test_exclude_trailing_path_delimiter_001() +{ + let str_result = "data/test/UtilsDirectoryTest"; + let str_name = directory_ex::ffi::RustExcludeTrailingPathDelimiter(&str_result.to_string()); + assert_eq!(str_result, str_name); +} + +#[test] +fn test_include_trailing_path_delimiter_001() +{ + let str_result = "data/test/UtilsDirectoryTest/"; + let str_name = directory_ex::ffi::RustIncludeTrailingPathDelimiter(&str_result.to_string()); + assert_eq!(str_result, str_name); +} + +#[test] +fn test_get_dir_files_001() +{ + let resultfile = ["/data/test/TestFile.txt", "/data/test/UtilsDirectoryTest"]; + File::create(resultfile[0]).expect("Failed to create file"); + File::create(resultfile[1]).expect("Failed to create file"); + + let path = String::from("/data/"); + let mut files: Vec = Vec::new(); + directory_ex::ffi::RustGetDirFiles(&path, &mut files); + + let mut found = false; + for element in files.iter() { + if element == resultfile[0] { + found = true; + break; + } + } + assert!(found); + + found = false; + for element in files.iter() { + if element == resultfile[1] { + found = true; + break; + } + } + assert!(found); + + let_cxx_string!(file1 = "/data/test/TestFile.txt"); + let_cxx_string!(file2 = "/data/test/UtilsDirectoryTest"); + directory_ex::ffi::RemoveFile(&file1); + directory_ex::ffi::RemoveFile(&file2); +} + +#[test] +fn test_force_create_directory_001() +{ + let_cxx_string!(dirpath = "/data/test_dir/test2/test3"); + let mut ret = directory_ex::ffi::ForceCreateDirectory(&dirpath); + assert!(ret); + ret = directory_ex::ffi::IsEmptyFolder(&dirpath); + assert!(ret); +} + +#[test] +fn test_force_remove_directory_001() +{ + let_cxx_string!(dirpath = "/data/test_dir/test2/test4"); + directory_ex::ffi::ForceCreateDirectory(&dirpath); + let ret = directory_ex::ffi::ForceRemoveDirectory(&dirpath); + assert!(ret); +} + +#[test] +fn test_force_remove_directory_002() +{ + let_cxx_string!(dirpath = "/data/test/utils_directory_tmp/"); + let ret = directory_ex::ffi::ForceRemoveDirectory(&dirpath); + assert!(!ret); +} + +#[test] +fn test_remove_file_001() +{ + let_cxx_string!(dirpath = "/data/test_dir"); + let mut ret = directory_ex::ffi::ForceCreateDirectory(&dirpath); + assert!(ret); + match File::create("/data/test_dir/test.txt") { + Ok(_file) => { + let_cxx_string!(filename = "/data/test_dir/test.txt"); + ret = directory_ex::ffi::RemoveFile(&filename); + assert!(ret); + }, + Err(error) => { + println!("create file error: {}", error); + } + } + ret = directory_ex::ffi::ForceRemoveDirectory(&dirpath); + assert!(ret); +} + +#[test] +fn test_get_folder_size_001() +{ + let_cxx_string!(dirpath = "/data/test_folder/"); + let mut ret = directory_ex::ffi::ForceCreateDirectory(&dirpath); + assert!(ret); + fs::write("/data/test_folder/test.txt", "This is a line.\nThis is another line.\n").unwrap(); + let resultsize = directory_ex::ffi::GetFolderSize(&dirpath); + let resultcomp = 38; + assert_eq!(resultsize, resultcomp); + + let mut mode = directory_ex::S_IRWXU | directory_ex::S_IRWXG | directory_ex::S_IRWXO; + let_cxx_string!(txt = "/data/test_folder/test.txt"); + ret = directory_ex::ffi::ChangeModeFile(&txt, &mode); + assert!(ret); + + mode = directory_ex::S_IRUSR | directory_ex::S_IRGRP | directory_ex::S_IROTH; + ret = directory_ex::ffi::ChangeModeDirectory(&dirpath, &mode); + assert!(ret); + + ret = directory_ex::ffi::ForceRemoveDirectory(&dirpath); + assert!(ret); +} + +#[test] +fn test_change_mode_file_001() +{ + let_cxx_string!(dirpath = "/data/test/utils_directory_tmp/test.txt"); + let mode = directory_ex::S_IRWXU | directory_ex::S_IRWXG | directory_ex::S_IRWXO; + let ret = directory_ex::ffi::ChangeModeFile(&dirpath, &mode); + assert!(!ret); +} + +#[test] +fn test_change_mode_directory_001() +{ + let_cxx_string!(dirpath = ""); + let mode = directory_ex::S_IRUSR | directory_ex::S_IRGRP | directory_ex::S_IROTH; + let ret = directory_ex::ffi::ChangeModeDirectory(&dirpath, &mode); + assert!(!ret); + + let resultsize = directory_ex::ffi::GetFolderSize(&dirpath); + let resultcomp = 0; + assert_eq!(resultsize, resultcomp); +} + +#[test] +fn test_path_to_real_path_001() +{ + let path = "/data/test".to_string(); + let mut realpath = String::new(); + let ret = directory_ex::ffi::RustPathToRealPath(&path, &mut realpath); + assert!(ret); + assert_eq!(path, realpath); +} + +#[test] +fn test_path_to_real_path_002() +{ + let path = "/data/../data/test".to_string(); + let mut realpath = String::new(); + let ret = directory_ex::ffi::RustPathToRealPath(&path, &mut realpath); + assert!(ret); + assert_eq!("/data/test", realpath); +} + +#[test] +fn test_path_to_real_path_003() +{ + let path = "./".to_string(); + let mut realpath = String::new(); + let ret = directory_ex::ffi::RustPathToRealPath(&path, &mut realpath); + assert!(ret); + assert_eq!("/data/test", realpath); +} + +#[test] +fn test_path_to_real_path_004() +{ + let path = String::new(); + let mut realpath = String::new(); + let ret = directory_ex::ffi::RustPathToRealPath(&path, &mut realpath); + assert!(!ret); +} + +#[test] +fn test_path_to_real_path_005() +{ + let path = "/data/test/data/test/data/test/data/test/data/test/data/ \ + test/data/test/data/test/data/test/data/test/data/test/data/test/data/ \ + test/data/test/data/test/data/test/data/test/data/test/data/test/data/ \ + test/data/test/data/test/data/test/data/test/data/test/data/test/data/ \ + test/data/test/data/test/data/test".to_string(); + let mut realpath = String::new(); + let ret = directory_ex::ffi::RustPathToRealPath(&path, &mut realpath); + assert!(!ret); +} + +#[test] +fn test_path_to_real_path_006() +{ + let path: String = "x".repeat(directory_ex::PATH_MAX); + let mut realpath = String::new(); + let ret = directory_ex::ffi::RustPathToRealPath(&path, &mut realpath); + assert!(!ret); +} \ No newline at end of file diff --git a/base/test/unittest/rust/utils_rust_file_test.rs b/base/test/unittest/rust/utils_rust_file_test.rs new file mode 100644 index 0000000..b314f1b --- /dev/null +++ b/base/test/unittest/rust/utils_rust_file_test.rs @@ -0,0 +1,603 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#![feature(file_create_new)] +use utils_rust::file_ex; +use std::fs::File; +use std::io::prelude::*; +use std::fs::remove_file; +use std::os::unix::io::{AsRawFd, RawFd}; +use std::ffi::c_char; + +pub const CONTENT_STR: &str = "TTtt@#$%^&*()_+~`"; +pub const FILE_PATH: &str = "./tmp.txt"; +pub const NULL_STR: &str = ""; +pub const MAX_FILE_LENGTH: usize = 32 * 1024 * 1024; + +// This code is converted from 43 functions of the utils_file_test.cpp. + +pub fn create_test_file(path: &String, content: &String) -> bool { + if let Ok(mut file) = File::create(path) { + if let Err(err) = file.write_all(content.as_bytes()) { + println!("Error writing to file: {}", err); + return false; + } + true + } else { + println!("Failed to create file: {}", path); + false + } +} + +pub fn remove_test_file(path: &String) -> Result<(), std::io::Error> { + remove_file(path) +} + +#[test] +fn test_load_string_from_file_001() { + let mut str = String::new(); + let filename = String::from("/proc/meminfo"); + assert!(file_ex::ffi::RustLoadStringFromFile(&filename, &mut str)); + + let mut str2 = String::new(); + let file = File::open(&filename).expect("Failed to open file"); + let fd: RawFd = file.as_raw_fd(); + assert!(file_ex::ffi::RustLoadStringFromFd(fd, &mut str2)); + assert_eq!(str.len(), str2.len()); + + let mut buff: Vec = Vec::new(); + let ret = file_ex::ffi::RustLoadBufferFromFile(&filename, &mut buff); + assert!(ret); + assert_eq!(str2.len(), buff.len()); +} + +#[test] +fn test_load_string_from_file_002() { + let mut str = String::new(); + let filename = NULL_STR.to_string(); + assert!(!file_ex::ffi::RustLoadStringFromFile(&filename, &mut str)); + assert!(str.is_empty()); +} + +#[test] +fn test_load_string_from_file_003() { + let mut str = String::new(); + let filename = FILE_PATH.to_string() + ".003"; + let content = NULL_STR.to_string(); + create_test_file(&filename, &content); + assert!(file_ex::ffi::RustLoadStringFromFile(&filename, &mut str)); + let _err = remove_test_file(&filename); + assert_eq!(str, content); +} + +#[test] +fn test_load_string_from_file_004() { + let mut str = String::new(); + let filename = FILE_PATH.to_string() + ".004"; + let content = CONTENT_STR.to_string(); + create_test_file(&filename, &content); + assert!(file_ex::ffi::RustLoadStringFromFile(&filename, &mut str)); + let _err = remove_test_file(&filename); + assert_eq!(str, content); +} + +#[test] +fn test_load_string_from_file_005() { + let mut str = String::new(); + let filename = FILE_PATH.to_string() + ".005"; + let content: String = "t".repeat(MAX_FILE_LENGTH); + create_test_file(&filename, &content); + assert!(file_ex::ffi::RustLoadStringFromFile(&filename, &mut str)); + let _err = remove_test_file(&filename); + assert_eq!(str, content); +} + +#[test] +fn test_load_string_from_file_006() { + let mut str = String::new(); + let filename = FILE_PATH.to_string() + ".006"; + let content: String = "t".repeat(MAX_FILE_LENGTH + 1); + create_test_file(&filename, &content); + assert!(!file_ex::ffi::RustLoadStringFromFile(&filename, &mut str)); + let _err = remove_test_file(&filename); + assert!(str.is_empty()); +} + +#[test] +fn test_load_string_from_fd_001() { + let mut result = String::new(); + assert!(!file_ex::ffi::RustLoadStringFromFd(-1, &mut result)); + assert_eq!(result, ""); +} + +#[test] +fn test_load_string_from_fd_002() { + let mut result = String::new(); + let filename =FILE_PATH.to_string() + ".008"; + let content = NULL_STR.to_string(); + create_test_file(&filename, &content); + let file = File::open(&filename).expect("Failed to open file"); + let fd: RawFd = file.as_raw_fd(); + assert!(file_ex::ffi::RustLoadStringFromFd(fd, &mut result)); + let _err = remove_test_file(&filename); + assert_eq!(result, content); +} + +#[test] +fn test_load_string_from_fd_003() { + let mut result = String::new(); + let filename = FILE_PATH.to_string() + ".009"; + let content = CONTENT_STR.to_string(); + create_test_file(&filename, &content); + let file = File::open(&filename).expect("Failed to open file"); + let fd: RawFd = file.as_raw_fd(); + assert!(file_ex::ffi::RustLoadStringFromFd(fd, &mut result)); + let _err = remove_test_file(&filename); + assert_eq!(result, content); +} + +#[test] +fn test_load_string_from_fd_004() { + let mut result = String::new(); + let filename = FILE_PATH.to_string() + ".010"; + let content: String = "t".repeat(MAX_FILE_LENGTH); + create_test_file(&filename, &content); + let file = File::open(&filename).expect("Failed to open file"); + let fd: RawFd = file.as_raw_fd(); + assert!(file_ex::ffi::RustLoadStringFromFd(fd, &mut result)); + let _err = remove_test_file(&filename); + assert_eq!(result, content); +} + +#[test] +fn test_load_string_from_fd_005() { + let mut result = String::new(); + let filename = FILE_PATH.to_string() + ".011"; + let content: String = "t".repeat(MAX_FILE_LENGTH + 1); + create_test_file(&filename, &content); + let file = File::open(&filename).expect("Failed to open file"); + let fd: RawFd = file.as_raw_fd(); + assert!(!file_ex::ffi::RustLoadStringFromFd(fd, &mut result)); + let _err = remove_test_file(&filename); + assert_ne!(result, content); +} + +#[test] +fn test_load_string_from_fd_006() { + let mut result = String::new(); + let filename = FILE_PATH.to_string() + ".012"; + let content = CONTENT_STR.to_string(); + create_test_file(&filename, &content); + let fd: i32; + { + let file = File::open(&filename).expect("Failed to open file"); + fd = file.as_raw_fd(); + } + assert!(!file_ex::ffi::RustLoadStringFromFd(fd, &mut result)); + let _err = remove_test_file(&filename); + assert_eq!(result, ""); +} + +#[test] +fn test_save_string_to_file_001() { + let path = FILE_PATH.to_string() + ".013"; + let content = CONTENT_STR.to_string(); + let new_content = NULL_STR.to_string(); + create_test_file(&path, &content); + let ret = file_ex::ffi::RustSaveStringToFile(&path, &new_content, true); + assert!(ret); + + let mut load_result = String::new(); + assert!(file_ex::ffi::RustLoadStringFromFile(&path, &mut load_result)); + let _err = remove_test_file(&path); + assert_eq!(load_result, content); +} + +#[test] +fn test_save_string_to_file_002() { + let path = FILE_PATH.to_string() + ".014"; + let content = "Before truncated!".to_string(); + create_test_file(&path, &content); + + let new_content = CONTENT_STR.to_string(); + assert!(file_ex::ffi::RustSaveStringToFile(&path, &new_content, true)); + + let mut load_result = String::new(); + assert!(file_ex::ffi::RustLoadStringFromFile(&path, &mut load_result)); + let _err = remove_test_file(&path); + assert_eq!(load_result, new_content); +} + +#[test] +fn test_save_string_to_file_003() { + let path = FILE_PATH.to_string() + ".015"; + let content = "Before truncated!".to_string(); + create_test_file(&path, &content); + + let new_content = NULL_STR.to_string(); + assert!(file_ex::ffi::RustSaveStringToFile(&path, &new_content, true)); + + let mut load_result = String::new(); + let ret = file_ex::ffi::RustLoadStringFromFile(&path, &mut load_result); + let _err = remove_test_file(&path); + assert!(ret); + assert_eq!(load_result, content); +} + +#[test] +fn test_save_string_to_file_004() { + let path = FILE_PATH.to_string()+ ".016"; + let new_content = NULL_STR.to_string(); + let content = "Before truncated!".to_string(); + create_test_file(&path, &content); + assert!(file_ex::ffi::RustSaveStringToFile(&path, &new_content, false)); + + let mut load_result = String::new(); + let ret = file_ex::ffi::RustLoadStringFromFile(&path, &mut load_result); + let _err = remove_test_file(&path); + assert!(ret); + assert_eq!(load_result, content); +} + +#[test] +fn test_save_string_to_file_005() { + let path = FILE_PATH.to_string()+ ".017"; + let content = "Before truncated!".to_string(); + create_test_file(&path, &content); + + let new_content = CONTENT_STR.to_string(); + assert!(file_ex::ffi::RustSaveStringToFile(&path, &new_content, false)); + + let mut load_result = String::new(); + let ret = file_ex::ffi::RustLoadStringFromFile(&path, &mut load_result); + let _err = remove_test_file(&path); + assert!(ret); + assert_eq!(load_result, content + &new_content); +} + +#[test] +fn test_save_string_to_fd_001() { + let mut content = String::new(); + let mut ret = file_ex::ffi::RustSaveStringToFd(0, &content); + assert!(!ret); + ret = file_ex::ffi::RustSaveStringToFd(-1, &content); + assert!(!ret); + + content = CONTENT_STR.to_string(); + ret = file_ex::ffi::RustSaveStringToFd(0, &content); + assert!(!ret); + ret = file_ex::ffi::RustSaveStringToFd(-1, &content); + assert!(!ret); +} + +#[test] +fn test_save_string_to_fd_002() { + let content = String::new(); + let filename = FILE_PATH.to_string() + ".019"; + let mut file = File::create_new(&filename).expect("Failed to create file"); + let mut fd: RawFd = file.as_raw_fd(); + let mut ret = file_ex::ffi::RustSaveStringToFd(fd, &content); + assert!(ret); + + let mut load_result = String::new(); + file = File::open(&filename).expect("Failed to open file"); + fd = file.as_raw_fd(); + ret = file_ex::ffi::RustLoadStringFromFd(fd, &mut load_result); + let _err = remove_test_file(&filename); + assert!(ret); + assert_eq!(load_result, ""); +} + +#[test] +fn test_save_string_to_fd_003() { + let content = CONTENT_STR.to_string(); + let filename = FILE_PATH.to_string() + ".020"; + let mut file = File::create_new(&filename).expect("Failed to create file"); + let mut fd: RawFd = file.as_raw_fd(); + let mut ret = file_ex::ffi::RustSaveStringToFd(fd, &content); + assert!(ret); + + let mut load_result = String::new(); + file = File::open(&filename).expect("Failed to open file"); + fd = file.as_raw_fd(); + ret = file_ex::ffi::RustLoadStringFromFd(fd, &mut load_result); + let _err = remove_test_file(&filename); + assert!(ret); + assert_eq!(load_result, content); +} + +#[test] +fn test_save_string_to_fd_004() { + let content = CONTENT_STR.to_string(); + let filename = FILE_PATH.to_string() + ".021"; + File::create(&filename).expect("Failed to create file"); + let mut file = File::open(&filename).expect("Failed to open file"); + let mut fd: RawFd = file.as_raw_fd(); + let mut ret = file_ex::ffi::RustSaveStringToFd(fd, &content); + assert!(!ret); + + let mut load_result = String::new(); + file = File::open(&filename).expect("Failed to open file"); + fd = file.as_raw_fd(); + ret = file_ex::ffi::RustLoadStringFromFd(fd, &mut load_result); + let _err = remove_test_file(&filename); + assert!(ret); + assert_eq!(load_result, ""); +} + +#[test] +fn test_load_buffer_from_file_001() { + let mut buff: Vec = Vec::new(); + let filename = FILE_PATH.to_string() + ".022"; + let ret = file_ex::ffi::RustLoadBufferFromFile(&filename, &mut buff); + assert!(!ret); + assert_eq!(0, buff.len()); +} + +#[test] +fn test_load_buffer_from_file_002() { + let mut buff: Vec = Vec::new(); + let filename = FILE_PATH.to_string() + ".023"; + let content = "".to_string(); + create_test_file(&filename, &content); + let ret = file_ex::ffi::RustLoadBufferFromFile(&filename, &mut buff); + let _err = remove_test_file(&filename); + assert!(ret); + assert_eq!(0, buff.len()); +} + +#[test] +fn test_load_buffer_from_file_003() { + let mut buff: Vec = Vec::new(); + let filename = FILE_PATH.to_string() + ".024"; + let content = "TXB".to_string(); + create_test_file(&filename, &content); + let ret = file_ex::ffi::RustLoadBufferFromFile(&filename, &mut buff); + let _err = remove_test_file(&filename); + assert!(ret); + assert_eq!(3, buff.len()); + assert_eq!('T' as c_char, buff[0]); + assert_eq!('X' as c_char, buff[1]); + assert_eq!('B' as c_char, buff[2]); +} + +#[test] +fn test_load_buffer_from_file_004() { + let mut buff: Vec = Vec::new(); + let filename = FILE_PATH.to_string() + ".025"; + let content = "t".repeat(MAX_FILE_LENGTH + 1); + create_test_file(&filename, &content); + let ret = file_ex::ffi::RustLoadBufferFromFile(&filename, &mut buff); + let _err = remove_test_file(&filename); + assert!(!ret); + assert_eq!(0, buff.len()); +} + +#[test] +fn test_save_buffer_to_file_001() { + let filename = FILE_PATH.to_string() + ".026"; + let content = "ttxx".to_string(); + create_test_file(&filename, &content); + let buff: Vec = Vec::new(); + let ret = file_ex::ffi::RustSaveBufferToFile(&filename, &buff, false); + assert!(ret); + + let mut load_result = String::new(); + let ret = file_ex::ffi::RustLoadStringFromFile(&filename, &mut load_result); + let _err = remove_test_file(&filename); + assert!(ret); + assert_eq!(load_result, content); +} + +#[test] +fn test_save_buffer_to_file_002() { + let filename = FILE_PATH.to_string() + ".027"; + let content = "ttxx".to_string(); + create_test_file(&filename, &content); + + let new_content: Vec = vec!['x' as c_char, 'x' as c_char, 't' as c_char, 't' as c_char]; + let ret = file_ex::ffi::RustSaveBufferToFile(&filename, &new_content, true); + assert!(ret); + + let mut load_result = String::new(); + let ret = file_ex::ffi::RustLoadStringFromFile(&filename, &mut load_result); + let _err = remove_test_file(&filename); + assert!(ret); + assert_eq!(load_result, String::from_utf8_lossy(&new_content)); +} + +#[test] +fn test_save_buffer_to_file_003() { + let filename = FILE_PATH.to_string() + ".028"; + let content = "ttxx".to_string(); + create_test_file(&filename, &content); + + let new_content: Vec = vec!['x' as c_char, 'x' as c_char, 't' as c_char, 't' as c_char]; + let mut ret = file_ex::ffi::RustSaveBufferToFile(&filename, &new_content, false); + assert!(ret); + + let mut load_result = String::new(); + ret = file_ex::ffi::RustLoadStringFromFile(&filename, &mut load_result); + let _err = remove_test_file(&filename); + assert!(ret); + assert_eq!(&load_result, &(content + &String::from_utf8_lossy(&new_content))); +} + +#[test] +fn test_string_exists_in_file_001() { + let str_value = "abc".to_string(); + let filename = String::new(); + assert!(!file_ex::ffi::RustStringExistsInFile(&filename, &str_value, true)); + assert!(!str_value.is_empty()); +} + +#[test] +fn test_string_exists_in_file_002() { + let str_value = NULL_STR.to_string(); + let filename = FILE_PATH.to_string() + ".030"; + let content = "hello world!".to_string(); + create_test_file(&filename, &content); + assert!(!file_ex::ffi::RustStringExistsInFile(&filename, &str_value, true)); + let _err = remove_test_file(&filename); +} + +#[test] +fn test_string_exists_in_file_003() { + let str_value = "world".to_string(); + let filename = FILE_PATH.to_string() + ".031"; + let content = "hello world!".to_string(); + create_test_file(&filename, &content); + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value, true)); + let _err = remove_test_file(&filename); +} + +#[test] +fn test_string_exists_in_file_004() { + let str_value1 = "t".repeat(MAX_FILE_LENGTH + 1); + let str_value2 = "t".repeat(MAX_FILE_LENGTH); + let filename = FILE_PATH.to_string() + ".032"; + let content = "t".repeat(MAX_FILE_LENGTH); + create_test_file(&filename, &content); + assert!(!file_ex::ffi::RustStringExistsInFile(&filename, &str_value1, true)); + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value2, true)); + let _err = remove_test_file(&filename); +} + +#[test] +fn test_string_exists_in_file_005() { + let str_value = "woRld".to_string(); + let filename = FILE_PATH.to_string() + ".033"; + let content = "hello world!".to_string(); + create_test_file(&filename, &content); + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value, false)); + assert!(!file_ex::ffi::RustStringExistsInFile(&filename, &str_value, true)); + let _err = remove_test_file(&filename); +} + +#[test] +fn test_string_exists_in_file_006() { + let str_value1 = "woRld".to_string(); + let str_value2 = "123".to_string(); + let str_value3 = "llo ".to_string(); + let str_value4 = "123 w".to_string(); + let str_value5 = "hi".to_string(); + let filename = FILE_PATH.to_string() + ".034"; + let content = "Test, hello 123 World!".to_string(); + create_test_file(&filename, &content); + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value1, false)); + assert!(!file_ex::ffi::RustStringExistsInFile(&filename, &str_value1, true)); + + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value2, false)); + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value2, true)); + + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value3, false)); + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value3, true)); + + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value4, false)); + assert!(!file_ex::ffi::RustStringExistsInFile(&filename, &str_value4, true)); + + assert!(!file_ex::ffi::RustStringExistsInFile(&filename, &str_value5, false)); + assert!(!file_ex::ffi::RustStringExistsInFile(&filename, &str_value5, true)); + let _err = remove_test_file(&filename); +} + +#[test] +fn test_string_exists_in_file_007() { + let str_value1 = "is".to_string(); + let str_value2 = "\n\ris".to_string(); + let filename = FILE_PATH.to_string() + ".035"; + let content = "Test, special string\n\ris ok".to_string(); + create_test_file(&filename, &content); + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value1, false)); + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value1, true)); + + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value2, false)); + assert!(file_ex::ffi::RustStringExistsInFile(&filename, &str_value2, true)); + let _err = remove_test_file(&filename); +} + +#[test] +fn test_file_exist_001() +{ + let filepath = "/proc/meminfo".to_string(); + let filepath1 = "/proc/meminfo1".to_string(); + + assert!(file_ex::ffi::RustFileExists(&filepath)); + assert!(!(file_ex::ffi::RustFileExists(&filepath1))); +} + +#[test] +fn test_count_str_in_file_001() +{ + let str = "abc".to_string(); + let filename = "".to_string(); + assert_eq!(file_ex::ffi::RustCountStrInFile(&filename, &str, true), -1); + assert!(!str.is_empty()); +} + +#[test] +fn test_count_str_in_file_002() +{ + let str = NULL_STR.to_string(); + let filename = FILE_PATH.to_string() + ".038"; + let content = "hello world!".to_string(); + create_test_file(&filename, &content); + assert_eq!(file_ex::ffi::RustCountStrInFile(&filename, &str, true), -1); + let _err = remove_test_file(&filename); +} + +#[test] +fn test_count_str_in_file_003() +{ + let str1 = "t".repeat(MAX_FILE_LENGTH + 1); + let str2 = "t".repeat(MAX_FILE_LENGTH); + let filename = FILE_PATH.to_string() + ".039"; + let content = "t".repeat(MAX_FILE_LENGTH); + create_test_file(&filename, &content); + assert_eq!(file_ex::ffi::RustCountStrInFile(&filename, &str1, true), 0); + assert_eq!(file_ex::ffi::RustCountStrInFile(&filename, &str2, true), 1); + let _err = remove_test_file(&filename); +} + +#[test] +fn test_count_str_in_file_004() +{ + let str1 = "very".to_string(); + let str2 = "VERY".to_string(); + let str3 = "abc".to_string(); + let filename = FILE_PATH.to_string() + ".040"; + let content = "This is very very long string for test.\n Very Good,\r VERY HAPPY.".to_string(); + create_test_file(&filename, &content); + assert_eq!(file_ex::ffi::RustCountStrInFile(&filename, &str1, true), 2); + assert_eq!(file_ex::ffi::RustCountStrInFile(&filename, &str1, false), 4); + + assert_eq!(file_ex::ffi::RustCountStrInFile(&filename, &str2, true), 1); + assert_eq!(file_ex::ffi::RustCountStrInFile(&filename, &str2, false), 4); + + assert_eq!(file_ex::ffi::RustCountStrInFile(&filename, &str3, true), 0); + let _err = remove_test_file(&filename); +} + +#[test] +fn test_count_str_in_file_005() +{ + let str1 = "aba".to_string(); + let filename = FILE_PATH.to_string() + ".041"; + let content = "This is abababaBABa.".to_string(); + create_test_file(&filename, &content); + assert_eq!(file_ex::ffi::RustCountStrInFile(&filename, &str1, true), 2); + assert_eq!(file_ex::ffi::RustCountStrInFile(&filename, &str1, false), 3); + let _err = remove_test_file(&filename); +} \ No newline at end of file -- Gitee