Use builders in test framework components
authorCharles Giessen <charles@lunarg.com>
Wed, 8 Dec 2021 19:44:48 +0000 (12:44 -0700)
committerCharles Giessen <46324611+charles-lunarg@users.noreply.github.com>
Sat, 11 Dec 2021 00:08:23 +0000 (17:08 -0700)
Make use of BUILDER_VALUE and BUILDER_VECTOR in the various structs of the test
framework. This allows easier usage of the components by allowing a builder
style continuation of setting parameters in the drivers and physical devices.

tests/framework/icd/physical_device.h
tests/framework/icd/test_icd.h
tests/framework/test_util.cpp
tests/framework/test_util.h

index 4e4076f..6fc4ddf 100644 (file)
@@ -34,39 +34,21 @@ 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;
-    }
-    PhysicalDevice& set_features(VkPhysicalDeviceFeatures features) {
-        this->features = features;
-        return *this;
-    }
-    PhysicalDevice& set_memory_properties(VkPhysicalDeviceMemoryProperties memory_properties) {
-        this->memory_properties = memory_properties;
-        return *this;
-    }
-    PhysicalDevice& add_queue_family_properties(VkQueueFamilyProperties properties, bool support_present = true) {
-        queue_family_properties.push_back(MockQueueFamilyProperties(properties, support_present));
-        return *this;
-    }
-    PhysicalDevice& add_queue_family_properties(MockQueueFamilyProperties properties) {
-        queue_family_properties.push_back(properties);
-        return *this;
-    }
+
     DispatchableHandle<VkPhysicalDevice> vk_physical_device;
-    std::string deviceName;
-    VkPhysicalDeviceProperties properties{};
-    VkPhysicalDeviceFeatures features{};
-    VkPhysicalDeviceMemoryProperties memory_properties{};
-    std::vector<MockQueueFamilyProperties> queue_family_properties;
-    std::vector<VkFormatProperties> format_properties;
+    BUILDER_VALUE(PhysicalDevice, std::string, deviceName, "")
+    BUILDER_VALUE(PhysicalDevice, VkPhysicalDeviceProperties, properties, {})
+    BUILDER_VALUE(PhysicalDevice, VkPhysicalDeviceFeatures, features, {})
+    BUILDER_VALUE(PhysicalDevice, VkPhysicalDeviceMemoryProperties, memory_properties, {})
+
+    BUILDER_VECTOR(PhysicalDevice, MockQueueFamilyProperties, queue_family_properties, queue_family_properties)
+    BUILDER_VECTOR(PhysicalDevice, VkFormatProperties, format_properties, format_properties)
 
-    std::vector<Extension> extensions;
+    BUILDER_VECTOR(PhysicalDevice, Extension, extensions, extension)
 
-    VkSurfaceCapabilitiesKHR surface_capabilities;
-    std::vector<VkSurfaceFormatKHR> surface_formats;
-    std::vector<VkPresentModeKHR> surface_present_modes;
+    BUILDER_VALUE(PhysicalDevice, VkSurfaceCapabilitiesKHR, surface_capabilities, {})
+    BUILDER_VECTOR(PhysicalDevice, VkSurfaceFormatKHR, surface_formats, surface_format)
+    BUILDER_VECTOR(PhysicalDevice, VkPresentModeKHR, surface_present_modes, surface_present_mode)
 
     // VkDevice handles created from this physical device
     std::vector<VkDevice> device_handles;
