Collect steps execution result 66/113566/2
authorMichal Jagiello <michal.jagiello@t-mobile.pl>
Tue, 6 Oct 2020 09:56:13 +0000 (09:56 +0000)
committerMichal Jagiello <michal.jagiello@t-mobile.pl>
Tue, 6 Oct 2020 10:25:28 +0000 (10:25 +0000)
Create a decorator to collect step execution result and store them in storage class.
Storage class prepare a dictionary with step class name and execution result.

Issue-ID: INT-1733
Change-Id: I9c4030a0740085a9acca461c1581683c469ecbcf
Signed-off-by: Michal Jagiello <michal.jagiello@t-mobile.pl>
17 files changed:
src/onaptests/steps/base.py
src/onaptests/steps/cloud/complex_create.py
src/onaptests/steps/cloud/connect_service_subscription_to_cloud_region.py
src/onaptests/steps/cloud/customer_create.py
src/onaptests/steps/cloud/customer_service_subscription_create.py
src/onaptests/steps/cloud/link_cloud_to_complex.py
src/onaptests/steps/cloud/register_cloud.py
src/onaptests/steps/instantiate/service_ala_carte.py
src/onaptests/steps/instantiate/vf_module_ala_carte.py
src/onaptests/steps/instantiate/vnf_ala_carte.py
src/onaptests/steps/onboard/service.py
src/onaptests/steps/onboard/vendor.py
src/onaptests/steps/onboard/vf.py
src/onaptests/steps/onboard/vsp.py
src/onaptests/steps/reports_collection.py [new file with mode: 0644]
tests/test_reports_collection.py [new file with mode: 0644]
tests/test_store_state.py [new file with mode: 0644]

index 5407a85..57217fb 100644 (file)
@@ -6,6 +6,9 @@ from typing import List
 from onapsdk.configuration import settings
 from onapsdk.aai.business import Customer
 
+from .reports_collection import ReportsCollection
+
+
 class BaseStep(ABC):
     """Base step class."""
 
@@ -36,6 +39,7 @@ class BaseStep(ABC):
         self._steps: List["BaseStep"] = []
         self._cleanup: bool = cleanup
         self._parent: "BaseStep" = None
+        self._reports_collection: ReportsCollection = None
 
     def add_step(self, step: "BaseStep") -> None:
         """Add substep.
@@ -68,6 +72,39 @@ class BaseStep(ABC):
         """
         return self._parent is None
 
+    @property
+    def reports_collection(self) -> ReportsCollection:
+        """Collection to store step reports.
+
+        Store there if step result is "PASS" or "FAIL"
+
+        Returns:
+            Queue: Thread safe collection to store reports
+
+        """
+        if not self.is_root:
+            return self.parent.reports_collection
+        if not self._reports_collection:
+            self._reports_collection = ReportsCollection()
+        return self._reports_collection
+
+    @property
+    def name(self) -> str:
+        """Step name."""
+        return self.__class__.__name__
+
+    @classmethod
+    def store_state(cls, fun):
+        def wrapper(self, *args, **kwargs):
+            try:
+                ret = fun(self, *args, **kwargs)
+                self.reports_collection.put({self.name: "PASS"})
+                return ret
+            except Exception:
+                self.reports_collection.put({self.name: "FAIL"})
+                raise
+        return wrapper
+
     def execute(self) -> None:
         """Step's action.
 
index 37ad49f..b4d110d 100644 (file)
@@ -7,6 +7,7 @@ from ..base import BaseStep
 class ComplexCreateStep(BaseStep):
     """Complex creation step."""
 
+    @BaseStep.store_state
     def execute(self):
         """Create complex.
 
index cc0f7b7..636f8cd 100644 (file)
@@ -25,6 +25,7 @@ class ConnectServiceSubToCloudRegionStep(BaseStep):
         self.add_step(LinkCloudRegionToComplexStep(cleanup=cleanup))
         self.add_step(CustomerServiceSubscriptionCreateStep(cleanup=cleanup))
 
+    @BaseStep.store_state
     def execute(self):
         """Connect service subsription to cloud region and tenant.
 
index 2bdf312..3c0ef11 100644 (file)
@@ -7,6 +7,7 @@ from ..base import BaseStep
 class CustomerCreateStep(BaseStep):
     """Customer creation step."""
 
+    @BaseStep.store_state
     def execute(self):
         """Create cutomer.
 
index ebe478f..707d79b 100644 (file)
@@ -18,6 +18,7 @@ class CustomerServiceSubscriptionCreateStep(BaseStep):
         super().__init__(cleanup=cleanup)
         self.add_step(CustomerCreateStep(cleanup=cleanup))
 
+    @BaseStep.store_state
     def execute(self):
         """Create customer service subsription.
 
index a6b0a96..22c4aac 100644 (file)
@@ -18,6 +18,7 @@ class LinkCloudRegionToComplexStep(BaseStep):
         super().__init__(cleanup=cleanup)
         self.add_step(ComplexCreateStep(cleanup=cleanup))
 
+    @BaseStep.store_state
     def execute(self):
         """Link cloud region to complex.
 
index c6871b8..6836b12 100644 (file)
@@ -10,6 +10,7 @@ from ..base import BaseStep
 class RegisterCloudRegionStep(BaseStep):
     """Cloud region registration step."""
 
+    @BaseStep.store_state
     def execute(self):
         """Register cloud region
 
index eb98f19..b3b56c4 100644 (file)
@@ -30,6 +30,7 @@ class ServiceAlaCarteInstantiateStep(BaseStep):
             self.add_step(ServiceOnboardStep(cleanup))
             self.add_step(ConnectServiceSubToCloudRegionStep(cleanup))
 
+    @BaseStep.store_state
     def execute(self):
         """Instantiate service.
 
