From 809f7c0580b10a2e211e128b4f90f4e30936c0ca Mon Sep 17 00:00:00 2001
From: Yasufumi Ogawa <yasufum.o@gmail.com>
Date: Fri, 21 Jun 2024 21:51:56 +0900
Subject: [PATCH] Mock replacement for unit tests with external URL

This patch replaces unit tests that reference external URL with Mocks
that use internal files. This is because the test fails if the external
URL destination file is moved.

Depends-On: https://review.opendev.org/c/openstack/tosca-parser/+/924703
Change-Id: Ifb9bca3e9011942f33c550d19c53df140beff1a3
Signed-off-by: Yasufumi Ogawa <yasufum.o@gmail.com>
Co-Authored-By: Yoshiro Watanabe <fj3838ct@fujitsu.com>
---
 translator/osc/v1/tests/test_translate.py     | 72 ++++++++++++-----
 ...le_instance_wordpress_with_url_import.yaml |  2 +-
 .../tests/test_tosca_hot_translation.py       | 80 ++++++++++++++-----
 3 files changed, 109 insertions(+), 45 deletions(-)

diff --git a/translator/osc/v1/tests/test_translate.py b/translator/osc/v1/tests/test_translate.py
index 67bcf9cf..306bfe91 100644
--- a/translator/osc/v1/tests/test_translate.py
+++ b/translator/osc/v1/tests/test_translate.py
@@ -10,6 +10,7 @@
 #   License for the specific language governing permissions and limitations
 #   under the License.
 
+import os
 import testtools
 from unittest import mock
 
@@ -19,9 +20,11 @@ except ImportError:
     from io import StringIO
 import toscaparser.utils.yamlparser
 
+import toscaparser
 from toscaparser.common.exception import ExceptionCollector
 from toscaparser.common.exception import URLException
 from toscaparser.common.exception import ValidationError
+from toscaparser.tosca_template import ToscaTemplate
 from toscaparser.utils.gettextutils import _
 from translator.common.utils import CompareUtils
 from translator.common.utils import YamlUtils
@@ -305,7 +308,8 @@ class TestTranslateTemplate(testtools.TestCase):
         params = {'cpus': '2', 'context_root': 'my_web_app'}
         self._check_success(tosca_file, hot_file, params)
 
-    def test_osc_translate_template_with_url_import(self):
+    @mock.patch.object(translate.ToscaTemplate, '_tpl_imports')
+    def test_osc_translate_template_with_url_import(self, mock_tpl_imports):
         tosca_file = utils.get_template_path(
             "tosca_single_instance_wordpress_with_url_import.yaml")
         hot_file = utils.get_template_path(
@@ -316,12 +320,15 @@ class TestTranslateTemplate(testtools.TestCase):
                   'db_root_pwd': 'passw0rd',
                   'db_port': 3366,
                   'cpus': 8}
+        import_file_path = utils.get_template_path(
+            "custom_types/wordpress.yaml")
+        mock_tpl_imports.return_value = [import_file_path]
         self._check_success(tosca_file, hot_file, params)
 
-    def test_osc_translate_template_by_url_with_local_import(self):
-        tosca_file = ("https://raw.githubusercontent.com/openstack/" +
-                      "heat-translator/master/translator/tests/data/" +
-                      "tosca_single_instance_wordpress.yaml")
+    @mock.patch.object(translate, 'ToscaTemplate')
+    def test_osc_translate_template_by_url_with_local_import(
+        self, mock_tosca_template):
+        tosca_file = "https://example.com/tosca_single_instance_wordpress.yaml"
         hot_file = utils.get_template_path(
             "hot_output/" +
             "hot_single_instance_wordpress.yaml")
@@ -331,13 +338,19 @@ class TestTranslateTemplate(testtools.TestCase):
                   'db_root_pwd': 'passw0rd',
                   'db_port': 3366,
                   'cpus': 8}
+        file_path = utils.get_template_path(
+            "tosca_single_instance_wordpress.yaml")
+        mock_tosca_template.return_value = ToscaTemplate(
+            file_path, params, True)
         self._check_success(tosca_file, hot_file, params)
 
