[Bf-blender-cvs] [7e45a760b4f] soc-2021-geometry-nodes-regression-test: Added backward support for existing tests.

Himanshi Kalra noreply at git.blender.org
Wed Jul 7 15:40:31 CEST 2021


Commit: 7e45a760b4fc786af4674a0e44398d65cf709af2
Author: Himanshi Kalra
Date:   Wed Jul 7 18:46:09 2021 +0530
Branches: soc-2021-geometry-nodes-regression-test
https://developer.blender.org/rB7e45a760b4fc786af4674a0e44398d65cf709af2

Added backward support for existing tests.

- Added create_expected_object if it doesn't exist.
- Added a counter condition for recusrion.
- Added optional test_name in basemesh test.
- Added code of previous MeshTest to SpecMeshTest.
- Changed default value of apply_modifier(s) flag and do_compare flag.

===================================================================

M	tests/python/modules/base_mesh_test.py

===================================================================

diff --git a/tests/python/modules/base_mesh_test.py b/tests/python/modules/base_mesh_test.py
index 1e8f48b74fc..d855af74c6d 100644
--- a/tests/python/modules/base_mesh_test.py
+++ b/tests/python/modules/base_mesh_test.py
@@ -3,24 +3,42 @@ import bpy
 import os
 import sys
 
-from modules.spec_classes import ModifierSpec, DeformModifierSpec, OperatorSpecEditMode, OperatorSpecObjectMode
+from modules.spec_classes import ModifierSpec, DeformModifierSpec, OperatorSpecEditMode, OperatorSpecObjectMode, ParticleSystemSpec
 
 
 class MeshTest(ABC):
-    def __init__(self, test_object_name, exp_object_name, threshold=None):
+    def __init__(self, test_object_name, exp_object_name, test_name=None, threshold=None):
         self.test_object_name = test_object_name
         self.exp_object_name = exp_object_name
+        self.test_name = test_name
         self.threshold = threshold
         self.update = os.getenv("BLENDER_TEST_UPDATE") is not None
+        self.verbose = os.getenv("BLENDER_VERBOSE") is not None
         # self.eval_object_name = "evaluated_object"
 
-        # Private flag to indicate whether the blend file was updated after the test.
-        self._test_updated = False
+
+        self.test_updated_counter = 0
         objects = bpy.data.objects
         self.test_object = objects[self.test_object_name]
+        # self.expected_object = objects[self.exp_object_name]
 
-        # TODO - create exp object, in case doesn't exist.
-        self.expected_object = objects[self.exp_object_name]
+        if self.update:
+            if objects.find(exp_object_name) > -1:
+                self.expected_object = objects[self.exp_object_name]
+            else:
+                self.create_expected_object()
+        else:
+            self.expected_object = objects[self.exp_object_name]
+
+    
+    def create_expected_object(self):
+        print("Creating expected object...")
+        evaluated_object = self.create_evaluated_object()
+        self.expected_object = evaluated_object
+        self.expected_object.name = self.exp_object_name
+        x, y, z = self.test_object.location
+        self.expected_object.location = (x, y+10, z)
+        bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath)
 
     def create_evaluated_object(self):
         bpy.context.view_layer.objects.active = self.test_object
@@ -40,11 +58,13 @@ class MeshTest(ABC):
     @staticmethod
     def _print_result(result):
         comparison_result, selection_result, validation_result = result
-        print("Mesh Compariosn: {}".format(comparison_result))
+        print("Mesh Comparison: {}".format(comparison_result))
         print("Selection Result: {}".format(selection_result))
         print("Mesh Validation: {}".format(validation_result))
+        print()
 
     def run_test(self):
+        # self.test_updated_counter = 0
         evaluated_test_object = self.create_evaluated_object()
         self.apply_operations(evaluated_test_object)
         result = self.compare_meshes(evaluated_test_object)
@@ -53,25 +73,35 @@ class MeshTest(ABC):
 
         if comparison_result == "Same" and selection_result == "Same" and validation_result == "Valid":
             self.passed_test(result)
+            # Clean up.
+            if self.verbose:
+                print("Cleaning up...")
+            # Delete evaluated_test_object.
+            bpy.ops.object.delete()
+            # bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath)
+            
+            return True
 
         elif self.update:
             self.failed_test(result)
             self.update_failed_test(evaluated_test_object)
+            if self.test_updated_counter == 1:
+                self.run_test()
+            else:
+                print("The test fails consistently. Exiting...")
 
         else:
             self.failed_test(result)
 
-        # Real implementation.
-        pass
 
     def failed_test(self, result):
-        print("The test failed with the following: ")
+        print("\nFAILED {} test with the following: ".format(self.test_name))
         self._print_result(result)
         # Real implementation.
         pass
 
     def passed_test(self, result):
-        print("The tests passed successfully.")
+        print("\nPASSED {} test successfully.".format(self.test_name))
         self._print_result(result)
         # Real implementation
         pass
@@ -117,7 +147,7 @@ class MeshTest(ABC):
 
         # Save file.
         bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath)
