# -*- coding: utf-8 -*- # Copyright 2014 Mirantis, Inc. # # 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. from __future__ import unicode_literals import mock import os from os.path import join as join_path from fuel_plugin_builder.actions.build import BaseBuildPlugin from fuel_plugin_builder.actions.build import BuildPluginV1 from fuel_plugin_builder.actions.build import BuildPluginV2 from fuel_plugin_builder.actions.build import BuildPluginV3 from fuel_plugin_builder import errors from fuel_plugin_builder.tests.base import BaseTestCase class BaseBuild(BaseTestCase): # Prevent test runner to run tests in base __test__ = False # Redefine class builder_class = None releases = [ {'os': 'ubuntu', 'deployment_scripts_path': 'deployment_scripts_path', 'repository_path': 'repository_path'}] def setUp(self): self.plugins_name = 'fuel_plugin' self.plugin_path = '/tmp/{0}'.format(self.plugins_name) self.builder = self.create_builder(self.plugin_path) def create_builder(self, plugin_path, meta=None): meta = meta or self.meta with mock.patch( 'fuel_plugin_builder.actions.build.utils.parse_yaml', return_value=meta): return self.builder_class(plugin_path) def test_run(self): mocked_methods = [ 'clean', 'run_pre_build_hook', 'check', 'build_repos', 'add_checksums_file', 'make_package'] self.mock_methods(self.builder, mocked_methods) self.builder.run() self.builder.clean.assert_called_once_with() self.builder.run_pre_build_hook.assert_called_once_with() self.builder.check.assert_called_once_with() self.builder.add_checksums_file() self.builder.build_repos.assert_called_once_with() self.builder.make_package() @mock.patch('fuel_plugin_builder.actions.build.utils.which') @mock.patch('fuel_plugin_builder.actions.build.utils.exec_cmd', return_value=True) def test_run_pre_build_hook(self, exec_cmd_mock, which_mock): self.builder.run_pre_build_hook() exec_cmd_mock.assert_called_once_with(self.builder.pre_build_hook_cmd, self.builder.plugin_path) which_mock.assert_called_once_with( join_path(self.builder.plugin_path, self.builder.pre_build_hook_cmd)) @mock.patch('fuel_plugin_builder.actions.build.utils') def test_build_repos(self, utils_mock): with mock.patch.object( self.builder_class, 'build_ubuntu_repos') as build_ubuntu_mock: with mock.patch.object( self.builder_class, 'build_centos_repos') as build_centos_mock: self.builder.build_repos() utils_mock.create_dir.assert_called_once_with( self.builder.build_src_dir) utils_mock.copy_files_in_dir.assert_called_once_with( '/tmp/fuel_plugin/*', self.builder.build_src_dir) build_centos_mock.assert_called_once_with([]) build_ubuntu_mock.assert_called_once_with([ '/tmp/fuel_plugin/.build/src/repository_path']) @mock.patch('fuel_plugin_builder.actions.build.utils') def test_build_ubuntu_repos(self, utils_mock): path = '/repo/path' self.builder.build_ubuntu_repos([path]) utils_mock.exec_piped_cmds.assert_called_once_with( ['dpkg-scanpackages .', 'gzip -c9 > Packages.gz'], cwd=path) @mock.patch('fuel_plugin_builder.actions.build.utils') def test_build_centos_repos(self, utils_mock): path = '/repo/path' self.builder.build_centos_repos([path]) utils_mock.create_dir.assert_called_once_with( '/repo/path/Packages') utils_mock.move_files_in_dir.assert_called_once_with( '/repo/path/*.rpm', '/repo/path/Packages') utils_mock.exec_cmd.assert_called_once_with( 'createrepo -o /repo/path /repo/path') @mock.patch.object(BaseBuildPlugin, '_check_requirements') @mock.patch.object(BaseBuildPlugin, '_check_structure') def test_check(self, check_structure_mock, check_requirements_mock): self.builder.check() check_structure_mock.assert_called_once_with() check_requirements_mock.assert_called_once_with() @mock.patch('fuel_plugin_builder.actions.build.utils.which', return_value=True) def test_check_requirements(self, _): self.builder._check_requirements() @mock.patch('fuel_plugin_builder.actions.build.ValidatorManager') def test_check_structure(self, manager_class_mock): validator_manager_obj = mock.MagicMock() manager_class_mock.return_value = validator_manager_obj validator_mock = mock.MagicMock() validator_manager_obj.get_validator.return_value = validator_mock self.builder._check_structure() manager_class_mock.assert_called_once_with(self.plugin_path) validator_manager_obj.get_validator.assert_called_once_with() validator_mock.validate.assert_called_once_with() @mock.patch( 'fuel_plugin_builder.actions.build.utils.create_checksums_file') def test_add_checksums_file(self, create_checksums_file_mock): self.builder.add_checksums_file() create_checksums_file_mock.assert_called_once_with( self.builder.build_src_dir, self.builder.checksums_path) @mock.patch('fuel_plugin_builder.actions.build.utils') def test_clean(self, utils_mock): self.builder.clean() utils_mock.assert_has_calls([ mock.call.remove(self.builder.build_dir), mock.call.create_dir(self.builder.build_dir), mock.call.remove_by_mask(self.builder.result_package_mask)]) class TestBaseBuildV1(BaseBuild): __test__ = True builder_class = BuildPluginV1 meta = { 'releases': BaseBuild.releases, 'version': '1.2.3', 'name': 'plugin_name' } @mock.patch('fuel_plugin_builder.actions.build.utils') def test_make_package(self, utils_mock): self.builder.make_package() tar_path = '/tmp/fuel_plugin/plugin_name-1.2.3.fp' utils_mock.make_tar_gz.assert_called_once_with( self.builder.build_src_dir, tar_path, 'plugin_name-1.2.3') @mock.patch('fuel_plugin_builder.actions.build.utils.which', return_value=False) def test_check_requirements_raises_error(self, _): self.assertRaisesRegexp( errors.FuelCannotFindCommandError, 'Cannot find commands "rpm, createrepo, dpkg-scanpackages", ' 'install required commands and try again', self.builder._check_requirements) class TestBaseBuildV2(BaseBuild): __test__ = True builder_class = BuildPluginV2 meta = { 'releases': BaseBuild.releases, 'version': '1.2.3', 'name': 'plugin_name', 'title': 'Plugin title', 'description': 'Description', 'licenses': ['Apache', 'BSD'], 'authors': ['author1', 'author2'], 'homepage': 'url' } def path_from_plugin(self, plugin_path, path): return join_path(plugin_path, path) @mock.patch('fuel_plugin_builder.actions.build.utils') def check_make_package(self, builder, plugin_path, utils_mock): plugin_path = plugin_path utils_mock.get_current_year.return_value = '2014' builder.make_package() rpm_src_path = self.path_from_plugin(plugin_path, '.build/rpm/SOURCES') utils_mock.create_dir.assert_called_once_with(rpm_src_path) fp_dst = self.path_from_plugin( plugin_path, '.build/rpm/SOURCES/plugin_name-1.2.fp') utils_mock.make_tar_gz.assert_called_once_with( self.path_from_plugin(plugin_path, '.build/src'), fp_dst, 'plugin_name-1.2') spec_src = os.path.abspath(join_path( os.path.dirname(__file__), '..', self.builder.rpm_spec_src_path)) utils_mock.render_to_file.assert_called_once_with( spec_src, join_path(plugin_path, '.build/rpm/plugin_rpm.spec'), {'vendor': 'author1, author2', 'description': 'Description', 'license': 'Apache and BSD', 'summary': 'Plugin title', 'version': '1.2.3', 'homepage': 'url', 'name': 'plugin_name-1.2', 'year': '2014'}) utils_mock.exec_cmd.assert_called_once_with( 'rpmbuild -vv --nodeps --define "_topdir {0}" -bb ' '{1}'.format( self.path_from_plugin(plugin_path, '.build/rpm'), self.path_from_plugin(plugin_path, '.build/rpm/plugin_rpm.spec'))) utils_mock.copy_files_in_dir.assert_called_once_with( self.path_from_plugin(plugin_path, '.build/rpm/RPMS/noarch/*.rpm'), plugin_path ) def test_make_package(self): self.check_make_package(self.builder, self.plugin_path) def test_make_package_with_non_ascii_chars_in_path(self): plugin_path = '/tmp/ั‚ะตัั‚/' + self.plugins_name builder = self.create_builder(plugin_path) self.check_make_package(builder, plugin_path) @mock.patch('fuel_plugin_builder.actions.build.utils.which', return_value=False) def test_check_requirements_raises_error(self, _): self.assertRaisesRegexp( errors.FuelCannotFindCommandError, 'Cannot find commands "rpmbuild, rpm, createrepo, ' 'dpkg-scanpackages", install required commands and try again', self.builder._check_requirements) @mock.patch('fuel_plugin_builder.actions.build.utils') def test_build_ubuntu_repos(self, utils_mock): path = '/repo/path' self.builder.build_ubuntu_repos([path]) utils_mock.exec_piped_cmds.assert_called_once_with( ['dpkg-scanpackages .', 'gzip -c9 > Packages.gz'], cwd=path) release_src = os.path.abspath(join_path( os.path.dirname(__file__), '..', self.builder.release_tmpl_src_path)) utils_mock.render_to_file.assert_called_once_with( release_src, '/repo/path/Release', {'major_version': '1.2', 'plugin_name': 'plugin_name'}) class TestBaseBuildV3(BaseBuild): __test__ = True builder_class = BuildPluginV3 meta = { 'releases': BaseBuild.releases, 'version': '1.2.3', 'name': 'plugin_name', 'title': 'Plugin title', 'description': 'Description', 'licenses': ['Apache', 'BSD'], 'authors': ['author1', 'author2'], 'homepage': 'url' } def path_from_plugin(self, path): return join_path(self.plugin_path, path) @mock.patch('fuel_plugin_builder.actions.build.utils') def _test_make_package(self, utils_mock): utils_mock.get_current_year.return_value = '2014' utils_mock.read_if_exist.side_effect = ['echo uninst', 'echo preinst', 'echo postinst'] self.builder.make_package() rpm_src_path = self.path_from_plugin('.build/rpm/SOURCES') utils_mock.create_dir.assert_called_once_with(rpm_src_path) fp_dst = self.path_from_plugin('.build/rpm/SOURCES/plugin_name-1.2.fp') utils_mock.make_tar_gz.assert_called_once_with( self.path_from_plugin('.build/src'), fp_dst, 'plugin_name-1.2') utils_mock.exec_cmd.assert_called_once_with( 'rpmbuild -vv --nodeps --define "_topdir {0}" -bb ' '{1}'.format( self.path_from_plugin('.build/rpm'), self.path_from_plugin('.build/rpm/plugin_rpm.spec'))) utils_mock.copy_files_in_dir.assert_called_once_with( self.path_from_plugin('.build/rpm/RPMS/noarch/*.rpm'), self.plugin_path) utils_mock.read_if_exist.assert_has_calls([ mock.call(self.path_from_plugin('uninstall.sh')), mock.call(self.path_from_plugin('pre_install.sh')), mock.call(self.path_from_plugin('post_install.sh'))]) return utils_mock def test_make_package(self): utils_mock = self._test_make_package() spec_src = os.path.abspath(join_path( os.path.dirname(__file__), '..', self.builder.rpm_spec_src_path)) utils_mock.render_to_file.assert_called_once_with( spec_src, join_path(self.plugin_path, '.build/rpm/plugin_rpm.spec'), {'vendor': 'author1, author2', 'description': 'Description', 'license': 'Apache and BSD', 'summary': 'Plugin title', 'version': '1.2.3', 'homepage': 'url', 'name': 'plugin_name-1.2', 'year': '2014', 'preinstall_hook': 'echo preinst', 'postinstall_hook': 'echo postinst', 'uninstall_hook': 'echo uninst', 'build_version': '1'}) def test_make_package_with_build_version(self): meta = { 'releases': BaseBuild.releases, 'version': '1.2.3', 'name': 'plugin_name', 'title': 'Plugin title', 'description': 'Description', 'licenses': ['Apache', 'BSD'], 'authors': ['author1', 'author2'], 'homepage': 'url', 'build_version': '34' } self.builder = self.create_builder(self.plugin_path, meta=meta) utils_mock = self._test_make_package() spec_src = os.path.abspath(join_path( os.path.dirname(__file__), '..', self.builder.rpm_spec_src_path)) utils_mock.render_to_file.assert_called_once_with( spec_src, join_path(self.plugin_path, '.build/rpm/plugin_rpm.spec'), {'vendor': 'author1, author2', 'description': 'Description', 'license': 'Apache and BSD', 'summary': 'Plugin title', 'version': '1.2.3', 'homepage': 'url', 'name': 'plugin_name-1.2', 'year': '2014', 'preinstall_hook': 'echo preinst', 'postinstall_hook': 'echo postinst', 'uninstall_hook': 'echo uninst', 'build_version': '34'})