@@ -138,6 +139,7 @@ class YamlTemplateServiceAlaCarteInstantiateStep(YamlTemplateBaseStep):
             return self._service_instance_name
         return self.parent.service_instance_name
 
+    @YamlTemplateBaseStep.store_state
     def execute(self):
         """Instantiate service.
 
index 3a22159..14ef2d8 100644 (file)
@@ -96,6 +96,7 @@ class YamlTemplateVfModuleAlaCarteInstantiateStep(YamlTemplateBaseStep):
                         value=vnf_parameter["value"]
                     )
 
+    @YamlTemplateBaseStep.store_state
     def execute(self) -> None:
         """Instantiate Vf module.
 
index f52857d..0ab498d 100644 (file)
@@ -75,6 +75,7 @@ class YamlTemplateVnfAlaCarteInstantiateStep(YamlTemplateBaseStep):
             return self._service_instance_name
         return self.parent.service_instance_name
 
+    @YamlTemplateBaseStep.store_state
     def execute(self):
         """Instantiate vnf.
 
index 42a1db4..87211bd 100644 (file)
@@ -20,6 +20,7 @@ class ServiceOnboardStep(BaseStep):
         super().__init__(cleanup=cleanup)
         self.add_step(VfOnboardStep(cleanup=cleanup))
 
+    @BaseStep.store_state
     def execute(self):
         """Onboard service.
 
@@ -79,6 +80,7 @@ class YamlTemplateServiceOnboardStep(YamlTemplateBaseStep):
         else:
             return self.parent.service_name
 
+    @YamlTemplateBaseStep.store_state
     def execute(self):
         """Onboard service."""
         super().execute()
index 8a4cb48..49d721b 100644 (file)
@@ -7,6 +7,7 @@ from ..base import BaseStep
 class VendorOnboardStep(BaseStep):
     """Vendor onboard step."""
 
+    @BaseStep.store_state
     def execute(self):
         """Onboard vendor.
 
index 2cda931..f26d66d 100644 (file)
@@ -18,6 +18,7 @@ class VfOnboardStep(BaseStep):
         super().__init__(cleanup=cleanup)
         self.add_step(VspOnboardStep(cleanup=cleanup))
 
+    @BaseStep.store_state
     def execute(self):
         """Onboard Vf.
 
@@ -56,6 +57,7 @@ class YamlTemplateVfOnboardStep(YamlTemplateBaseStep):
         """
         return self.parent.yaml_template[self.parent.service_name]
 
+    @YamlTemplateBaseStep.store_state
     def execute(self):
         """Onboard Vfs from YAML template."""
         super().execute()
index 8ac47b5..ba6020a 100644 (file)
@@ -19,6 +19,7 @@ class VspOnboardStep(BaseStep):
         super().__init__(cleanup=cleanup)
         self.add_step(VendorOnboardStep(cleanup=cleanup))
 
+    @BaseStep.store_state
     def execute(self):
         """Onboard Vsp.
 
@@ -58,6 +59,7 @@ class YamlTemplateVspOnboardStep(YamlTemplateBaseStep):
         """
         return self.parent.yaml_template
 
+    @YamlTemplateBaseStep.store_state
     def execute(self):
         """Onboard Vsps from YAML template.
 
diff --git a/src/onaptests/steps/reports_collection.py b/src/onaptests/steps/reports_collection.py
new file mode 100644 (file)
index 0000000..b61b571
--- /dev/null
@@ -0,0 +1,35 @@
+from typing import Dict
+
+
+class ReportsCollection:
+    """Collection to store steps execution statuses."""
+
+    def __init__(self) -> None:
+        """Initialize collection."""
+        self._collection: list = []
+
+    def put(self, item: Dict[str, str]) -> None:
+        """Put execution status dictionary.
+
+        Args:
+            item (Dict[str, str]): Step name with status dictionary
+
+        """
+        self._collection.append(item)
+
+    @property
+    def report(self) -> Dict[str, str]:
+        """Get report.
+
+        Build a dictionary with execution statuses.
+
+        Returns:
+            Dict[str, str]: Steps name with status dictionary
+
+        """
+        report: Dict[str, str] = {}
+        for element in self._collection[::-1]:
+            print(element)
+            print(type(element))
+            report.update(element)
+        return report
diff --git a/tests/test_reports_collection.py b/tests/test_reports_collection.py
new file mode 100644 (file)
index 0000000..264b6b4
--- /dev/null
@@ -0,0 +1,10 @@
+
+from onaptests.steps.reports_collection import ReportsCollection
+
+
+def test_reports_collection():
+    rc = ReportsCollection()
+    assert rc.report == {}
+
+    rc.put({"a": "b"})
+    assert rc.report == {"a": "b"}
diff --git a/tests/test_store_state.py b/tests/test_store_state.py
new file mode 100644 (file)
index 0000000..e0c8b6b
--- /dev/null
@@ -0,0 +1,29 @@
+import pytest
+from onaptests.steps.base import BaseStep
+
+
+class TestStep(BaseStep):
+
+    @BaseStep.store_state
+    def execute(self):
+        return super().execute()
+
+
+class TestFailStep(BaseStep):
+
+    @BaseStep.store_state
+    def execute(self):
+        super().execute()
+        raise Exception
+
+
+def test_store_state():
+    ts = TestStep()
+    ts.execute()
+    assert ts.reports_collection.report == {"TestStep": "PASS"}
+
+    fs = TestFailStep()
+    fs.add_step(TestStep())
+    with pytest.raises(Exception):
+        fs.execute()
+    fs.reports_collection.report == {"TestFailStep": "FAIL", "TestStep": "PASS"}