From def8df76745b5d33df207838a00c5945542032f3 Mon Sep 17 00:00:00 2001 From: Vahid Hashemian Date: Wed, 7 Oct 2015 14:33:11 -0700 Subject: [PATCH] Fix error message for invalid CSAR URLs Fix the error reported when the CSAR referenced by URL is not valid. And add a test case to verify the fix. Change-Id: I2d85e449e3f46f5ce57d748b51d25c1c69128169 Closes-Bug: #1502967 --- toscaparser/prereq/csar.py | 59 ++++++++++++++++---------------- toscaparser/tests/test_prereq.py | 42 +++++++++++++---------- 2 files changed, 54 insertions(+), 47 deletions(-) diff --git a/toscaparser/prereq/csar.py b/toscaparser/prereq/csar.py index 898931e..19479f0 100644 --- a/toscaparser/prereq/csar.py +++ b/toscaparser/prereq/csar.py @@ -32,48 +32,49 @@ except ImportError: # Python 3.x class CSAR(object): def __init__(self, csar_file, a_file=True): - self.csar_file = csar_file + self.path = csar_file self.a_file = a_file self.is_validated = False + self.csar = None def validate(self): """Validate the provided CSAR file.""" self.is_validated = True - # validate that the file exists - if self.a_file and not os.path.isfile(self.csar_file): - err_msg = (_('The file %s does not exist.') % self.csar_file) - raise ValidationError(message=err_msg) - - if not self.a_file: # a URL - if not UrlUtils.validate_url(self.csar_file): - err_msg = (_('The URL %s does not exist.') % self.csar_file) - raise ValidationError(message=err_msg) + # validate that the file or URL exists + missing_err_msg = (_('%s does not exist.') % self.path) + if self.a_file: + if not os.path.isfile(self.path): + raise ValidationError(message=missing_err_msg) else: - response = requests.get(self.csar_file) - self.csar_file = BytesIO(response.content) + self.csar = self.path + else: # a URL + if not UrlUtils.validate_url(self.path): + raise ValidationError(message=missing_err_msg) + else: + response = requests.get(self.path) + self.csar = BytesIO(response.content) # validate that it is a valid zip file - if not zipfile.is_zipfile(self.csar_file): - err_msg = (_('The file %s is not a valid zip file.') - % self.csar_file) + if not zipfile.is_zipfile(self.csar): + err_msg = (_('%s is not a valid zip file.') % self.path) raise ValidationError(message=err_msg) # validate that it contains the metadata file in the correct location - self.zfile = zipfile.ZipFile(self.csar_file, 'r') + self.zfile = zipfile.ZipFile(self.csar, 'r') filelist = self.zfile.namelist() if 'TOSCA-Metadata/TOSCA.meta' not in filelist: - err_msg = (_('The file %s is not a valid CSAR as it does not ' - 'contain the required file "TOSCA.meta" in the ' - 'folder "TOSCA-Metadata".') % self.csar_file) + err_msg = (_('%s is not a valid CSAR as it does not contain the ' + 'required file "TOSCA.meta" in the folder ' + '"TOSCA-Metadata".') % self.path) raise ValidationError(message=err_msg) # validate that 'Entry-Definitions' property exists in TOSCA.meta data = self.zfile.read('TOSCA-Metadata/TOSCA.meta') - invalid_yaml_err_msg = (_('The file "TOSCA-Metadata/TOSCA.meta" in %s ' - 'does not contain valid YAML content.') % - self.csar_file) + invalid_yaml_err_msg = (_('The file "TOSCA-Metadata/TOSCA.meta" in ' + 'the CSAR %s does not contain valid YAML ' + 'content.') % self.path) try: meta = yaml.load(data) if type(meta) is not dict: @@ -83,9 +84,9 @@ class CSAR(object): raise ValidationError(message=invalid_yaml_err_msg) if 'Entry-Definitions' not in self.metadata: - err_msg = (_('The CSAR file "%s" is missing the required metadata ' + err_msg = (_('The CSAR %s is missing the required metadata ' '"Entry-Definitions" in "TOSCA-Metadata/TOSCA.meta".') - % self.csar_file) + % self.path) raise ValidationError(message=err_msg) # validate that 'Entry-Definitions' metadata value points to an @@ -93,7 +94,7 @@ class CSAR(object): entry = self.metadata['Entry-Definitions'] if entry not in filelist: err_msg = (_('The "Entry-Definitions" file defined in the CSAR ' - '"%s" does not exist.') % self.csar_file) + '%s does not exist.') % self.path) raise ValidationError(message=err_msg) # validate that external references in the main template actually exist @@ -128,9 +129,9 @@ class CSAR(object): main_template = self.get_main_template() data = self.zfile.read(main_template) invalid_tosca_yaml_err_msg = ( - _('The file %(template)s in %(csar)s does not contain valid TOSCA ' - 'YAML content.') % {'template': main_template, - 'csar': self.csar_file}) + _('The file %(template)s in the CSAR %(csar)s does not contain ' + 'valid TOSCA YAML content.') % {'template': main_template, + 'csar': self.path}) try: tosca_yaml = yaml.load(data) if type(tosca_yaml) is not dict: @@ -152,7 +153,7 @@ class CSAR(object): if not self.is_validated: self.validate() folder = tempfile.NamedTemporaryFile().name - with zipfile.ZipFile(self.csar_file, "r") as zf: + with zipfile.ZipFile(self.csar, "r") as zf: zf.extractall(folder) return folder diff --git a/toscaparser/tests/test_prereq.py b/toscaparser/tests/test_prereq.py index f1ba365..fecaa5a 100644 --- a/toscaparser/tests/test_prereq.py +++ b/toscaparser/tests/test_prereq.py @@ -29,40 +29,46 @@ class CSARPrereqTest(TestCase): path = os.path.join(self.base_path, "data/CSAR/csar_not_there.zip") csar = CSAR(path) error = self.assertRaises(ValidationError, csar.validate) - self.assertEqual(_('The file %s does not exist.') % path, str(error)) + self.assertEqual(_('%s does not exist.') % path, str(error)) def test_file_is_zip(self): path = os.path.join(self.base_path, "data/CSAR/csar_not_zip.zip") csar = CSAR(path) error = self.assertRaises(ValidationError, csar.validate) - self.assertEqual(_('The file %s is not a valid zip file.') % path, - str(error)) + self.assertEqual(_('%s is not a valid zip file.') % path, str(error)) + + def test_url_is_zip(self): + path = "https://github.com/openstack/tosca-parser/raw/master/" \ + "toscaparser/tests/data/CSAR/csar_not_zip.zip" + csar = CSAR(path, False) + error = self.assertRaises(ValidationError, csar.validate) + self.assertEqual(_('%s is not a valid zip file.') % path, str(error)) def test_metadata_file_exists(self): path = os.path.join(self.base_path, "data/CSAR/csar_no_metadata_file.zip") csar = CSAR(path) error = self.assertRaises(ValidationError, csar.validate) - self.assertEqual(_('The file %s is not a valid CSAR as it does not ' - 'contain the required file "TOSCA.meta" in the ' - 'folder "TOSCA-Metadata".') % path, str(error)) + self.assertEqual(_('%s is not a valid CSAR as it does not contain the ' + 'required file "TOSCA.meta" in the folder ' + '"TOSCA-Metadata".') % path, str(error)) def test_valid_metadata_file_exists(self): path = os.path.join(self.base_path, "data/CSAR/csar_wrong_metadata_file.zip") csar = CSAR(path) error = self.assertRaises(ValidationError, csar.validate) - self.assertEqual(_('The file %s is not a valid CSAR as it does not ' - 'contain the required file "TOSCA.meta" in the ' - 'folder "TOSCA-Metadata".') % path, str(error)) + self.assertEqual(_('%s is not a valid CSAR as it does not contain the ' + 'required file "TOSCA.meta" in the folder ' + '"TOSCA-Metadata".') % path, str(error)) def test_metadata_is_yaml(self): path = os.path.join(self.base_path, "data/CSAR/csar_metadata_not_yaml.zip") csar = CSAR(path) error = self.assertRaises(ValidationError, csar.validate) - self.assertEqual(_('The file "TOSCA-Metadata/TOSCA.meta" in %s does ' - 'not contain valid YAML content.') % path, + self.assertEqual(_('The file "TOSCA-Metadata/TOSCA.meta" in the CSAR ' + '%s does not contain valid YAML content.') % path, str(error)) def test_metadata_exists(self): @@ -70,8 +76,8 @@ class CSARPrereqTest(TestCase): "data/CSAR/csar_missing_metadata.zip") csar = CSAR(path) error = self.assertRaises(ValidationError, csar.validate) - self.assertEqual(_('The CSAR file "%s" is missing the required ' - 'metadata "Entry-Definitions" in ' + self.assertEqual(_('The CSAR %s is missing the required metadata ' + '"Entry-Definitions" in ' '"TOSCA-Metadata/TOSCA.meta".') % path, str(error)) def test_entry_def_exists(self): @@ -80,7 +86,7 @@ class CSARPrereqTest(TestCase): csar = CSAR(path) error = self.assertRaises(ValidationError, csar.validate) self.assertEqual(_('The "Entry-Definitions" file defined in the CSAR ' - '"%s" does not exist.') % path, str(error)) + '%s does not exist.') % path, str(error)) def test_csar_invalid_import_path(self): path = os.path.join(self.base_path, @@ -141,8 +147,8 @@ class CSARPrereqTest(TestCase): "data/CSAR/csar_metadata_not_yaml.zip") csar = CSAR(path) error = self.assertRaises(ValidationError, csar.get_author) - self.assertEqual(_('The file "TOSCA-Metadata/TOSCA.meta" in %s does ' - 'not contain valid YAML content.') % path, + self.assertEqual(_('The file "TOSCA-Metadata/TOSCA.meta" in the CSAR ' + '%s does not contain valid YAML content.') % path, str(error)) def test_metadata_valid_csar(self): @@ -153,8 +159,8 @@ class CSARPrereqTest(TestCase): 'Created-By': 'OASIS TOSCA TC', 'Entry-Definitions': 'tosca_helloworld.yaml'} self.assertEqual(expected_meta, csar.get_metadata(), - 'The extracted metadata of the CSAR file %(csar)s ' - 'does not match the expected metadata %(meta)s' + 'The extracted metadata of the CSAR %(csar)s does ' + 'not match the expected metadata %(meta)s' % {'csar': path, 'meta': expected_meta.__str__()}) self.assertEqual(1.1, csar.get_version()) self.assertEqual('OASIS TOSCA TC', csar.get_author())