text: # Copyright (c) 2016 AT&T Corp
  # All Rights Reserved.
  #
  #    Licensed under the Apache License, Version 2.0 (the "License"); you may
  #    not use this file 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.
  
  import os
  import random
  import semantic_version
  import shutil
  import string
  import tempfile
  from unittest import mock
  
  from murano.packages import exceptions
  from murano.packages import package_base
  import murano.tests.unit.base as test_base
  
  
  class TestPackageBase(test_base.MuranoTestCase):
  
      @classmethod
      def setUpClass(cls):
          super(TestPackageBase, cls).setUpClass()
          package_base.PackageBase.__abstractmethods__ = set()
          cls.source_directory = tempfile.mkdtemp(dir=tempfile.tempdir)
          cls.version = semantic_version.Version.coerce('1.2.3')
          cls.mock_manifest = {
              'Name': 'mock_display_name',
              'FullName': 'mock_full_name',
              'Type': 'Application',
              'Version': '1.2.3',
              'Description': 'test_description',
              'Author': 'test_author',
              'Supplier': 'test_supplier',
              'Tags': ['tag1', 'tag2', 'tag3'],
              'Logo': None
          }
          cls.package_base = package_base.PackageBase('test_format',
                                                      'test_runtime_version',
                                                      cls.source_directory,
                                                      cls.mock_manifest)
  
      @classmethod
      def tearDownClass(cls):
          if os.path.isdir(cls.source_directory):
              shutil.rmtree(cls.source_directory)
  
      def test_create_package_base_without_full_name(self):
          with self.assertRaisesRegex(exceptions.PackageFormatError,
                                      'FullName is not specified'):
              package_base.PackageBase('test_format',
                                       'test_runtime_version',
                                       'test_source_directory',
                                       manifest={'FullName': None})
  
      def test_create_package_base_with_invalid_full_name(self):
          full_names = ['.invalid_name_1', 'invalid..name..2', 'invalid name 3']
          for full_name in full_names:
              expected_error_message = 'Invalid FullName {0}'.format(full_name)
              with self.assertRaisesRegex(exceptions.PackageFormatError,
                                          expected_error_message):
                  package_base.PackageBase('test_format',
                                           'test_runtime_version',
                                           'test_source_directory',
                                           manifest={'FullName': full_name})
  
      def test_create_package_base_with_invalid_type(self):
          package_type = 'Invalid'
          with self.assertRaisesRegex(exceptions.PackageFormatError,
                                      'Invalid package Type {0}'
                                      .format(package_type)):
              package_base.PackageBase('test_format',
                                       'test_runtime_version',
                                       'test_source_directory',
                                       manifest={'FullName': 'mock_full_name',
                                                 'Type': package_type})
  
      def test_requirements_negative(self):
          with self.assertRaisesRegex(NotImplementedError, None):
              self.package_base.requirements
  
      def test_classes_negative(self):
          with self.assertRaisesRegex(NotImplementedError, None):
              self.package_base.classes
  
      def test_get_class_negative(self):
          with self.assertRaisesRegex(NotImplementedError, None):
              self.package_base.get_class(None)
  
      def test_ui_negative(self):
          with self.assertRaisesRegex(NotImplementedError, None):
              self.package_base.ui
  
      def test_full_name(self):
          self.assertEqual(self.mock_manifest['FullName'],
                           self.package_base.full_name)
  
      def test_source_directory(self):
          self.assertEqual(self.source_directory,
                           self.package_base.source_directory)
  
      def test_version(self):
          self.assertEqual(self.version,
                           self.package_base.version)
  
      def test_package_type(self):
          self.assertEqual(self.mock_manifest['Type'],
                           self.package_base.package_type)
  
      def test_display_name(self):
          self.assertEqual(self.mock_manifest['Name'],
                           self.package_base.display_name)
  
      def test_description(self):
          self.assertEqual(self.mock_manifest['Description'],
                           self.package_base.description)
  
      def test_author(self):
          self.assertEqual(self.mock_manifest['Author'],
                           self.package_base.author)
  
      def test_supplier(self):
          self.assertEqual(self.mock_manifest['Supplier'],
                           self.package_base.supplier)
  
      def test_tags(self):
          self.assertEqual(self.mock_manifest['Tags'],
                           self.package_base.tags)
  
      def test_logo_without_file_name(self):
          self.assertIsNone(self.package_base.logo)
  
      def test_logo_with_invalid_logo_path(self):
          expected_error_message = 'Unable to load logo'
          self.package_base._logo = ''.join(random.choice(string.ascii_letters)
                                            for _ in range(10))
          with self.assertRaisesRegex(exceptions.PackageLoadError,
                                      expected_error_message):
              self.package_base.logo
          self.package_base._logo = self.mock_manifest['Logo']
  
      @mock.patch('murano.packages.package_base.imghdr',
                  what=mock.MagicMock(return_value='xyz'))
      def test_load_image_with_invalid_extension(self, mock_imghdr):
          expected_error_message = 'Unsupported Format.'
          with self.assertRaisesRegex(exceptions.PackageLoadError,
                                      expected_error_message):
              self.package_base._load_image('logo.xyz', 'logo.xyz', 'logo')
              full_path = os.path.join(self.package_base._source_directory,
                                       'logo.xyz')
              mock_imghdr.what.assert_called_once_with(full_path)
  
      @mock.patch('murano.packages.package_base.imghdr',
                  what=mock.MagicMock(return_value='png'))
      @mock.patch('murano.packages.package_base.os')
      def test_load_image_with_oversized_image(self, mock_os, mock_imghdr):
          mock_os.stat.return_value = mock.MagicMock(st_size=5000 * 1024)
          mock_os.isfile = mock.MagicMock(return_value=True)
          expected_error_message = 'Max allowed size is {0}'.format(500 * 1024)
          with self.assertRaisesRegex(exceptions.PackageLoadError,
                                      expected_error_message):
              self.package_base._load_image('logo.xyz', 'logo.xyz', 'logo')
  
      def test_meta(self):
          self.assertIsNone(self.package_base.meta)
  
      def test_get_resource(self):
          test_name = 'test_resource_name'
          expected_dir = os.path.join(self.source_directory, 'Resources',
                                      test_name)
          self.assertEqual(expected_dir, self.package_base.get_resource(
              test_name))
  