@@ -74,7 +56,7 @@ struct PhysicalDevice {
     // List of function names which are 'known' to the physical device but have test defined implementations
     // The purpose of this list is so that vkGetDeviceProcAddr returns 'a real function pointer' in tests
     // without actually implementing any of the logic inside of it.
-    std::vector<VulkanFunction> known_device_functions;
+    BUILDER_VECTOR(PhysicalDevice, VulkanFunction, known_device_functions, device_function)
 };
 
 struct PhysicalDeviceGroup {
index ece8f15..16eb87a 100644 (file)
@@ -56,22 +56,23 @@ struct TestICD {
     CalledNegotiateInterface called_negotiate_interface = CalledNegotiateInterface::not_called;
 
     InterfaceVersionCheck interface_version_check = InterfaceVersionCheck::not_called;
-    uint32_t min_icd_interface_version = 0;
-    uint32_t max_icd_interface_version = 6;
+    BUILDER_VALUE(TestICD, uint32_t, min_icd_interface_version, 0)
+    BUILDER_VALUE(TestICD, uint32_t, max_icd_interface_version, 6)
     uint32_t icd_interface_version_received = 0;
 
     CalledEnumerateAdapterPhysicalDevices called_enumerate_adapter_physical_devices =
         CalledEnumerateAdapterPhysicalDevices::not_called;
 
-    bool enable_icd_wsi = false;
+    BUILDER_VALUE(TestICD, bool, enable_icd_wsi, false);
     UsingICDProvidedWSI is_using_icd_wsi = UsingICDProvidedWSI::not_using;
 
-    uint32_t icd_api_version = VK_MAKE_VERSION(1, 0, 0);
-    std::vector<LayerDefinition> instance_layers;
-    std::vector<Extension> instance_extensions;
-    std::vector<PhysicalDevice> physical_devices;
+    BUILDER_VALUE(TestICD, uint32_t, icd_api_version, VK_MAKE_VERSION(1, 0, 0))
+    BUILDER_VECTOR(TestICD, LayerDefinition, instance_layers, instance_layer)
+    BUILDER_VECTOR(TestICD, Extension, instance_extensions, instance_extension)
 
-    std::vector<PhysicalDeviceGroup> physical_device_groups;
+    BUILDER_VECTOR_MOVE_ONLY(TestICD, PhysicalDevice, physical_devices, physical_device);
+
+    BUILDER_VECTOR(TestICD, PhysicalDeviceGroup, physical_device_groups, physical_device_group);
 
     DispatchableHandle<VkInstance> instance_handle;
     std::vector<DispatchableHandle<VkDevice>> device_handles;
@@ -82,44 +83,15 @@ struct TestICD {
     // Unknown instance and physical device functions. Add a `VulkanFunction` to this list which will be searched in
     // vkGetInstanceProcAddr for custom_instance_functions and vk_icdGetPhysicalDeviceProcAddr for custom_physical_device_functions.
     // To add unknown device functions, add it to the PhysicalDevice directly (in the known_device_functions member)
-    std::vector<VulkanFunction> custom_instance_functions;
-    std::vector<VulkanFunction> custom_physical_device_functions;
+    BUILDER_VECTOR(TestICD, VulkanFunction, custom_instance_functions, custom_instance_function)
+    BUILDER_VECTOR(TestICD, VulkanFunction, custom_physical_device_functions, custom_physical_device_function)
 
     // Must explicitely state support for the tooling info extension, that way we can control if vkGetInstanceProcAddr returns a
     // function pointer for vkGetPhysicalDeviceToolPropertiesEXT
-    bool supports_tooling_info_ext = false;
+    BUILDER_VALUE(TestICD, bool, supports_tooling_info_ext, false)
     // List of tooling properties that this driver 'supports'
     std::vector<VkPhysicalDeviceToolPropertiesEXT> tooling_properties;
 
-    TestICD() {}
-    ~TestICD() {}
-
-    TestICD& SetMinICDInterfaceVersion(uint32_t icd_interface_version) {
-        this->min_icd_interface_version = icd_interface_version;
-        return *this;
-    }
-    TestICD& SetICDAPIVersion(uint32_t api_version) {
-        this->icd_api_version = api_version;
-        return *this;
-    }
-    TestICD& AddInstanceLayer(LayerDefinition layer) { return AddInstanceLayers({layer}); }
-
-    TestICD& AddInstanceLayers(std::vector<LayerDefinition> layers) {
-        this->instance_layers.reserve(layers.size() + this->instance_layers.size());
-        for (auto& layer : layers) {
-            this->instance_layers.push_back(layer);
-        }
-        return *this;
-    }
-    TestICD& AddInstanceExtension(Extension extension) { return AddInstanceExtensions({extension}); }
-
-    TestICD& AddInstanceExtensions(std::vector<Extension> extensions) {
-        this->instance_extensions.reserve(extensions.size() + this->instance_extensions.size());
-        for (auto& extension : extensions) {
-            this->instance_extensions.push_back(extension);
-        }
-        return *this;
-    }
     PhysicalDevice& GetPhysDevice(VkPhysicalDevice physicalDevice) {
         for (auto& phys_dev : physical_devices) {
             if (phys_dev.vk_physical_device.handle == physicalDevice) return phys_dev;
index 8b1f621..923de83 100644 (file)
@@ -247,6 +247,7 @@ std::string fixup_backslashes_in_path(std::string const& in_path) {
     }
     return out;
 }
+fs::path fixup_backslashes_in_path(fs::path const& in_path) { return fixup_backslashes_in_path(in_path.str()); }
 
 path& path::operator+=(path const& in) {
     contents += in.contents;
index f88a36a..e8ce12c 100644 (file)
@@ -136,9 +136,17 @@ enum class DebugMode {
 struct ManifestICD;    // forward declaration for FolderManager::write
 struct ManifestLayer;  // forward declaration for FolderManager::write
 
+#ifdef _WIN32
+// Environment variable list separator - not for filesystem paths
+const char OS_ENV_VAR_LIST_SEPARATOR = ';';
+#else
+// Environment variable list separator - not for filesystem paths
+const char OS_ENV_VAR_LIST_SEPARATOR = ':';
+#endif
+
 namespace fs {
 std::string make_native(std::string const&);
-std::string fixup_backslashes_in_path(std::string const& in_path);
+
 struct path {
    private:
 #if defined(WIN32)
@@ -193,6 +201,9 @@ struct path {
     std::string contents;
 };
 
+std::string fixup_backslashes_in_path(std::string const& in_path);
+fs::path fixup_backslashes_in_path(fs::path const& in_path);
+
 int create_folder(path const& path);
 int delete_folder(path const& folder);
 
@@ -469,11 +480,22 @@ inline std::string version_to_string(uint32_t version) {
 // type = type of the variable
 // name = name of the variable
 // singular_name = used for the `add_singluar_name` member function
-#define BUILDER_VECTOR(class_name, type, name, singular_name)    \
-    std::vector<type> name;                                      \
-    class_name& add_##singular_name(type const& singular_name) { \
-        this->name.push_back(singular_name);                     \
-        return *this;                                            \
+#define BUILDER_VECTOR(class_name, type, name, singular_name)                    \
+    std::vector<type> name;                                                      \
+    class_name& add_##singular_name(type const& singular_name) {                 \
+        this->name.push_back(singular_name);                                     \
+        return *this;                                                            \
+    }                                                                            \
+    class_name& add_##singular_name##s(std::vector<type> const& singular_name) { \
+        for (auto& elem : singular_name) this->name.push_back(elem);             \
+        return *this;                                                            \
+    }
+// Like BUILDER_VECTOR but for move only types - where passing in means giving up ownership
+#define BUILDER_VECTOR_MOVE_ONLY(class_name, type, name, singular_name) \
+    std::vector<type> name;                                             \
+    class_name& add_##singular_name(type&& singular_name) {             \
+        this->name.push_back(std::move(singular_name));                 \
+        return *this;                                                   \
     }
 
 struct ManifestVersion {