-    def test_osc_translate_template_by_url_with_local_abspath_import(self):
-        tosca_file = ("https://raw.githubusercontent.com/openstack/" +
-                      "heat-translator/master/translator/tests/data/" +
-                      "tosca_single_instance_wordpress_with_local_abspath" +
-                      "_import.yaml")
+    @mock.patch.object(toscaparser.utils.urlutils.UrlUtils, 'validate_url')
+    @mock.patch.object(os.path, 'isfile')
+    @mock.patch.object(ToscaTemplate, '_get_path')
+    def test_osc_translate_template_by_url_with_local_abspath_import(
+        self, mock_get_path, mock_isfile, mock_validate_url):
+        tosca_file = ("https://example.com/tosca_single_instance_wordpress_"
+                      "with_local_abspath_import.yaml")
         hot_file = utils.get_template_path(
             "hot_output/" +
             "hot_single_instance_wordpress.yaml")
@@ -347,19 +360,23 @@ class TestTranslateTemplate(testtools.TestCase):
                   'db_root_pwd': 'passw0rd',
                   'db_port': 3366,
                   'cpus': 8}
+        file_path = utils.get_template_path(
+            'tosca_single_instance_wordpress_with_local_abspath_import.yaml')
+        mock_get_path.return_value = file_path
+        mock_isfile.return_value = True
+        mock_validate_url.side_effect = [False, True, False, True]
 
-        expected_msg = _('Absolute file name "/tmp/wordpress.yaml" cannot be '
-                         'used in a URL-based input template "https://raw.'
-                         'githubusercontent.com/openstack/heat-translator/'
-                         'master/translator/tests/data/tosca_single_instance_'
-                         'wordpress_with_local_abspath_import.yaml".')
+        expected_msg = ('Absolute file name "/tmp/wordpress.yaml" cannot be '
+                        f'used in a URL-based input template "{file_path}".')
         self._check_error(tosca_file, hot_file, params, ValidationError,
                           expected_msg, ImportError)
 
-    def test_osc_translate_template_by_url_with_url_import(self):
-        tosca_url = ("https://raw.githubusercontent.com/openstack/" +
-                     "heat-translator/master/translator/tests/data/" +
-                     "tosca_single_instance_wordpress_with_url_import.yaml")
+    @mock.patch.object(translate.ToscaTemplate, '_tpl_imports')
+    @mock.patch.object(translate, 'ToscaTemplate')
+    def test_osc_translate_template_by_url_with_url_import(
+        self, mock_tosca_template, mock_tpl_imports):
+        tosca_url = ("https://example.com/tosca_single_instance_wordpress_"
+                     "with_url_import.yaml")
         hot_file = utils.get_template_path(
             "hot_output/" +
             "hot_single_instance_wordpress.yaml")
@@ -369,6 +386,13 @@ class TestTranslateTemplate(testtools.TestCase):
                   'db_root_pwd': 'passw0rd',
                   'db_port': 3366,
                   'cpus': 8}
+        file_path = utils.get_template_path(
+            "tosca_single_instance_wordpress_with_url_import.yaml")
+        import_file_path = utils.get_template_path(
+            "custom_types/wordpress.yaml")
+        mock_tpl_imports.return_value = [import_file_path]
+        mock_tosca_template.return_value = ToscaTemplate(
+            file_path, params, True)
         self._check_success(tosca_url, hot_file, params)
 
     def test_osc_translate_hello_world_csar(self):
@@ -391,14 +415,18 @@ class TestTranslateTemplate(testtools.TestCase):
                   'cpus': 8}
         self._check_success(tosca_file, hot_file, params)
 
-    def test_osc_translate_elk_csar_from_url(self):
-        tosca_file = ("https://github.com/openstack/heat-translator/raw/" +
-                      "master/translator/tests/data/csar_elk.zip")
+    @mock.patch.object(translate, 'ToscaTemplate')
+    def test_osc_translate_elk_csar_from_url(
+        self, mock_tosca_template):
+        tosca_file = "https://example.com/csar_elk.zip"
         hot_file = utils.get_template_path(
             "hot_output/hot_elk_from_csar.yaml")
         params = {'github_url':
                   'http://github.com/paypal/rest-api-sample-app-nodejs.git',
                   'my_cpus': 4}
