test: Control process elevation on Windows

Since the loader only uses environment variables if the process is
not running with elevated priviledges, the test harness needs to be
able to control that aspect to ensure consistency as CI systems may
run the tests in an 'elevated' context.

Change-Id: I8b15a1ecd4ab4960049ba198af8199943e872bba
This commit is contained in:
Charles Giessen
2021-06-06 04:01:28 -06:00
committed by Charles Giessen
parent b9f4dd01e2
commit f6fab4352d
5 changed files with 71 additions and 31 deletions
+1
View File
@@ -32,6 +32,7 @@
struct PhysicalDevice {
PhysicalDevice() {}
PhysicalDevice(std::string name) : deviceName(name) {}
PhysicalDevice(const char* name) : deviceName(name) {}
PhysicalDevice& set_properties(VkPhysicalDeviceProperties properties) {
this->properties = properties;
return *this;
+4
View File
@@ -110,6 +110,10 @@ struct PlatformShim {
// platform specific shim interface
#if defined(WIN32)
// Control Platform Elevation Level
unsigned long elevation_level = SECURITY_MANDATORY_LOW_RID;
void set_elevation_level(unsigned long new_elevation_level) { elevation_level = new_elevation_level; }
void add_dxgi_adapter(fs::path const& manifest_path, GpuType gpu_preference, uint32_t known_driver_index,
DXGI_ADAPTER_DESC1 desc1);
void add_d3dkmt_adapter(SHIM_D3DKMT_ADAPTERINFO adapter, fs::path const& path);
+7
View File
@@ -41,6 +41,11 @@ extern "C" {
static LibraryWrapper gdi32_dll;
using PFN_GetSidSubAuthority = PDWORD (__stdcall *)(PSID pSid, DWORD nSubAuthority);
static PFN_GetSidSubAuthority fpGetSidSubAuthority = GetSidSubAuthority;
PDWORD __stdcall ShimGetSidSubAuthority(PSID pSid, DWORD nSubAuthority) { return &platform_shim.elevation_level; }
static PFN_LoaderEnumAdapters2 fpEnumAdapters2 = nullptr;
static PFN_LoaderQueryAdapterInfo fpQueryAdapterInfo = nullptr;
@@ -302,6 +307,7 @@ void WINAPI DetourFunctions() {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID &)fpGetSidSubAuthority, ShimGetSidSubAuthority);
DetourAttach(&(PVOID &)fpEnumAdapters2, ShimEnumAdapters2);
DetourAttach(&(PVOID &)fpQueryAdapterInfo, ShimQueryAdapterInfo);
DetourAttach(&(PVOID &)REAL_CM_Get_Device_ID_List_SizeW, SHIM_CM_Get_Device_ID_List_SizeW);
@@ -325,6 +331,7 @@ void WINAPI DetourFunctions() {
void DetachFunctions() {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID &)fpGetSidSubAuthority, ShimGetSidSubAuthority);
DetourDetach(&(PVOID &)fpEnumAdapters2, ShimEnumAdapters2);
DetourDetach(&(PVOID &)fpQueryAdapterInfo, ShimQueryAdapterInfo);
DetourDetach(&(PVOID &)REAL_CM_Get_Device_ID_List_SizeW, SHIM_CM_Get_Device_ID_List_SizeW);
+3
View File
@@ -39,6 +39,9 @@ PlatformShimWrapper::PlatformShimWrapper(DebugMode debug_mode) : debug_mode(debu
#endif
platform_shim->setup_override(debug_mode);
platform_shim->reset(debug_mode);
// leave it permanently on at full blast
set_env_var("VK_LOADER_DEBUG", "all");
}
PlatformShimWrapper::~PlatformShimWrapper() {
platform_shim->reset(debug_mode);
+56 -31
View File
@@ -27,36 +27,61 @@
#include "test_environment.h"
struct ICDSetup {
ICDSetup(const char* icd_path, const char* manifest_name)
: _manifest_name(manifest_name), driver_store(FRAMEWORK_BUILD_DIRECTORY, "version_test_manifests") {
ManifestICD icd_manifest;
icd_manifest.lib_path = icd_path;
icd_manifest.api_version = VK_MAKE_VERSION(1, 0, 0);
driver_store.write(manifest_name, icd_manifest);
set_env_var("VK_LOADER_DEBUG", "all");
set_env_var("VK_ICD_FILENAMES", (driver_store.location() / manifest_name).str());
auto str = get_env_var("VK_ICD_FILENAMES");
driver_wrapper = LibraryWrapper(fs::path(icd_path));
get_new_test_icd = driver_wrapper.get_symbol<GetNewTestICDFunc>(GET_NEW_TEST_ICD_FUNC_STR);
class ICDEnvVarSetup : public ::testing::Test {
protected:
virtual void SetUp() {}
virtual void TearDown() {
remove_env_var("VK_ICD_FILENAMES");
platform_shim->platform_shim->clear_override();
driver_store->remove(manifest_name);
vulkan_functions.reset();
platform_shim.reset();
driver_store.reset();
}
~ICDSetup() { remove_env_var("VK_ICD_FILENAMES"); driver_store.remove(_manifest_name); }
std::string _manifest_name;
fs::FolderManager driver_store;
public:
std::string manifest_name;
std::unique_ptr<detail::PlatformShimWrapper> platform_shim;
std::unique_ptr<fs::FolderManager> driver_store;
std::unique_ptr<fs::FolderManager> null_dir;
LibraryWrapper driver_wrapper;
GetNewTestICDFunc get_new_test_icd;
VulkanFunctions vulkan_functions;
std::unique_ptr<VulkanFunctions> vulkan_functions;
};
void SetupICDEnvVar(ICDEnvVarSetup& env, const char* icd_path, const char* manifest_name) {
env.manifest_name = manifest_name;
env.platform_shim = std::unique_ptr<detail::PlatformShimWrapper>(new detail::PlatformShimWrapper());
env.platform_shim->platform_shim->setup_override();
env.driver_store =
std::unique_ptr<fs::FolderManager>(new fs::FolderManager(FRAMEWORK_BUILD_DIRECTORY, "version_test_manifests"));
env.null_dir = std::unique_ptr<fs::FolderManager>(new fs::FolderManager(FRAMEWORK_BUILD_DIRECTORY, "null_dir"));
env.platform_shim->platform_shim->redirect_all_paths(env.null_dir->location());
env.driver_wrapper = LibraryWrapper(fs::path(icd_path));
env.get_new_test_icd = env.driver_wrapper.get_symbol<GetNewTestICDFunc>(GET_NEW_TEST_ICD_FUNC_STR);
#if defined(WIN32)
env.platform_shim->platform_shim->set_elevation_level(SECURITY_MANDATORY_LOW_RID);
#endif
ManifestICD icd_manifest;
icd_manifest.lib_path = icd_path;
icd_manifest.api_version = VK_MAKE_VERSION(1, 0, 0);
env.driver_store->write(manifest_name, icd_manifest);
set_env_var("VK_ICD_FILENAMES", (env.driver_store->location() / manifest_name).str());
env.vulkan_functions = std::unique_ptr<VulkanFunctions>(new VulkanFunctions());
}
// Don't support vk_icdNegotiateLoaderICDInterfaceVersion
// Loader calls vk_icdGetInstanceProcAddr second
// does not support vk_icdGetInstanceProcAddr
// must export vkGetInstanceProcAddr, vkCreateInstance, vkEnumerateInstanceExtensionProperties
TEST(DriverNone, version_0) {
ICDSetup setup(TEST_ICD_PATH_EXPORT_NONE, "test_icd_export_none.json");
auto* driver = setup.get_new_test_icd();
TEST_F(ICDEnvVarSetup, version_0_none) {
SetupICDEnvVar(*this, TEST_ICD_PATH_EXPORT_NONE, "test_icd_export_none.json");
auto* driver = get_new_test_icd();
InstWrapper inst{setup.vulkan_functions};
InstWrapper inst{*vulkan_functions};
InstanceCreateInfo inst_create_info;
ASSERT_EQ(CreateInst(inst, inst_create_info), VK_SUCCESS);
@@ -65,11 +90,11 @@ TEST(DriverNone, version_0) {
// Don't support vk_icdNegotiateLoaderICDInterfaceVersion
// the loader calls vk_icdGetInstanceProcAddr first
TEST(DriverICDGIPA, version_1) {
ICDSetup setup(TEST_ICD_PATH_EXPORT_ICD_GIPA, "test_icd_export_icd_gipa.json");
auto* driver = setup.get_new_test_icd();
TEST_F(ICDEnvVarSetup, version_1_icd_gipa) {
SetupICDEnvVar(*this, TEST_ICD_PATH_EXPORT_ICD_GIPA, "test_icd_export_icd_gipa.json");
auto* driver = get_new_test_icd();
InstWrapper inst{setup.vulkan_functions};
InstWrapper inst{*vulkan_functions};
InstanceCreateInfo inst_create_info;
ASSERT_EQ(CreateInst(inst, inst_create_info), VK_SUCCESS);
@@ -78,12 +103,12 @@ TEST(DriverICDGIPA, version_1) {
// support vk_icdNegotiateLoaderICDInterfaceVersion but not vk_icdGetInstanceProcAddr
// should assert that `interface_vers == 0` due to version mismatch, only checkable in Debug Mode
TEST(DriverNegotiateInterfaceVersionDeathTest, version_negotiate_interface_version) {
TEST_F(ICDEnvVarSetup, version_negotiate_interface_version_death_test) {
// may be needed to surpress debug assert popups on windows
//::testing::FLAGS_gtest_death_test_style = "threadsafe";
ICDSetup setup(TEST_ICD_PATH_EXPORT_NEGOTIATE_INTERFACE_VERSION, "test_icd_export_negotiate_interface_version.json");
SetupICDEnvVar(*this, TEST_ICD_PATH_EXPORT_NEGOTIATE_INTERFACE_VERSION, "test_icd_export_negotiate_interface_version.json");
InstWrapper inst{setup.vulkan_functions};
InstWrapper inst{*vulkan_functions};
InstanceCreateInfo inst_create_info;
#if !defined(NDEBUG)
#if defined(WIN32)
@@ -97,11 +122,11 @@ TEST(DriverNegotiateInterfaceVersionDeathTest, version_negotiate_interface_versi
}
// export vk_icdNegotiateLoaderICDInterfaceVersion and vk_icdGetInstanceProcAddr
TEST(DriverNegotiateInterfaceVersionAndICDGIPA, version_2) {
ICDSetup setup(TEST_ICD_PATH_VERSION_2, "test_icd_version_2.json");
auto* driver = setup.get_new_test_icd();
TEST_F(ICDEnvVarSetup, version_2_negotiate_interface_version_and_icd_gipa) {
SetupICDEnvVar(*this, TEST_ICD_PATH_VERSION_2, "test_icd_version_2.json");
auto* driver = get_new_test_icd();
InstWrapper inst{setup.vulkan_functions};
InstWrapper inst{*vulkan_functions};
InstanceCreateInfo inst_create_info;
ASSERT_EQ(CreateInst(inst, inst_create_info), VK_SUCCESS);