[VVP] adding heat template-validate test 13/88413/5
authorstark, steven <steven.stark@att.com>
Thu, 23 May 2019 20:50:25 +0000 (13:50 -0700)
committerstark, steven <steven.stark@att.com>
Thu, 23 May 2019 21:51:24 +0000 (14:51 -0700)
Issue-ID: VVP-218
Signed-off-by: stark, steven <steven.stark@att.com>
Change-Id: If88f9b4b620aaffe61ead3b6f7d5c74dcfd14cba

ice_validator/tests/conftest.py
ice_validator/tests/fixtures/test_valid_heat/fail/fail.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_valid_heat/fail/fail1.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_valid_heat/fail/fail2.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_valid_heat/fail/fail3.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_valid_heat/fail/fail4.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_valid_heat/fail/nestedbad.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_valid_heat/pass/pass.yaml [new file with mode: 0644]
ice_validator/tests/test_valid_heat.py [new file with mode: 0644]
ice_validator/vvp-config.yaml
requirements.txt

index 07a66f2..db87e18 100644 (file)
@@ -56,6 +56,9 @@ import xlsxwriter
 from six import string_types
 
 import version
+import logging
+
+logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.ERROR)
 
 __path__ = [os.path.dirname(os.path.abspath(__file__))]
 
diff --git a/ice_validator/tests/fixtures/test_valid_heat/fail/fail.yaml b/ice_validator/tests/fixtures/test_valid_heat/fail/fail.yaml
new file mode 100644 (file)
index 0000000..e28fcd2
--- /dev/null
@@ -0,0 +1,16 @@
+heat_template_version: 2014-10-16 
+description: This is a test heat template 
+parameters: 
+  testparam: 
+    type: string 
+    description: This is a test parameter
+resources: 
+  test_resource: 
+    type: OS::BAD::RandomString 
+    properties: 
+      length: { get_param: testparam }
\ No newline at end of file
diff --git a/ice_validator/tests/fixtures/test_valid_heat/fail/fail1.yaml b/ice_validator/tests/fixtures/test_valid_heat/fail/fail1.yaml
new file mode 100644 (file)
index 0000000..5606308
--- /dev/null
@@ -0,0 +1,16 @@
+heat_template_version: 2014-10-16 
+description: This is a test heat template 
+parameters: 
+  testparam: 
+    type: string 
+    description: This is a test parameter
+resources: 
+  test_resource: 
+    type: OS::Heat::RandomString 
+    properties: 
+      notprop: { get_param: testparam }
\ No newline at end of file
diff --git a/ice_validator/tests/fixtures/test_valid_heat/fail/fail2.yaml b/ice_validator/tests/fixtures/test_valid_heat/fail/fail2.yaml
new file mode 100644 (file)
index 0000000..742f5c8
--- /dev/null
@@ -0,0 +1,12 @@
+heat_template_version: 2014-10-16 
+description: This is a test heat template 
+parameters: 
+  testparam: 
+    type: string 
+    description: This is a test parameter
+
+# no resources
\ No newline at end of file
diff --git a/ice_validator/tests/fixtures/test_valid_heat/fail/fail3.yaml b/ice_validator/tests/fixtures/test_valid_heat/fail/fail3.yaml
new file mode 100644 (file)
index 0000000..f8c5446
--- /dev/null
@@ -0,0 +1,20 @@
+heat_template_version: 2014-10-16 
+description: This is a test heat template 
+parameters: 
+  testparam: 
+    type: string 
+    description: This is a test parameter
+resources: 
+  test_resource: 
+    type: OS::Heat::RandomString 
+    properties: 
+      length: { get_param: testparam }
+
+outputs:
+  badoutput:
+    value: { get_attr: [test_resource, notanattr, 0] }
\ No newline at end of file
diff --git a/ice_validator/tests/fixtures/test_valid_heat/fail/fail4.yaml b/ice_validator/tests/fixtures/test_valid_heat/fail/fail4.yaml
new file mode 100644 (file)
index 0000000..5855817
--- /dev/null
@@ -0,0 +1,16 @@
+heat_template_version: 2014-10-16 
+description: This is a test heat template 
+parameters: 
+  testparam: 
+    type: string 
+    description: This is a test parameter
+resources: 
+  test_resource: 
+    type: nestedbad.yaml 
+    properties: 
+      wrongprop: { get_param: testparam }
\ No newline at end of file
diff --git a/ice_validator/tests/fixtures/test_valid_heat/fail/nestedbad.yaml b/ice_validator/tests/fixtures/test_valid_heat/fail/nestedbad.yaml
new file mode 100644 (file)
index 0000000..3a550ec
--- /dev/null
@@ -0,0 +1,16 @@
+heat_template_version: 2014-10-16 
+description: This is a test heat template 
+parameters: 
+  testparam: 
+    type: string 
+    description: This is a test parameter
+resources: 
+  test_resource: 
+    type: OS::Nova::Server 
+    properties: 
+      notaprop: { get_param: testparam }
diff --git a/ice_validator/tests/fixtures/test_valid_heat/pass/pass.yaml b/ice_validator/tests/fixtures/test_valid_heat/pass/pass.yaml
new file mode 100644 (file)
index 0000000..c2fdd95
--- /dev/null
@@ -0,0 +1,16 @@
+heat_template_version: 2014-10-16 
+description: This is a test heat template 
+parameters: 
+  testparam: 
+    type: string 
+    description: This is a test parameter
+resources: 
+  test_resource: 
+    type: OS::Heat::RandomString 
+    properties: 
+      length: { get_param: testparam }
\ No newline at end of file
diff --git a/ice_validator/tests/test_valid_heat.py b/ice_validator/tests/test_valid_heat.py
new file mode 100644 (file)
index 0000000..2387a2c
--- /dev/null
@@ -0,0 +1,143 @@
+# -*- coding: utf8 -*-
+# ============LICENSE_START=======================================================
+# org.onap.vvp/validation-scripts
+# ===================================================================
+# Copyright © 2019 AT&T Intellectual Property. All rights reserved.
+# ===================================================================
+#
+# Unless otherwise specified, all software contained herein is licensed
+# under the Apache License, Version 2.0 (the "License");
+# you may not use this software except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#             http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+#
+# Unless otherwise specified, all documentation contained herein is licensed
+# under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+# you may not use this documentation except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#             https://creativecommons.org/licenses/by/4.0/
+#
+# Unless required by applicable law or agreed to in writing, documentation
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# ============LICENSE_END============================================
+import mock
+import os
+import pytest
+
+from heat.common import template_format
+from heat.engine import resources
+from heat.engine import service
+from heat.tests.openstack.nova import fakes as fakes_nova
+from heat.tests import utils
+
+from tests import cached_yaml as yaml
+from tests.utils.nested_files import get_list_of_nested_files
+from tests.helpers import categories, validates
+
+
+def load_file(filename, file_cache):
+    basename = os.path.basename(filename)
+    if basename not in file_cache:
+        with open(filename, "r") as fh:
+            file_cache[basename] = fh.read()
+
+    return file_cache[basename]
+
+
+def generate_parameters(yml_data):
+    parameters = yml_data.get("parameters", {})
+    dummy_params = {}
+
+    for p, v in parameters.items():
+        param_type = v.get("type", "")
+        if param_type == "comma_delimited_list":
+            param = "1,2,3"
+        elif param_type == "string":
+            param = "123"
+        elif param_type == "json":
+            param = {"abc": "123"}
+        elif param_type == "number":
+            param = 123
+        elif param_type == "boolean":
+            param = True
+        else:
+            param = "123"
+        dummy_params[p] = param
+
+    return {"parameters": dummy_params}
+
+
+class HOTValidator:
+    def __init__(self, yaml_file, files, yml_data):
+        resources.initialise()
+        self.fc = fakes_nova.FakeClient()
+        self.gc = fakes_nova.FakeClient()
+        resources.initialise()
+        self.ctx = utils.dummy_context()
+        self.mock_isa = mock.patch(
+            "heat.engine.resource.Resource.is_service_available",
+            return_value=(True, None),
+        )
+        self.mock_is_service_available = self.mock_isa.start()
+        self.engine = service.EngineService("a", "t")
+
+        self.yaml_file = yaml_file
+        self.files = files
+        self.yml_data = yml_data
+
+    def validate_heat(self):
+        ymldata = load_file(self.yaml_file, self.files)
+        parameters = generate_parameters(self.yml_data)
+
+        t = template_format.parse(ymldata)
+
+        try:
+            res = dict(
+                self.engine.validate_template(
+                    self.ctx, t, files=self.files, params=parameters, show_nested=False
+                )
+            )
+        except Exception as e:
+            res = {"Error": e.__context__}
+
+        if isinstance(res, dict) and "Error" in res:
+            return res.get("Error")
+        else:
+            return None
+
+
+@validates("R-92635")
+@categories("openstack")
+def test_heat(yaml_file):
+    with open(yaml_file, "r") as f:
+        yml = yaml.load(f)
+
+    # skip if resources are not defined
+    if "resources" not in yml:
+        pytest.skip("No resources specified in the heat template")
+
+    files = {}
+    dirname = os.path.dirname(yaml_file)
+    for file in set(get_list_of_nested_files(yml, dirname)):
+        load_file(file, files)
+
+    validator = HOTValidator(yaml_file, files, yml)
+    msg = validator.validate_heat()
+
+    assert not msg, "Invalid OpenStack Heat detected in {}: {}".format(
+        os.path.basename(yaml_file), msg
+    )
index f5f835c..e6259ba 100644 (file)
@@ -45,6 +45,12 @@ categories:
     description:
       Checks certain parameters are excluded from the .env file, per HOT Requirements.
       Required for ASDC onboarding, not needed for manual Openstack testing.
+  - name: OpenStack Heat Testing (Beta)
+    category: openstack
+    description:
+      Uses the latest OpenStack Heat community version available to validate that
+      a heat template is valid OpenStack Heat. This testing is equivalent to using
+      heat template-validate from the command line.
 settings:
   polling-freqency: 1000
   default-verbosity: Standard
index 6df29ca..ae23630 100644 (file)
@@ -49,3 +49,5 @@ jinja2==2.10
 yamllint==1.12.1
 six==1.12.0
 pyinstaller 
+mock
+openstack-heat