+        zip_file_path = utils.get_template_path("csar_elk.zip")
+        mock_tosca_template.return_value = ToscaTemplate(
+            zip_file_path, params, True)
         self._check_success(tosca_file, hot_file, params)
 
     def test_osc_translate_csar_not_zip(self):
diff --git a/translator/tests/data/tosca_single_instance_wordpress_with_url_import.yaml b/translator/tests/data/tosca_single_instance_wordpress_with_url_import.yaml
index 69dbfebc..024ba3ff 100644
--- a/translator/tests/data/tosca_single_instance_wordpress_with_url_import.yaml
+++ b/translator/tests/data/tosca_single_instance_wordpress_with_url_import.yaml
@@ -4,7 +4,7 @@ description: >
   TOSCA simple profile with wordpress, web server and mysql on the same server.
 
 imports:
-  - https://raw.githubusercontent.com/openstack/heat-translator/master/translator/tests/data/custom_types/wordpress.yaml
+  - https://example.com/custom_types/wordpress.yaml
 
 topology_template:
   inputs:
diff --git a/translator/tests/test_tosca_hot_translation.py b/translator/tests/test_tosca_hot_translation.py
index 21d9fd03..9cddee92 100644
--- a/translator/tests/test_tosca_hot_translation.py
+++ b/translator/tests/test_tosca_hot_translation.py
@@ -12,7 +12,9 @@
 
 import json
 import os
+from unittest import mock
 
+import toscaparser
 from toscaparser.common.exception import ExceptionCollector
 from toscaparser.common.exception import URLException
 from toscaparser.common.exception import ValidationError
@@ -264,7 +266,8 @@ class ToscaHotTranslationTest(TestCase):
         params = {'cpus': '2', 'context_root': 'my_web_app'}
         self._test_successful_translation(tosca_file, hot_file, params)
 
-    def test_hot_translate_template_with_url_import(self):
+    @mock.patch.object(ToscaTemplate, '_tpl_imports')
+    def test_hot_translate_template_with_url_import(self, mock_tpl_imports):
         tosca_file = '../tests/data/' \
                      'tosca_single_instance_wordpress_with_url_import.yaml'
         hot_file = '../tests/data/hot_output/' \
@@ -275,12 +278,16 @@ class ToscaHotTranslationTest(TestCase):
                   'db_root_pwd': 'passw0rd',
                   'db_port': 3366,
                   'cpus': 8}
+        import_file_path = os.path.normpath(os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "../tests/data/custom_types/wordpress.yaml"))
+        mock_tpl_imports.return_value = [import_file_path]
         self._test_successful_translation(tosca_file, hot_file, params)
 
-    def test_hot_translate_template_by_url_with_local_import(self):
-        tosca_file = 'https://raw.githubusercontent.com/openstack/' \
-                     'heat-translator/master/translator/tests/data/' \
-                     'tosca_single_instance_wordpress.yaml'
+    @mock.patch.object(toscaparser.tosca_template, 'ToscaTemplate')
+    def test_hot_translate_template_by_url_with_local_import(
+        self, mock_tosca_template):
+        tosca_file = "https://example.com/tosca_single_instance_wordpress.yaml"
         hot_file = '../tests/data/hot_output/' \
                    'hot_single_instance_wordpress.yaml'
         params = {'db_name': 'wordpress',
@@ -289,13 +296,20 @@ class ToscaHotTranslationTest(TestCase):
                   'db_root_pwd': 'passw0rd',
                   'db_port': 3366,
                   'cpus': 8}
+        file_path = os.path.normpath(os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "../tests/data/tosca_single_instance_wordpress.yaml"))
+        mock_tosca_template.return_value = ToscaTemplate(
+            file_path, params, True)
         self._test_successful_translation(tosca_file, hot_file, params)
 
-    def test_hot_translate_template_by_url_with_local_abspath_import(self):
-        tosca_file = 'https://raw.githubusercontent.com/openstack/' \
-                     'heat-translator/master/translator/tests/data/' \
-                     'tosca_single_instance_wordpress_with_local_abspath' \
-                     '_import.yaml'
+    @mock.patch.object(toscaparser.utils.urlutils.UrlUtils, 'validate_url')
+    @mock.patch.object(os.path, 'isfile')
+    @mock.patch.object(ToscaTemplate, '_get_path')
+    def test_hot_translate_template_by_url_with_local_abspath_import(
+        self, mock_get_path, mock_isfile, mock_validate_url):
+        tosca_file = ("https://example.com/tosca_single_instance_wordpress_"
+                      "with_local_abspath_import.yaml")
         hot_file = '../tests/data/hot_output/' \
                    'hot_single_instance_wordpress.yaml'
         params = {'db_name': 'wordpress',
@@ -304,20 +318,27 @@ class ToscaHotTranslationTest(TestCase):
                   'db_root_pwd': 'passw0rd',
                   'db_port': 3366,
                   'cpus': 8}
