diff --git a/src/common/util/include/openvino/util/file_util.hpp b/src/common/util/include/openvino/util/file_util.hpp index 506197cd98649a..6eee9c3da0c102 100644 --- a/src/common/util/include/openvino/util/file_util.hpp +++ b/src/common/util/include/openvino/util/file_util.hpp @@ -346,8 +346,25 @@ inline std::basic_string make_path(const std::basic_string& folder, const return folder + ov::util::FileTraits::file_separator + file; } -inline ov::util::Path make_path(const wchar_t* file) { - return {std::wstring(file)}; +/** + * @brief Creates std::filesystem::path provided by source. + * + * The purpose of this function is to hide platform specific issue with path creation like on Windows create from + * literal std::string with unicode characters can lead to different path name than expected. + * + * @param source Source to create path. Supported types are same as for std::filesystem::path constructor. + * @return std::filesystem::path object. + */ +template +std::filesystem::path make_path(const Source& source) { + if constexpr (std::is_same_v, wchar_t*>) { + return {std::wstring(source)}; + } else if constexpr (std::is_same_v && + std::is_same_v) { + return {ov::util::string_to_wstring(source)}; + } else { + return {source}; + } } } // namespace util diff --git a/src/inference/src/dev/core_impl.cpp b/src/inference/src/dev/core_impl.cpp index 56e918714f7610..86843b71c79fcc 100644 --- a/src/inference/src/dev/core_impl.cpp +++ b/src/inference/src/dev/core_impl.cpp @@ -1781,14 +1781,7 @@ ov::CoreConfig::CacheConfig ov::CoreConfig::get_cache_config_for_device(const ov ov::CoreConfig::CacheConfig ov::CoreConfig::CacheConfig::create(const std::string& dir) { CacheConfig cache_config{dir, nullptr}; if (!dir.empty()) { - if constexpr (std::is_same_v) { - // if path native type is same as wstring type (e.g. Windows) convert to wstring - // in case of string has unicode without conversion wrong created dir may have incorrect name - // should be removed if cache_dir will path instead of string - ov::util::create_directory_recursive(ov::util::string_to_wstring(dir)); - } else { - ov::util::create_directory_recursive(dir); - } + ov::util::create_directory_recursive(ov::util::make_path(dir)); cache_config._cacheManager = std::make_shared(dir); } return cache_config; diff --git a/src/tests/test_utils/common_test_utils/include/common_test_utils/file_utils.hpp b/src/tests/test_utils/common_test_utils/include/common_test_utils/file_utils.hpp index 817e91f94bc355..49e577adb2dca8 100644 --- a/src/tests/test_utils/common_test_utils/include/common_test_utils/file_utils.hpp +++ b/src/tests/test_utils/common_test_utils/include/common_test_utils/file_utils.hpp @@ -6,9 +6,11 @@ #include +#include #include #include #include +#include #include #include "common_test_utils/common_utils.hpp" @@ -259,6 +261,10 @@ class MockPlugin : public ov::IPlugin { int32_t num_streams{0}; }; +using StringPathVariant = std::variant; + +std::filesystem::path to_fs_path(const StringPathVariant& param); + } // namespace utils } // namespace test } // namespace ov diff --git a/src/tests/test_utils/common_test_utils/src/file_utils.cpp b/src/tests/test_utils/common_test_utils/src/file_utils.cpp index edf6ecb8a241a5..4e3ef07f44af8c 100644 --- a/src/tests/test_utils/common_test_utils/src/file_utils.cpp +++ b/src/tests/test_utils/common_test_utils/src/file_utils.cpp @@ -21,6 +21,7 @@ # include #endif +#include "openvino/util/variant_visitor.hpp" namespace ov { namespace test { namespace utils { @@ -231,6 +232,24 @@ std::string getRelativePath(const std::string& from, const std::string& to) { return output; } +std::filesystem::path to_fs_path(const StringPathVariant& param) { + return std::visit(ov::util::VariantVisitor{ +#if defined(OPENVINO_ENABLE_UNICODE_PATH_SUPPORT) && defined(_WIN32) + [](const std::string& p) { + if (std::any_of(p.begin(), p.end(), [](unsigned char c) { + return c > 127; + })) { + return std::filesystem::path(ov::util::string_to_wstring(p)); + } else { + return std::filesystem::path(p); + } + }, +#endif + [](const auto& p) { + return std::filesystem::path(p); + }}, + param); +} } // namespace utils } // namespace test } // namespace ov diff --git a/src/tests/test_utils/common_test_utils/tests/file_util_test.cpp b/src/tests/test_utils/common_test_utils/tests/file_util_test.cpp index 545c988101ab73..1119318f06027b 100644 --- a/src/tests/test_utils/common_test_utils/tests/file_util_test.cpp +++ b/src/tests/test_utils/common_test_utils/tests/file_util_test.cpp @@ -2,18 +2,20 @@ // SPDX-License-Identifier: Apache-2.0 // -#include "openvino/util/file_util.hpp" - #include #include #include #include #include +#include #include +#include "common_test_utils/common_utils.hpp" +#include "common_test_utils/file_utils.hpp" #include "openvino/core/visibility.hpp" #include "openvino/util/file_path.hpp" +#include "openvino/util/file_util.hpp" namespace ov::test { using std::string; @@ -633,4 +635,54 @@ TEST_F(FileUtilTest, androidWithCutFileSizeTest) { EXPECT_EQ(ov::util::file_size(ov::util::Path("android_test_file_20.txt!_to_cut.jar")), 20); } #endif + +class FileUtilTestP : public FileUtilTest, public ::testing::WithParamInterface { +protected: + std::filesystem::path get_path_param() const { + return std::visit( + [](const auto& p) { + // Use OV util to hide some platform details with path creation + return ov::util::make_path(p); + }, + GetParam()); + } +}; + +INSTANTIATE_TEST_SUITE_P(string_paths, + FileUtilTestP, + testing::Values("test_encoder/test_encoder.encrypted/", + "test_encoder/test_encoder.encrypted")); +INSTANTIATE_TEST_SUITE_P(u16_paths, + FileUtilTestP, + testing::Values(u"test_encoder/dot.folder", u"test_encoder/dot.folder/")); + +INSTANTIATE_TEST_SUITE_P(u32_paths, + FileUtilTestP, + testing::Values(U"test_encoder/dot.folder", U"test_encoder/dot.folder/")); + +INSTANTIATE_TEST_SUITE_P(wstring_paths, + FileUtilTestP, + testing::Values(L"test_encoder/test_encoder.encrypted", + L"test_encoder/test_encoder.encrypted/")); + +#ifdef OPENVINO_ENABLE_UNICODE_PATH_SUPPORT +INSTANTIATE_TEST_SUITE_P( + unicode_paths, + FileUtilTestP, + testing::Values("这是.folder", L"这是_folder", L"这是_folder/", u"这是_folder/", U"这是_folder/")); +#endif + +TEST_P(FileUtilTestP, create_directories) { + const auto test_dir = utils::generateTestFilePrefix(); + const auto path = std::filesystem::path(test_dir) / get_path_param(); + const auto exp_path = std::filesystem::path(test_dir) / utils::to_fs_path(GetParam()); + + ov::util::create_directory_recursive(path); + + EXPECT_EQ(path, exp_path); + ASSERT_TRUE(std::filesystem::exists(path)); + ASSERT_TRUE(std::filesystem::exists(exp_path)); + + std::filesystem::remove_all(test_dir); +} } // namespace ov::test