From 0ad591fa3c2a68e555e80f45a4d6cb52dfdaf8f0 Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Tue, 28 Jun 2022 17:46:39 -0600 Subject: [PATCH] Make tests get files in a consistent order Use the order defined the FolderManager's to define the order readdir uses, rather than leaving it undetermined. This makes tests more consistent by forcing layers and drivers to always be found in the same order on all systems. Note: MacOS doesn't currently have consistent ordering due to a crash with ASAN. But even if ASAN isn't running, the dirent structure is being filled out incorrectly, causing further test failures. While not ideal to disable consistent ordering on MacOS, it is needed for linux and thus the issue isn't high enough priority to resolve. --- tests/framework/shim/shim.h | 26 +++++++++- tests/framework/shim/shim_common.cpp | 11 +++- tests/framework/shim/unix_shim.cpp | 73 +++++++++++++++++++++++++-- tests/framework/shim/windows_shim.cpp | 14 ++--- tests/framework/test_environment.cpp | 60 ++++++++++++---------- tests/framework/test_environment.h | 28 ++++++---- tests/framework/test_util.cpp | 15 +++++- tests/framework/test_util.h | 8 ++- tests/loader_envvar_tests.cpp | 4 +- tests/loader_layer_tests.cpp | 19 +++---- 10 files changed, 191 insertions(+), 67 deletions(-) diff --git a/tests/framework/shim/shim.h b/tests/framework/shim/shim.h index 80e64708..bb0ad9a3 100644 --- a/tests/framework/shim/shim.h +++ b/tests/framework/shim/shim.h @@ -109,10 +109,28 @@ struct D3DKMT_Adapter { D3DKMT_Adapter& add_path(fs::path src, std::vector& dest); }; +#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) + +struct DirEntry { + DIR* directory; + std::string folder_path; + std::vector contents; + size_t current_index; +}; + #endif + +struct FrameworkEnvironment; // forward declaration + // Necessary to have inline definitions as shim is a dll and thus functions // defined in the .cpp wont be found by the rest of the application struct PlatformShim { + PlatformShim() = default; + PlatformShim(std::vector* folders) : folders(folders) {} + + // Used to get info about which drivers & layers have been added to folders + std::vector* folders; + // Test Framework interface void reset(); @@ -170,20 +188,24 @@ struct PlatformShim { void set_elevated_privilege(bool elev) { use_fake_elevation = elev; } bool use_fake_elevation = false; + + std::vector dir_entries; #endif }; std::vector parse_env_var_list(std::string const& var); std::string category_path_name(ManifestCategory category); +std::vector get_folder_contents(std::vector* folders, std::string folder_name) noexcept; + extern "C" { // dynamically link on windows and macos #if defined(WIN32) || defined(__APPLE__) -using PFN_get_platform_shim = PlatformShim* (*)(); +using PFN_get_platform_shim = PlatformShim* (*)(std::vector* folders); #define GET_PLATFORM_SHIM_STR "get_platform_shim" #elif defined(__linux__) || defined(__FreeBSD__) // statically link on linux -PlatformShim* get_platform_shim(); +PlatformShim* get_platform_shim(std::vector* folders); #endif } diff --git a/tests/framework/shim/shim_common.cpp b/tests/framework/shim/shim_common.cpp index 1cf2ec76..721aabef 100644 --- a/tests/framework/shim/shim_common.cpp +++ b/tests/framework/shim/shim_common.cpp @@ -60,6 +60,15 @@ std::vector parse_env_var_list(std::string const& var) { return items; } +std::vector get_folder_contents(std::vector* folders, std::string folder_name) noexcept { + for (auto& folder : *folders) { + if (folder.location() == folder_name) { + return folder.get_files(); + } + } + return {}; +} + #if defined(WIN32) D3DKMT_Adapter& D3DKMT_Adapter::add_driver_manifest_path(fs::path const& src) { return add_path(src, driver_paths); } @@ -200,4 +209,4 @@ void PlatformShim::set_path(ManifestCategory category, fs::path const& path) { redirect_path(fs::path(SYSCONFDIR) / "vulkan" / category_path_name(category), path); } -#endif \ No newline at end of file +#endif diff --git a/tests/framework/shim/unix_shim.cpp b/tests/framework/shim/unix_shim.cpp index cf8453ed..1fdadbcf 100644 --- a/tests/framework/shim/unix_shim.cpp +++ b/tests/framework/shim/unix_shim.cpp @@ -30,20 +30,22 @@ static PlatformShim platform_shim; extern "C" { #if defined(__linux__) || defined(__FreeBSD__) -PlatformShim* get_platform_shim() { - platform_shim = PlatformShim(); +PlatformShim* get_platform_shim(std::vector* folders) { + platform_shim = PlatformShim(folders); return &platform_shim; } #elif defined(__APPLE__) -FRAMEWORK_EXPORT PlatformShim* get_platform_shim() { - platform_shim = PlatformShim(); +FRAMEWORK_EXPORT PlatformShim* get_platform_shim(std::vector* folders) { + platform_shim = PlatformShim(folders); return &platform_shim; } #endif -// Necessary for MacOS function himming +// Necessary for MacOS function shimming #if defined(__linux__) || defined(__FreeBSD__) #define OPENDIR_FUNC_NAME opendir +#define READDIR_FUNC_NAME readdir +#define CLOSEDIR_FUNC_NAME closedir #define ACCESS_FUNC_NAME access #define FOPEN_FUNC_NAME fopen #define GETEUID_FUNC_NAME geteuid @@ -56,6 +58,8 @@ FRAMEWORK_EXPORT PlatformShim* get_platform_shim() { #endif #elif defined(__APPLE__) #define OPENDIR_FUNC_NAME my_opendir +#define READDIR_FUNC_NAME my_readdir +#define CLOSEDIR_FUNC_NAME my_closedir #define ACCESS_FUNC_NAME my_access #define FOPEN_FUNC_NAME my_fopen #define GETEUID_FUNC_NAME my_geteuid @@ -69,6 +73,8 @@ FRAMEWORK_EXPORT PlatformShim* get_platform_shim() { #endif using PFN_OPENDIR = DIR* (*)(const char* path_name); +using PFN_READDIR = struct dirent* (*)(DIR* dir_stream); +using PFN_CLOSEDIR = int (*)(DIR* dir_stream); using PFN_ACCESS = int (*)(const char* pathname, int mode); using PFN_FOPEN = FILE* (*)(const char* filename, const char* mode); using PFN_GETEUID = uid_t (*)(void); @@ -78,6 +84,8 @@ using PFN_SEC_GETENV = char* (*)(const char* name); #endif static PFN_OPENDIR real_opendir = nullptr; +static PFN_READDIR real_readdir = nullptr; +static PFN_CLOSEDIR real_closedir = nullptr; static PFN_ACCESS real_access = nullptr; static PFN_FOPEN real_fopen = nullptr; static PFN_GETEUID real_geteuid = nullptr; @@ -96,6 +104,7 @@ FRAMEWORK_EXPORT DIR* OPENDIR_FUNC_NAME(const char* path_name) { if (platform_shim.is_fake_path(path_name)) { auto fake_path_name = platform_shim.get_fake_path(fs::path(path_name)); dir = real_opendir(fake_path_name.c_str()); + platform_shim.dir_entries.push_back(DirEntry{dir, std::string(path_name), {}, false}); } else { dir = real_opendir(path_name); } @@ -103,6 +112,57 @@ FRAMEWORK_EXPORT DIR* OPENDIR_FUNC_NAME(const char* path_name) { return dir; } +FRAMEWORK_EXPORT struct dirent* READDIR_FUNC_NAME(DIR* dir_stream) { + if (!real_readdir) real_readdir = (PFN_READDIR)dlsym(RTLD_NEXT, "readdir"); + auto it = std::find_if(platform_shim.dir_entries.begin(), platform_shim.dir_entries.end(), + [dir_stream](DirEntry const& entry) { return entry.directory == dir_stream; }); + + if (it == platform_shim.dir_entries.end()) { + return real_readdir(dir_stream); + } + // Folder was found but this is the first file to be read from it + if (it->current_index == 0) { + std::vector folder_contents; + std::vector dirent_filenames; + while (true) { + struct dirent* dir_entry = real_readdir(dir_stream); + if (NULL == dir_entry) { + break; + } + folder_contents.push_back(dir_entry); + dirent_filenames.push_back(&dir_entry->d_name[0]); + } + auto real_path = platform_shim.redirection_map.at(it->folder_path); + auto filenames = get_folder_contents(platform_shim.folders, real_path.str()); + + // Add the dirent structures in the order they appear in the FolderManager + // Ignore anything which wasn't in the FolderManager + for (auto const& file : filenames) { + for (size_t i = 0; i < dirent_filenames.size(); i++) { + if (file == dirent_filenames.at(i)) { + it->contents.push_back(folder_contents.at(i)); + break; + } + } + } + } + if (it->current_index >= it->contents.size()) return nullptr; + return it->contents.at(it->current_index++); +} + +FRAMEWORK_EXPORT int CLOSEDIR_FUNC_NAME(DIR* dir_stream) { + if (!real_closedir) real_closedir = (PFN_CLOSEDIR)dlsym(RTLD_NEXT, "closedir"); + + auto it = std::find_if(platform_shim.dir_entries.begin(), platform_shim.dir_entries.end(), + [dir_stream](DirEntry const& entry) { return entry.directory == dir_stream; }); + + if (it != platform_shim.dir_entries.end()) { + platform_shim.dir_entries.erase(it); + } + + return real_closedir(dir_stream); +} + FRAMEWORK_EXPORT int ACCESS_FUNC_NAME(const char* in_pathname, int mode) { if (!real_access) real_access = (PFN_ACCESS)dlsym(RTLD_NEXT, "access"); @@ -197,6 +257,9 @@ struct Interposer { }; __attribute__((used)) static Interposer _interpose_opendir MACOS_ATTRIB = {VOIDP_CAST(my_opendir), VOIDP_CAST(opendir)}; +// don't intercept readdir as it crashes when using ASAN with macOS +// __attribute__((used)) static Interposer _interpose_readdir MACOS_ATTRIB = {VOIDP_CAST(my_readdir), VOIDP_CAST(readdir)}; +__attribute__((used)) static Interposer _interpose_closedir MACOS_ATTRIB = {VOIDP_CAST(my_closedir), VOIDP_CAST(closedir)}; __attribute__((used)) static Interposer _interpose_access MACOS_ATTRIB = {VOIDP_CAST(my_access), VOIDP_CAST(access)}; __attribute__((used)) static Interposer _interpose_fopen MACOS_ATTRIB = {VOIDP_CAST(my_fopen), VOIDP_CAST(fopen)}; __attribute__((used)) static Interposer _interpose_euid MACOS_ATTRIB = {VOIDP_CAST(my_geteuid), VOIDP_CAST(geteuid)}; diff --git a/tests/framework/shim/windows_shim.cpp b/tests/framework/shim/windows_shim.cpp index 87edf0de..15117606 100644 --- a/tests/framework/shim/windows_shim.cpp +++ b/tests/framework/shim/windows_shim.cpp @@ -224,7 +224,7 @@ HRESULT __stdcall ShimEnumAdapters1_1(IDXGIFactory1 *This, return DXGI_ERROR_INVALID_CALL; } if (ppAdapter != nullptr) { - auto* pAdapter = create_IDXGIAdapter1(); + auto *pAdapter = create_IDXGIAdapter1(); *ppAdapter = pAdapter; platform_shim.dxgi_adapter_map[pAdapter] = Adapter; } @@ -239,7 +239,7 @@ HRESULT __stdcall ShimEnumAdapters1_6(IDXGIFactory6 *This, return DXGI_ERROR_INVALID_CALL; } if (ppAdapter != nullptr) { - auto* pAdapter = create_IDXGIAdapter1(); + auto *pAdapter = create_IDXGIAdapter1(); *ppAdapter = pAdapter; platform_shim.dxgi_adapter_map[pAdapter] = Adapter; } @@ -256,7 +256,7 @@ HRESULT __stdcall ShimEnumAdapterByGpuPreference(IDXGIFactory6 *This, _In_ UINT assert(GpuPreference == DXGI_GPU_PREFERENCE::DXGI_GPU_PREFERENCE_UNSPECIFIED && "Test shim assumes the GpuPreference is unspecified."); if (ppvAdapter != nullptr) { - auto* pAdapter = create_IDXGIAdapter1(); + auto *pAdapter = create_IDXGIAdapter1(); *ppvAdapter = pAdapter; platform_shim.dxgi_adapter_map[pAdapter] = Adapter; } @@ -351,10 +351,12 @@ LSTATUS __stdcall ShimRegEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpValueName, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData) { const std::string *path = get_path_of_created_key(hKey); if (path == nullptr) return ERROR_NO_MORE_ITEMS; + const auto *location_ptr = get_registry_vector(*path); if (location_ptr == nullptr) return ERROR_NO_MORE_ITEMS; const auto &location = *location_ptr; if (dwIndex >= location.size()) return ERROR_NO_MORE_ITEMS; + if (*lpcchValueName < location[dwIndex].name.size()) return ERROR_NO_MORE_ITEMS; for (size_t i = 0; i < location[dwIndex].name.size(); i++) { lpValueName[i] = location[dwIndex].name[i]; @@ -466,8 +468,8 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved) { } return TRUE; } -FRAMEWORK_EXPORT PlatformShim *get_platform_shim() { - platform_shim = PlatformShim(); +FRAMEWORK_EXPORT PlatformShim *get_platform_shim(std::vector *folders) { + platform_shim = PlatformShim(folders); return &platform_shim; } -} \ No newline at end of file +} diff --git a/tests/framework/test_environment.cpp b/tests/framework/test_environment.cpp index 9bb65e6f..92c88bb8 100644 --- a/tests/framework/test_environment.cpp +++ b/tests/framework/test_environment.cpp @@ -136,14 +136,14 @@ void FillDebugUtilsCreateDetails(InstanceCreateInfo& create_info, DebugUtilsWrap create_info.instance_info.pNext = wrapper.get(); } -PlatformShimWrapper::PlatformShimWrapper() noexcept { +PlatformShimWrapper::PlatformShimWrapper(std::vector* folders) noexcept { #if defined(WIN32) || defined(__APPLE__) shim_library = LibraryWrapper(SHIM_LIBRARY_NAME); PFN_get_platform_shim get_platform_shim_func = shim_library.get_symbol(GET_PLATFORM_SHIM_STR); assert(get_platform_shim_func != NULL && "Must be able to get \"platform_shim\""); - platform_shim = get_platform_shim_func(); + platform_shim = get_platform_shim_func(folders); #elif defined(__linux__) || defined(__FreeBSD__) - platform_shim = get_platform_shim(); + platform_shim = get_platform_shim(folders); #endif platform_shim->reset(); @@ -184,29 +184,29 @@ TestLayer& TestLayerHandle::reset_layer() noexcept { fs::path TestLayerHandle::get_layer_full_path() noexcept { return layer_library.lib_path; } fs::path TestLayerHandle::get_layer_manifest_path() noexcept { return manifest_path; } -FrameworkEnvironment::FrameworkEnvironment() noexcept - : platform_shim(), - null_folder(FRAMEWORK_BUILD_DIRECTORY, "null_dir"), - icd_folder(FRAMEWORK_BUILD_DIRECTORY, "icd_manifests"), - icd_env_vars_folder(FRAMEWORK_BUILD_DIRECTORY, "icd_env_vars_manifests"), - explicit_layer_folder(FRAMEWORK_BUILD_DIRECTORY, "explicit_layer_manifests"), - explicit_env_var_layer_folder(FRAMEWORK_BUILD_DIRECTORY, "explicit_env_var_layer_folder"), - explicit_add_env_var_layer_folder(FRAMEWORK_BUILD_DIRECTORY, "explicit_add_env_var_layer_folder"), - implicit_layer_folder(FRAMEWORK_BUILD_DIRECTORY, "implicit_layer_manifests"), - override_layer_folder(FRAMEWORK_BUILD_DIRECTORY, "override_layer_manifests"), - vulkan_functions() { - platform_shim->redirect_all_paths(null_folder.location()); - platform_shim->set_path(ManifestCategory::icd, icd_folder.location()); - platform_shim->set_path(ManifestCategory::explicit_layer, explicit_layer_folder.location()); - platform_shim->set_path(ManifestCategory::implicit_layer, implicit_layer_folder.location()); +FrameworkEnvironment::FrameworkEnvironment() noexcept : platform_shim(&folders), vulkan_functions() { + // This order is important, it matches the enum ManifestLocation, used to index the folders vector + folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("null_dir")); + folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("icd_manifests")); + folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("icd_env_vars_manifests")); + folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_layer_manifests")); + folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_env_var_layer_folder")); + folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("explicit_add_env_var_layer_folder")); + folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("implicit_layer_manifests")); + folders.emplace_back(FRAMEWORK_BUILD_DIRECTORY, std::string("override_layer_manifests")); + + platform_shim->redirect_all_paths(get_folder(ManifestLocation::null).location()); + platform_shim->set_path(ManifestCategory::icd, get_folder(ManifestLocation::driver).location()); + platform_shim->set_path(ManifestCategory::explicit_layer, get_folder(ManifestLocation::explicit_layer).location()); + platform_shim->set_path(ManifestCategory::implicit_layer, get_folder(ManifestLocation::implicit_layer).location()); } void FrameworkEnvironment::add_icd(TestICDDetails icd_details) noexcept { size_t cur_icd_index = icds.size(); - fs::FolderManager* folder = &icd_folder; + fs::FolderManager* folder = &get_folder(ManifestLocation::driver); if (icd_details.discovery_type == ManifestDiscoveryType::env_var || icd_details.discovery_type == ManifestDiscoveryType::add_env_var) { - folder = &icd_env_vars_folder; + folder = &get_folder(ManifestLocation::driver_env_var); } if (!icd_details.is_fake) { fs::path new_driver_name = fs::path(icd_details.icd_manifest.lib_path).stem() + "_" + std::to_string(cur_icd_index) + @@ -265,30 +265,30 @@ void FrameworkEnvironment::add_explicit_layer(TestLayerDetails layer_details) no } void FrameworkEnvironment::add_layer_impl(TestLayerDetails layer_details, ManifestCategory category) { - fs::FolderManager* fs_ptr = &explicit_layer_folder; + fs::FolderManager* fs_ptr = &get_folder(ManifestLocation::explicit_layer); switch (layer_details.discovery_type) { default: case (ManifestDiscoveryType::generic): - if (category == ManifestCategory::implicit_layer) fs_ptr = &implicit_layer_folder; + if (category == ManifestCategory::implicit_layer) fs_ptr = &get_folder(ManifestLocation::implicit_layer); break; case (ManifestDiscoveryType::env_var): - fs_ptr = &explicit_env_var_layer_folder; + fs_ptr = &get_folder(ManifestLocation::explicit_layer_env_var); if (!env_var_vk_layer_paths.empty()) { env_var_vk_layer_paths += OS_ENV_VAR_LIST_SEPARATOR; } - env_var_vk_layer_paths += explicit_env_var_layer_folder.location().str(); + env_var_vk_layer_paths += fs_ptr->location().str(); set_env_var("VK_LAYER_PATH", env_var_vk_layer_paths); break; case (ManifestDiscoveryType::add_env_var): - fs_ptr = &explicit_add_env_var_layer_folder; + fs_ptr = &get_folder(ManifestLocation::explicit_layer_add_env_var); if (!add_env_var_vk_layer_paths.empty()) { add_env_var_vk_layer_paths += OS_ENV_VAR_LIST_SEPARATOR; } - add_env_var_vk_layer_paths += explicit_add_env_var_layer_folder.location().str(); + add_env_var_vk_layer_paths += fs_ptr->location().str(); set_env_var("VK_ADD_LAYER_PATH", add_env_var_vk_layer_paths); break; case (ManifestDiscoveryType::override_folder): - fs_ptr = &override_layer_folder; + fs_ptr = &get_folder(ManifestLocation::override_layer); break; case (ManifestDiscoveryType::none): break; @@ -331,6 +331,10 @@ TestLayer& FrameworkEnvironment::reset_layer(size_t index) noexcept { return lay fs::path FrameworkEnvironment::get_test_layer_path(size_t index) noexcept { return layers[index].get_layer_full_path(); } fs::path FrameworkEnvironment::get_layer_manifest_path(size_t index) noexcept { return layers[index].get_layer_manifest_path(); } +fs::FolderManager& FrameworkEnvironment::get_folder(ManifestLocation location) noexcept { + // index it directly using the enum location since they will always be in that order + return folders.at(static_cast(location)); +} void setup_WSI_in_ICD(TestICD& icd) { icd.enable_icd_wsi = true; #ifdef VK_USE_PLATFORM_ANDROID_KHR @@ -494,4 +498,4 @@ VkSurfaceKHR create_surface(InstWrapper& inst, const char* api_selection) { #endif return surface; -} \ No newline at end of file +} diff --git a/tests/framework/test_environment.h b/tests/framework/test_environment.h index fe2bba3e..4d33c28d 100644 --- a/tests/framework/test_environment.h +++ b/tests/framework/test_environment.h @@ -258,8 +258,10 @@ VkResult CreateDebugUtilsMessenger(DebugUtilsWrapper& debug_utils); void FillDebugUtilsCreateDetails(InstanceCreateInfo& create_info, DebugUtilsLogger& logger); void FillDebugUtilsCreateDetails(InstanceCreateInfo& create_info, DebugUtilsWrapper& wrapper); +struct FrameworkEnvironment; // forward declaration + struct PlatformShimWrapper { - PlatformShimWrapper() noexcept; + PlatformShimWrapper(std::vector* folders) noexcept; ~PlatformShimWrapper() noexcept; PlatformShimWrapper(PlatformShimWrapper const&) = delete; PlatformShimWrapper& operator=(PlatformShimWrapper const&) = delete; @@ -328,6 +330,17 @@ struct TestLayerDetails { BUILDER_VALUE(TestLayerDetails, bool, is_fake, false); }; +enum class ManifestLocation { + null = 0, + driver = 1, + driver_env_var = 2, + explicit_layer = 3, + explicit_layer_env_var = 4, + explicit_layer_add_env_var = 5, + implicit_layer = 6, + override_layer = 7 +}; + struct FrameworkEnvironment { FrameworkEnvironment() noexcept; @@ -349,15 +362,10 @@ struct FrameworkEnvironment { fs::path get_test_layer_path(size_t index = 0) noexcept; fs::path get_layer_manifest_path(size_t index = 0) noexcept; + fs::FolderManager& get_folder(ManifestLocation location) noexcept; + PlatformShimWrapper platform_shim; - fs::FolderManager null_folder; - fs::FolderManager icd_folder; - fs::FolderManager icd_env_vars_folder; - fs::FolderManager explicit_layer_folder; - fs::FolderManager explicit_env_var_layer_folder; - fs::FolderManager explicit_add_env_var_layer_folder; - fs::FolderManager implicit_layer_folder; - fs::FolderManager override_layer_folder; + std::vector folders; DebugUtilsLogger debug_log; VulkanFunctions vulkan_functions; @@ -381,4 +389,4 @@ void setup_WSI_in_ICD(TestICD& icd); void setup_WSI_in_create_instance(InstWrapper& inst); // api_selection: optionally provide a VK_USE_PLATFORM_XXX string to select which API to create a surface with // Note: MUST provide api_selection on platforms with multiple viable API's, such as linux and MacOS -VkSurfaceKHR create_surface(InstWrapper& inst, const char* api_selection = nullptr); \ No newline at end of file +VkSurfaceKHR create_surface(InstWrapper& inst, const char* api_selection = nullptr); diff --git a/tests/framework/test_util.cpp b/tests/framework/test_util.cpp index 1c27c086..e77b2c37 100644 --- a/tests/framework/test_util.cpp +++ b/tests/framework/test_util.cpp @@ -429,11 +429,12 @@ std::wstring native_path(const std::string& utf8) { return widen(utf8); } const std::string& native_path(const std::string& utf8) { return utf8; } #endif -FolderManager::FolderManager(path root_path, std::string name) : folder(root_path / name) { +FolderManager::FolderManager(path root_path, std::string name) noexcept : folder(root_path / name) { delete_folder_contents(folder); create_folder(folder); } -FolderManager::~FolderManager() { +FolderManager::~FolderManager() noexcept { + if (folder.str().empty()) return; auto list_of_files_to_delete = files; // remove(file) modifies the files variable, copy the list before deleting it // Note: the allocation tests currently leak the loaded driver handles because in an OOM scenario the loader doesn't bother @@ -444,6 +445,16 @@ FolderManager::~FolderManager() { } delete_folder(folder); } +FolderManager::FolderManager(FolderManager&& other) noexcept : folder(other.folder), files(other.files) { + other.folder.str().clear(); +} +FolderManager& FolderManager::operator=(FolderManager&& other) noexcept { + folder = other.folder; + files = other.files; + other.folder.str().clear(); + return *this; +} + path FolderManager::write_manifest(std::string const& name, std::string const& contents) { path out_path = folder / name; auto found = std::find(files.begin(), files.end(), name); diff --git a/tests/framework/test_util.h b/tests/framework/test_util.h index d6fe1636..f3ee26b2 100644 --- a/tests/framework/test_util.h +++ b/tests/framework/test_util.h @@ -203,10 +203,12 @@ int delete_folder(path const& folder); class FolderManager { public: - explicit FolderManager(path root_path, std::string name); - ~FolderManager(); + explicit FolderManager(path root_path, std::string name) noexcept; + ~FolderManager() noexcept; FolderManager(FolderManager const&) = delete; FolderManager& operator=(FolderManager const&) = delete; + FolderManager(FolderManager&& other) noexcept; + FolderManager& operator=(FolderManager&& other) noexcept; path write_manifest(std::string const& name, std::string const& contents); @@ -219,6 +221,8 @@ class FolderManager { // location of the managed folder path location() const { return folder; } + std::vector get_files() const { return files; } + private: path folder; std::vector files; diff --git a/tests/loader_envvar_tests.cpp b/tests/loader_envvar_tests.cpp index fb36aa32..b7d7534f 100644 --- a/tests/loader_envvar_tests.cpp +++ b/tests/loader_envvar_tests.cpp @@ -261,7 +261,7 @@ TEST(EnvVarICDOverrideSetup, TestOnlyLayerEnvVar) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); env.get_test_icd().physical_devices.push_back({}); - env.platform_shim->redirect_path("/tmp/carol", env.explicit_env_var_layer_folder.location()); + env.platform_shim->redirect_path("/tmp/carol", env.get_folder(ManifestLocation::explicit_layer_env_var).location()); const char* layer_name = "TestLayer"; env.add_explicit_layer( @@ -310,7 +310,7 @@ TEST(EnvVarICDOverrideSetup, TestOnlyAddLayerEnvVar) { FrameworkEnvironment env{}; env.add_icd(TestICDDetails(TEST_ICD_PATH_VERSION_2_EXPORT_ICD_GPDPA)); env.get_test_icd().physical_devices.push_back({}); - env.platform_shim->redirect_path("/tmp/carol", env.explicit_add_env_var_layer_folder.location()); + env.platform_shim->redirect_path("/tmp/carol", env.get_folder(ManifestLocation::explicit_layer_add_env_var).location()); const char* layer_name = "TestLayer"; env.add_explicit_layer( diff --git a/tests/loader_layer_tests.cpp b/tests/loader_layer_tests.cpp index be5e18b6..de2a7f5f 100644 --- a/tests/loader_layer_tests.cpp +++ b/tests/loader_layer_tests.cpp @@ -1046,15 +1046,16 @@ TEST(OverrideMetaLayer, OverridePathsInteractionWithVK_LAYER_PATH) { "regular_test_layer.json"} .set_discovery_type(ManifestDiscoveryType::override_folder)); - env.add_implicit_layer(ManifestLayer{} - .set_file_format_version(ManifestVersion(1, 2, 0)) - .add_layer(ManifestLayer::LayerDescription{} - .set_name(lunarg_meta_layer_name) - .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) - .add_component_layer(regular_layer_name) - .set_disable_environment("DisableMeIfYouCan") - .add_override_path(env.override_layer_folder.location().str())), - "meta_test_layer.json"); + env.add_implicit_layer( + ManifestLayer{} + .set_file_format_version(ManifestVersion(1, 2, 0)) + .add_layer(ManifestLayer::LayerDescription{} + .set_name(lunarg_meta_layer_name) + .set_api_version(VK_MAKE_API_VERSION(0, 1, 1, 0)) + .add_component_layer(regular_layer_name) + .set_disable_environment("DisableMeIfYouCan") + .add_override_path(env.get_folder(ManifestLocation::override_layer).location().str())), + "meta_test_layer.json"); InstWrapper inst{env.vulkan_functions}; inst.create_info.set_api_version(1, 1, 0); -- 2.34.1