-        expected_msg = _('Absolute file name "/tmp/wordpress.yaml" cannot be '
-                         'used in a URL-based input template "https://raw.'
-                         'githubusercontent.com/openstack/heat-translator/'
-                         'master/translator/tests/data/tosca_single_instance_'
-                         'wordpress_with_local_abspath_import.yaml".')
+        file_path = os.path.normpath(os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "../tests/data/tosca_single_instance_wordpress_with_local_"
+            "abspath_import.yaml"))
+        mock_get_path.return_value = file_path
+        mock_isfile.return_value = True
+        mock_validate_url.side_effect = [False, True, False, True]
+
+        expected_msg = ('Absolute file name "/tmp/wordpress.yaml" cannot be '
+                        f'used in a URL-based input template "{file_path}".')
         msg_path = False
         self._test_failed_translation(tosca_file, hot_file, params,
                                       expected_msg, msg_path, ValidationError,
                                       ImportError)
 
-    def test_hot_translate_template_by_url_with_url_import(self):
-        tosca_url = 'https://raw.githubusercontent.com/openstack/' \
-                    'heat-translator/master/translator/tests/data/' \
-                    'tosca_single_instance_wordpress_with_url_import.yaml'
+    @mock.patch.object(ToscaTemplate, '_tpl_imports')
+    @mock.patch.object(toscaparser.tosca_template, 'ToscaTemplate')
+    def test_hot_translate_template_by_url_with_url_import(
+        self, mock_tosca_template, mock_tpl_imports):
+        tosca_url = ("https://example.com/tosca_single_instance_wordpress_"
+                     "with_url_import.yaml")
         hot_file = '../tests/data/hot_output/' \
                    'hot_single_instance_wordpress.yaml'
         params = {'db_name': 'wordpress',
@@ -326,6 +347,16 @@ class ToscaHotTranslationTest(TestCase):
                   'db_root_pwd': 'passw0rd',
                   'db_port': 3366,
                   'cpus': 8}
+        file_path = os.path.normpath(os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "../tests/data/tosca_single_instance_wordpress_with_url_"
+            "import.yaml"))
+        import_file_path = os.path.normpath(os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "../tests/data/custom_types/wordpress.yaml"))
+        mock_tpl_imports.return_value = [import_file_path]
+        mock_tosca_template.return_value = ToscaTemplate(
+            file_path, params, True)
         self._test_successful_translation(tosca_url, hot_file, params)
 
     def test_translate_hello_world_csar(self):
@@ -345,13 +376,18 @@ class ToscaHotTranslationTest(TestCase):
                   'cpus': 8}
         self._test_successful_translation(tosca_file, hot_file, params)
 
-    def test_translate_elk_csar_from_url(self):
-        tosca_file = 'https://github.com/openstack/heat-translator/raw/' \
-                     'master/translator/tests/data/csar_elk.zip'
+    @mock.patch.object(toscaparser.tosca_template, 'ToscaTemplate')
+    def test_translate_elk_csar_from_url(self, mock_tosca_template):
+        tosca_file = "https://example.com/csar_elk.zip"
         hot_file = '../tests/data/hot_output/hot_elk_from_csar.yaml'
         params = {'github_url':
                   'http://github.com/paypal/rest-api-sample-app-nodejs.git',
                   'my_cpus': 4}
+        zip_file_path = os.path.normpath(os.path.join(
+            os.path.dirname(os.path.abspath(__file__)),
+            "../tests/data/csar_elk.zip"))
+        mock_tosca_template.return_value = ToscaTemplate(
+            zip_file_path, params, True)
         self._test_successful_translation(tosca_file, hot_file, params)
 
     def test_translate_csar_not_zip(self):