-        self._test_updated = True
+        self.test_updated_counter += 1
         self.expected_object = evaluated_test_object
 
         # Real implementation.
@@ -125,7 +155,7 @@ class MeshTest(ABC):
     def compare_meshes(self, evaluated_object):
         objects = bpy.data.objects
         evaluated_test_mesh = objects[evaluated_object.name].data
-        expected_mesh = objects[self.exp_object_name].data
+        expected_mesh = self.expected_object.data
         result_codes = []
 
         # Mesh Comparison.
@@ -139,12 +169,12 @@ class MeshTest(ABC):
 
         # Selection comparison.
 
-        selected_evaluatated_verts = [
+        selected_evaluated_verts = [
             v.index for v in evaluated_test_mesh.vertices if v.select]
         selected_expected_verts = [
             v.index for v in expected_mesh.vertices if v.select]
 
-        if selected_evaluatated_verts == selected_expected_verts:
+        if selected_evaluated_verts == selected_expected_verts:
             result_selection = "Same"
         else:
             result_selection = "Selection doesn't match."
@@ -169,13 +199,312 @@ class MeshTest(ABC):
 
 
 class SpecMeshTest(MeshTest):
-    def __init__(self, test_name, test_object_name, exp_object_name, operation_stack=None, threshold=None):
+    def __init__(self, test_name, test_object_name, exp_object_name, operations_stack=None, apply_modifier=True,
+        do_compare=True, threshold=None):
+        
+        super().__init__(test_object_name, exp_object_name, test_name, threshold)
         self.test_name = test_name
-        super().__init__(test_object_name, exp_object_name, threshold)
-        pass
+        if operations_stack is None:
+            self.operations_stack = []
+        else:
+            self.operations_stack = operations_stack 
+        self.apply_modifier = apply_modifier
+        self.do_compare = do_compare
 
-    def apply_operations(self):
-        pass
+    def apply_operations(self, evaluated_test_object):
+        # Add modifiers and operators.
+        print("Applying operations...")
+        for operation in self.operations_stack:
+            if isinstance(operation, ModifierSpec):
+                self._add_modifier(evaluated_test_object, operation)
+                if self.apply_modifier:
+                    self._apply_modifier(
+                        evaluated_test_object, operation.modifier_name)
+
+            elif isinstance(operation, OperatorSpecEditMode):
+                self._apply_operator_edit_mode(
+                    evaluated_test_object, operation)
+
+            elif isinstance(operation, OperatorSpecObjectMode):
+                self._apply_operator_object_mode(operation)
+
+            elif isinstance(operation, DeformModifierSpec):
+                self._apply_deform_modifier(evaluated_test_object, operation)
+
+            elif isinstance(operation, ParticleSystemSpec):
+                self._apply_particle_system(evaluated_test_object, operation)
+
+            else:
+                raise ValueError("Expected operation of type {} or {} or {} or {}. Got {}".
+                                 format(type(ModifierSpec), type(OperatorSpecEditMode),
+                                        type(OperatorSpecObjectMode), type(ParticleSystemSpec), type(operation)))
+
+    def _set_parameters_impl(self, modifier, modifier_parameters, nested_settings_path, modifier_name):
+        """
+        Doing a depth first traversal of the modifier parameters and setting their values.
+        :param: modifier: Of type modifier, its altered to become a setting in recursion.
+        :param: modifier_parameters : dict or sequence, a simple/nested dictionary of modifier parameters.
+        :param: nested_settings_path : list(stack): helps in tracing path to each node.
+        """
+        if not isinstance(modifier_parameters, dict):
+            param_setting = None
+            for i, setting in enumerate(nested_settings_path):
+
+                # We want to set the attribute only when we have reached the last setting.
+                # Applying of intermediate settings is meaningless.
+                if i == len(nested_settings_path) - 1:
+                    setattr(modifier, setting, modifier_parameters)
+
+                elif hasattr(modifier, setting):
+                    param_setting = getattr(modifier, setting)
+                    # getattr doesn't accept canvas_surfaces["Surface"], but we need to pass it to setattr.
+                    if setting == "canvas_surfaces":
+                        modifier = param_setting.active
+                    else:
+                        modifier = param_setting
+                else:
+                    # Clean up first
+                    bpy.ops.object.delete()
+                    raise Exception("Modifier '{}' has no parameter named '{}'".
+                                    format(modifier_name, setting))
+
+            # It pops the current node before moving on to its sibling.
+            nested_settings_path.pop()
+            return
+
+        for key in modifier_parameters:
+            nested_settings_path.append(key)
+            self._set_parameters_impl(
+                modifier, modifier_parameters[key], nested_settings_path, modifier_name)
+
+        if nested_settings_path:
+            nested_settings_path.pop()
+
+    def set_parameters(self, modifier, modifier_parameters):
+        """
+        Wrapper for _set_parameters_util
+        """
+        settings = []
+        modifier_name = modifier.name
+        self._set_parameters_impl(
+            modifier, modifier_parameters, settings, modifier_name)
+
+    def _add_modifier(self, test_object, modifier

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list